forked from mirror/go-json
Add only type
This commit is contained in:
parent
058b3ae1ea
commit
8411c9142c
296
coverage_test.go
296
coverage_test.go
|
@ -14,6 +14,27 @@ func int8ptr(v int8) *int8 {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func headIntPtrNilNotRoot() interface{} {
|
||||||
|
v := struct {
|
||||||
|
A struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}
|
||||||
|
}{}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrHeadIntNotRoot() interface{} {
|
||||||
|
v := struct {
|
||||||
|
A *struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
}
|
||||||
|
}{A: new(struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
})}
|
||||||
|
v.A.A = 1
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
func TestCoverage(t *testing.T) {
|
func TestCoverage(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -21,44 +42,78 @@ func TestCoverage(t *testing.T) {
|
||||||
data interface{}
|
data interface{}
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "IntHead",
|
name: "HeadIntZero",
|
||||||
|
expected: `{"a":0}`,
|
||||||
|
data: struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadInt",
|
||||||
expected: `{"a":1}`,
|
expected: `{"a":1}`,
|
||||||
data: struct {
|
data: struct {
|
||||||
A int `json:"a"`
|
A int `json:"a"`
|
||||||
}{A: 1},
|
}{A: 1},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "IntPtrHead",
|
name: "HeadIntPtr",
|
||||||
expected: `{"a":1}`,
|
expected: `{"a":1}`,
|
||||||
data: struct {
|
data: struct {
|
||||||
A *int `json:"a"`
|
A *int `json:"a"`
|
||||||
}{A: intptr(1)},
|
}{A: intptr(1)},
|
||||||
},
|
},
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
name: "IntPtrNilHead",
|
name: "HeadIntPtrNil",
|
||||||
expected: `{"a":null}`,
|
expected: `{"a":null}`,
|
||||||
data: struct {
|
data: struct {
|
||||||
A *int `json:"a"`
|
A *int `json:"a"`
|
||||||
}{A: nil},
|
}{A: nil},
|
||||||
},
|
},
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
name: "PtrIntHead",
|
name: "PtrHeadIntZero",
|
||||||
|
expected: `{"a":0}`,
|
||||||
|
data: &struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadInt",
|
||||||
expected: `{"a":1}`,
|
expected: `{"a":1}`,
|
||||||
data: &struct {
|
data: &struct {
|
||||||
A int `json:"a"`
|
A int `json:"a"`
|
||||||
}{A: 1},
|
}{A: 1},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "PtrIntPtrHead",
|
name: "PtrHeadIntPtr",
|
||||||
expected: `{"a":1}`,
|
expected: `{"a":1}`,
|
||||||
data: &struct {
|
data: &struct {
|
||||||
A *int `json:"a"`
|
A *int `json:"a"`
|
||||||
}{A: intptr(1)},
|
}{A: intptr(1)},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "IntField",
|
name: "PtrHeadIntPtrNil",
|
||||||
|
expected: `{"a":null}`,
|
||||||
|
data: &struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}{A: nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntNil",
|
||||||
|
expected: `null`,
|
||||||
|
data: (*struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
})(nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntZeroMultiFields",
|
||||||
|
expected: `{"a":0,"b":0}`,
|
||||||
|
data: struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntMultiFields",
|
||||||
expected: `{"a":1,"b":2}`,
|
expected: `{"a":1,"b":2}`,
|
||||||
data: struct {
|
data: struct {
|
||||||
A int `json:"a"`
|
A int `json:"a"`
|
||||||
|
@ -66,13 +121,232 @@ func TestCoverage(t *testing.T) {
|
||||||
}{A: 1, B: 2},
|
}{A: 1, B: 2},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "IntPtrField",
|
name: "HeadIntPtrMultiFields",
|
||||||
expected: `{"a":1,"b":2}`,
|
expected: `{"a":1,"b":2}`,
|
||||||
data: struct {
|
data: struct {
|
||||||
A *int `json:"a"`
|
A *int `json:"a"`
|
||||||
B *int `json:"b"`
|
B *int `json:"b"`
|
||||||
}{A: intptr(1), B: intptr(2)},
|
}{A: intptr(1), B: intptr(2)},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntPtrNilMultiFieldsd",
|
||||||
|
expected: `{"a":null,"b":null}`,
|
||||||
|
data: struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
B *int `json:"b"`
|
||||||
|
}{A: nil, B: nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntZeroMultiFields",
|
||||||
|
expected: `{"a":0,"b":0}`,
|
||||||
|
data: &struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntMultiFields",
|
||||||
|
expected: `{"a":1,"b":2}`,
|
||||||
|
data: &struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}{A: 1, B: 2},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntPtrMultiFields",
|
||||||
|
expected: `{"a":1,"b":2}`,
|
||||||
|
data: &struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
B *int `json:"b"`
|
||||||
|
}{A: intptr(1), B: intptr(2)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntPtrNilMultiFields",
|
||||||
|
expected: `{"a":null,"b":null}`,
|
||||||
|
data: &struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
B *int `json:"b"`
|
||||||
|
}{A: nil, B: nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntNilMultiFields",
|
||||||
|
expected: `null`,
|
||||||
|
data: (*struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
B *int `json:"b"`
|
||||||
|
})(nil),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "HeadIntZeroNotRoot",
|
||||||
|
expected: `{"A":{"a":0}}`,
|
||||||
|
data: struct {
|
||||||
|
A struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
}
|
||||||
|
}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntNotRoot",
|
||||||
|
expected: `{"A":{"a":1}}`,
|
||||||
|
data: struct {
|
||||||
|
A struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
}
|
||||||
|
}{A: struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
}{A: 1}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntPtrNotRoot",
|
||||||
|
expected: `{"A":{"a":1}}`,
|
||||||
|
data: struct {
|
||||||
|
A struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}
|
||||||
|
}{A: struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}{intptr(1)}},
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
name: "HeadIntPtrNilNotRoot",
|
||||||
|
expected: `{"A":{"a":null}}`,
|
||||||
|
data: struct {
|
||||||
|
A struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}
|
||||||
|
}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntZeroNotRoot",
|
||||||
|
expected: `{"A":{"a":0}}`,
|
||||||
|
data: struct {
|
||||||
|
A *struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
}
|
||||||
|
}{A: new(struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
})},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntNotRoot",
|
||||||
|
expected: `{"A":{"a":1}}`,
|
||||||
|
data: struct {
|
||||||
|
A *struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
}
|
||||||
|
}{A: &(struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
}{A: 1})},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntPtrNotRoot",
|
||||||
|
expected: `{"A":{"a":1}}`,
|
||||||
|
data: struct {
|
||||||
|
A *struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}
|
||||||
|
}{A: &(struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}{A: intptr(1)})},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntPtrNilNotRoot",
|
||||||
|
expected: `{"A":{"a":null}}`,
|
||||||
|
data: struct {
|
||||||
|
A *struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}
|
||||||
|
}{A: &(struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}{A: nil})},
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntNilNotRoot",
|
||||||
|
expected: `{"A":null}`,
|
||||||
|
data: struct {
|
||||||
|
A *struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
}
|
||||||
|
}{A: nil},
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
name: "HeadIntZeroMultiFields",
|
||||||
|
expected: `{"a":0,"b":0}`,
|
||||||
|
data: struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntMultiFields",
|
||||||
|
expected: `{"a":1,"b":2}`,
|
||||||
|
data: struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}{A: 1, B: 2},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntPtrMultiFields",
|
||||||
|
expected: `{"a":1,"b":2}`,
|
||||||
|
data: struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
B *int `json:"b"`
|
||||||
|
}{A: intptr(1), B: intptr(2)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntPtrNilMultiFieldsd",
|
||||||
|
expected: `{"a":null,"b":null}`,
|
||||||
|
data: struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
B *int `json:"b"`
|
||||||
|
}{A: nil, B: nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntZeroMultiFields",
|
||||||
|
expected: `{"a":0,"b":0}`,
|
||||||
|
data: &struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntMultiFields",
|
||||||
|
expected: `{"a":1,"b":2}`,
|
||||||
|
data: &struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}{A: 1, B: 2},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntPtrMultiFields",
|
||||||
|
expected: `{"a":1,"b":2}`,
|
||||||
|
data: &struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
B *int `json:"b"`
|
||||||
|
}{A: intptr(1), B: intptr(2)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntPtrNilMultiFields",
|
||||||
|
expected: `{"a":null,"b":null}`,
|
||||||
|
data: &struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
B *int `json:"b"`
|
||||||
|
}{A: nil, B: nil},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntNilMultiFields",
|
||||||
|
expected: `null`,
|
||||||
|
data: (*struct {
|
||||||
|
A *int `json:"a"`
|
||||||
|
B *int `json:"b"`
|
||||||
|
})(nil),
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "Int8Head",
|
name: "Int8Head",
|
||||||
expected: `{"a":1}`,
|
expected: `{"a":1}`,
|
||||||
|
@ -133,10 +407,10 @@ func TestCoverage(t *testing.T) {
|
||||||
enc := NewEncoder(&buf)
|
enc := NewEncoder(&buf)
|
||||||
enc.SetEscapeHTML(htmlEscape)
|
enc.SetEscapeHTML(htmlEscape)
|
||||||
if err := enc.Encode(test.data); err != nil {
|
if err := enc.Encode(test.data); err != nil {
|
||||||
t.Fatalf("%s(htmlEscape:%T): %s: %s", test.name, htmlEscape, test.expected, err)
|
t.Errorf("%s(htmlEscape:%T): %s: %s", test.name, htmlEscape, test.expected, err)
|
||||||
}
|
}
|
||||||
if strings.TrimRight(buf.String(), "\n") != test.expected {
|
if strings.TrimRight(buf.String(), "\n") != test.expected {
|
||||||
t.Fatalf("%s(htmlEscape:%T): expected %q but got %q", test.name, htmlEscape, test.expected, buf.String())
|
t.Errorf("%s(htmlEscape:%T): expected %q but got %q", test.name, htmlEscape, test.expected, buf.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -536,7 +536,131 @@ func (e *Encoder) compileMap(ctx *encodeCompileContext, withLoad bool) (*opcode,
|
||||||
return (*opcode)(unsafe.Pointer(header)), nil
|
return (*opcode)(unsafe.Pointer(header)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) typeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
|
func (e *Encoder) typeToHeaderType(ctx *encodeCompileContext, code *opcode, isOnlyPtrField bool) opType {
|
||||||
|
if isOnlyPtrField {
|
||||||
|
// 1. pointer struct + primitive type field
|
||||||
|
// 2. struct + primitive pointer type field
|
||||||
|
switch code.op {
|
||||||
|
case opPtr:
|
||||||
|
ptrNum := 1
|
||||||
|
c := code
|
||||||
|
ctx.decIndex()
|
||||||
|
for {
|
||||||
|
if code.next.op == opPtr {
|
||||||
|
ptrNum++
|
||||||
|
code = code.next
|
||||||
|
ctx.decIndex()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c.ptrNum = ptrNum
|
||||||
|
if ptrNum > 1 {
|
||||||
|
switch code.next.op {
|
||||||
|
case opInt:
|
||||||
|
return opStructFieldHeadIntNPtrOnly
|
||||||
|
case opInt8:
|
||||||
|
return opStructFieldHeadInt8NPtrOnly
|
||||||
|
case opInt16:
|
||||||
|
return opStructFieldHeadInt16NPtrOnly
|
||||||
|
case opInt32:
|
||||||
|
return opStructFieldHeadInt32NPtrOnly
|
||||||
|
case opInt64:
|
||||||
|
return opStructFieldHeadInt64NPtrOnly
|
||||||
|
case opUint:
|
||||||
|
return opStructFieldHeadUintNPtrOnly
|
||||||
|
case opUint8:
|
||||||
|
return opStructFieldHeadUint8NPtrOnly
|
||||||
|
case opUint16:
|
||||||
|
return opStructFieldHeadUint16NPtrOnly
|
||||||
|
case opUint32:
|
||||||
|
return opStructFieldHeadUint32NPtrOnly
|
||||||
|
case opUint64:
|
||||||
|
return opStructFieldHeadUint64NPtrOnly
|
||||||
|
case opFloat32:
|
||||||
|
return opStructFieldHeadFloat32NPtrOnly
|
||||||
|
case opFloat64:
|
||||||
|
return opStructFieldHeadFloat64NPtrOnly
|
||||||
|
case opString:
|
||||||
|
return opStructFieldHeadStringNPtrOnly
|
||||||
|
case opBool:
|
||||||
|
return opStructFieldHeadBoolNPtrOnly
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch code.next.op {
|
||||||
|
case opInt:
|
||||||
|
return opStructFieldHeadIntPtrOnly
|
||||||
|
case opInt8:
|
||||||
|
return opStructFieldHeadInt8PtrOnly
|
||||||
|
case opInt16:
|
||||||
|
return opStructFieldHeadInt16PtrOnly
|
||||||
|
case opInt32:
|
||||||
|
return opStructFieldHeadInt32PtrOnly
|
||||||
|
case opInt64:
|
||||||
|
return opStructFieldHeadInt64PtrOnly
|
||||||
|
case opUint:
|
||||||
|
return opStructFieldHeadUintPtrOnly
|
||||||
|
case opUint8:
|
||||||
|
return opStructFieldHeadUint8PtrOnly
|
||||||
|
case opUint16:
|
||||||
|
return opStructFieldHeadUint16PtrOnly
|
||||||
|
case opUint32:
|
||||||
|
return opStructFieldHeadUint32PtrOnly
|
||||||
|
case opUint64:
|
||||||
|
return opStructFieldHeadUint64PtrOnly
|
||||||
|
case opFloat32:
|
||||||
|
return opStructFieldHeadFloat32PtrOnly
|
||||||
|
case opFloat64:
|
||||||
|
return opStructFieldHeadFloat64PtrOnly
|
||||||
|
case opString:
|
||||||
|
return opStructFieldHeadStringPtrOnly
|
||||||
|
case opBool:
|
||||||
|
return opStructFieldHeadBoolPtrOnly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case opInt:
|
||||||
|
return opStructFieldHeadIntOnly
|
||||||
|
case opInt8:
|
||||||
|
return opStructFieldHeadInt8Only
|
||||||
|
case opInt16:
|
||||||
|
return opStructFieldHeadInt16Only
|
||||||
|
case opInt32:
|
||||||
|
return opStructFieldHeadInt32Only
|
||||||
|
case opInt64:
|
||||||
|
return opStructFieldHeadInt64Only
|
||||||
|
case opUint:
|
||||||
|
return opStructFieldHeadUintOnly
|
||||||
|
case opUint8:
|
||||||
|
return opStructFieldHeadUint8Only
|
||||||
|
case opUint16:
|
||||||
|
return opStructFieldHeadUint16Only
|
||||||
|
case opUint32:
|
||||||
|
return opStructFieldHeadUint32Only
|
||||||
|
case opUint64:
|
||||||
|
return opStructFieldHeadUint64Only
|
||||||
|
case opFloat32:
|
||||||
|
return opStructFieldHeadFloat32Only
|
||||||
|
case opFloat64:
|
||||||
|
return opStructFieldHeadFloat64Only
|
||||||
|
case opString:
|
||||||
|
return opStructFieldHeadStringOnly
|
||||||
|
case opBool:
|
||||||
|
return opStructFieldHeadBoolOnly
|
||||||
|
case opMapHead:
|
||||||
|
return opStructFieldHeadMap
|
||||||
|
case opMapHeadLoad:
|
||||||
|
return opStructFieldHeadMapLoad
|
||||||
|
case opArrayHead:
|
||||||
|
return opStructFieldHeadArray
|
||||||
|
case opSliceHead:
|
||||||
|
return opStructFieldHeadSlice
|
||||||
|
case opStructFieldHead:
|
||||||
|
return opStructFieldHeadStruct
|
||||||
|
case opMarshalJSON:
|
||||||
|
return opStructFieldHeadMarshalJSON
|
||||||
|
case opMarshalText:
|
||||||
|
return opStructFieldHeadMarshalText
|
||||||
|
}
|
||||||
|
} else {
|
||||||
switch code.op {
|
switch code.op {
|
||||||
case opPtr:
|
case opPtr:
|
||||||
ptrNum := 1
|
ptrNum := 1
|
||||||
|
@ -657,6 +781,7 @@ func (e *Encoder) typeToHeaderType(ctx *encodeCompileContext, code *opcode) opTy
|
||||||
case opMarshalText:
|
case opMarshalText:
|
||||||
return opStructFieldHeadMarshalText
|
return opStructFieldHeadMarshalText
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return opStructFieldHead
|
return opStructFieldHead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,8 +909,8 @@ func (e *Encoder) typeToFieldType(ctx *encodeCompileContext, code *opcode) opTyp
|
||||||
return opStructField
|
return opStructField
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) optimizeStructHeader(ctx *encodeCompileContext, code *opcode, tag *structTag) opType {
|
func (e *Encoder) optimizeStructHeader(ctx *encodeCompileContext, code *opcode, tag *structTag, isOnlyPtrField bool) opType {
|
||||||
headType := e.typeToHeaderType(ctx, code)
|
headType := e.typeToHeaderType(ctx, code, isOnlyPtrField)
|
||||||
switch {
|
switch {
|
||||||
case tag.isOmitEmpty:
|
case tag.isOmitEmpty:
|
||||||
headType = headType.headToOmitEmptyHead()
|
headType = headType.headToOmitEmptyHead()
|
||||||
|
@ -821,9 +946,9 @@ func (e *Encoder) compiledCode(ctx *encodeCompileContext) *opcode {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode {
|
func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag, isOnlyPtrField bool) *opcode {
|
||||||
fieldCode.indent--
|
fieldCode.indent--
|
||||||
op := e.optimizeStructHeader(ctx, valueCode, tag)
|
op := e.optimizeStructHeader(ctx, valueCode, tag, isOnlyPtrField)
|
||||||
fieldCode.op = op
|
fieldCode.op = op
|
||||||
fieldCode.ptrNum = valueCode.ptrNum
|
fieldCode.ptrNum = valueCode.ptrNum
|
||||||
switch op {
|
switch op {
|
||||||
|
@ -1103,17 +1228,10 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if fieldNum == 1 && valueCode.op == opPtr && !isPtr {
|
|
||||||
// if field number is one and primitive pointer type,
|
// if field number is one and primitive pointer type,
|
||||||
// it should encode as **not** pointer .
|
// it should encode as special opcode.
|
||||||
switch valueCode.next.op {
|
isOnlyPtrField := fieldNum == 1 && (valueCode.op == opPtr && !isPtr || valueCode.op != opPtr && isPtr)
|
||||||
case opInt, opInt8, opInt16, opInt32, opInt64,
|
|
||||||
opUint, opUint8, opUint16, opUint32, opUint64,
|
|
||||||
opFloat32, opFloat64, opBool, opString, opBytes:
|
|
||||||
valueCode = valueCode.next
|
|
||||||
ctx.decOpcodeIndex()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key := fmt.Sprintf(`"%s":`, tag.key)
|
key := fmt.Sprintf(`"%s":`, tag.key)
|
||||||
escapedKey := fmt.Sprintf(`%s:`, string(encodeEscapedString([]byte{}, tag.key)))
|
escapedKey := fmt.Sprintf(`%s:`, string(encodeEscapedString([]byte{}, tag.key)))
|
||||||
fieldCode := &opcode{
|
fieldCode := &opcode{
|
||||||
|
@ -1131,7 +1249,7 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
}
|
}
|
||||||
if fieldIdx == 0 {
|
if fieldIdx == 0 {
|
||||||
fieldCode.headIdx = fieldCode.idx
|
fieldCode.headIdx = fieldCode.idx
|
||||||
code = e.structHeader(ctx, fieldCode, valueCode, tag)
|
code = e.structHeader(ctx, fieldCode, valueCode, tag, isOnlyPtrField)
|
||||||
head = fieldCode
|
head = fieldCode
|
||||||
prevField = fieldCode
|
prevField = fieldCode
|
||||||
} else {
|
} else {
|
||||||
|
|
263
encode_vm.go
263
encode_vm.go
|
@ -1236,6 +1236,22 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
code = code.next
|
code = code.next
|
||||||
store(ctxptr, code.idx, ptr)
|
store(ctxptr, code.idx, ptr)
|
||||||
}
|
}
|
||||||
|
case opStructFieldPtrHeadIntOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldHeadIntOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.key...)
|
||||||
|
b = appendInt(b, int64(e.ptrToInt(p)))
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructFieldPtrHeadInt:
|
case opStructFieldPtrHeadInt:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -1247,22 +1263,28 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
store(ctxptr, code.idx, e.ptrToPtr(p))
|
store(ctxptr, code.idx, e.ptrToPtr(p))
|
||||||
fallthrough
|
fallthrough
|
||||||
case opStructFieldHeadInt:
|
case opStructFieldHeadInt:
|
||||||
ptr := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if ptr == 0 {
|
|
||||||
if code.op == opStructFieldPtrHeadInt {
|
|
||||||
b = encodeNull(b)
|
|
||||||
b = encodeComma(b)
|
|
||||||
} else {
|
|
||||||
b = append(b, '{', '}', ',')
|
|
||||||
}
|
|
||||||
code = code.end.next
|
|
||||||
} else {
|
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
b = append(b, code.key...)
|
b = append(b, code.key...)
|
||||||
b = appendInt(b, int64(e.ptrToInt(ptr+code.offset)))
|
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
|
case opStructEscapedFieldPtrHeadIntOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
fallthrough
|
||||||
|
case opStructEscapedFieldHeadIntOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.escapedKey...)
|
||||||
|
b = appendInt(b, int64(e.ptrToInt(p)))
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructEscapedFieldPtrHeadInt:
|
case opStructEscapedFieldPtrHeadInt:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -1274,22 +1296,33 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
store(ctxptr, code.idx, e.ptrToPtr(p))
|
store(ctxptr, code.idx, e.ptrToPtr(p))
|
||||||
fallthrough
|
fallthrough
|
||||||
case opStructEscapedFieldHeadInt:
|
case opStructEscapedFieldHeadInt:
|
||||||
ptr := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if ptr == 0 {
|
|
||||||
if code.op == opStructEscapedFieldPtrHeadInt {
|
|
||||||
b = encodeNull(b)
|
|
||||||
b = encodeComma(b)
|
|
||||||
} else {
|
|
||||||
b = append(b, '{', '}', ',')
|
|
||||||
}
|
|
||||||
code = code.end.next
|
|
||||||
} else {
|
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
b = append(b, code.escapedKey...)
|
b = append(b, code.escapedKey...)
|
||||||
b = appendInt(b, int64(e.ptrToInt(ptr+code.offset)))
|
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
|
case opStructFieldPtrHeadIntPtrOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
store(ctxptr, code.idx, e.ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldHeadIntPtrOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.key...)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
} else {
|
||||||
|
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
||||||
|
}
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructFieldPtrHeadIntPtr:
|
case opStructFieldPtrHeadIntPtr:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -1304,8 +1337,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
b = encodeNull(b)
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
code = code.end.next
|
code = code.end.next
|
||||||
} else {
|
break
|
||||||
|
}
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
b = append(b, code.key...)
|
b = append(b, code.key...)
|
||||||
p = e.ptrToPtr(p)
|
p = e.ptrToPtr(p)
|
||||||
|
@ -1314,6 +1349,26 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
} else {
|
} else {
|
||||||
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
||||||
}
|
}
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
|
case opStructEscapedFieldPtrHeadIntPtrOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, e.ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructEscapedFieldHeadIntPtrOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.escapedKey...)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
} else {
|
||||||
|
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
||||||
}
|
}
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
|
@ -1331,8 +1386,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
b = encodeNull(b)
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
code = code.end.next
|
code = code.end.next
|
||||||
} else {
|
break
|
||||||
|
}
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
b = append(b, code.escapedKey...)
|
b = append(b, code.escapedKey...)
|
||||||
p = e.ptrToPtr(p)
|
p = e.ptrToPtr(p)
|
||||||
|
@ -1341,9 +1398,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
} else {
|
} else {
|
||||||
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
||||||
}
|
}
|
||||||
code = code.next
|
|
||||||
}
|
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructFieldHeadIntNPtr:
|
case opStructFieldHeadIntNPtr:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -1413,6 +1469,22 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
|
case opStructFieldPtrHeadInt8Only:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldHeadInt8Only:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.key...)
|
||||||
|
b = appendInt(b, int64(e.ptrToInt8(p)))
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructFieldPtrHeadInt8:
|
case opStructFieldPtrHeadInt8:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -1440,6 +1512,22 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
|
case opStructEscapedFieldPtrHeadInt8Only:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case opStructEscapedFieldHeadInt8Only:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.escapedKey...)
|
||||||
|
b = appendInt(b, int64(e.ptrToInt8(p)))
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructEscapedFieldPtrHeadInt8:
|
case opStructEscapedFieldPtrHeadInt8:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -1467,6 +1555,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
|
case opStructFieldPtrHeadInt8PtrOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, e.ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldHeadInt8PtrOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.key...)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
} else {
|
||||||
|
b = appendInt(b, int64(e.ptrToInt8(p)))
|
||||||
|
}
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructFieldPtrHeadInt8Ptr:
|
case opStructFieldPtrHeadInt8Ptr:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -1494,6 +1603,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
|
case opStructEscapedFieldPtrHeadInt8PtrOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, e.ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructEscapedFieldHeadInt8PtrOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.escapedKey...)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
} else {
|
||||||
|
b = appendInt(b, int64(e.ptrToInt8(p)))
|
||||||
|
}
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructEscapedFieldPtrHeadInt8Ptr:
|
case opStructEscapedFieldPtrHeadInt8Ptr:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -2390,6 +2520,22 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
|
case opStructEscapedFieldPtrHeadEscapedStringOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case opStructEscapedFieldHeadEscapedStringOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.escapedKey...)
|
||||||
|
b = encodeEscapedString(b, e.ptrToString(p))
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructEscapedFieldPtrHeadEscapedString:
|
case opStructEscapedFieldPtrHeadEscapedString:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -2470,6 +2616,22 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
|
case opStructEscapedFieldPtrHeadBoolOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case opStructEscapedFieldHeadBoolOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.escapedKey...)
|
||||||
|
b = encodeBool(b, e.ptrToBool(p))
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructEscapedFieldPtrHeadBool:
|
case opStructEscapedFieldPtrHeadBool:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -3827,6 +3989,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case opStructEscapedFieldPtrHeadOmitEmptyIntOnly:
|
||||||
|
ptr := load(ctxptr, code.idx)
|
||||||
|
if ptr != 0 {
|
||||||
|
store(ctxptr, code.idx, e.ptrToPtr(ptr))
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case opStructEscapedFieldHeadOmitEmptyIntOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
v := e.ptrToInt(p)
|
||||||
|
if v == 0 {
|
||||||
|
code = code.nextField
|
||||||
|
} else {
|
||||||
|
b = append(b, code.escapedKey...)
|
||||||
|
b = appendInt(b, int64(v))
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
|
}
|
||||||
case opStructEscapedFieldPtrHeadOmitEmptyInt:
|
case opStructEscapedFieldPtrHeadOmitEmptyInt:
|
||||||
ptr := load(ctxptr, code.idx)
|
ptr := load(ctxptr, code.idx)
|
||||||
if ptr != 0 {
|
if ptr != 0 {
|
||||||
|
@ -6782,6 +6962,22 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case opStructEscapedFieldPtrHeadStringTagInt64PtrOnly:
|
||||||
|
ptr := load(ctxptr, code.idx)
|
||||||
|
if ptr != 0 {
|
||||||
|
store(ctxptr, code.idx, e.ptrToPtr(ptr))
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case opStructEscapedFieldHeadStringTagInt64PtrOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.escapedKey...)
|
||||||
|
b = append(b, '"')
|
||||||
|
b = appendInt(b, e.ptrToInt64(p))
|
||||||
|
b = append(b, '"')
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructEscapedFieldPtrHeadStringTagInt64:
|
case opStructEscapedFieldPtrHeadStringTagInt64:
|
||||||
ptr := load(ctxptr, code.idx)
|
ptr := load(ctxptr, code.idx)
|
||||||
if ptr != 0 {
|
if ptr != 0 {
|
||||||
|
@ -7496,6 +7692,21 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
||||||
b = encodeComma(b)
|
b = encodeComma(b)
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
|
case opStructEscapedFieldPtrHeadStringTagBoolOnly:
|
||||||
|
ptr := load(ctxptr, code.idx)
|
||||||
|
if ptr != 0 {
|
||||||
|
store(ctxptr, code.idx, e.ptrToPtr(ptr))
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case opStructEscapedFieldHeadStringTagBoolOnly:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.escapedKey...)
|
||||||
|
b = append(b, '"')
|
||||||
|
b = encodeBool(b, e.ptrToBool(p))
|
||||||
|
b = append(b, '"')
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.next
|
||||||
case opStructEscapedFieldPtrHeadStringTagBool:
|
case opStructEscapedFieldPtrHeadStringTagBool:
|
||||||
ptr := load(ctxptr, code.idx)
|
ptr := load(ctxptr, code.idx)
|
||||||
if ptr != 0 {
|
if ptr != 0 {
|
||||||
|
|
Loading…
Reference in New Issue