mirror of https://github.com/goccy/go-json.git
Merge pull request #162 from goccy/feature/fix-marshaler
Fix encoding of MarshalJSON of function type
This commit is contained in:
commit
9903d614e3
|
@ -39,6 +39,16 @@ func (c *coverPtrMarshalJSONString) MarshalJSON() ([]byte, error) {
|
||||||
return []byte(c.C), nil
|
return []byte(c.C), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type coverFuncMarshalJSON func()
|
||||||
|
|
||||||
|
func (f coverFuncMarshalJSON) MarshalJSON() ([]byte, error) {
|
||||||
|
if f == nil {
|
||||||
|
return []byte(`null`), nil
|
||||||
|
}
|
||||||
|
f()
|
||||||
|
return []byte(`"func"`), nil
|
||||||
|
}
|
||||||
|
|
||||||
func TestCoverMarshalJSON(t *testing.T) {
|
func TestCoverMarshalJSON(t *testing.T) {
|
||||||
type structMarshalJSON struct {
|
type structMarshalJSON struct {
|
||||||
A coverMarshalJSON `json:"a"`
|
A coverMarshalJSON `json:"a"`
|
||||||
|
@ -82,6 +92,31 @@ func TestCoverMarshalJSON(t *testing.T) {
|
||||||
name string
|
name string
|
||||||
data interface{}
|
data interface{}
|
||||||
}{
|
}{
|
||||||
|
{
|
||||||
|
name: "FuncMarshalJSON",
|
||||||
|
data: coverFuncMarshalJSON(func() {}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "StructFuncMarshalJSON",
|
||||||
|
data: struct {
|
||||||
|
A coverFuncMarshalJSON
|
||||||
|
}{A: func() {}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "StructFuncMarshalJSONMultiFields",
|
||||||
|
data: struct {
|
||||||
|
A coverFuncMarshalJSON
|
||||||
|
B coverFuncMarshalJSON
|
||||||
|
}{A: func() {}, B: func() {}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrStructFuncMarshalJSONMultiFields",
|
||||||
|
data: &struct {
|
||||||
|
A coverFuncMarshalJSON
|
||||||
|
B coverFuncMarshalJSON
|
||||||
|
C coverFuncMarshalJSON
|
||||||
|
}{A: func() {}, B: nil, C: func() {}},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "MarshalJSON",
|
name: "MarshalJSON",
|
||||||
data: coverMarshalJSON{A: 1},
|
data: coverMarshalJSON{A: 1},
|
||||||
|
@ -3652,6 +3687,7 @@ func TestCoverMarshalJSON(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
for _, indent := range []bool{true, false} {
|
for _, indent := range []bool{true, false} {
|
||||||
for _, htmlEscape := range []bool{true, false} {
|
for _, htmlEscape := range []bool{true, false} {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
@ -3669,5 +3705,6 @@ func TestCoverMarshalJSON(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -506,6 +506,7 @@ func compileMarshalJSON(ctx *compileContext) (*Opcode, error) {
|
||||||
if !typ.Implements(marshalJSONType) && runtime.PtrTo(typ).Implements(marshalJSONType) {
|
if !typ.Implements(marshalJSONType) && runtime.PtrTo(typ).Implements(marshalJSONType) {
|
||||||
code.AddrForMarshaler = true
|
code.AddrForMarshaler = true
|
||||||
}
|
}
|
||||||
|
code.IsNilableType = isNilableType(typ)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
return code, nil
|
return code, nil
|
||||||
}
|
}
|
||||||
|
@ -516,6 +517,7 @@ func compileMarshalText(ctx *compileContext) (*Opcode, error) {
|
||||||
if !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType) {
|
if !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType) {
|
||||||
code.AddrForMarshaler = true
|
code.AddrForMarshaler = true
|
||||||
}
|
}
|
||||||
|
code.IsNilableType = isNilableType(typ)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
return code, nil
|
return code, nil
|
||||||
}
|
}
|
||||||
|
@ -1274,12 +1276,10 @@ func isNilableType(typ *runtime.Type) bool {
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
return true
|
return true
|
||||||
case reflect.Interface:
|
|
||||||
return true
|
|
||||||
case reflect.Slice:
|
|
||||||
return true
|
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
return true
|
return true
|
||||||
|
case reflect.Func:
|
||||||
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -1418,6 +1418,7 @@ func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) {
|
||||||
Nilcheck: nilcheck,
|
Nilcheck: nilcheck,
|
||||||
AddrForMarshaler: addrForMarshaler,
|
AddrForMarshaler: addrForMarshaler,
|
||||||
IsNextOpPtrType: strings.Contains(valueCode.Op.String(), "Ptr"),
|
IsNextOpPtrType: strings.Contains(valueCode.Op.String(), "Ptr"),
|
||||||
|
IsNilableType: isNilableType,
|
||||||
}
|
}
|
||||||
if fieldIdx == 0 {
|
if fieldIdx == 0 {
|
||||||
fieldCode.HeadIdx = fieldCode.Idx
|
fieldCode.HeadIdx = fieldCode.Idx
|
||||||
|
|
|
@ -559,7 +559,7 @@ func AppendIndent(ctx *RuntimeContext, b []byte, indent int) []byte {
|
||||||
func IsNilForMarshaler(v interface{}) bool {
|
func IsNilForMarshaler(v interface{}) bool {
|
||||||
rv := reflect.ValueOf(v)
|
rv := reflect.ValueOf(v)
|
||||||
switch rv.Kind() {
|
switch rv.Kind() {
|
||||||
case reflect.Interface, reflect.Map, reflect.Ptr:
|
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Func:
|
||||||
return rv.IsNil()
|
return rv.IsNil()
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
return rv.IsNil() || rv.Len() == 0
|
return rv.IsNil() || rv.Len() == 0
|
||||||
|
|
|
@ -26,6 +26,7 @@ type Opcode struct {
|
||||||
Nilcheck bool // whether needs to nilcheck or not
|
Nilcheck bool // whether needs to nilcheck or not
|
||||||
AddrForMarshaler bool // whether needs to addr for marshaler or not
|
AddrForMarshaler bool // whether needs to addr for marshaler or not
|
||||||
IsNextOpPtrType bool // whether next operation is ptr type or not
|
IsNextOpPtrType bool // whether next operation is ptr type or not
|
||||||
|
IsNilableType bool // whether type is nilable or not
|
||||||
RshiftNum uint8 // use to take bit for judging whether negative integer or not
|
RshiftNum uint8 // use to take bit for judging whether negative integer or not
|
||||||
Mask uint64 // mask for number
|
Mask uint64 // mask for number
|
||||||
Indent int // indent number
|
Indent int // indent number
|
||||||
|
@ -242,6 +243,7 @@ func (c *Opcode) copy(codeMap map[uintptr]*Opcode) *Opcode {
|
||||||
Nilcheck: c.Nilcheck,
|
Nilcheck: c.Nilcheck,
|
||||||
AddrForMarshaler: c.AddrForMarshaler,
|
AddrForMarshaler: c.AddrForMarshaler,
|
||||||
IsNextOpPtrType: c.IsNextOpPtrType,
|
IsNextOpPtrType: c.IsNextOpPtrType,
|
||||||
|
IsNilableType: c.IsNilableType,
|
||||||
Indent: c.Indent,
|
Indent: c.Indent,
|
||||||
Idx: c.Idx,
|
Idx: c.Idx,
|
||||||
HeadIdx: c.HeadIdx,
|
HeadIdx: c.HeadIdx,
|
||||||
|
|
|
@ -3,7 +3,6 @@ package vm
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
@ -271,7 +270,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
code = code.Next
|
code = code.Next
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
if code.IsNilableType && code.Indirect {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
bb, err := appendMarshalJSON(code, b, ptrToInterface(code, p), false)
|
bb, err := appendMarshalJSON(code, b, ptrToInterface(code, p), false)
|
||||||
|
@ -298,7 +297,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
code = code.Next
|
code = code.Next
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
if code.IsNilableType && code.Indirect {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
bb, err := appendMarshalText(code, b, ptrToInterface(code, p), false)
|
bb, err := appendMarshalText(code, b, ptrToInterface(code, p), false)
|
||||||
|
@ -2711,7 +2710,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2755,7 +2754,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2798,7 +2797,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
if !code.AnonymousHead {
|
if !code.AnonymousHead {
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2924,7 +2923,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2968,7 +2967,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3011,7 +3010,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
if !code.AnonymousHead {
|
if !code.AnonymousHead {
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3623,7 +3622,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3640,7 +3639,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3685,7 +3684,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3702,7 +3701,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
case encoder.OpStructFieldOmitEmptyMarshalText:
|
case encoder.OpStructFieldOmitEmptyMarshalText:
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
|
|
@ -3,7 +3,6 @@ package vm_escaped
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
@ -271,7 +270,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
code = code.Next
|
code = code.Next
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
if code.IsNilableType && code.Indirect {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
bb, err := appendMarshalJSON(code, b, ptrToInterface(code, p), true)
|
bb, err := appendMarshalJSON(code, b, ptrToInterface(code, p), true)
|
||||||
|
@ -298,7 +297,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
code = code.Next
|
code = code.Next
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
if code.IsNilableType && code.Indirect {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
bb, err := appendMarshalText(code, b, ptrToInterface(code, p), true)
|
bb, err := appendMarshalText(code, b, ptrToInterface(code, p), true)
|
||||||
|
@ -2711,7 +2710,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2755,7 +2754,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2798,7 +2797,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
if !code.AnonymousHead {
|
if !code.AnonymousHead {
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2924,7 +2923,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2968,7 +2967,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3011,7 +3010,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
if !code.AnonymousHead {
|
if !code.AnonymousHead {
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3623,7 +3622,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3640,7 +3639,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3685,7 +3684,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3702,7 +3701,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
case encoder.OpStructFieldOmitEmptyMarshalText:
|
case encoder.OpStructFieldOmitEmptyMarshalText:
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
@ -269,7 +268,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
code = code.Next
|
code = code.Next
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
if code.IsNilableType && code.Indirect {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p), code.Indent, true)
|
bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p), code.Indent, true)
|
||||||
|
@ -296,7 +295,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
code = code.Next
|
code = code.Next
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
if code.IsNilableType && code.Indirect {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
bb, err := appendMarshalText(code, b, ptrToInterface(code, p), true)
|
bb, err := appendMarshalText(code, b, ptrToInterface(code, p), true)
|
||||||
|
@ -2844,7 +2843,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = appendIndent(ctx, b, code.Indent+1)
|
b = appendIndent(ctx, b, code.Indent+1)
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2890,7 +2889,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = appendIndent(ctx, b, code.Indent+1)
|
b = appendIndent(ctx, b, code.Indent+1)
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2933,7 +2932,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
if !code.AnonymousHead {
|
if !code.AnonymousHead {
|
||||||
b = append(b, '{', '\n')
|
b = append(b, '{', '\n')
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3067,7 +3066,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = appendIndent(ctx, b, code.Indent+1)
|
b = appendIndent(ctx, b, code.Indent+1)
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3113,7 +3112,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = appendIndent(ctx, b, code.Indent+1)
|
b = appendIndent(ctx, b, code.Indent+1)
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3156,7 +3155,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
if !code.AnonymousHead {
|
if !code.AnonymousHead {
|
||||||
b = append(b, '{', '\n')
|
b = append(b, '{', '\n')
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3870,7 +3869,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3887,7 +3886,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3940,7 +3939,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, code.EscapedKey...)
|
b = append(b, code.EscapedKey...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3957,7 +3956,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
case encoder.OpStructFieldOmitEmptyMarshalText:
|
case encoder.OpStructFieldOmitEmptyMarshalText:
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
@ -275,7 +274,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
code = code.Next
|
code = code.Next
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
if code.IsNilableType && code.Indirect {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p), code.Indent, false)
|
bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p), code.Indent, false)
|
||||||
|
@ -302,7 +301,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
code = code.Next
|
code = code.Next
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
if code.IsNilableType && code.Indirect {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
bb, err := appendMarshalText(code, b, ptrToInterface(code, p), false)
|
bb, err := appendMarshalText(code, b, ptrToInterface(code, p), false)
|
||||||
|
@ -2850,7 +2849,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = appendIndent(ctx, b, code.Indent+1)
|
b = appendIndent(ctx, b, code.Indent+1)
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2896,7 +2895,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = appendIndent(ctx, b, code.Indent+1)
|
b = appendIndent(ctx, b, code.Indent+1)
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -2939,7 +2938,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
if !code.AnonymousHead {
|
if !code.AnonymousHead {
|
||||||
b = append(b, '{', '\n')
|
b = append(b, '{', '\n')
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3073,7 +3072,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = appendIndent(ctx, b, code.Indent+1)
|
b = appendIndent(ctx, b, code.Indent+1)
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3119,7 +3118,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = appendIndent(ctx, b, code.Indent+1)
|
b = appendIndent(ctx, b, code.Indent+1)
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3162,7 +3161,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
if !code.AnonymousHead {
|
if !code.AnonymousHead {
|
||||||
b = append(b, '{', '\n')
|
b = append(b, '{', '\n')
|
||||||
}
|
}
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
||||||
p = ptrToPtr(p + code.Offset)
|
p = ptrToPtr(p + code.Offset)
|
||||||
}
|
}
|
||||||
|
@ -3876,7 +3875,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3893,7 +3892,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3946,7 +3945,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
b = append(b, code.Key...)
|
b = append(b, code.Key...)
|
||||||
b = append(b, ' ')
|
b = append(b, ' ')
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
@ -3963,7 +3962,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
||||||
case encoder.OpStructFieldOmitEmptyMarshalText:
|
case encoder.OpStructFieldOmitEmptyMarshalText:
|
||||||
p := load(ctxptr, code.HeadIdx)
|
p := load(ctxptr, code.HeadIdx)
|
||||||
p += code.Offset
|
p += code.Offset
|
||||||
if code.Type.Kind() == reflect.Ptr {
|
if code.IsNilableType {
|
||||||
p = ptrToPtr(p)
|
p = ptrToPtr(p)
|
||||||
}
|
}
|
||||||
if p == 0 && code.Nilcheck {
|
if p == 0 && code.Nilcheck {
|
||||||
|
|
Loading…
Reference in New Issue