Merge pull request #259 from goccy/feature/improve-encoding-interface-perf

Improve encoding performance of empty interface type
This commit is contained in:
Masaaki Goshima 2021-06-25 23:06:45 +09:00 committed by GitHub
commit 3829400241
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 691 additions and 574 deletions

View File

@ -200,6 +200,7 @@ func (t OpType) FieldToOmitEmptyField() OpType {
createOpType("Recursive", "Op"), createOpType("Recursive", "Op"),
createOpType("RecursivePtr", "Op"), createOpType("RecursivePtr", "Op"),
createOpType("RecursiveEnd", "Op"), createOpType("RecursiveEnd", "Op"),
createOpType("InterfaceEnd", "Op"),
createOpType("StructAnonymousEnd", "StructEnd"), createOpType("StructAnonymousEnd", "StructEnd"),
} }
for _, typ := range primitiveTypesUpper { for _, typ := range primitiveTypesUpper {

View File

@ -190,15 +190,52 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
code = code.Next code = code.Next
break break
} }
bb, err := appendInterface(ctx, codeSet, code, b, iface, ptrOffset)
ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface))
ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ)))
if err != nil { if err != nil {
return nil, err return nil, err
} }
ctxptr = ctx.Ptr()
totalLength := uintptr(code.Length) + 3
nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3
var c *encoder.Opcode
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
c = ifaceCodeSet.InterfaceEscapeKeyCode
} else {
c = ifaceCodeSet.InterfaceNoescapeKeyCode
}
curlen := uintptr(len(ctx.Ptrs))
offsetNum := ptrOffset / uintptrSize
oldOffset := ptrOffset
ptrOffset += totalLength * uintptrSize
oldBaseIndent := ctx.BaseIndent
indentDiffFromTop := c.Indent - 1
ctx.BaseIndent += code.Indent - indentDiffFromTop
newLen := offsetNum + totalLength + nextTotalLength
if curlen < newLen {
ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
}
ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
end := ifaceCodeSet.EndCode
store(ctxptr, c.Idx, uintptr(iface.ptr))
store(ctxptr, end.Idx, oldOffset)
store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, end, uintptr(oldBaseIndent))
code = c
case encoder.OpInterfaceEnd:
offset := load(ctxptr, code.Idx)
// restore ctxptr
restoreIndent(ctx, code, ctxptr)
ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
b = bb codePtr := load(ctxptr, code.ElemIdx)
code = code.Next code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
ctxptr = ctx.Ptr() + offset
ptrOffset = offset
case encoder.OpMarshalJSONPtr: case encoder.OpMarshalJSONPtr:
p := load(ctxptr, code.Idx) p := load(ctxptr, code.Idx)
if p == 0 { if p == 0 {
@ -496,7 +533,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
store(ctxptr, c.Idx, ptr) store(ctxptr, c.Idx, ptr)
store(ctxptr, c.End.Next.Idx, oldOffset) store(ctxptr, c.End.Next.Idx, oldOffset)
store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, c, uintptr(oldBaseIndent)) storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent))
code = c code = c
recursiveLevel++ recursiveLevel++
case encoder.OpRecursiveEnd: case encoder.OpRecursiveEnd:

View File

@ -78,12 +78,19 @@ func compileToGetCodeSetSlowPath(typeptr uintptr) (*OpcodeSet, error) {
} }
noescapeKeyCode = copyOpcode(noescapeKeyCode) noescapeKeyCode = copyOpcode(noescapeKeyCode)
escapeKeyCode = copyOpcode(escapeKeyCode) escapeKeyCode = copyOpcode(escapeKeyCode)
setTotalLengthToInterfaceOp(noescapeKeyCode)
setTotalLengthToInterfaceOp(escapeKeyCode)
interfaceNoescapeKeyCode := copyToInterfaceOpcode(noescapeKeyCode)
interfaceEscapeKeyCode := copyToInterfaceOpcode(escapeKeyCode)
codeLength := noescapeKeyCode.TotalLength() codeLength := noescapeKeyCode.TotalLength()
codeSet := &OpcodeSet{ codeSet := &OpcodeSet{
Type: copiedType, Type: copiedType,
NoescapeKeyCode: noescapeKeyCode, NoescapeKeyCode: noescapeKeyCode,
EscapeKeyCode: escapeKeyCode, EscapeKeyCode: escapeKeyCode,
InterfaceNoescapeKeyCode: interfaceNoescapeKeyCode,
InterfaceEscapeKeyCode: interfaceEscapeKeyCode,
CodeLength: codeLength, CodeLength: codeLength,
EndCode: ToEndCode(interfaceNoescapeKeyCode),
} }
storeOpcodeSet(typeptr, codeSet, opcodeMap) storeOpcodeSet(typeptr, codeSet, opcodeMap)
return codeSet, nil return codeSet, nil

View File

@ -37,12 +37,19 @@ func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) {
} }
noescapeKeyCode = copyOpcode(noescapeKeyCode) noescapeKeyCode = copyOpcode(noescapeKeyCode)
escapeKeyCode = copyOpcode(escapeKeyCode) escapeKeyCode = copyOpcode(escapeKeyCode)
setTotalLengthToInterfaceOp(noescapeKeyCode)
setTotalLengthToInterfaceOp(escapeKeyCode)
interfaceNoescapeKeyCode := copyToInterfaceOpcode(noescapeKeyCode)
interfaceEscapeKeyCode := copyToInterfaceOpcode(escapeKeyCode)
codeLength := noescapeKeyCode.TotalLength() codeLength := noescapeKeyCode.TotalLength()
codeSet := &OpcodeSet{ codeSet := &OpcodeSet{
Type: copiedType, Type: copiedType,
NoescapeKeyCode: noescapeKeyCode, NoescapeKeyCode: noescapeKeyCode,
EscapeKeyCode: escapeKeyCode, EscapeKeyCode: escapeKeyCode,
InterfaceNoescapeKeyCode: interfaceNoescapeKeyCode,
InterfaceEscapeKeyCode: interfaceEscapeKeyCode,
CodeLength: codeLength, CodeLength: codeLength,
EndCode: ToEndCode(interfaceNoescapeKeyCode),
} }
cachedOpcodeSets[index] = codeSet cachedOpcodeSets[index] = codeSet
return codeSet, nil return codeSet, nil

View File

@ -44,12 +44,19 @@ func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) {
noescapeKeyCode = copyOpcode(noescapeKeyCode) noescapeKeyCode = copyOpcode(noescapeKeyCode)
escapeKeyCode = copyOpcode(escapeKeyCode) escapeKeyCode = copyOpcode(escapeKeyCode)
setTotalLengthToInterfaceOp(noescapeKeyCode)
setTotalLengthToInterfaceOp(escapeKeyCode)
interfaceNoescapeKeyCode := copyToInterfaceOpcode(noescapeKeyCode)
interfaceEscapeKeyCode := copyToInterfaceOpcode(escapeKeyCode)
codeLength := noescapeKeyCode.TotalLength() codeLength := noescapeKeyCode.TotalLength()
codeSet := &OpcodeSet{ codeSet := &OpcodeSet{
Type: copiedType, Type: copiedType,
NoescapeKeyCode: noescapeKeyCode, NoescapeKeyCode: noescapeKeyCode,
EscapeKeyCode: escapeKeyCode, EscapeKeyCode: escapeKeyCode,
InterfaceNoescapeKeyCode: interfaceNoescapeKeyCode,
InterfaceEscapeKeyCode: interfaceEscapeKeyCode,
CodeLength: codeLength, CodeLength: codeLength,
EndCode: ToEndCode(interfaceNoescapeKeyCode),
} }
setsMu.Lock() setsMu.Lock()
cachedOpcodeSets[index] = codeSet cachedOpcodeSets[index] = codeSet

View File

@ -97,7 +97,10 @@ type OpcodeSet struct {
Type *runtime.Type Type *runtime.Type
NoescapeKeyCode *Opcode NoescapeKeyCode *Opcode
EscapeKeyCode *Opcode EscapeKeyCode *Opcode
InterfaceNoescapeKeyCode *Opcode
InterfaceEscapeKeyCode *Opcode
CodeLength int CodeLength int
EndCode *Opcode
} }
type CompiledCode struct { type CompiledCode struct {

View File

@ -285,6 +285,46 @@ func copyOpcode(code *Opcode) *Opcode {
return code.copy(codeMap) return code.copy(codeMap)
} }
func setTotalLengthToInterfaceOp(code *Opcode) {
c := code
for c.Op != OpEnd && c.Op != OpInterfaceEnd {
if c.Op == OpInterface {
c.Length = uint32(code.TotalLength())
}
switch c.Op.CodeType() {
case CodeArrayElem, CodeSliceElem, CodeMapKey:
c = c.End
default:
c = c.Next
}
}
}
func ToEndCode(code *Opcode) *Opcode {
c := code
for c.Op != OpEnd && c.Op != OpInterfaceEnd {
switch c.Op.CodeType() {
case CodeArrayElem, CodeSliceElem, CodeMapKey:
c = c.End
default:
c = c.Next
}
}
return c
}
func copyToInterfaceOpcode(code *Opcode) *Opcode {
copied := copyOpcode(code)
c := copied
c = ToEndCode(c)
copied.Op = copied.Op.PtrHeadToHead()
c.Idx += uintptrSize
c.ElemIdx = c.Idx + uintptrSize
c.Length = c.Idx + 2*uintptrSize
c.Op = OpInterfaceEnd
return copied
}
func newOpCodeWithNext(ctx *compileContext, op OpType, next *Opcode) *Opcode { func newOpCodeWithNext(ctx *compileContext, op OpType, next *Opcode) *Opcode {
return &Opcode{ return &Opcode{
Op: op, Op: op,
@ -354,7 +394,8 @@ func (c *Opcode) BeforeLastCode() *Opcode {
func (c *Opcode) TotalLength() int { func (c *Opcode) TotalLength() int {
var idx int var idx int
for code := c; code.Op != OpEnd; { code := c
for code.Op != OpEnd && code.Op != OpInterfaceEnd {
maxIdx := int(code.MaxIdx() / uintptrSize) maxIdx := int(code.MaxIdx() / uintptrSize)
if idx < maxIdx { if idx < maxIdx {
idx = maxIdx idx = maxIdx
@ -369,6 +410,10 @@ func (c *Opcode) TotalLength() int {
code = code.Next code = code.Next
} }
} }
maxIdx := int(code.MaxIdx() / uintptrSize)
if idx < maxIdx {
idx = maxIdx
}
return idx + 1 return idx + 1
} }
@ -508,7 +553,7 @@ func (c *Opcode) dumpValue(code *Opcode) string {
func (c *Opcode) Dump() string { func (c *Opcode) Dump() string {
codes := []string{} codes := []string{}
for code := c; code.Op != OpEnd; { for code := c; code.Op != OpEnd && code.Op != OpInterfaceEnd; {
switch code.Op.CodeType() { switch code.Op.CodeType() {
case CodeSliceHead: case CodeSliceHead:
codes = append(codes, c.dumpHead(code)) codes = append(codes, c.dumpHead(code))

View File

@ -22,7 +22,7 @@ const (
CodeStructEnd CodeType = 11 CodeStructEnd CodeType = 11
) )
var opTypeStrings = [400]string{ var opTypeStrings = [401]string{
"End", "End",
"Interface", "Interface",
"Ptr", "Ptr",
@ -36,6 +36,7 @@ var opTypeStrings = [400]string{
"Recursive", "Recursive",
"RecursivePtr", "RecursivePtr",
"RecursiveEnd", "RecursiveEnd",
"InterfaceEnd",
"StructAnonymousEnd", "StructAnonymousEnd",
"Int", "Int",
"Uint", "Uint",
@ -441,397 +442,398 @@ const (
OpRecursive OpType = 10 OpRecursive OpType = 10
OpRecursivePtr OpType = 11 OpRecursivePtr OpType = 11
OpRecursiveEnd OpType = 12 OpRecursiveEnd OpType = 12
OpStructAnonymousEnd OpType = 13 OpInterfaceEnd OpType = 13
OpInt OpType = 14 OpStructAnonymousEnd OpType = 14
OpUint OpType = 15 OpInt OpType = 15
OpFloat32 OpType = 16 OpUint OpType = 16
OpFloat64 OpType = 17 OpFloat32 OpType = 17
OpBool OpType = 18 OpFloat64 OpType = 18
OpString OpType = 19 OpBool OpType = 19
OpBytes OpType = 20 OpString OpType = 20
OpNumber OpType = 21 OpBytes OpType = 21
OpArray OpType = 22 OpNumber OpType = 22
OpMap OpType = 23 OpArray OpType = 23
OpSlice OpType = 24 OpMap OpType = 24
OpStruct OpType = 25 OpSlice OpType = 25
OpMarshalJSON OpType = 26 OpStruct OpType = 26
OpMarshalText OpType = 27 OpMarshalJSON OpType = 27
OpIntString OpType = 28 OpMarshalText OpType = 28
OpUintString OpType = 29 OpIntString OpType = 29
OpFloat32String OpType = 30 OpUintString OpType = 30
OpFloat64String OpType = 31 OpFloat32String OpType = 31
OpBoolString OpType = 32 OpFloat64String OpType = 32
OpStringString OpType = 33 OpBoolString OpType = 33
OpNumberString OpType = 34 OpStringString OpType = 34
OpIntPtr OpType = 35 OpNumberString OpType = 35
OpUintPtr OpType = 36 OpIntPtr OpType = 36
OpFloat32Ptr OpType = 37 OpUintPtr OpType = 37
OpFloat64Ptr OpType = 38 OpFloat32Ptr OpType = 38
OpBoolPtr OpType = 39 OpFloat64Ptr OpType = 39
OpStringPtr OpType = 40 OpBoolPtr OpType = 40
OpBytesPtr OpType = 41 OpStringPtr OpType = 41
OpNumberPtr OpType = 42 OpBytesPtr OpType = 42
OpArrayPtr OpType = 43 OpNumberPtr OpType = 43
OpMapPtr OpType = 44 OpArrayPtr OpType = 44
OpSlicePtr OpType = 45 OpMapPtr OpType = 45
OpMarshalJSONPtr OpType = 46 OpSlicePtr OpType = 46
OpMarshalTextPtr OpType = 47 OpMarshalJSONPtr OpType = 47
OpInterfacePtr OpType = 48 OpMarshalTextPtr OpType = 48
OpIntPtrString OpType = 49 OpInterfacePtr OpType = 49
OpUintPtrString OpType = 50 OpIntPtrString OpType = 50
OpFloat32PtrString OpType = 51 OpUintPtrString OpType = 51
OpFloat64PtrString OpType = 52 OpFloat32PtrString OpType = 52
OpBoolPtrString OpType = 53 OpFloat64PtrString OpType = 53
OpStringPtrString OpType = 54 OpBoolPtrString OpType = 54
OpNumberPtrString OpType = 55 OpStringPtrString OpType = 55
OpStructHeadInt OpType = 56 OpNumberPtrString OpType = 56
OpStructHeadOmitEmptyInt OpType = 57 OpStructHeadInt OpType = 57
OpStructPtrHeadInt OpType = 58 OpStructHeadOmitEmptyInt OpType = 58
OpStructPtrHeadOmitEmptyInt OpType = 59 OpStructPtrHeadInt OpType = 59
OpStructHeadUint OpType = 60 OpStructPtrHeadOmitEmptyInt OpType = 60
OpStructHeadOmitEmptyUint OpType = 61 OpStructHeadUint OpType = 61
OpStructPtrHeadUint OpType = 62 OpStructHeadOmitEmptyUint OpType = 62
OpStructPtrHeadOmitEmptyUint OpType = 63 OpStructPtrHeadUint OpType = 63
OpStructHeadFloat32 OpType = 64 OpStructPtrHeadOmitEmptyUint OpType = 64
OpStructHeadOmitEmptyFloat32 OpType = 65 OpStructHeadFloat32 OpType = 65
OpStructPtrHeadFloat32 OpType = 66 OpStructHeadOmitEmptyFloat32 OpType = 66
OpStructPtrHeadOmitEmptyFloat32 OpType = 67 OpStructPtrHeadFloat32 OpType = 67
OpStructHeadFloat64 OpType = 68 OpStructPtrHeadOmitEmptyFloat32 OpType = 68
OpStructHeadOmitEmptyFloat64 OpType = 69 OpStructHeadFloat64 OpType = 69
OpStructPtrHeadFloat64 OpType = 70 OpStructHeadOmitEmptyFloat64 OpType = 70
OpStructPtrHeadOmitEmptyFloat64 OpType = 71 OpStructPtrHeadFloat64 OpType = 71
OpStructHeadBool OpType = 72 OpStructPtrHeadOmitEmptyFloat64 OpType = 72
OpStructHeadOmitEmptyBool OpType = 73 OpStructHeadBool OpType = 73
OpStructPtrHeadBool OpType = 74 OpStructHeadOmitEmptyBool OpType = 74
OpStructPtrHeadOmitEmptyBool OpType = 75 OpStructPtrHeadBool OpType = 75
OpStructHeadString OpType = 76 OpStructPtrHeadOmitEmptyBool OpType = 76
OpStructHeadOmitEmptyString OpType = 77 OpStructHeadString OpType = 77
OpStructPtrHeadString OpType = 78 OpStructHeadOmitEmptyString OpType = 78
OpStructPtrHeadOmitEmptyString OpType = 79 OpStructPtrHeadString OpType = 79
OpStructHeadBytes OpType = 80 OpStructPtrHeadOmitEmptyString OpType = 80
OpStructHeadOmitEmptyBytes OpType = 81 OpStructHeadBytes OpType = 81
OpStructPtrHeadBytes OpType = 82 OpStructHeadOmitEmptyBytes OpType = 82
OpStructPtrHeadOmitEmptyBytes OpType = 83 OpStructPtrHeadBytes OpType = 83
OpStructHeadNumber OpType = 84 OpStructPtrHeadOmitEmptyBytes OpType = 84
OpStructHeadOmitEmptyNumber OpType = 85 OpStructHeadNumber OpType = 85
OpStructPtrHeadNumber OpType = 86 OpStructHeadOmitEmptyNumber OpType = 86
OpStructPtrHeadOmitEmptyNumber OpType = 87 OpStructPtrHeadNumber OpType = 87
OpStructHeadArray OpType = 88 OpStructPtrHeadOmitEmptyNumber OpType = 88
OpStructHeadOmitEmptyArray OpType = 89 OpStructHeadArray OpType = 89
OpStructPtrHeadArray OpType = 90 OpStructHeadOmitEmptyArray OpType = 90
OpStructPtrHeadOmitEmptyArray OpType = 91 OpStructPtrHeadArray OpType = 91
OpStructHeadMap OpType = 92 OpStructPtrHeadOmitEmptyArray OpType = 92
OpStructHeadOmitEmptyMap OpType = 93 OpStructHeadMap OpType = 93
OpStructPtrHeadMap OpType = 94 OpStructHeadOmitEmptyMap OpType = 94
OpStructPtrHeadOmitEmptyMap OpType = 95 OpStructPtrHeadMap OpType = 95
OpStructHeadSlice OpType = 96 OpStructPtrHeadOmitEmptyMap OpType = 96
OpStructHeadOmitEmptySlice OpType = 97 OpStructHeadSlice OpType = 97
OpStructPtrHeadSlice OpType = 98 OpStructHeadOmitEmptySlice OpType = 98
OpStructPtrHeadOmitEmptySlice OpType = 99 OpStructPtrHeadSlice OpType = 99
OpStructHeadStruct OpType = 100 OpStructPtrHeadOmitEmptySlice OpType = 100
OpStructHeadOmitEmptyStruct OpType = 101 OpStructHeadStruct OpType = 101
OpStructPtrHeadStruct OpType = 102 OpStructHeadOmitEmptyStruct OpType = 102
OpStructPtrHeadOmitEmptyStruct OpType = 103 OpStructPtrHeadStruct OpType = 103
OpStructHeadMarshalJSON OpType = 104 OpStructPtrHeadOmitEmptyStruct OpType = 104
OpStructHeadOmitEmptyMarshalJSON OpType = 105 OpStructHeadMarshalJSON OpType = 105
OpStructPtrHeadMarshalJSON OpType = 106 OpStructHeadOmitEmptyMarshalJSON OpType = 106
OpStructPtrHeadOmitEmptyMarshalJSON OpType = 107 OpStructPtrHeadMarshalJSON OpType = 107
OpStructHeadMarshalText OpType = 108 OpStructPtrHeadOmitEmptyMarshalJSON OpType = 108
OpStructHeadOmitEmptyMarshalText OpType = 109 OpStructHeadMarshalText OpType = 109
OpStructPtrHeadMarshalText OpType = 110 OpStructHeadOmitEmptyMarshalText OpType = 110
OpStructPtrHeadOmitEmptyMarshalText OpType = 111 OpStructPtrHeadMarshalText OpType = 111
OpStructHeadIntString OpType = 112 OpStructPtrHeadOmitEmptyMarshalText OpType = 112
OpStructHeadOmitEmptyIntString OpType = 113 OpStructHeadIntString OpType = 113
OpStructPtrHeadIntString OpType = 114 OpStructHeadOmitEmptyIntString OpType = 114
OpStructPtrHeadOmitEmptyIntString OpType = 115 OpStructPtrHeadIntString OpType = 115
OpStructHeadUintString OpType = 116 OpStructPtrHeadOmitEmptyIntString OpType = 116
OpStructHeadOmitEmptyUintString OpType = 117 OpStructHeadUintString OpType = 117
OpStructPtrHeadUintString OpType = 118 OpStructHeadOmitEmptyUintString OpType = 118
OpStructPtrHeadOmitEmptyUintString OpType = 119 OpStructPtrHeadUintString OpType = 119
OpStructHeadFloat32String OpType = 120 OpStructPtrHeadOmitEmptyUintString OpType = 120
OpStructHeadOmitEmptyFloat32String OpType = 121 OpStructHeadFloat32String OpType = 121
OpStructPtrHeadFloat32String OpType = 122 OpStructHeadOmitEmptyFloat32String OpType = 122
OpStructPtrHeadOmitEmptyFloat32String OpType = 123 OpStructPtrHeadFloat32String OpType = 123
OpStructHeadFloat64String OpType = 124 OpStructPtrHeadOmitEmptyFloat32String OpType = 124
OpStructHeadOmitEmptyFloat64String OpType = 125 OpStructHeadFloat64String OpType = 125
OpStructPtrHeadFloat64String OpType = 126 OpStructHeadOmitEmptyFloat64String OpType = 126
OpStructPtrHeadOmitEmptyFloat64String OpType = 127 OpStructPtrHeadFloat64String OpType = 127
OpStructHeadBoolString OpType = 128 OpStructPtrHeadOmitEmptyFloat64String OpType = 128
OpStructHeadOmitEmptyBoolString OpType = 129 OpStructHeadBoolString OpType = 129
OpStructPtrHeadBoolString OpType = 130 OpStructHeadOmitEmptyBoolString OpType = 130
OpStructPtrHeadOmitEmptyBoolString OpType = 131 OpStructPtrHeadBoolString OpType = 131
OpStructHeadStringString OpType = 132 OpStructPtrHeadOmitEmptyBoolString OpType = 132
OpStructHeadOmitEmptyStringString OpType = 133 OpStructHeadStringString OpType = 133
OpStructPtrHeadStringString OpType = 134 OpStructHeadOmitEmptyStringString OpType = 134
OpStructPtrHeadOmitEmptyStringString OpType = 135 OpStructPtrHeadStringString OpType = 135
OpStructHeadNumberString OpType = 136 OpStructPtrHeadOmitEmptyStringString OpType = 136
OpStructHeadOmitEmptyNumberString OpType = 137 OpStructHeadNumberString OpType = 137
OpStructPtrHeadNumberString OpType = 138 OpStructHeadOmitEmptyNumberString OpType = 138
OpStructPtrHeadOmitEmptyNumberString OpType = 139 OpStructPtrHeadNumberString OpType = 139
OpStructHeadIntPtr OpType = 140 OpStructPtrHeadOmitEmptyNumberString OpType = 140
OpStructHeadOmitEmptyIntPtr OpType = 141 OpStructHeadIntPtr OpType = 141
OpStructPtrHeadIntPtr OpType = 142 OpStructHeadOmitEmptyIntPtr OpType = 142
OpStructPtrHeadOmitEmptyIntPtr OpType = 143 OpStructPtrHeadIntPtr OpType = 143
OpStructHeadUintPtr OpType = 144 OpStructPtrHeadOmitEmptyIntPtr OpType = 144
OpStructHeadOmitEmptyUintPtr OpType = 145 OpStructHeadUintPtr OpType = 145
OpStructPtrHeadUintPtr OpType = 146 OpStructHeadOmitEmptyUintPtr OpType = 146
OpStructPtrHeadOmitEmptyUintPtr OpType = 147 OpStructPtrHeadUintPtr OpType = 147
OpStructHeadFloat32Ptr OpType = 148 OpStructPtrHeadOmitEmptyUintPtr OpType = 148
OpStructHeadOmitEmptyFloat32Ptr OpType = 149 OpStructHeadFloat32Ptr OpType = 149
OpStructPtrHeadFloat32Ptr OpType = 150 OpStructHeadOmitEmptyFloat32Ptr OpType = 150
OpStructPtrHeadOmitEmptyFloat32Ptr OpType = 151 OpStructPtrHeadFloat32Ptr OpType = 151
OpStructHeadFloat64Ptr OpType = 152 OpStructPtrHeadOmitEmptyFloat32Ptr OpType = 152
OpStructHeadOmitEmptyFloat64Ptr OpType = 153 OpStructHeadFloat64Ptr OpType = 153
OpStructPtrHeadFloat64Ptr OpType = 154 OpStructHeadOmitEmptyFloat64Ptr OpType = 154
OpStructPtrHeadOmitEmptyFloat64Ptr OpType = 155 OpStructPtrHeadFloat64Ptr OpType = 155
OpStructHeadBoolPtr OpType = 156 OpStructPtrHeadOmitEmptyFloat64Ptr OpType = 156
OpStructHeadOmitEmptyBoolPtr OpType = 157 OpStructHeadBoolPtr OpType = 157
OpStructPtrHeadBoolPtr OpType = 158 OpStructHeadOmitEmptyBoolPtr OpType = 158
OpStructPtrHeadOmitEmptyBoolPtr OpType = 159 OpStructPtrHeadBoolPtr OpType = 159
OpStructHeadStringPtr OpType = 160 OpStructPtrHeadOmitEmptyBoolPtr OpType = 160
OpStructHeadOmitEmptyStringPtr OpType = 161 OpStructHeadStringPtr OpType = 161
OpStructPtrHeadStringPtr OpType = 162 OpStructHeadOmitEmptyStringPtr OpType = 162
OpStructPtrHeadOmitEmptyStringPtr OpType = 163 OpStructPtrHeadStringPtr OpType = 163
OpStructHeadBytesPtr OpType = 164 OpStructPtrHeadOmitEmptyStringPtr OpType = 164
OpStructHeadOmitEmptyBytesPtr OpType = 165 OpStructHeadBytesPtr OpType = 165
OpStructPtrHeadBytesPtr OpType = 166 OpStructHeadOmitEmptyBytesPtr OpType = 166
OpStructPtrHeadOmitEmptyBytesPtr OpType = 167 OpStructPtrHeadBytesPtr OpType = 167
OpStructHeadNumberPtr OpType = 168 OpStructPtrHeadOmitEmptyBytesPtr OpType = 168
OpStructHeadOmitEmptyNumberPtr OpType = 169 OpStructHeadNumberPtr OpType = 169
OpStructPtrHeadNumberPtr OpType = 170 OpStructHeadOmitEmptyNumberPtr OpType = 170
OpStructPtrHeadOmitEmptyNumberPtr OpType = 171 OpStructPtrHeadNumberPtr OpType = 171
OpStructHeadArrayPtr OpType = 172 OpStructPtrHeadOmitEmptyNumberPtr OpType = 172
OpStructHeadOmitEmptyArrayPtr OpType = 173 OpStructHeadArrayPtr OpType = 173
OpStructPtrHeadArrayPtr OpType = 174 OpStructHeadOmitEmptyArrayPtr OpType = 174
OpStructPtrHeadOmitEmptyArrayPtr OpType = 175 OpStructPtrHeadArrayPtr OpType = 175
OpStructHeadMapPtr OpType = 176 OpStructPtrHeadOmitEmptyArrayPtr OpType = 176
OpStructHeadOmitEmptyMapPtr OpType = 177 OpStructHeadMapPtr OpType = 177
OpStructPtrHeadMapPtr OpType = 178 OpStructHeadOmitEmptyMapPtr OpType = 178
OpStructPtrHeadOmitEmptyMapPtr OpType = 179 OpStructPtrHeadMapPtr OpType = 179
OpStructHeadSlicePtr OpType = 180 OpStructPtrHeadOmitEmptyMapPtr OpType = 180
OpStructHeadOmitEmptySlicePtr OpType = 181 OpStructHeadSlicePtr OpType = 181
OpStructPtrHeadSlicePtr OpType = 182 OpStructHeadOmitEmptySlicePtr OpType = 182
OpStructPtrHeadOmitEmptySlicePtr OpType = 183 OpStructPtrHeadSlicePtr OpType = 183
OpStructHeadMarshalJSONPtr OpType = 184 OpStructPtrHeadOmitEmptySlicePtr OpType = 184
OpStructHeadOmitEmptyMarshalJSONPtr OpType = 185 OpStructHeadMarshalJSONPtr OpType = 185
OpStructPtrHeadMarshalJSONPtr OpType = 186 OpStructHeadOmitEmptyMarshalJSONPtr OpType = 186
OpStructPtrHeadOmitEmptyMarshalJSONPtr OpType = 187 OpStructPtrHeadMarshalJSONPtr OpType = 187
OpStructHeadMarshalTextPtr OpType = 188 OpStructPtrHeadOmitEmptyMarshalJSONPtr OpType = 188
OpStructHeadOmitEmptyMarshalTextPtr OpType = 189 OpStructHeadMarshalTextPtr OpType = 189
OpStructPtrHeadMarshalTextPtr OpType = 190 OpStructHeadOmitEmptyMarshalTextPtr OpType = 190
OpStructPtrHeadOmitEmptyMarshalTextPtr OpType = 191 OpStructPtrHeadMarshalTextPtr OpType = 191
OpStructHeadInterfacePtr OpType = 192 OpStructPtrHeadOmitEmptyMarshalTextPtr OpType = 192
OpStructHeadOmitEmptyInterfacePtr OpType = 193 OpStructHeadInterfacePtr OpType = 193
OpStructPtrHeadInterfacePtr OpType = 194 OpStructHeadOmitEmptyInterfacePtr OpType = 194
OpStructPtrHeadOmitEmptyInterfacePtr OpType = 195 OpStructPtrHeadInterfacePtr OpType = 195
OpStructHeadIntPtrString OpType = 196 OpStructPtrHeadOmitEmptyInterfacePtr OpType = 196
OpStructHeadOmitEmptyIntPtrString OpType = 197 OpStructHeadIntPtrString OpType = 197
OpStructPtrHeadIntPtrString OpType = 198 OpStructHeadOmitEmptyIntPtrString OpType = 198
OpStructPtrHeadOmitEmptyIntPtrString OpType = 199 OpStructPtrHeadIntPtrString OpType = 199
OpStructHeadUintPtrString OpType = 200 OpStructPtrHeadOmitEmptyIntPtrString OpType = 200
OpStructHeadOmitEmptyUintPtrString OpType = 201 OpStructHeadUintPtrString OpType = 201
OpStructPtrHeadUintPtrString OpType = 202 OpStructHeadOmitEmptyUintPtrString OpType = 202
OpStructPtrHeadOmitEmptyUintPtrString OpType = 203 OpStructPtrHeadUintPtrString OpType = 203
OpStructHeadFloat32PtrString OpType = 204 OpStructPtrHeadOmitEmptyUintPtrString OpType = 204
OpStructHeadOmitEmptyFloat32PtrString OpType = 205 OpStructHeadFloat32PtrString OpType = 205
OpStructPtrHeadFloat32PtrString OpType = 206 OpStructHeadOmitEmptyFloat32PtrString OpType = 206
OpStructPtrHeadOmitEmptyFloat32PtrString OpType = 207 OpStructPtrHeadFloat32PtrString OpType = 207
OpStructHeadFloat64PtrString OpType = 208 OpStructPtrHeadOmitEmptyFloat32PtrString OpType = 208
OpStructHeadOmitEmptyFloat64PtrString OpType = 209 OpStructHeadFloat64PtrString OpType = 209
OpStructPtrHeadFloat64PtrString OpType = 210 OpStructHeadOmitEmptyFloat64PtrString OpType = 210
OpStructPtrHeadOmitEmptyFloat64PtrString OpType = 211 OpStructPtrHeadFloat64PtrString OpType = 211
OpStructHeadBoolPtrString OpType = 212 OpStructPtrHeadOmitEmptyFloat64PtrString OpType = 212
OpStructHeadOmitEmptyBoolPtrString OpType = 213 OpStructHeadBoolPtrString OpType = 213
OpStructPtrHeadBoolPtrString OpType = 214 OpStructHeadOmitEmptyBoolPtrString OpType = 214
OpStructPtrHeadOmitEmptyBoolPtrString OpType = 215 OpStructPtrHeadBoolPtrString OpType = 215
OpStructHeadStringPtrString OpType = 216 OpStructPtrHeadOmitEmptyBoolPtrString OpType = 216
OpStructHeadOmitEmptyStringPtrString OpType = 217 OpStructHeadStringPtrString OpType = 217
OpStructPtrHeadStringPtrString OpType = 218 OpStructHeadOmitEmptyStringPtrString OpType = 218
OpStructPtrHeadOmitEmptyStringPtrString OpType = 219 OpStructPtrHeadStringPtrString OpType = 219
OpStructHeadNumberPtrString OpType = 220 OpStructPtrHeadOmitEmptyStringPtrString OpType = 220
OpStructHeadOmitEmptyNumberPtrString OpType = 221 OpStructHeadNumberPtrString OpType = 221
OpStructPtrHeadNumberPtrString OpType = 222 OpStructHeadOmitEmptyNumberPtrString OpType = 222
OpStructPtrHeadOmitEmptyNumberPtrString OpType = 223 OpStructPtrHeadNumberPtrString OpType = 223
OpStructHead OpType = 224 OpStructPtrHeadOmitEmptyNumberPtrString OpType = 224
OpStructHeadOmitEmpty OpType = 225 OpStructHead OpType = 225
OpStructPtrHead OpType = 226 OpStructHeadOmitEmpty OpType = 226
OpStructPtrHeadOmitEmpty OpType = 227 OpStructPtrHead OpType = 227
OpStructFieldInt OpType = 228 OpStructPtrHeadOmitEmpty OpType = 228
OpStructFieldOmitEmptyInt OpType = 229 OpStructFieldInt OpType = 229
OpStructEndInt OpType = 230 OpStructFieldOmitEmptyInt OpType = 230
OpStructEndOmitEmptyInt OpType = 231 OpStructEndInt OpType = 231
OpStructFieldUint OpType = 232 OpStructEndOmitEmptyInt OpType = 232
OpStructFieldOmitEmptyUint OpType = 233 OpStructFieldUint OpType = 233
OpStructEndUint OpType = 234 OpStructFieldOmitEmptyUint OpType = 234
OpStructEndOmitEmptyUint OpType = 235 OpStructEndUint OpType = 235
OpStructFieldFloat32 OpType = 236 OpStructEndOmitEmptyUint OpType = 236
OpStructFieldOmitEmptyFloat32 OpType = 237 OpStructFieldFloat32 OpType = 237
OpStructEndFloat32 OpType = 238 OpStructFieldOmitEmptyFloat32 OpType = 238
OpStructEndOmitEmptyFloat32 OpType = 239 OpStructEndFloat32 OpType = 239
OpStructFieldFloat64 OpType = 240 OpStructEndOmitEmptyFloat32 OpType = 240
OpStructFieldOmitEmptyFloat64 OpType = 241 OpStructFieldFloat64 OpType = 241
OpStructEndFloat64 OpType = 242 OpStructFieldOmitEmptyFloat64 OpType = 242
OpStructEndOmitEmptyFloat64 OpType = 243 OpStructEndFloat64 OpType = 243
OpStructFieldBool OpType = 244 OpStructEndOmitEmptyFloat64 OpType = 244
OpStructFieldOmitEmptyBool OpType = 245 OpStructFieldBool OpType = 245
OpStructEndBool OpType = 246 OpStructFieldOmitEmptyBool OpType = 246
OpStructEndOmitEmptyBool OpType = 247 OpStructEndBool OpType = 247
OpStructFieldString OpType = 248 OpStructEndOmitEmptyBool OpType = 248
OpStructFieldOmitEmptyString OpType = 249 OpStructFieldString OpType = 249
OpStructEndString OpType = 250 OpStructFieldOmitEmptyString OpType = 250
OpStructEndOmitEmptyString OpType = 251 OpStructEndString OpType = 251
OpStructFieldBytes OpType = 252 OpStructEndOmitEmptyString OpType = 252
OpStructFieldOmitEmptyBytes OpType = 253 OpStructFieldBytes OpType = 253
OpStructEndBytes OpType = 254 OpStructFieldOmitEmptyBytes OpType = 254
OpStructEndOmitEmptyBytes OpType = 255 OpStructEndBytes OpType = 255
OpStructFieldNumber OpType = 256 OpStructEndOmitEmptyBytes OpType = 256
OpStructFieldOmitEmptyNumber OpType = 257 OpStructFieldNumber OpType = 257
OpStructEndNumber OpType = 258 OpStructFieldOmitEmptyNumber OpType = 258
OpStructEndOmitEmptyNumber OpType = 259 OpStructEndNumber OpType = 259
OpStructFieldArray OpType = 260 OpStructEndOmitEmptyNumber OpType = 260
OpStructFieldOmitEmptyArray OpType = 261 OpStructFieldArray OpType = 261
OpStructEndArray OpType = 262 OpStructFieldOmitEmptyArray OpType = 262
OpStructEndOmitEmptyArray OpType = 263 OpStructEndArray OpType = 263
OpStructFieldMap OpType = 264 OpStructEndOmitEmptyArray OpType = 264
OpStructFieldOmitEmptyMap OpType = 265 OpStructFieldMap OpType = 265
OpStructEndMap OpType = 266 OpStructFieldOmitEmptyMap OpType = 266
OpStructEndOmitEmptyMap OpType = 267 OpStructEndMap OpType = 267
OpStructFieldSlice OpType = 268 OpStructEndOmitEmptyMap OpType = 268
OpStructFieldOmitEmptySlice OpType = 269 OpStructFieldSlice OpType = 269
OpStructEndSlice OpType = 270 OpStructFieldOmitEmptySlice OpType = 270
OpStructEndOmitEmptySlice OpType = 271 OpStructEndSlice OpType = 271
OpStructFieldStruct OpType = 272 OpStructEndOmitEmptySlice OpType = 272
OpStructFieldOmitEmptyStruct OpType = 273 OpStructFieldStruct OpType = 273
OpStructEndStruct OpType = 274 OpStructFieldOmitEmptyStruct OpType = 274
OpStructEndOmitEmptyStruct OpType = 275 OpStructEndStruct OpType = 275
OpStructFieldMarshalJSON OpType = 276 OpStructEndOmitEmptyStruct OpType = 276
OpStructFieldOmitEmptyMarshalJSON OpType = 277 OpStructFieldMarshalJSON OpType = 277
OpStructEndMarshalJSON OpType = 278 OpStructFieldOmitEmptyMarshalJSON OpType = 278
OpStructEndOmitEmptyMarshalJSON OpType = 279 OpStructEndMarshalJSON OpType = 279
OpStructFieldMarshalText OpType = 280 OpStructEndOmitEmptyMarshalJSON OpType = 280
OpStructFieldOmitEmptyMarshalText OpType = 281 OpStructFieldMarshalText OpType = 281
OpStructEndMarshalText OpType = 282 OpStructFieldOmitEmptyMarshalText OpType = 282
OpStructEndOmitEmptyMarshalText OpType = 283 OpStructEndMarshalText OpType = 283
OpStructFieldIntString OpType = 284 OpStructEndOmitEmptyMarshalText OpType = 284
OpStructFieldOmitEmptyIntString OpType = 285 OpStructFieldIntString OpType = 285
OpStructEndIntString OpType = 286 OpStructFieldOmitEmptyIntString OpType = 286
OpStructEndOmitEmptyIntString OpType = 287 OpStructEndIntString OpType = 287
OpStructFieldUintString OpType = 288 OpStructEndOmitEmptyIntString OpType = 288
OpStructFieldOmitEmptyUintString OpType = 289 OpStructFieldUintString OpType = 289
OpStructEndUintString OpType = 290 OpStructFieldOmitEmptyUintString OpType = 290
OpStructEndOmitEmptyUintString OpType = 291 OpStructEndUintString OpType = 291
OpStructFieldFloat32String OpType = 292 OpStructEndOmitEmptyUintString OpType = 292
OpStructFieldOmitEmptyFloat32String OpType = 293 OpStructFieldFloat32String OpType = 293
OpStructEndFloat32String OpType = 294 OpStructFieldOmitEmptyFloat32String OpType = 294
OpStructEndOmitEmptyFloat32String OpType = 295 OpStructEndFloat32String OpType = 295
OpStructFieldFloat64String OpType = 296 OpStructEndOmitEmptyFloat32String OpType = 296
OpStructFieldOmitEmptyFloat64String OpType = 297 OpStructFieldFloat64String OpType = 297
OpStructEndFloat64String OpType = 298 OpStructFieldOmitEmptyFloat64String OpType = 298
OpStructEndOmitEmptyFloat64String OpType = 299 OpStructEndFloat64String OpType = 299
OpStructFieldBoolString OpType = 300 OpStructEndOmitEmptyFloat64String OpType = 300
OpStructFieldOmitEmptyBoolString OpType = 301 OpStructFieldBoolString OpType = 301
OpStructEndBoolString OpType = 302 OpStructFieldOmitEmptyBoolString OpType = 302
OpStructEndOmitEmptyBoolString OpType = 303 OpStructEndBoolString OpType = 303
OpStructFieldStringString OpType = 304 OpStructEndOmitEmptyBoolString OpType = 304
OpStructFieldOmitEmptyStringString OpType = 305 OpStructFieldStringString OpType = 305
OpStructEndStringString OpType = 306 OpStructFieldOmitEmptyStringString OpType = 306
OpStructEndOmitEmptyStringString OpType = 307 OpStructEndStringString OpType = 307
OpStructFieldNumberString OpType = 308 OpStructEndOmitEmptyStringString OpType = 308
OpStructFieldOmitEmptyNumberString OpType = 309 OpStructFieldNumberString OpType = 309
OpStructEndNumberString OpType = 310 OpStructFieldOmitEmptyNumberString OpType = 310
OpStructEndOmitEmptyNumberString OpType = 311 OpStructEndNumberString OpType = 311
OpStructFieldIntPtr OpType = 312 OpStructEndOmitEmptyNumberString OpType = 312
OpStructFieldOmitEmptyIntPtr OpType = 313 OpStructFieldIntPtr OpType = 313
OpStructEndIntPtr OpType = 314 OpStructFieldOmitEmptyIntPtr OpType = 314
OpStructEndOmitEmptyIntPtr OpType = 315 OpStructEndIntPtr OpType = 315
OpStructFieldUintPtr OpType = 316 OpStructEndOmitEmptyIntPtr OpType = 316
OpStructFieldOmitEmptyUintPtr OpType = 317 OpStructFieldUintPtr OpType = 317
OpStructEndUintPtr OpType = 318 OpStructFieldOmitEmptyUintPtr OpType = 318
OpStructEndOmitEmptyUintPtr OpType = 319 OpStructEndUintPtr OpType = 319
OpStructFieldFloat32Ptr OpType = 320 OpStructEndOmitEmptyUintPtr OpType = 320
OpStructFieldOmitEmptyFloat32Ptr OpType = 321 OpStructFieldFloat32Ptr OpType = 321
OpStructEndFloat32Ptr OpType = 322 OpStructFieldOmitEmptyFloat32Ptr OpType = 322
OpStructEndOmitEmptyFloat32Ptr OpType = 323 OpStructEndFloat32Ptr OpType = 323
OpStructFieldFloat64Ptr OpType = 324 OpStructEndOmitEmptyFloat32Ptr OpType = 324
OpStructFieldOmitEmptyFloat64Ptr OpType = 325 OpStructFieldFloat64Ptr OpType = 325
OpStructEndFloat64Ptr OpType = 326 OpStructFieldOmitEmptyFloat64Ptr OpType = 326
OpStructEndOmitEmptyFloat64Ptr OpType = 327 OpStructEndFloat64Ptr OpType = 327
OpStructFieldBoolPtr OpType = 328 OpStructEndOmitEmptyFloat64Ptr OpType = 328
OpStructFieldOmitEmptyBoolPtr OpType = 329 OpStructFieldBoolPtr OpType = 329
OpStructEndBoolPtr OpType = 330 OpStructFieldOmitEmptyBoolPtr OpType = 330
OpStructEndOmitEmptyBoolPtr OpType = 331 OpStructEndBoolPtr OpType = 331
OpStructFieldStringPtr OpType = 332 OpStructEndOmitEmptyBoolPtr OpType = 332
OpStructFieldOmitEmptyStringPtr OpType = 333 OpStructFieldStringPtr OpType = 333
OpStructEndStringPtr OpType = 334 OpStructFieldOmitEmptyStringPtr OpType = 334
OpStructEndOmitEmptyStringPtr OpType = 335 OpStructEndStringPtr OpType = 335
OpStructFieldBytesPtr OpType = 336 OpStructEndOmitEmptyStringPtr OpType = 336
OpStructFieldOmitEmptyBytesPtr OpType = 337 OpStructFieldBytesPtr OpType = 337
OpStructEndBytesPtr OpType = 338 OpStructFieldOmitEmptyBytesPtr OpType = 338
OpStructEndOmitEmptyBytesPtr OpType = 339 OpStructEndBytesPtr OpType = 339
OpStructFieldNumberPtr OpType = 340 OpStructEndOmitEmptyBytesPtr OpType = 340
OpStructFieldOmitEmptyNumberPtr OpType = 341 OpStructFieldNumberPtr OpType = 341
OpStructEndNumberPtr OpType = 342 OpStructFieldOmitEmptyNumberPtr OpType = 342
OpStructEndOmitEmptyNumberPtr OpType = 343 OpStructEndNumberPtr OpType = 343
OpStructFieldArrayPtr OpType = 344 OpStructEndOmitEmptyNumberPtr OpType = 344
OpStructFieldOmitEmptyArrayPtr OpType = 345 OpStructFieldArrayPtr OpType = 345
OpStructEndArrayPtr OpType = 346 OpStructFieldOmitEmptyArrayPtr OpType = 346
OpStructEndOmitEmptyArrayPtr OpType = 347 OpStructEndArrayPtr OpType = 347
OpStructFieldMapPtr OpType = 348 OpStructEndOmitEmptyArrayPtr OpType = 348
OpStructFieldOmitEmptyMapPtr OpType = 349 OpStructFieldMapPtr OpType = 349
OpStructEndMapPtr OpType = 350 OpStructFieldOmitEmptyMapPtr OpType = 350
OpStructEndOmitEmptyMapPtr OpType = 351 OpStructEndMapPtr OpType = 351
OpStructFieldSlicePtr OpType = 352 OpStructEndOmitEmptyMapPtr OpType = 352
OpStructFieldOmitEmptySlicePtr OpType = 353 OpStructFieldSlicePtr OpType = 353
OpStructEndSlicePtr OpType = 354 OpStructFieldOmitEmptySlicePtr OpType = 354
OpStructEndOmitEmptySlicePtr OpType = 355 OpStructEndSlicePtr OpType = 355
OpStructFieldMarshalJSONPtr OpType = 356 OpStructEndOmitEmptySlicePtr OpType = 356
OpStructFieldOmitEmptyMarshalJSONPtr OpType = 357 OpStructFieldMarshalJSONPtr OpType = 357
OpStructEndMarshalJSONPtr OpType = 358 OpStructFieldOmitEmptyMarshalJSONPtr OpType = 358
OpStructEndOmitEmptyMarshalJSONPtr OpType = 359 OpStructEndMarshalJSONPtr OpType = 359
OpStructFieldMarshalTextPtr OpType = 360 OpStructEndOmitEmptyMarshalJSONPtr OpType = 360
OpStructFieldOmitEmptyMarshalTextPtr OpType = 361 OpStructFieldMarshalTextPtr OpType = 361
OpStructEndMarshalTextPtr OpType = 362 OpStructFieldOmitEmptyMarshalTextPtr OpType = 362
OpStructEndOmitEmptyMarshalTextPtr OpType = 363 OpStructEndMarshalTextPtr OpType = 363
OpStructFieldInterfacePtr OpType = 364 OpStructEndOmitEmptyMarshalTextPtr OpType = 364
OpStructFieldOmitEmptyInterfacePtr OpType = 365 OpStructFieldInterfacePtr OpType = 365
OpStructEndInterfacePtr OpType = 366 OpStructFieldOmitEmptyInterfacePtr OpType = 366
OpStructEndOmitEmptyInterfacePtr OpType = 367 OpStructEndInterfacePtr OpType = 367
OpStructFieldIntPtrString OpType = 368 OpStructEndOmitEmptyInterfacePtr OpType = 368
OpStructFieldOmitEmptyIntPtrString OpType = 369 OpStructFieldIntPtrString OpType = 369
OpStructEndIntPtrString OpType = 370 OpStructFieldOmitEmptyIntPtrString OpType = 370
OpStructEndOmitEmptyIntPtrString OpType = 371 OpStructEndIntPtrString OpType = 371
OpStructFieldUintPtrString OpType = 372 OpStructEndOmitEmptyIntPtrString OpType = 372
OpStructFieldOmitEmptyUintPtrString OpType = 373 OpStructFieldUintPtrString OpType = 373
OpStructEndUintPtrString OpType = 374 OpStructFieldOmitEmptyUintPtrString OpType = 374
OpStructEndOmitEmptyUintPtrString OpType = 375 OpStructEndUintPtrString OpType = 375
OpStructFieldFloat32PtrString OpType = 376 OpStructEndOmitEmptyUintPtrString OpType = 376
OpStructFieldOmitEmptyFloat32PtrString OpType = 377 OpStructFieldFloat32PtrString OpType = 377
OpStructEndFloat32PtrString OpType = 378 OpStructFieldOmitEmptyFloat32PtrString OpType = 378
OpStructEndOmitEmptyFloat32PtrString OpType = 379 OpStructEndFloat32PtrString OpType = 379
OpStructFieldFloat64PtrString OpType = 380 OpStructEndOmitEmptyFloat32PtrString OpType = 380
OpStructFieldOmitEmptyFloat64PtrString OpType = 381 OpStructFieldFloat64PtrString OpType = 381
OpStructEndFloat64PtrString OpType = 382 OpStructFieldOmitEmptyFloat64PtrString OpType = 382
OpStructEndOmitEmptyFloat64PtrString OpType = 383 OpStructEndFloat64PtrString OpType = 383
OpStructFieldBoolPtrString OpType = 384 OpStructEndOmitEmptyFloat64PtrString OpType = 384
OpStructFieldOmitEmptyBoolPtrString OpType = 385 OpStructFieldBoolPtrString OpType = 385
OpStructEndBoolPtrString OpType = 386 OpStructFieldOmitEmptyBoolPtrString OpType = 386
OpStructEndOmitEmptyBoolPtrString OpType = 387 OpStructEndBoolPtrString OpType = 387
OpStructFieldStringPtrString OpType = 388 OpStructEndOmitEmptyBoolPtrString OpType = 388
OpStructFieldOmitEmptyStringPtrString OpType = 389 OpStructFieldStringPtrString OpType = 389
OpStructEndStringPtrString OpType = 390 OpStructFieldOmitEmptyStringPtrString OpType = 390
OpStructEndOmitEmptyStringPtrString OpType = 391 OpStructEndStringPtrString OpType = 391
OpStructFieldNumberPtrString OpType = 392 OpStructEndOmitEmptyStringPtrString OpType = 392
OpStructFieldOmitEmptyNumberPtrString OpType = 393 OpStructFieldNumberPtrString OpType = 393
OpStructEndNumberPtrString OpType = 394 OpStructFieldOmitEmptyNumberPtrString OpType = 394
OpStructEndOmitEmptyNumberPtrString OpType = 395 OpStructEndNumberPtrString OpType = 395
OpStructField OpType = 396 OpStructEndOmitEmptyNumberPtrString OpType = 396
OpStructFieldOmitEmpty OpType = 397 OpStructField OpType = 397
OpStructEnd OpType = 398 OpStructFieldOmitEmpty OpType = 398
OpStructEndOmitEmpty OpType = 399 OpStructEnd OpType = 399
OpStructEndOmitEmpty OpType = 400
) )
func (t OpType) String() string { func (t OpType) String() string {
if int(t) >= 400 { if int(t) >= 401 {
return "" return ""
} }
return opTypeStrings[int(t)] return opTypeStrings[int(t)]

View File

@ -123,39 +123,6 @@ func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte
return b return b
} }
func appendInterface(ctx *encoder.RuntimeContext, codeSet *encoder.OpcodeSet, _ *encoder.Opcode, b []byte, iface *emptyInterface, ptrOffset uintptr) ([]byte, error) {
ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface))
ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ)))
if err != nil {
return nil, err
}
totalLength := uintptr(codeSet.CodeLength)
nextTotalLength := uintptr(ifaceCodeSet.CodeLength)
curlen := uintptr(len(ctx.Ptrs))
offsetNum := ptrOffset / uintptrSize
newLen := offsetNum + totalLength + nextTotalLength
if curlen < newLen {
ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
}
oldPtrs := ctx.Ptrs
newPtrs := ctx.Ptrs[(ptrOffset+totalLength*uintptrSize)/uintptrSize:]
newPtrs[0] = uintptr(iface.ptr)
ctx.Ptrs = newPtrs
bb, err := Run(ctx, b, ifaceCodeSet)
if err != nil {
return nil, err
}
ctx.Ptrs = oldPtrs
return bb, nil
}
func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
return encoder.AppendMarshalJSON(ctx, code, b, v) return encoder.AppendMarshalJSON(ctx, code, b, v)
} }

View File

@ -190,15 +190,52 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
code = code.Next code = code.Next
break break
} }
bb, err := appendInterface(ctx, codeSet, code, b, iface, ptrOffset)
ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface))
ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ)))
if err != nil { if err != nil {
return nil, err return nil, err
} }
ctxptr = ctx.Ptr()
totalLength := uintptr(code.Length) + 3
nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3
var c *encoder.Opcode
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
c = ifaceCodeSet.InterfaceEscapeKeyCode
} else {
c = ifaceCodeSet.InterfaceNoescapeKeyCode
}
curlen := uintptr(len(ctx.Ptrs))
offsetNum := ptrOffset / uintptrSize
oldOffset := ptrOffset
ptrOffset += totalLength * uintptrSize
oldBaseIndent := ctx.BaseIndent
indentDiffFromTop := c.Indent - 1
ctx.BaseIndent += code.Indent - indentDiffFromTop
newLen := offsetNum + totalLength + nextTotalLength
if curlen < newLen {
ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
}
ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
end := ifaceCodeSet.EndCode
store(ctxptr, c.Idx, uintptr(iface.ptr))
store(ctxptr, end.Idx, oldOffset)
store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, end, uintptr(oldBaseIndent))
code = c
case encoder.OpInterfaceEnd:
offset := load(ctxptr, code.Idx)
// restore ctxptr
restoreIndent(ctx, code, ctxptr)
ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
b = bb codePtr := load(ctxptr, code.ElemIdx)
code = code.Next code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
ctxptr = ctx.Ptr() + offset
ptrOffset = offset
case encoder.OpMarshalJSONPtr: case encoder.OpMarshalJSONPtr:
p := load(ctxptr, code.Idx) p := load(ctxptr, code.Idx)
if p == 0 { if p == 0 {
@ -496,7 +533,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
store(ctxptr, c.Idx, ptr) store(ctxptr, c.Idx, ptr)
store(ctxptr, c.End.Next.Idx, oldOffset) store(ctxptr, c.End.Next.Idx, oldOffset)
store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, c, uintptr(oldBaseIndent)) storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent))
code = c code = c
recursiveLevel++ recursiveLevel++
case encoder.OpRecursiveEnd: case encoder.OpRecursiveEnd:

View File

@ -176,39 +176,6 @@ func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte
return b return b
} }
func appendInterface(ctx *encoder.RuntimeContext, codeSet *encoder.OpcodeSet, _ *encoder.Opcode, b []byte, iface *emptyInterface, ptrOffset uintptr) ([]byte, error) {
ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface))
ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ)))
if err != nil {
return nil, err
}
totalLength := uintptr(codeSet.CodeLength)
nextTotalLength := uintptr(ifaceCodeSet.CodeLength)
curlen := uintptr(len(ctx.Ptrs))
offsetNum := ptrOffset / uintptrSize
newLen := offsetNum + totalLength + nextTotalLength
if curlen < newLen {
ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
}
oldPtrs := ctx.Ptrs
newPtrs := ctx.Ptrs[(ptrOffset+totalLength*uintptrSize)/uintptrSize:]
newPtrs[0] = uintptr(iface.ptr)
ctx.Ptrs = newPtrs
bb, err := Run(ctx, b, ifaceCodeSet)
if err != nil {
return nil, err
}
ctx.Ptrs = oldPtrs
return bb, nil
}
func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
return encoder.AppendMarshalJSON(ctx, code, b, v) return encoder.AppendMarshalJSON(ctx, code, b, v)
} }

View File

@ -190,15 +190,52 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
code = code.Next code = code.Next
break break
} }
bb, err := appendInterface(ctx, codeSet, code, b, iface, ptrOffset)
ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface))
ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ)))
if err != nil { if err != nil {
return nil, err return nil, err
} }
ctxptr = ctx.Ptr()
totalLength := uintptr(code.Length) + 3
nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3
var c *encoder.Opcode
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
c = ifaceCodeSet.InterfaceEscapeKeyCode
} else {
c = ifaceCodeSet.InterfaceNoescapeKeyCode
}
curlen := uintptr(len(ctx.Ptrs))
offsetNum := ptrOffset / uintptrSize
oldOffset := ptrOffset
ptrOffset += totalLength * uintptrSize
oldBaseIndent := ctx.BaseIndent
indentDiffFromTop := c.Indent - 1
ctx.BaseIndent += code.Indent - indentDiffFromTop
newLen := offsetNum + totalLength + nextTotalLength
if curlen < newLen {
ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
}
ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
end := ifaceCodeSet.EndCode
store(ctxptr, c.Idx, uintptr(iface.ptr))
store(ctxptr, end.Idx, oldOffset)
store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, end, uintptr(oldBaseIndent))
code = c
case encoder.OpInterfaceEnd:
offset := load(ctxptr, code.Idx)
// restore ctxptr
restoreIndent(ctx, code, ctxptr)
ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
b = bb codePtr := load(ctxptr, code.ElemIdx)
code = code.Next code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
ctxptr = ctx.Ptr() + offset
ptrOffset = offset
case encoder.OpMarshalJSONPtr: case encoder.OpMarshalJSONPtr:
p := load(ctxptr, code.Idx) p := load(ctxptr, code.Idx)
if p == 0 { if p == 0 {
@ -496,7 +533,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
store(ctxptr, c.Idx, ptr) store(ctxptr, c.Idx, ptr)
store(ctxptr, c.End.Next.Idx, oldOffset) store(ctxptr, c.End.Next.Idx, oldOffset)
store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, c, uintptr(oldBaseIndent)) storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent))
code = c code = c
recursiveLevel++ recursiveLevel++
case encoder.OpRecursiveEnd: case encoder.OpRecursiveEnd:

View File

@ -163,43 +163,6 @@ func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
return append(b, ':', ' ') return append(b, ':', ' ')
} }
func appendInterface(ctx *encoder.RuntimeContext, codeSet *encoder.OpcodeSet, code *encoder.Opcode, b []byte, iface *emptyInterface, ptrOffset uintptr) ([]byte, error) {
ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface))
ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ)))
if err != nil {
return nil, err
}
totalLength := uintptr(codeSet.CodeLength)
nextTotalLength := uintptr(ifaceCodeSet.CodeLength)
curlen := uintptr(len(ctx.Ptrs))
offsetNum := ptrOffset / uintptrSize
newLen := offsetNum + totalLength + nextTotalLength
if curlen < newLen {
ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
}
oldPtrs := ctx.Ptrs
newPtrs := ctx.Ptrs[(ptrOffset+totalLength*uintptrSize)/uintptrSize:]
newPtrs[0] = uintptr(iface.ptr)
ctx.Ptrs = newPtrs
oldBaseIndent := ctx.BaseIndent
ctx.BaseIndent = code.Indent
bb, err := Run(ctx, b, ifaceCodeSet)
if err != nil {
return nil, err
}
ctx.BaseIndent = oldBaseIndent
ctx.Ptrs = oldPtrs
return bb, nil
}
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte { func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
b = appendIndent(ctx, b, code.Indent+1) b = appendIndent(ctx, b, code.Indent+1)
b = append(b, key...) b = append(b, key...)
@ -292,7 +255,7 @@ func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uin
} }
func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) { func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) {
store(ctxptr, code.End.Next.Length, indent) store(ctxptr, code.Length, indent)
} }
func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {

View File

@ -190,15 +190,52 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
code = code.Next code = code.Next
break break
} }
bb, err := appendInterface(ctx, codeSet, code, b, iface, ptrOffset)
ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface))
ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ)))
if err != nil { if err != nil {
return nil, err return nil, err
} }
ctxptr = ctx.Ptr()
totalLength := uintptr(code.Length) + 3
nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3
var c *encoder.Opcode
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
c = ifaceCodeSet.InterfaceEscapeKeyCode
} else {
c = ifaceCodeSet.InterfaceNoescapeKeyCode
}
curlen := uintptr(len(ctx.Ptrs))
offsetNum := ptrOffset / uintptrSize
oldOffset := ptrOffset
ptrOffset += totalLength * uintptrSize
oldBaseIndent := ctx.BaseIndent
indentDiffFromTop := c.Indent - 1
ctx.BaseIndent += code.Indent - indentDiffFromTop
newLen := offsetNum + totalLength + nextTotalLength
if curlen < newLen {
ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
}
ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
end := ifaceCodeSet.EndCode
store(ctxptr, c.Idx, uintptr(iface.ptr))
store(ctxptr, end.Idx, oldOffset)
store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, end, uintptr(oldBaseIndent))
code = c
case encoder.OpInterfaceEnd:
offset := load(ctxptr, code.Idx)
// restore ctxptr
restoreIndent(ctx, code, ctxptr)
ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
b = bb codePtr := load(ctxptr, code.ElemIdx)
code = code.Next code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
ctxptr = ctx.Ptr() + offset
ptrOffset = offset
case encoder.OpMarshalJSONPtr: case encoder.OpMarshalJSONPtr:
p := load(ctxptr, code.Idx) p := load(ctxptr, code.Idx)
if p == 0 { if p == 0 {
@ -496,7 +533,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
store(ctxptr, c.Idx, ptr) store(ctxptr, c.Idx, ptr)
store(ctxptr, c.End.Next.Idx, oldOffset) store(ctxptr, c.End.Next.Idx, oldOffset)
store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, c, uintptr(oldBaseIndent)) storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent))
code = c code = c
recursiveLevel++ recursiveLevel++
case encoder.OpRecursiveEnd: case encoder.OpRecursiveEnd:

View File

@ -111,43 +111,6 @@ func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
return append(b, ':', ' ') return append(b, ':', ' ')
} }
func appendInterface(ctx *encoder.RuntimeContext, codeSet *encoder.OpcodeSet, code *encoder.Opcode, b []byte, iface *emptyInterface, ptrOffset uintptr) ([]byte, error) {
ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface))
ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ)))
if err != nil {
return nil, err
}
totalLength := uintptr(codeSet.CodeLength)
nextTotalLength := uintptr(ifaceCodeSet.CodeLength)
curlen := uintptr(len(ctx.Ptrs))
offsetNum := ptrOffset / uintptrSize
newLen := offsetNum + totalLength + nextTotalLength
if curlen < newLen {
ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
}
oldPtrs := ctx.Ptrs
newPtrs := ctx.Ptrs[(ptrOffset+totalLength*uintptrSize)/uintptrSize:]
newPtrs[0] = uintptr(iface.ptr)
ctx.Ptrs = newPtrs
oldBaseIndent := ctx.BaseIndent
ctx.BaseIndent = code.Indent
bb, err := Run(ctx, b, ifaceCodeSet)
if err != nil {
return nil, err
}
ctx.BaseIndent = oldBaseIndent
ctx.Ptrs = oldPtrs
return bb, nil
}
func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte { func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
b = appendIndent(ctx, b, code.Indent+1) b = appendIndent(ctx, b, code.Indent+1)
b = append(b, key...) b = append(b, key...)
@ -229,7 +192,7 @@ func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uin
} }
func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) { func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) {
store(ctxptr, code.End.Next.Length, indent) store(ctxptr, code.Length, indent)
} }
func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {

View File

@ -190,15 +190,52 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
code = code.Next code = code.Next
break break
} }
bb, err := appendInterface(ctx, codeSet, code, b, iface, ptrOffset)
ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface))
ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ)))
if err != nil { if err != nil {
return nil, err return nil, err
} }
ctxptr = ctx.Ptr()
totalLength := uintptr(code.Length) + 3
nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3
var c *encoder.Opcode
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
c = ifaceCodeSet.InterfaceEscapeKeyCode
} else {
c = ifaceCodeSet.InterfaceNoescapeKeyCode
}
curlen := uintptr(len(ctx.Ptrs))
offsetNum := ptrOffset / uintptrSize
oldOffset := ptrOffset
ptrOffset += totalLength * uintptrSize
oldBaseIndent := ctx.BaseIndent
indentDiffFromTop := c.Indent - 1
ctx.BaseIndent += code.Indent - indentDiffFromTop
newLen := offsetNum + totalLength + nextTotalLength
if curlen < newLen {
ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
}
ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
end := ifaceCodeSet.EndCode
store(ctxptr, c.Idx, uintptr(iface.ptr))
store(ctxptr, end.Idx, oldOffset)
store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, end, uintptr(oldBaseIndent))
code = c
case encoder.OpInterfaceEnd:
offset := load(ctxptr, code.Idx)
// restore ctxptr
restoreIndent(ctx, code, ctxptr)
ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
b = bb codePtr := load(ctxptr, code.ElemIdx)
code = code.Next code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
ctxptr = ctx.Ptr() + offset
ptrOffset = offset
case encoder.OpMarshalJSONPtr: case encoder.OpMarshalJSONPtr:
p := load(ctxptr, code.Idx) p := load(ctxptr, code.Idx)
if p == 0 { if p == 0 {
@ -496,7 +533,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
store(ctxptr, c.Idx, ptr) store(ctxptr, c.Idx, ptr)
store(ctxptr, c.End.Next.Idx, oldOffset) store(ctxptr, c.End.Next.Idx, oldOffset)
store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
storeIndent(ctxptr, c, uintptr(oldBaseIndent)) storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent))
code = c code = c
recursiveLevel++ recursiveLevel++
case encoder.OpRecursiveEnd: case encoder.OpRecursiveEnd: