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
|
||||
}
|
||||
|
||||
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) {
|
||||
type structMarshalJSON struct {
|
||||
A coverMarshalJSON `json:"a"`
|
||||
|
@ -82,6 +92,31 @@ func TestCoverMarshalJSON(t *testing.T) {
|
|||
name string
|
||||
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",
|
||||
data: coverMarshalJSON{A: 1},
|
||||
|
@ -3652,22 +3687,24 @@ func TestCoverMarshalJSON(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
for _, indent := range []bool{true, false} {
|
||||
for _, htmlEscape := range []bool{true, false} {
|
||||
var buf bytes.Buffer
|
||||
enc := json.NewEncoder(&buf)
|
||||
enc.SetEscapeHTML(htmlEscape)
|
||||
if indent {
|
||||
enc.SetIndent("", " ")
|
||||
}
|
||||
if err := enc.Encode(test.data); err != nil {
|
||||
t.Fatalf("%s(htmlEscape:%v,indent:%v): %+v: %s", test.name, htmlEscape, indent, test.data, err)
|
||||
}
|
||||
stdresult := encodeByEncodingJSON(test.data, indent, htmlEscape)
|
||||
if buf.String() != stdresult {
|
||||
t.Errorf("%s(htmlEscape:%v,indent:%v): doesn't compatible with encoding/json. expected %q but got %q", test.name, htmlEscape, indent, stdresult, buf.String())
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
for _, indent := range []bool{true, false} {
|
||||
for _, htmlEscape := range []bool{true, false} {
|
||||
var buf bytes.Buffer
|
||||
enc := json.NewEncoder(&buf)
|
||||
enc.SetEscapeHTML(htmlEscape)
|
||||
if indent {
|
||||
enc.SetIndent("", " ")
|
||||
}
|
||||
if err := enc.Encode(test.data); err != nil {
|
||||
t.Fatalf("%s(htmlEscape:%v,indent:%v): %+v: %s", test.name, htmlEscape, indent, test.data, err)
|
||||
}
|
||||
stdresult := encodeByEncodingJSON(test.data, indent, htmlEscape)
|
||||
if buf.String() != stdresult {
|
||||
t.Errorf("%s(htmlEscape:%v,indent:%v): doesn't compatible with encoding/json. expected %q but got %q", test.name, htmlEscape, indent, stdresult, buf.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -506,6 +506,7 @@ func compileMarshalJSON(ctx *compileContext) (*Opcode, error) {
|
|||
if !typ.Implements(marshalJSONType) && runtime.PtrTo(typ).Implements(marshalJSONType) {
|
||||
code.AddrForMarshaler = true
|
||||
}
|
||||
code.IsNilableType = isNilableType(typ)
|
||||
ctx.incIndex()
|
||||
return code, nil
|
||||
}
|
||||
|
@ -516,6 +517,7 @@ func compileMarshalText(ctx *compileContext) (*Opcode, error) {
|
|||
if !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType) {
|
||||
code.AddrForMarshaler = true
|
||||
}
|
||||
code.IsNilableType = isNilableType(typ)
|
||||
ctx.incIndex()
|
||||
return code, nil
|
||||
}
|
||||
|
@ -1274,12 +1276,10 @@ func isNilableType(typ *runtime.Type) bool {
|
|||
switch typ.Kind() {
|
||||
case reflect.Ptr:
|
||||
return true
|
||||
case reflect.Interface:
|
||||
return true
|
||||
case reflect.Slice:
|
||||
return true
|
||||
case reflect.Map:
|
||||
return true
|
||||
case reflect.Func:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
@ -1418,6 +1418,7 @@ func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) {
|
|||
Nilcheck: nilcheck,
|
||||
AddrForMarshaler: addrForMarshaler,
|
||||
IsNextOpPtrType: strings.Contains(valueCode.Op.String(), "Ptr"),
|
||||
IsNilableType: isNilableType,
|
||||
}
|
||||
if fieldIdx == 0 {
|
||||
fieldCode.HeadIdx = fieldCode.Idx
|
||||
|
|
|
@ -559,7 +559,7 @@ func AppendIndent(ctx *RuntimeContext, b []byte, indent int) []byte {
|
|||
func IsNilForMarshaler(v interface{}) bool {
|
||||
rv := reflect.ValueOf(v)
|
||||
switch rv.Kind() {
|
||||
case reflect.Interface, reflect.Map, reflect.Ptr:
|
||||
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Func:
|
||||
return rv.IsNil()
|
||||
case reflect.Slice:
|
||||
return rv.IsNil() || rv.Len() == 0
|
||||
|
|
|
@ -26,6 +26,7 @@ type Opcode struct {
|
|||
Nilcheck bool // whether needs to nilcheck or not
|
||||
AddrForMarshaler bool // whether needs to addr for marshaler 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
|
||||
Mask uint64 // mask for number
|
||||
Indent int // indent number
|
||||
|
@ -242,6 +243,7 @@ func (c *Opcode) copy(codeMap map[uintptr]*Opcode) *Opcode {
|
|||
Nilcheck: c.Nilcheck,
|
||||
AddrForMarshaler: c.AddrForMarshaler,
|
||||
IsNextOpPtrType: c.IsNextOpPtrType,
|
||||
IsNilableType: c.IsNilableType,
|
||||
Indent: c.Indent,
|
||||
Idx: c.Idx,
|
||||
HeadIdx: c.HeadIdx,
|
||||
|
|
|
@ -3,7 +3,6 @@ package vm
|
|||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"unsafe"
|
||||
|
||||
|
@ -271,7 +270,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
code = code.Next
|
||||
break
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
||||
if code.IsNilableType && code.Indirect {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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
|
||||
break
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
||||
if code.IsNilableType && code.Indirect {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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, code.Key...)
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
||||
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, code.Key...)
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -2798,7 +2797,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
if !code.AnonymousHead {
|
||||
b = append(b, '{')
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
||||
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, code.Key...)
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
||||
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, code.Key...)
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -3011,7 +3010,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
if !code.AnonymousHead {
|
||||
b = append(b, '{')
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
||||
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)
|
||||
b = append(b, code.Key...)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
@ -3640,7 +3639,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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)
|
||||
b = append(b, code.Key...)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
@ -3702,7 +3701,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
case encoder.OpStructFieldOmitEmptyMarshalText:
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
|
|
@ -3,7 +3,6 @@ package vm_escaped
|
|||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"unsafe"
|
||||
|
||||
|
@ -271,7 +270,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
code = code.Next
|
||||
break
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
||||
if code.IsNilableType && code.Indirect {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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
|
||||
break
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
||||
if code.IsNilableType && code.Indirect {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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, code.EscapedKey...)
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
||||
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, code.EscapedKey...)
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -2798,7 +2797,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
if !code.AnonymousHead {
|
||||
b = append(b, '{')
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
||||
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, code.EscapedKey...)
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
||||
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, code.EscapedKey...)
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -3011,7 +3010,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
if !code.AnonymousHead {
|
||||
b = append(b, '{')
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
||||
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)
|
||||
b = append(b, code.EscapedKey...)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
@ -3640,7 +3639,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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)
|
||||
b = append(b, code.EscapedKey...)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
@ -3702,7 +3701,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
case encoder.OpStructFieldOmitEmptyMarshalText:
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"unsafe"
|
||||
|
||||
|
@ -269,7 +268,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
code = code.Next
|
||||
break
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
||||
if code.IsNilableType && code.Indirect {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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
|
||||
break
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
||||
if code.IsNilableType && code.Indirect {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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 = append(b, code.EscapedKey...)
|
||||
b = append(b, ' ')
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
||||
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 = append(b, code.EscapedKey...)
|
||||
b = append(b, ' ')
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -2933,7 +2932,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
if !code.AnonymousHead {
|
||||
b = append(b, '{', '\n')
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
||||
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 = append(b, code.EscapedKey...)
|
||||
b = append(b, ' ')
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
||||
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 = append(b, code.EscapedKey...)
|
||||
b = append(b, ' ')
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -3156,7 +3155,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
if !code.AnonymousHead {
|
||||
b = append(b, '{', '\n')
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -3870,7 +3869,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
b = append(b, ' ')
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
@ -3887,7 +3886,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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, ' ')
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
@ -3957,7 +3956,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
case encoder.OpStructFieldOmitEmptyMarshalText:
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"unsafe"
|
||||
|
||||
|
@ -275,7 +274,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
code = code.Next
|
||||
break
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
||||
if code.IsNilableType && code.Indirect {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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
|
||||
break
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr && code.Indirect {
|
||||
if code.IsNilableType && code.Indirect {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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 = append(b, code.Key...)
|
||||
b = append(b, ' ')
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalJSON {
|
||||
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 = append(b, code.Key...)
|
||||
b = append(b, ' ')
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalJSON {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -2939,7 +2938,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
if !code.AnonymousHead {
|
||||
b = append(b, '{', '\n')
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
|
||||
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 = append(b, code.Key...)
|
||||
b = append(b, ' ')
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadMarshalText {
|
||||
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 = append(b, code.Key...)
|
||||
b = append(b, ' ')
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadStringTagMarshalText {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -3162,7 +3161,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
if !code.AnonymousHead {
|
||||
b = append(b, '{', '\n')
|
||||
}
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
if code.Indirect || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
|
||||
p = ptrToPtr(p + code.Offset)
|
||||
}
|
||||
|
@ -3876,7 +3875,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
b = append(b, ' ')
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
@ -3893,7 +3892,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
case encoder.OpStructFieldOmitEmptyMarshalJSON:
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
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, ' ')
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
@ -3963,7 +3962,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
|
|||
case encoder.OpStructFieldOmitEmptyMarshalText:
|
||||
p := load(ctxptr, code.HeadIdx)
|
||||
p += code.Offset
|
||||
if code.Type.Kind() == reflect.Ptr {
|
||||
if code.IsNilableType {
|
||||
p = ptrToPtr(p)
|
||||
}
|
||||
if p == 0 && code.Nilcheck {
|
||||
|
|
Loading…
Reference in New Issue