Fix encoding of MarshalJSON of function type

This commit is contained in:
Masaaki Goshima 2021-03-22 21:29:16 +09:00
parent 6128c69078
commit 2bda5ef91f
8 changed files with 108 additions and 72 deletions

View File

@ -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())
}
}
}
}
})
}
}

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {