diff --git a/cmd/generator/main.go b/cmd/generator/main.go index 971dc5b..c6a3c9e 100644 --- a/cmd/generator/main.go +++ b/cmd/generator/main.go @@ -220,6 +220,7 @@ func (t opType) fieldToStringTagField() opType { opTypes := []opType{ {"End", "EndIndent", "Op"}, {"Interface", "InterfaceIndent", "Op"}, + {"InterfaceEnd", "InterfaceEndIndent", "Op"}, {"Ptr", "PtrIndent", "Op"}, {"SliceHead", "SliceHeadIndent", "SliceHead"}, {"RootSliceHead", "RootSliceHeadIndent", "SliceHead"}, @@ -252,6 +253,7 @@ func (t opType) fieldToStringTagField() opType { {"StructFieldOmitEmpty", "StructFieldOmitEmptyIndent", "StructField"}, {"StructFieldStringTag", "StructFieldStringTagIndent", "StructField"}, {"StructFieldRecursive", "StructFieldRecursiveIndent", "StructFieldRecursive"}, + {"StructFieldRecursiveEnd", "StructFieldRecursiveEndIndent", "Op"}, {"StructEnd", "StructEndIndent", "StructField"}, {"StructAnonymousEnd", "StructAnonymousEndIndent", "StructField"}, } diff --git a/encode.go b/encode.go index 58f019a..e192e34 100644 --- a/encode.go +++ b/encode.go @@ -19,7 +19,6 @@ type Encoder struct { enabledHTMLEscape bool prefix []byte indentStr []byte - indent int structTypeToCompiledCode map[uintptr]*compiledCode structTypeToCompiledIndentCode map[uintptr]*compiledCode } @@ -37,8 +36,9 @@ type opcodeMap struct { } type opcodeSet struct { - codeIndent sync.Pool - code sync.Pool + codeIndent *opcode + code *opcode + ctx sync.Pool } func (m *opcodeMap) get(k uintptr) *opcodeSet { @@ -123,7 +123,6 @@ func (e *Encoder) release() { func (e *Encoder) reset() { e.buf = e.buf[:0] - e.indent = 0 e.enabledHTMLEscape = true e.enabledIndent = false } @@ -159,54 +158,68 @@ func (e *Encoder) encode(v interface{}) error { if codeSet := cachedOpcode.get(typeptr); codeSet != nil { var code *opcode if e.enabledIndent { - code = codeSet.codeIndent.Get().(*opcode) + code = codeSet.codeIndent } else { - code = codeSet.code.Get().(*opcode) + code = codeSet.code } + ctx := codeSet.ctx.Get().(*encodeRuntimeContext) p := uintptr(header.ptr) - code.ptr = p - if err := e.run(code); err != nil { - return err - } - if e.enabledIndent { - codeSet.codeIndent.Put(code) - } else { - codeSet.code.Put(code) - } - return nil + ctx.init(p) + err := e.run(ctx, code) + codeSet.ctx.Put(ctx) + return err } // noescape trick for header.typ ( reflect.*rtype ) copiedType := (*rtype)(unsafe.Pointer(typeptr)) - codeIndent, err := e.compileHead(copiedType, true) + codeIndent, err := e.compileHead(&encodeCompileContext{ + typ: copiedType, + root: true, + withIndent: true, + }) if err != nil { return err } - code, err := e.compileHead(copiedType, false) + code, err := e.compileHead(&encodeCompileContext{ + typ: copiedType, + root: true, + withIndent: false, + }) if err != nil { return err } + codeLength := code.totalLength() codeSet := &opcodeSet{ - codeIndent: sync.Pool{ + codeIndent: codeIndent, + code: code, + ctx: sync.Pool{ New: func() interface{} { - return copyOpcode(codeIndent) - }, - }, - code: sync.Pool{ - New: func() interface{} { - return copyOpcode(code) + return &encodeRuntimeContext{ + ptrs: make([]uintptr, codeLength), + keepRefs: make([]unsafe.Pointer, 8), + } }, }, } cachedOpcode.set(typeptr, codeSet) p := uintptr(header.ptr) + ctx := codeSet.ctx.Get().(*encodeRuntimeContext) + ctx.init(p) + + var c *opcode if e.enabledIndent { - codeIndent.ptr = p - return e.run(codeIndent) + c = codeIndent + } else { + c = code } - code.ptr = p - return e.run(code) + + if err := e.run(ctx, c); err != nil { + codeSet.ctx.Put(ctx) + return err + } + codeSet.ctx.Put(ctx) + return nil } func (e *Encoder) encodeInt(v int) { diff --git a/encode_compile.go b/encode_compile.go index 9dc7ec2..fcbb05d 100644 --- a/encode_compile.go +++ b/encode_compile.go @@ -6,17 +6,17 @@ import ( "unsafe" ) -func (e *Encoder) compileHead(typ *rtype, withIndent bool) (*opcode, error) { - root := true +func (e *Encoder) compileHead(ctx *encodeCompileContext) (*opcode, error) { + typ := ctx.typ switch { case typ.Implements(marshalJSONType): - return newOpCode(opMarshalJSON, typ, e.indent, newEndOp(e.indent)), nil + return e.compileMarshalJSON(ctx) case rtype_ptrTo(typ).Implements(marshalJSONType): - return newOpCode(opMarshalJSON, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil + return e.compileMarshalJSONPtr(ctx) case typ.Implements(marshalTextType): - return newOpCode(opMarshalText, typ, e.indent, newEndOp(e.indent)), nil + return e.compileMarshalText(ctx) case rtype_ptrTo(typ).Implements(marshalTextType): - return newOpCode(opMarshalText, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil + return e.compileMarshalTextPtr(ctx) } isPtr := false if typ.Kind() == reflect.Ptr { @@ -24,11 +24,11 @@ func (e *Encoder) compileHead(typ *rtype, withIndent bool) (*opcode, error) { isPtr = true } if typ.Kind() == reflect.Map { - return e.compileMap(typ, isPtr, root, withIndent) + return e.compileMap(ctx.withType(typ), isPtr) } else if typ.Kind() == reflect.Struct { - return e.compileStruct(typ, isPtr, root, withIndent) + return e.compileStruct(ctx.withType(typ), isPtr) } - return e.compile(typ, root, withIndent) + return e.compile(ctx.withType(typ)) } func (e *Encoder) implementsMarshaler(typ *rtype) bool { @@ -45,215 +45,240 @@ func (e *Encoder) implementsMarshaler(typ *rtype) bool { return false } -func (e *Encoder) compile(typ *rtype, root, withIndent bool) (*opcode, error) { +func (e *Encoder) compile(ctx *encodeCompileContext) (*opcode, error) { + typ := ctx.typ switch { case typ.Implements(marshalJSONType): - return newOpCode(opMarshalJSON, typ, e.indent, newEndOp(e.indent)), nil + return e.compileMarshalJSON(ctx) case rtype_ptrTo(typ).Implements(marshalJSONType): - return newOpCode(opMarshalJSON, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil + return e.compileMarshalJSONPtr(ctx) case typ.Implements(marshalTextType): - return newOpCode(opMarshalText, typ, e.indent, newEndOp(e.indent)), nil + return e.compileMarshalText(ctx) case rtype_ptrTo(typ).Implements(marshalTextType): - return newOpCode(opMarshalText, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil + return e.compileMarshalTextPtr(ctx) } switch typ.Kind() { case reflect.Ptr: - return e.compilePtr(typ, root, withIndent) + return e.compilePtr(ctx) case reflect.Slice: elem := typ.Elem() if !e.implementsMarshaler(elem) && elem.Kind() == reflect.Uint8 { - return e.compileBytes(typ) + return e.compileBytes(ctx) } - return e.compileSlice(typ, root, withIndent) + return e.compileSlice(ctx) case reflect.Array: - return e.compileArray(typ, root, withIndent) + return e.compileArray(ctx) case reflect.Map: - return e.compileMap(typ, true, root, withIndent) + return e.compileMap(ctx, true) case reflect.Struct: - return e.compileStruct(typ, false, root, withIndent) + return e.compileStruct(ctx, false) case reflect.Interface: - return e.compileInterface(typ, root) + return e.compileInterface(ctx) case reflect.Int: - return e.compileInt(typ) + return e.compileInt(ctx) case reflect.Int8: - return e.compileInt8(typ) + return e.compileInt8(ctx) case reflect.Int16: - return e.compileInt16(typ) + return e.compileInt16(ctx) case reflect.Int32: - return e.compileInt32(typ) + return e.compileInt32(ctx) case reflect.Int64: - return e.compileInt64(typ) + return e.compileInt64(ctx) case reflect.Uint: - return e.compileUint(typ) + return e.compileUint(ctx) case reflect.Uint8: - return e.compileUint8(typ) + return e.compileUint8(ctx) case reflect.Uint16: - return e.compileUint16(typ) + return e.compileUint16(ctx) case reflect.Uint32: - return e.compileUint32(typ) + return e.compileUint32(ctx) case reflect.Uint64: - return e.compileUint64(typ) + return e.compileUint64(ctx) case reflect.Uintptr: - return e.compileUint(typ) + return e.compileUint(ctx) case reflect.Float32: - return e.compileFloat32(typ) + return e.compileFloat32(ctx) case reflect.Float64: - return e.compileFloat64(typ) + return e.compileFloat64(ctx) case reflect.String: - return e.compileString(typ) + return e.compileString(ctx) case reflect.Bool: - return e.compileBool(typ) + return e.compileBool(ctx) } return nil, &UnsupportedTypeError{Type: rtype2type(typ)} } -func (e *Encoder) compileKey(typ *rtype, root, withIndent bool) (*opcode, error) { +func (e *Encoder) compileKey(ctx *encodeCompileContext) (*opcode, error) { + typ := ctx.typ switch { case typ.Implements(marshalJSONType): - return newOpCode(opMarshalJSON, typ, e.indent, newEndOp(e.indent)), nil + return e.compileMarshalJSON(ctx) case rtype_ptrTo(typ).Implements(marshalJSONType): - return newOpCode(opMarshalJSON, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil + return e.compileMarshalJSONPtr(ctx) case typ.Implements(marshalTextType): - return newOpCode(opMarshalText, typ, e.indent, newEndOp(e.indent)), nil + return e.compileMarshalText(ctx) case rtype_ptrTo(typ).Implements(marshalTextType): - return newOpCode(opMarshalText, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil + return e.compileMarshalTextPtr(ctx) } switch typ.Kind() { case reflect.Ptr: - return e.compilePtr(typ, root, withIndent) + return e.compilePtr(ctx) case reflect.Interface: - return e.compileInterface(typ, root) - case reflect.Int: - return e.compileInt(typ) - case reflect.Int8: - return e.compileInt8(typ) - case reflect.Int16: - return e.compileInt16(typ) - case reflect.Int32: - return e.compileInt32(typ) - case reflect.Int64: - return e.compileInt64(typ) - case reflect.Uint: - return e.compileUint(typ) - case reflect.Uint8: - return e.compileUint8(typ) - case reflect.Uint16: - return e.compileUint16(typ) - case reflect.Uint32: - return e.compileUint32(typ) - case reflect.Uint64: - return e.compileUint64(typ) - case reflect.Uintptr: - return e.compileUint(typ) - case reflect.Float32: - return e.compileFloat32(typ) - case reflect.Float64: - return e.compileFloat64(typ) + return e.compileInterface(ctx) case reflect.String: - return e.compileString(typ) - case reflect.Bool: - return e.compileBool(typ) + return e.compileString(ctx) } return nil, &UnsupportedTypeError{Type: rtype2type(typ)} } -func (e *Encoder) optimizeStructFieldPtrHead(typ *rtype, code *opcode) *opcode { - ptrHeadOp := code.op.headToPtrHead() - if code.op != ptrHeadOp { - code.op = ptrHeadOp - return code - } - return newOpCode(opPtr, typ, e.indent, code) -} - -func (e *Encoder) compilePtr(typ *rtype, root, withIndent bool) (*opcode, error) { - code, err := e.compile(typ.Elem(), root, withIndent) +func (e *Encoder) compilePtr(ctx *encodeCompileContext) (*opcode, error) { + ptrOpcodeIndex := ctx.opcodeIndex + ctx.incIndex() + code, err := e.compile(ctx.withType(ctx.typ.Elem())) if err != nil { return nil, err } - return e.optimizeStructFieldPtrHead(typ, code), nil + ptrHeadOp := code.op.headToPtrHead() + if code.op != ptrHeadOp { + code.op = ptrHeadOp + code.decOpcodeIndex() + ctx.decIndex() + return code, nil + } + c := ctx.context() + c.opcodeIndex = ptrOpcodeIndex + return newOpCodeWithNext(c, opPtr, code), nil } -func (e *Encoder) compileInt(typ *rtype) (*opcode, error) { - return newOpCode(opInt, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileMarshalJSON(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opMarshalJSON) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileInt8(typ *rtype) (*opcode, error) { - return newOpCode(opInt8, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileMarshalJSONPtr(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx.withType(rtype_ptrTo(ctx.typ)), opMarshalJSON) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileInt16(typ *rtype) (*opcode, error) { - return newOpCode(opInt16, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileMarshalText(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opMarshalText) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileInt32(typ *rtype) (*opcode, error) { - return newOpCode(opInt32, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileMarshalTextPtr(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx.withType(rtype_ptrTo(ctx.typ)), opMarshalText) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileInt64(typ *rtype) (*opcode, error) { - return newOpCode(opInt64, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileInt(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opInt) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileUint(typ *rtype) (*opcode, error) { - return newOpCode(opUint, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileInt8(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opInt8) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileUint8(typ *rtype) (*opcode, error) { - return newOpCode(opUint8, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileInt16(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opInt16) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileUint16(typ *rtype) (*opcode, error) { - return newOpCode(opUint16, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileInt32(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opInt32) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileUint32(typ *rtype) (*opcode, error) { - return newOpCode(opUint32, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileInt64(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opInt64) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileUint64(typ *rtype) (*opcode, error) { - return newOpCode(opUint64, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileUint(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opUint) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileFloat32(typ *rtype) (*opcode, error) { - return newOpCode(opFloat32, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileUint8(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opUint8) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileFloat64(typ *rtype) (*opcode, error) { - return newOpCode(opFloat64, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileUint16(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opUint16) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileString(typ *rtype) (*opcode, error) { - return newOpCode(opString, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileUint32(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opUint32) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileBool(typ *rtype) (*opcode, error) { - return newOpCode(opBool, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileUint64(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opUint64) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileBytes(typ *rtype) (*opcode, error) { - return newOpCode(opBytes, typ, e.indent, newEndOp(e.indent)), nil +func (e *Encoder) compileFloat32(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opFloat32) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileInterface(typ *rtype, root bool) (*opcode, error) { - return (*opcode)(unsafe.Pointer(&interfaceCode{ - opcodeHeader: &opcodeHeader{ - op: opInterface, - typ: typ, - indent: e.indent, - next: newEndOp(e.indent), - }, - root: root, - })), nil +func (e *Encoder) compileFloat64(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opFloat64) + ctx.incIndex() + return code, nil } -func (e *Encoder) compileSlice(typ *rtype, root, withIndent bool) (*opcode, error) { - elem := typ.Elem() +func (e *Encoder) compileString(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opString) + ctx.incIndex() + return code, nil +} + +func (e *Encoder) compileBool(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opBool) + ctx.incIndex() + return code, nil +} + +func (e *Encoder) compileBytes(ctx *encodeCompileContext) (*opcode, error) { + code := newOpCode(ctx, opBytes) + ctx.incIndex() + return code, nil +} + +func (e *Encoder) compileInterface(ctx *encodeCompileContext) (*opcode, error) { + code := newInterfaceCode(ctx) + ctx.incIndex() + return code, nil +} + +func (e *Encoder) compileSlice(ctx *encodeCompileContext) (*opcode, error) { + ctx.root = false + elem := ctx.typ.Elem() size := elem.Size() - e.indent++ - code, err := e.compile(elem, false, withIndent) - e.indent-- + header := newSliceHeaderCode(ctx) + ctx.incIndex() + code, err := e.compile(ctx.withType(ctx.typ.Elem()).incIndent()) if err != nil { return nil, err } @@ -262,17 +287,13 @@ func (e *Encoder) compileSlice(typ *rtype, root, withIndent bool) (*opcode, erro // ^ | // |________| - header := newSliceHeaderCode(e.indent) - elemCode := &sliceElemCode{ - opcodeHeader: &opcodeHeader{ - op: opSliceElem, - indent: e.indent, - }, - size: size, - } - end := newOpCode(opSliceEnd, nil, e.indent, newEndOp(e.indent)) - if withIndent { - if root { + elemCode := newSliceElemCode(ctx, header, size) + ctx.incIndex() + + end := newOpCode(ctx, opSliceEnd) + ctx.incIndex() + if ctx.withIndent { + if ctx.root { header.op = opRootSliceHeadIndent elemCode.op = opRootSliceElemIndent } else { @@ -291,15 +312,17 @@ func (e *Encoder) compileSlice(typ *rtype, root, withIndent bool) (*opcode, erro return (*opcode)(unsafe.Pointer(header)), nil } -func (e *Encoder) compileArray(typ *rtype, root, withIndent bool) (*opcode, error) { +func (e *Encoder) compileArray(ctx *encodeCompileContext) (*opcode, error) { + ctx.root = false + typ := ctx.typ elem := typ.Elem() alen := typ.Len() size := elem.Size() - e.indent++ - code, err := e.compile(elem, false, withIndent) - e.indent-- + header := newArrayHeaderCode(ctx, alen) + ctx.incIndex() + code, err := e.compile(ctx.withType(elem).incIndent()) if err != nil { return nil, err } @@ -307,17 +330,13 @@ func (e *Encoder) compileArray(typ *rtype, root, withIndent bool) (*opcode, erro // ^ | // |________| - header := newArrayHeaderCode(e.indent, alen) - elemCode := &arrayElemCode{ - opcodeHeader: &opcodeHeader{ - op: opArrayElem, - }, - len: uintptr(alen), - size: size, - } - end := newOpCode(opArrayEnd, nil, e.indent, newEndOp(e.indent)) + elemCode := newArrayElemCode(ctx, header, alen, size) + ctx.incIndex() - if withIndent { + end := newOpCode(ctx, opArrayEnd) + ctx.incIndex() + + if ctx.withIndent { header.op = opArrayHeadIndent elemCode.op = opArrayElemIndent end.op = opArrayEndIndent @@ -348,35 +367,43 @@ func mapiternext(it unsafe.Pointer) //go:noescape func maplen(m unsafe.Pointer) int -func (e *Encoder) compileMap(typ *rtype, withLoad, root, withIndent bool) (*opcode, error) { +func (e *Encoder) compileMap(ctx *encodeCompileContext, withLoad bool) (*opcode, error) { // header => code => value => code => key => code => value => code => end // ^ | // |_______________________| - e.indent++ - keyType := typ.Key() - keyCode, err := e.compileKey(keyType, false, withIndent) + ctx = ctx.incIndent() + header := newMapHeaderCode(ctx, withLoad) + ctx.incIndex() + + typ := ctx.typ + keyType := ctx.typ.Key() + keyCode, err := e.compileKey(ctx.withType(keyType)) if err != nil { return nil, err } + + value := newMapValueCode(ctx, header) + ctx.incIndex() + valueType := typ.Elem() - valueCode, err := e.compile(valueType, false, withIndent) + valueCode, err := e.compile(ctx.withType(valueType)) if err != nil { return nil, err } - key := newMapKeyCode(e.indent) - value := newMapValueCode(e.indent) + key := newMapKeyCode(ctx, header) + ctx.incIndex() - e.indent-- + ctx = ctx.decIndent() - header := newMapHeaderCode(typ, withLoad, e.indent) - header.key = key - header.value = value - end := newOpCode(opMapEnd, nil, e.indent, newEndOp(e.indent)) + header.mapKey = key + header.mapValue = value + end := newOpCode(ctx, opMapEnd) + ctx.incIndex() - if withIndent { + if ctx.withIndent { if header.op == opMapHead { - if root { + if ctx.root { header.op = opRootMapHeadIndent } else { header.op = opMapHeadIndent @@ -384,7 +411,7 @@ func (e *Encoder) compileMap(typ *rtype, withLoad, root, withIndent bool) (*opco } else { header.op = opMapHeadLoadIndent } - if root { + if ctx.root { key.op = opRootMapKeyIndent } else { key.op = opMapKeyIndent @@ -549,35 +576,30 @@ func (e *Encoder) optimizeStructField(op opType, tag *structTag, withIndent bool return fieldType } -func (e *Encoder) recursiveCode(typ *rtype, code *compiledCode) *opcode { - return (*opcode)(unsafe.Pointer(&recursiveCode{ - opcodeHeader: &opcodeHeader{ - op: opStructFieldRecursive, - typ: typ, - indent: e.indent, - next: newEndOp(e.indent), - }, - jmp: code, - })) +func (e *Encoder) recursiveCode(ctx *encodeCompileContext, jmp *compiledCode) *opcode { + code := newRecursiveCode(ctx, jmp) + ctx.incIndex() + return code } -func (e *Encoder) compiledCode(typ *rtype, withIndent bool) *opcode { +func (e *Encoder) compiledCode(ctx *encodeCompileContext) *opcode { + typ := ctx.typ typeptr := uintptr(unsafe.Pointer(typ)) - if withIndent { + if ctx.withIndent { if compiledCode, exists := e.structTypeToCompiledIndentCode[typeptr]; exists { - return e.recursiveCode(typ, compiledCode) + return e.recursiveCode(ctx, compiledCode) } } else { if compiledCode, exists := e.structTypeToCompiledCode[typeptr]; exists { - return e.recursiveCode(typ, compiledCode) + return e.recursiveCode(ctx, compiledCode) } } return nil } -func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, tag *structTag, withIndent bool) *opcode { +func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode { fieldCode.indent-- - op := e.optimizeStructHeader(valueCode.op, tag, withIndent) + op := e.optimizeStructHeader(valueCode.op, tag, ctx.withIndent) fieldCode.op = op switch op { case opStructFieldHead, @@ -608,12 +630,13 @@ func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, ta opStructFieldHeadStringTagIndent: return valueCode.beforeLastCode() } + ctx.decOpcodeIndex() return (*opcode)(unsafe.Pointer(fieldCode)) } -func (e *Encoder) structField(fieldCode *structFieldCode, valueCode *opcode, tag *structTag, withIndent bool) *opcode { +func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode { code := (*opcode)(unsafe.Pointer(fieldCode)) - op := e.optimizeStructField(valueCode.op, tag, withIndent) + op := e.optimizeStructField(valueCode.op, tag, ctx.withIndent) fieldCode.op = op switch op { case opStructField, @@ -644,10 +667,11 @@ func (e *Encoder) structField(fieldCode *structFieldCode, valueCode *opcode, tag opStructFieldStringTagIndent: return valueCode.beforeLastCode() } + ctx.decIndex() return code } -func (e *Encoder) isNotExistsField(head *structFieldCode) bool { +func (e *Encoder) isNotExistsField(head *opcode) bool { if head == nil { return false } @@ -669,12 +693,12 @@ func (e *Encoder) isNotExistsField(head *structFieldCode) bool { if head.next.op.codeType() != codeStructField { return false } - return e.isNotExistsField(head.next.toStructFieldCode()) + return e.isNotExistsField(head.next) } -func (e *Encoder) optimizeAnonymousFields(head *structFieldCode) { +func (e *Encoder) optimizeAnonymousFields(head *opcode) { code := head - var prev *structFieldCode + var prev *opcode for { if code.op == opStructEnd || code.op == opStructEndIndent { break @@ -682,29 +706,33 @@ func (e *Encoder) optimizeAnonymousFields(head *structFieldCode) { if code.op == opStructField || code.op == opStructFieldIndent { codeType := code.next.op.codeType() if codeType == codeStructField { - if e.isNotExistsField(code.next.toStructFieldCode()) { + if e.isNotExistsField(code.next) { code.next = code.nextField + diff := code.next.displayIdx - code.displayIdx + for i := 0; i < diff; i++ { + code.next.decOpcodeIndex() + } linkPrevToNextField(prev, code) code = prev } } } prev = code - code = code.nextField.toStructFieldCode() + code = code.nextField } } type structFieldPair struct { - prevField *structFieldCode - curField *structFieldCode + prevField *opcode + curField *opcode isTaggedKey bool linked bool } -func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, valueCode *structFieldCode) map[string][]structFieldPair { +func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, valueCode *opcode) map[string][]structFieldPair { anonymousFields := map[string][]structFieldPair{} f := valueCode - var prevAnonymousField *structFieldCode + var prevAnonymousField *opcode for { existsKey := tags.existsKey(f.displayKey) op := f.op.headToAnonymousHead() @@ -717,6 +745,10 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, value } else if f.op == opStructEnd { f.op = opStructAnonymousEnd } else if existsKey { + diff := f.nextField.displayIdx - f.displayIdx + for i := 0; i < diff; i++ { + f.nextField.decOpcodeIndex() + } linkPrevToNextField(prevAnonymousField, f) } @@ -725,7 +757,7 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, value break } prevAnonymousField = f - f = f.nextField.toStructFieldCode() + f = f.nextField continue } @@ -735,7 +767,7 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, value isTaggedKey: f.isTaggedKey, }) if f.next != nil && f.nextField != f.next && f.next.op.codeType() == codeStructField { - for k, v := range e.anonymousStructFieldPairMap(typ, tags, f.next.toStructFieldCode()) { + for k, v := range e.anonymousStructFieldPairMap(typ, tags, f.next) { anonymousFields[k] = append(anonymousFields[k], v...) } } @@ -743,7 +775,7 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, value break } prevAnonymousField = f - f = f.nextField.toStructFieldCode() + f = f.nextField } return anonymousFields } @@ -764,6 +796,10 @@ func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]s // head operation fieldPair.curField.op = opStructFieldAnonymousHead } else { + diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx + for i := 0; i < diff; i++ { + fieldPair.curField.nextField.decOpcodeIndex() + } linkPrevToNextField(fieldPair.prevField, fieldPair.curField) } fieldPair.linked = true @@ -777,6 +813,10 @@ func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]s // head operation fieldPair.curField.op = opStructFieldAnonymousHead } else { + diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx + for i := 0; i < diff; i++ { + fieldPair.curField.nextField.decOpcodeIndex() + } linkPrevToNextField(fieldPair.prevField, fieldPair.curField) } fieldPair.linked = true @@ -790,13 +830,15 @@ func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]s } } -func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opcode, error) { - if code := e.compiledCode(typ, withIndent); code != nil { +func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode, error) { + ctx.root = false + if code := e.compiledCode(ctx); code != nil { return code, nil } + typ := ctx.typ typeptr := uintptr(unsafe.Pointer(typ)) compiled := &compiledCode{} - if withIndent { + if ctx.withIndent { e.structTypeToCompiledIndentCode[typeptr] = compiled } else { e.structTypeToCompiledCode[typeptr] = compiled @@ -807,11 +849,11 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco fieldNum := typ.NumField() fieldIdx := 0 var ( - head *structFieldCode + head *opcode code *opcode - prevField *structFieldCode + prevField *opcode ) - e.indent++ + ctx = ctx.incIndent() tags := structTags{} anonymousFields := map[string][]structFieldPair{} for i := 0; i < fieldNum; i++ { @@ -833,12 +875,16 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco fieldType = rtype_ptrTo(fieldType) } } - valueCode, err := e.compile(fieldType, false, withIndent) + fieldOpcodeIndex := ctx.opcodeIndex + fieldPtrIndex := ctx.ptrIndex + ctx.incIndex() + valueCode, err := e.compile(ctx.withType(fieldType)) if err != nil { return nil, err } + if field.Anonymous { - for k, v := range e.anonymousStructFieldPairMap(typ, tags, valueCode.toStructFieldCode()) { + for k, v := range e.anonymousStructFieldPairMap(typ, tags, valueCode) { anonymousFields[k] = append(anonymousFields[k], v...) } } @@ -850,15 +896,16 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco opUint, opUint8, opUint16, opUint32, opUint64, opFloat32, opFloat64, opBool, opString, opBytes: valueCode = valueCode.next + ctx.decOpcodeIndex() } } key := fmt.Sprintf(`"%s":`, tag.key) - fieldCode := &structFieldCode{ - opcodeHeader: &opcodeHeader{ - typ: valueCode.typ, - next: valueCode, - indent: e.indent, - }, + fieldCode := &opcode{ + typ: valueCode.typ, + displayIdx: fieldOpcodeIndex, + idx: opcodeOffset(fieldPtrIndex), + next: valueCode, + indent: ctx.indent, anonymousKey: field.Anonymous, key: []byte(key), isTaggedKey: tag.isTaggedKey, @@ -866,29 +913,51 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco offset: field.Offset, } if fieldIdx == 0 { - code = e.structHeader(fieldCode, valueCode, tag, withIndent) + fieldCode.headIdx = fieldCode.idx + code = e.structHeader(ctx, fieldCode, valueCode, tag) head = fieldCode prevField = fieldCode } else { - fcode := (*opcode)(unsafe.Pointer(fieldCode)) - code.next = fcode - code = e.structField(fieldCode, valueCode, tag, withIndent) - prevField.nextField = fcode + fieldCode.headIdx = head.headIdx + code.next = fieldCode + code = e.structField(ctx, fieldCode, valueCode, tag) + prevField.nextField = fieldCode prevField = fieldCode } fieldIdx++ } - e.indent-- + ctx = ctx.decIndent() - structEndCode := (*opcode)(unsafe.Pointer(&structFieldCode{ - opcodeHeader: &opcodeHeader{ - op: opStructEnd, - typ: nil, - indent: e.indent, - }, - })) - structEndCode.next = newEndOp(e.indent) - if withIndent { + structEndCode := &opcode{ + op: opStructEnd, + typ: nil, + indent: ctx.indent, + next: newEndOp(ctx), + } + + // no struct field + if head == nil { + head = &opcode{ + op: opStructFieldHead, + typ: typ, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.ptrIndex), + headIdx: opcodeOffset(ctx.ptrIndex), + indent: ctx.indent, + nextField: structEndCode, + } + ctx.incIndex() + if ctx.withIndent { + head.op = opStructFieldHeadIndent + } + code = head + } + + structEndCode.displayIdx = ctx.opcodeIndex + structEndCode.idx = opcodeOffset(ctx.ptrIndex) + ctx.incIndex() + + if ctx.withIndent { structEndCode.op = opStructEndIndent } @@ -896,21 +965,6 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco prevField.nextField = structEndCode } - // no struct field - if head == nil { - head = &structFieldCode{ - opcodeHeader: &opcodeHeader{ - op: opStructFieldHead, - typ: typ, - indent: e.indent, - }, - nextField: structEndCode, - } - if withIndent { - head.op = opStructFieldHeadIndent - } - code = (*opcode)(unsafe.Pointer(head)) - } head.end = structEndCode code.next = structEndCode @@ -920,7 +974,7 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco ret := (*opcode)(unsafe.Pointer(head)) compiled.code = ret - if withIndent { + if ctx.withIndent { delete(e.structTypeToCompiledIndentCode, typeptr) } else { delete(e.structTypeToCompiledCode, typeptr) diff --git a/encode_context.go b/encode_context.go new file mode 100644 index 0000000..ce52702 --- /dev/null +++ b/encode_context.go @@ -0,0 +1,100 @@ +package json + +import ( + "reflect" + "unsafe" +) + +type encodeCompileContext struct { + typ *rtype + withIndent bool + root bool + opcodeIndex int + ptrIndex int + indent int + + parent *encodeCompileContext +} + +func (c *encodeCompileContext) context() *encodeCompileContext { + return &encodeCompileContext{ + typ: c.typ, + withIndent: c.withIndent, + root: c.root, + opcodeIndex: c.opcodeIndex, + ptrIndex: c.ptrIndex, + indent: c.indent, + parent: c, + } +} + +func (c *encodeCompileContext) withType(typ *rtype) *encodeCompileContext { + ctx := c.context() + ctx.typ = typ + return ctx +} + +func (c *encodeCompileContext) incIndent() *encodeCompileContext { + ctx := c.context() + ctx.indent++ + return ctx +} + +func (c *encodeCompileContext) decIndent() *encodeCompileContext { + ctx := c.context() + ctx.indent-- + return ctx +} + +func (c *encodeCompileContext) incIndex() { + c.incOpcodeIndex() + c.incPtrIndex() +} + +func (c *encodeCompileContext) decIndex() { + c.decOpcodeIndex() + c.decPtrIndex() +} + +func (c *encodeCompileContext) incOpcodeIndex() { + c.opcodeIndex++ + if c.parent != nil { + c.parent.incOpcodeIndex() + } +} + +func (c *encodeCompileContext) decOpcodeIndex() { + c.opcodeIndex-- + if c.parent != nil { + c.parent.decOpcodeIndex() + } +} + +func (c *encodeCompileContext) incPtrIndex() { + c.ptrIndex++ + if c.parent != nil { + c.parent.incPtrIndex() + } +} + +func (c *encodeCompileContext) decPtrIndex() { + c.ptrIndex-- + if c.parent != nil { + c.parent.decPtrIndex() + } +} + +type encodeRuntimeContext struct { + ptrs []uintptr + keepRefs []unsafe.Pointer +} + +func (c *encodeRuntimeContext) init(p uintptr) { + c.ptrs[0] = p + c.keepRefs = c.keepRefs[:0] +} + +func (c *encodeRuntimeContext) ptr() uintptr { + header := (*reflect.SliceHeader)(unsafe.Pointer(&c.ptrs)) + return header.Data +} diff --git a/encode_opcode.go b/encode_opcode.go index 3b78686..ea40704 100644 --- a/encode_opcode.go +++ b/encode_opcode.go @@ -2,51 +2,61 @@ package json import ( "fmt" - "reflect" "strings" "unsafe" ) -func copyOpcode(code *opcode) *opcode { - codeMap := map[uintptr]*opcode{} - return code.copy(codeMap) -} - -type opcodeHeader struct { - op opType - typ *rtype - ptr uintptr - indent int - next *opcode -} - -func (h *opcodeHeader) copy(codeMap map[uintptr]*opcode) *opcodeHeader { - return &opcodeHeader{ - op: h.op, - typ: h.typ, - ptr: h.ptr, - indent: h.indent, - next: h.next.copy(codeMap), - } -} +var uintptrSize = unsafe.Sizeof(uintptr(0)) type opcode struct { - *opcodeHeader + op opType // operation type + typ *rtype // go type + displayIdx int // opcode index + key []byte // struct field key + displayKey string // key text to display + isTaggedKey bool // whether tagged key + anonymousKey bool // whether anonymous key + root bool // whether root + indent int // indent number + + idx uintptr // offset to access ptr + headIdx uintptr // offset to access slice/struct head + elemIdx uintptr // offset to access array/slice/map elem + length uintptr // offset to access slice/map length or array length + mapIter uintptr // offset to access map iterator + offset uintptr // offset size from struct header + size uintptr // array/slice elem size + + mapKey *opcode // map key + mapValue *opcode // map value + elem *opcode // array/slice elem + end *opcode // array/slice/struct/map end + nextField *opcode // next struct field + next *opcode // next opcode + jmp *compiledCode // for recursive call } -func newOpCode(op opType, typ *rtype, indent int, next *opcode) *opcode { +func newOpCode(ctx *encodeCompileContext, op opType) *opcode { + return newOpCodeWithNext(ctx, op, newEndOp(ctx)) +} + +func opcodeOffset(idx int) uintptr { + return uintptr(idx) * uintptrSize +} + +func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode { return &opcode{ - opcodeHeader: &opcodeHeader{ - op: op, - typ: typ, - indent: indent, - next: next, - }, + op: op, + typ: ctx.typ, + displayIdx: ctx.opcodeIndex, + indent: ctx.indent, + idx: opcodeOffset(ctx.ptrIndex), + next: next, } } -func newEndOp(indent int) *opcode { - return newOpCode(opEnd, nil, indent, nil) +func newEndOp(ctx *encodeCompileContext) *opcode { + return newOpCodeWithNext(ctx, opEnd, nil) } func (c *opcode) beforeLastCode() *opcode { @@ -54,12 +64,8 @@ func (c *opcode) beforeLastCode() *opcode { for { var nextCode *opcode switch code.op.codeType() { - case codeArrayElem: - nextCode = code.toArrayElemCode().end - case codeSliceElem: - nextCode = code.toSliceElemCode().end - case codeMapKey: - nextCode = code.toMapKeyCode().end + case codeArrayElem, codeSliceElem, codeMapKey: + nextCode = code.end default: nextCode = code.next } @@ -71,270 +77,183 @@ func (c *opcode) beforeLastCode() *opcode { return nil } -func (c *opcode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil +func (c *opcode) totalLength() int { + var idx int + for code := c; code.op != opEnd; { + idx = int(code.idx / uintptrSize) + if code.op == opInterfaceEnd || code.op == opStructFieldRecursiveEnd { + break + } + switch code.op.codeType() { + case codeArrayElem, codeSliceElem, codeMapKey: + code = code.end + default: + code = code.next + } } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - var code *opcode - switch c.op.codeType() { - case codeArrayHead: - code = c.toArrayHeaderCode().copy(codeMap) - case codeArrayElem: - code = c.toArrayElemCode().copy(codeMap) - case codeSliceHead: - code = c.toSliceHeaderCode().copy(codeMap) - case codeSliceElem: - code = c.toSliceElemCode().copy(codeMap) - case codeMapHead: - code = c.toMapHeadCode().copy(codeMap) - case codeMapKey: - code = c.toMapKeyCode().copy(codeMap) - case codeMapValue: - code = c.toMapValueCode().copy(codeMap) - case codeStructFieldRecursive: - code = c.toRecursiveCode().copy(codeMap) - case codeStructField: - code = c.toStructFieldCode().copy(codeMap) - default: - code = &opcode{} - codeMap[addr] = code + return idx + 2 // opEnd + 1 +} - code.opcodeHeader = c.opcodeHeader.copy(codeMap) +func (c *opcode) decOpcodeIndex() { + for code := c; code.op != opEnd; { + code.displayIdx-- + code.idx -= uintptrSize + if code.headIdx > 0 { + code.headIdx -= uintptrSize + } + if code.elemIdx > 0 { + code.elemIdx -= uintptrSize + } + if code.mapIter > 0 { + code.mapIter -= uintptrSize + } + if code.length > 0 && code.op.codeType() != codeArrayHead && code.op.codeType() != codeArrayElem { + code.length -= uintptrSize + } + switch code.op.codeType() { + case codeArrayElem, codeSliceElem, codeMapKey: + code = code.end + default: + code = code.next + } } - return code +} + +func (c *opcode) dumpHead(code *opcode) string { + var length uintptr + if code.op.codeType() == codeArrayHead { + length = code.length + } else { + length = code.length / uintptrSize + } + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][headIdx:%d][elemIdx:%d][length:%d])`, + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.idx/uintptrSize, + code.headIdx/uintptrSize, + code.elemIdx/uintptrSize, + length, + ) +} + +func (c *opcode) dumpMapHead(code *opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][headIdx:%d][elemIdx:%d][length:%d][mapIter:%d])`, + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.idx/uintptrSize, + code.headIdx/uintptrSize, + code.elemIdx/uintptrSize, + code.length/uintptrSize, + code.mapIter/uintptrSize, + ) +} + +func (c *opcode) dumpElem(code *opcode) string { + var length uintptr + if code.op.codeType() == codeArrayElem { + length = code.length + } else { + length = code.length / uintptrSize + } + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][headIdx:%d][elemIdx:%d][length:%d][size:%d])`, + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.idx/uintptrSize, + code.headIdx/uintptrSize, + code.elemIdx/uintptrSize, + length, + code.size, + ) +} + +func (c *opcode) dumpField(code *opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][key:%s][offset:%d][headIdx:%d])`, + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.idx/uintptrSize, + code.displayKey, + code.offset, + code.headIdx/uintptrSize, + ) +} + +func (c *opcode) dumpKey(code *opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][elemIdx:%d][length:%d][mapIter:%d])`, + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.idx/uintptrSize, + code.elemIdx/uintptrSize, + code.length/uintptrSize, + code.mapIter/uintptrSize, + ) +} + +func (c *opcode) dumpValue(code *opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][mapIter:%d])`, + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.idx/uintptrSize, + code.mapIter/uintptrSize, + ) } func (c *opcode) dump() string { codes := []string{} for code := c; code.op != opEnd; { - indent := strings.Repeat(" ", code.indent) switch code.op.codeType() { - case codeArrayElem: - codes = append(codes, fmt.Sprintf("%s%s ( %p )", indent, code.op, unsafe.Pointer(code))) - code = code.toArrayElemCode().end - case codeSliceElem: - codes = append(codes, fmt.Sprintf("%s%s ( %p )", indent, code.op, unsafe.Pointer(code))) - code = code.toSliceElemCode().end + case codeSliceHead: + codes = append(codes, c.dumpHead(code)) + code = code.next + case codeMapHead: + codes = append(codes, c.dumpMapHead(code)) + code = code.next + case codeArrayElem, codeSliceElem: + codes = append(codes, c.dumpElem(code)) + code = code.end case codeMapKey: - codes = append(codes, fmt.Sprintf("%s%s ( %p )", indent, code.op, unsafe.Pointer(code))) - code = code.toMapKeyCode().end + codes = append(codes, c.dumpKey(code)) + code = code.end + case codeMapValue: + codes = append(codes, c.dumpValue(code)) + code = code.next case codeStructField: - sf := code.toStructFieldCode() - key := sf.displayKey - offset := sf.offset - codes = append(codes, fmt.Sprintf("%s%s [%s:%d] ( %p )", indent, code.op, key, offset, unsafe.Pointer(code))) + codes = append(codes, c.dumpField(code)) code = code.next default: - codes = append(codes, fmt.Sprintf("%s%s ( %p )", indent, code.op, unsafe.Pointer(code))) + codes = append(codes, fmt.Sprintf( + "[%d]%s%s ([idx:%d])", + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.idx/uintptrSize, + )) code = code.next } } return strings.Join(codes, "\n") } -func (c *opcode) toSliceHeaderCode() *sliceHeaderCode { - return (*sliceHeaderCode)(unsafe.Pointer(c)) -} - -func (c *opcode) toSliceElemCode() *sliceElemCode { - return (*sliceElemCode)(unsafe.Pointer(c)) -} - -func (c *opcode) toArrayHeaderCode() *arrayHeaderCode { - return (*arrayHeaderCode)(unsafe.Pointer(c)) -} - -func (c *opcode) toArrayElemCode() *arrayElemCode { - return (*arrayElemCode)(unsafe.Pointer(c)) -} - -func (c *opcode) toStructFieldCode() *structFieldCode { - return (*structFieldCode)(unsafe.Pointer(c)) -} - -func (c *opcode) toMapHeadCode() *mapHeaderCode { - return (*mapHeaderCode)(unsafe.Pointer(c)) -} - -func (c *opcode) toMapKeyCode() *mapKeyCode { - return (*mapKeyCode)(unsafe.Pointer(c)) -} - -func (c *opcode) toMapValueCode() *mapValueCode { - return (*mapValueCode)(unsafe.Pointer(c)) -} - -func (c *opcode) toInterfaceCode() *interfaceCode { - return (*interfaceCode)(unsafe.Pointer(c)) -} - -func (c *opcode) toRecursiveCode() *recursiveCode { - return (*recursiveCode)(unsafe.Pointer(c)) -} - -type sliceHeaderCode struct { - *opcodeHeader - elem *sliceElemCode - end *opcode -} - -func newSliceHeaderCode(indent int) *sliceHeaderCode { - return &sliceHeaderCode{ - opcodeHeader: &opcodeHeader{ - op: opSliceHead, - indent: indent, - }, - } -} - -func (c *sliceHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil - } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - header := &sliceHeaderCode{} - code := (*opcode)(unsafe.Pointer(header)) - codeMap[addr] = code - - header.opcodeHeader = c.opcodeHeader.copy(codeMap) - header.elem = (*sliceElemCode)(unsafe.Pointer(c.elem.copy(codeMap))) - header.end = c.end.copy(codeMap) - return code -} - -type sliceElemCode struct { - *opcodeHeader - idx uintptr - len uintptr - size uintptr - data uintptr - end *opcode -} - -func (c *sliceElemCode) set(header *reflect.SliceHeader) { - c.idx = uintptr(0) - c.len = uintptr(header.Len) - c.data = header.Data -} - -func (c *sliceElemCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil - } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - elem := &sliceElemCode{ - idx: c.idx, - len: c.len, - size: c.size, - data: c.data, - } - code := (*opcode)(unsafe.Pointer(elem)) - codeMap[addr] = code - - elem.opcodeHeader = c.opcodeHeader.copy(codeMap) - elem.end = c.end.copy(codeMap) - return code -} - -type arrayHeaderCode struct { - *opcodeHeader - len uintptr - elem *arrayElemCode - end *opcode -} - -func newArrayHeaderCode(indent, alen int) *arrayHeaderCode { - return &arrayHeaderCode{ - opcodeHeader: &opcodeHeader{ - op: opArrayHead, - indent: indent, - }, - len: uintptr(alen), - } -} - -func (c *arrayHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil - } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - header := &arrayHeaderCode{} - code := (*opcode)(unsafe.Pointer(header)) - codeMap[addr] = code - - header.opcodeHeader = c.opcodeHeader.copy(codeMap) - header.len = c.len - header.elem = (*arrayElemCode)(unsafe.Pointer(c.elem.copy(codeMap))) - header.end = c.end.copy(codeMap) - return code -} - -type arrayElemCode struct { - *opcodeHeader - idx uintptr - len uintptr - size uintptr - end *opcode -} - -func (c *arrayElemCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil - } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - elem := &arrayElemCode{ - idx: c.idx, - len: c.len, - size: c.size, - } - code := (*opcode)(unsafe.Pointer(elem)) - codeMap[addr] = code - - elem.opcodeHeader = c.opcodeHeader.copy(codeMap) - elem.end = c.end.copy(codeMap) - return code -} - -type structFieldCode struct { - *opcodeHeader - key []byte - displayKey string - isTaggedKey bool - offset uintptr - anonymousKey bool - nextField *opcode - end *opcode -} - -func linkPrevToNextField(prev, cur *structFieldCode) { +func linkPrevToNextField(prev, cur *opcode) { prev.nextField = cur.nextField - code := prev.toOpcode() - fcode := cur.toOpcode() + code := prev + fcode := cur for { var nextCode *opcode switch code.op.codeType() { - case codeArrayElem: - nextCode = code.toArrayElemCode().end - case codeSliceElem: - nextCode = code.toSliceElemCode().end - case codeMapKey: - nextCode = code.toMapKeyCode().end + case codeArrayElem, codeSliceElem, codeMapKey: + nextCode = code.end default: nextCode = code.next } @@ -348,208 +267,133 @@ func linkPrevToNextField(prev, cur *structFieldCode) { } } -func (c *structFieldCode) toOpcode() *opcode { - return (*opcode)(unsafe.Pointer(c)) +func newSliceHeaderCode(ctx *encodeCompileContext) *opcode { + idx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + elemIdx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + length := opcodeOffset(ctx.ptrIndex) + return &opcode{ + op: opSliceHead, + displayIdx: ctx.opcodeIndex, + idx: idx, + headIdx: idx, + elemIdx: elemIdx, + length: length, + indent: ctx.indent, + } } -func (c *structFieldCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil +func newSliceElemCode(ctx *encodeCompileContext, head *opcode, size uintptr) *opcode { + return &opcode{ + op: opSliceElem, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.ptrIndex), + headIdx: head.idx, + elemIdx: head.elemIdx, + length: head.length, + indent: ctx.indent, + size: size, } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - field := &structFieldCode{ - key: c.key, - isTaggedKey: c.isTaggedKey, - displayKey: c.displayKey, - anonymousKey: c.anonymousKey, - offset: c.offset, - } - code := (*opcode)(unsafe.Pointer(field)) - codeMap[addr] = code - - field.opcodeHeader = c.opcodeHeader.copy(codeMap) - field.nextField = c.nextField.copy(codeMap) - field.end = c.end.copy(codeMap) - return code } -type mapHeaderCode struct { - *opcodeHeader - key *mapKeyCode - value *mapValueCode - end *opcode +func newArrayHeaderCode(ctx *encodeCompileContext, alen int) *opcode { + idx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + elemIdx := opcodeOffset(ctx.ptrIndex) + return &opcode{ + op: opArrayHead, + displayIdx: ctx.opcodeIndex, + idx: idx, + headIdx: idx, + elemIdx: elemIdx, + indent: ctx.indent, + length: uintptr(alen), + } } -func (c *mapHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil +func newArrayElemCode(ctx *encodeCompileContext, head *opcode, length int, size uintptr) *opcode { + return &opcode{ + op: opArrayElem, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.ptrIndex), + elemIdx: head.elemIdx, + headIdx: head.headIdx, + length: uintptr(length), + size: size, } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - header := &mapHeaderCode{} - code := (*opcode)(unsafe.Pointer(header)) - codeMap[addr] = code - - header.opcodeHeader = c.opcodeHeader.copy(codeMap) - header.key = (*mapKeyCode)(unsafe.Pointer(c.key.copy(codeMap))) - header.value = (*mapValueCode)(unsafe.Pointer(c.value.copy(codeMap))) - header.end = c.end.copy(codeMap) - return code } -type mapKeyCode struct { - *opcodeHeader - idx int - len int - iter unsafe.Pointer - end *opcode -} - -func (c *mapKeyCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil - } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - key := &mapKeyCode{ - idx: c.idx, - len: c.len, - iter: c.iter, - } - code := (*opcode)(unsafe.Pointer(key)) - codeMap[addr] = code - - key.opcodeHeader = c.opcodeHeader.copy(codeMap) - key.end = c.end.copy(codeMap) - return code -} - -func (c *mapKeyCode) set(len int, iter unsafe.Pointer) { - c.idx = 0 - c.len = len - c.iter = iter -} - -type mapValueCode struct { - *opcodeHeader - iter unsafe.Pointer -} - -func (c *mapValueCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil - } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - value := &mapValueCode{ - iter: c.iter, - } - code := (*opcode)(unsafe.Pointer(value)) - codeMap[addr] = code - - value.opcodeHeader = c.opcodeHeader.copy(codeMap) - return code -} - -func (c *mapValueCode) set(iter unsafe.Pointer) { - c.iter = iter -} - -func newMapHeaderCode(typ *rtype, withLoad bool, indent int) *mapHeaderCode { +func newMapHeaderCode(ctx *encodeCompileContext, withLoad bool) *opcode { var op opType if withLoad { op = opMapHeadLoad } else { op = opMapHead } - return &mapHeaderCode{ - opcodeHeader: &opcodeHeader{ - op: op, - typ: typ, - indent: indent, - }, + idx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + elemIdx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + length := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + mapIter := opcodeOffset(ctx.ptrIndex) + return &opcode{ + op: op, + typ: ctx.typ, + displayIdx: ctx.opcodeIndex, + idx: idx, + elemIdx: elemIdx, + length: length, + mapIter: mapIter, + indent: ctx.indent, } } -func newMapKeyCode(indent int) *mapKeyCode { - return &mapKeyCode{ - opcodeHeader: &opcodeHeader{ - op: opMapKey, - indent: indent, - }, +func newMapKeyCode(ctx *encodeCompileContext, head *opcode) *opcode { + return &opcode{ + op: opMapKey, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.ptrIndex), + elemIdx: head.elemIdx, + length: head.length, + mapIter: head.mapIter, + indent: ctx.indent, } } -func newMapValueCode(indent int) *mapValueCode { - return &mapValueCode{ - opcodeHeader: &opcodeHeader{ - op: opMapValue, - indent: indent, - }, +func newMapValueCode(ctx *encodeCompileContext, head *opcode) *opcode { + return &opcode{ + op: opMapValue, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.ptrIndex), + elemIdx: head.elemIdx, + length: head.length, + mapIter: head.mapIter, + indent: ctx.indent, } } -type interfaceCode struct { - *opcodeHeader - root bool +func newInterfaceCode(ctx *encodeCompileContext) *opcode { + return &opcode{ + op: opInterface, + typ: ctx.typ, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.ptrIndex), + indent: ctx.indent, + root: ctx.root, + next: newEndOp(ctx), + } } -func (c *interfaceCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil +func newRecursiveCode(ctx *encodeCompileContext, jmp *compiledCode) *opcode { + return &opcode{ + op: opStructFieldRecursive, + typ: ctx.typ, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.ptrIndex), + indent: ctx.indent, + next: newEndOp(ctx), + jmp: jmp, } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - iface := &interfaceCode{} - code := (*opcode)(unsafe.Pointer(iface)) - codeMap[addr] = code - - iface.opcodeHeader = c.opcodeHeader.copy(codeMap) - return code -} - -type recursiveCode struct { - *opcodeHeader - jmp *compiledCode - seenPtr uintptr -} - -func (c *recursiveCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil - } - addr := uintptr(unsafe.Pointer(c)) - if code, exists := codeMap[addr]; exists { - return code - } - recur := &recursiveCode{seenPtr: c.seenPtr} - code := (*opcode)(unsafe.Pointer(recur)) - codeMap[addr] = code - - recur.opcodeHeader = c.opcodeHeader.copy(codeMap) - recur.jmp = &compiledCode{ - code: c.jmp.code.copy(codeMap), - } - return code -} - -func newRecursiveCode(recursive *recursiveCode) *opcode { - code := copyOpcode(recursive.jmp.code) - head := (*structFieldCode)(unsafe.Pointer(code)) - head.end.next = newEndOp(0) - code.ptr = recursive.ptr - - code.op = code.op.ptrHeadToHead() - return code } diff --git a/encode_optype.go b/encode_optype.go index 21c2835..dccc3d5 100644 --- a/encode_optype.go +++ b/encode_optype.go @@ -21,780 +21,784 @@ type opType int const ( opEnd opType = 0 opInterface opType = 1 - opPtr opType = 2 - opSliceHead opType = 3 - opRootSliceHead opType = 4 - opSliceElem opType = 5 - opRootSliceElem opType = 6 - opSliceEnd opType = 7 - opArrayHead opType = 8 - opArrayElem opType = 9 - opArrayEnd opType = 10 - opMapHead opType = 11 - opMapHeadLoad opType = 12 - opRootMapHead opType = 13 - opMapKey opType = 14 - opRootMapKey opType = 15 - opMapValue opType = 16 - opMapEnd opType = 17 - opStructFieldHead opType = 18 - opStructFieldHeadOmitEmpty opType = 19 - opStructFieldHeadStringTag opType = 20 - opStructFieldAnonymousHead opType = 21 - opStructFieldAnonymousHeadOmitEmpty opType = 22 - opStructFieldPtrAnonymousHeadOmitEmpty opType = 23 - opStructFieldAnonymousHeadStringTag opType = 24 - opStructFieldPtrAnonymousHeadStringTag opType = 25 - opStructFieldPtrHead opType = 26 - opStructFieldPtrHeadOmitEmpty opType = 27 - opStructFieldPtrHeadStringTag opType = 28 - opStructFieldPtrAnonymousHead opType = 29 - opStructField opType = 30 - opStructFieldOmitEmpty opType = 31 - opStructFieldStringTag opType = 32 - opStructFieldRecursive opType = 33 - opStructEnd opType = 34 - opStructAnonymousEnd opType = 35 - opInt opType = 36 - opInt8 opType = 37 - opInt16 opType = 38 - opInt32 opType = 39 - opInt64 opType = 40 - opUint opType = 41 - opUint8 opType = 42 - opUint16 opType = 43 - opUint32 opType = 44 - opUint64 opType = 45 - opFloat32 opType = 46 - opFloat64 opType = 47 - opBool opType = 48 - opString opType = 49 - opBytes opType = 50 - opArray opType = 51 - opMap opType = 52 - opMapLoad opType = 53 - opSlice opType = 54 - opStruct opType = 55 - opMarshalJSON opType = 56 - opMarshalText opType = 57 - opStructFieldHeadInt opType = 58 - opStructFieldHeadInt8 opType = 59 - opStructFieldHeadInt16 opType = 60 - opStructFieldHeadInt32 opType = 61 - opStructFieldHeadInt64 opType = 62 - opStructFieldHeadUint opType = 63 - opStructFieldHeadUint8 opType = 64 - opStructFieldHeadUint16 opType = 65 - opStructFieldHeadUint32 opType = 66 - opStructFieldHeadUint64 opType = 67 - opStructFieldHeadFloat32 opType = 68 - opStructFieldHeadFloat64 opType = 69 - opStructFieldHeadBool opType = 70 - opStructFieldHeadString opType = 71 - opStructFieldHeadBytes opType = 72 - opStructFieldHeadArray opType = 73 - opStructFieldHeadMap opType = 74 - opStructFieldHeadMapLoad opType = 75 - opStructFieldHeadSlice opType = 76 - opStructFieldHeadStruct opType = 77 - opStructFieldHeadMarshalJSON opType = 78 - opStructFieldHeadMarshalText opType = 79 - opStructFieldHeadOmitEmptyInt opType = 80 - opStructFieldHeadOmitEmptyInt8 opType = 81 - opStructFieldHeadOmitEmptyInt16 opType = 82 - opStructFieldHeadOmitEmptyInt32 opType = 83 - opStructFieldHeadOmitEmptyInt64 opType = 84 - opStructFieldHeadOmitEmptyUint opType = 85 - opStructFieldHeadOmitEmptyUint8 opType = 86 - opStructFieldHeadOmitEmptyUint16 opType = 87 - opStructFieldHeadOmitEmptyUint32 opType = 88 - opStructFieldHeadOmitEmptyUint64 opType = 89 - opStructFieldHeadOmitEmptyFloat32 opType = 90 - opStructFieldHeadOmitEmptyFloat64 opType = 91 - opStructFieldHeadOmitEmptyBool opType = 92 - opStructFieldHeadOmitEmptyString opType = 93 - opStructFieldHeadOmitEmptyBytes opType = 94 - opStructFieldHeadOmitEmptyArray opType = 95 - opStructFieldHeadOmitEmptyMap opType = 96 - opStructFieldHeadOmitEmptyMapLoad opType = 97 - opStructFieldHeadOmitEmptySlice opType = 98 - opStructFieldHeadOmitEmptyStruct opType = 99 - opStructFieldHeadOmitEmptyMarshalJSON opType = 100 - opStructFieldHeadOmitEmptyMarshalText opType = 101 - opStructFieldHeadStringTagInt opType = 102 - opStructFieldHeadStringTagInt8 opType = 103 - opStructFieldHeadStringTagInt16 opType = 104 - opStructFieldHeadStringTagInt32 opType = 105 - opStructFieldHeadStringTagInt64 opType = 106 - opStructFieldHeadStringTagUint opType = 107 - opStructFieldHeadStringTagUint8 opType = 108 - opStructFieldHeadStringTagUint16 opType = 109 - opStructFieldHeadStringTagUint32 opType = 110 - opStructFieldHeadStringTagUint64 opType = 111 - opStructFieldHeadStringTagFloat32 opType = 112 - opStructFieldHeadStringTagFloat64 opType = 113 - opStructFieldHeadStringTagBool opType = 114 - opStructFieldHeadStringTagString opType = 115 - opStructFieldHeadStringTagBytes opType = 116 - opStructFieldHeadStringTagArray opType = 117 - opStructFieldHeadStringTagMap opType = 118 - opStructFieldHeadStringTagMapLoad opType = 119 - opStructFieldHeadStringTagSlice opType = 120 - opStructFieldHeadStringTagStruct opType = 121 - opStructFieldHeadStringTagMarshalJSON opType = 122 - opStructFieldHeadStringTagMarshalText opType = 123 - opStructFieldAnonymousHeadInt opType = 124 - opStructFieldAnonymousHeadInt8 opType = 125 - opStructFieldAnonymousHeadInt16 opType = 126 - opStructFieldAnonymousHeadInt32 opType = 127 - opStructFieldAnonymousHeadInt64 opType = 128 - opStructFieldAnonymousHeadUint opType = 129 - opStructFieldAnonymousHeadUint8 opType = 130 - opStructFieldAnonymousHeadUint16 opType = 131 - opStructFieldAnonymousHeadUint32 opType = 132 - opStructFieldAnonymousHeadUint64 opType = 133 - opStructFieldAnonymousHeadFloat32 opType = 134 - opStructFieldAnonymousHeadFloat64 opType = 135 - opStructFieldAnonymousHeadBool opType = 136 - opStructFieldAnonymousHeadString opType = 137 - opStructFieldAnonymousHeadBytes opType = 138 - opStructFieldAnonymousHeadArray opType = 139 - opStructFieldAnonymousHeadMap opType = 140 - opStructFieldAnonymousHeadMapLoad opType = 141 - opStructFieldAnonymousHeadSlice opType = 142 - opStructFieldAnonymousHeadStruct opType = 143 - opStructFieldAnonymousHeadMarshalJSON opType = 144 - opStructFieldAnonymousHeadMarshalText opType = 145 - opStructFieldAnonymousHeadOmitEmptyInt opType = 146 - opStructFieldAnonymousHeadOmitEmptyInt8 opType = 147 - opStructFieldAnonymousHeadOmitEmptyInt16 opType = 148 - opStructFieldAnonymousHeadOmitEmptyInt32 opType = 149 - opStructFieldAnonymousHeadOmitEmptyInt64 opType = 150 - opStructFieldAnonymousHeadOmitEmptyUint opType = 151 - opStructFieldAnonymousHeadOmitEmptyUint8 opType = 152 - opStructFieldAnonymousHeadOmitEmptyUint16 opType = 153 - opStructFieldAnonymousHeadOmitEmptyUint32 opType = 154 - opStructFieldAnonymousHeadOmitEmptyUint64 opType = 155 - opStructFieldAnonymousHeadOmitEmptyFloat32 opType = 156 - opStructFieldAnonymousHeadOmitEmptyFloat64 opType = 157 - opStructFieldAnonymousHeadOmitEmptyBool opType = 158 - opStructFieldAnonymousHeadOmitEmptyString opType = 159 - opStructFieldAnonymousHeadOmitEmptyBytes opType = 160 - opStructFieldAnonymousHeadOmitEmptyArray opType = 161 - opStructFieldAnonymousHeadOmitEmptyMap opType = 162 - opStructFieldAnonymousHeadOmitEmptyMapLoad opType = 163 - opStructFieldAnonymousHeadOmitEmptySlice opType = 164 - opStructFieldAnonymousHeadOmitEmptyStruct opType = 165 - opStructFieldAnonymousHeadOmitEmptyMarshalJSON opType = 166 - opStructFieldAnonymousHeadOmitEmptyMarshalText opType = 167 - opStructFieldAnonymousHeadStringTagInt opType = 168 - opStructFieldAnonymousHeadStringTagInt8 opType = 169 - opStructFieldAnonymousHeadStringTagInt16 opType = 170 - opStructFieldAnonymousHeadStringTagInt32 opType = 171 - opStructFieldAnonymousHeadStringTagInt64 opType = 172 - opStructFieldAnonymousHeadStringTagUint opType = 173 - opStructFieldAnonymousHeadStringTagUint8 opType = 174 - opStructFieldAnonymousHeadStringTagUint16 opType = 175 - opStructFieldAnonymousHeadStringTagUint32 opType = 176 - opStructFieldAnonymousHeadStringTagUint64 opType = 177 - opStructFieldAnonymousHeadStringTagFloat32 opType = 178 - opStructFieldAnonymousHeadStringTagFloat64 opType = 179 - opStructFieldAnonymousHeadStringTagBool opType = 180 - opStructFieldAnonymousHeadStringTagString opType = 181 - opStructFieldAnonymousHeadStringTagBytes opType = 182 - opStructFieldAnonymousHeadStringTagArray opType = 183 - opStructFieldAnonymousHeadStringTagMap opType = 184 - opStructFieldAnonymousHeadStringTagMapLoad opType = 185 - opStructFieldAnonymousHeadStringTagSlice opType = 186 - opStructFieldAnonymousHeadStringTagStruct opType = 187 - opStructFieldAnonymousHeadStringTagMarshalJSON opType = 188 - opStructFieldAnonymousHeadStringTagMarshalText opType = 189 - opStructFieldPtrHeadInt opType = 190 - opStructFieldPtrHeadInt8 opType = 191 - opStructFieldPtrHeadInt16 opType = 192 - opStructFieldPtrHeadInt32 opType = 193 - opStructFieldPtrHeadInt64 opType = 194 - opStructFieldPtrHeadUint opType = 195 - opStructFieldPtrHeadUint8 opType = 196 - opStructFieldPtrHeadUint16 opType = 197 - opStructFieldPtrHeadUint32 opType = 198 - opStructFieldPtrHeadUint64 opType = 199 - opStructFieldPtrHeadFloat32 opType = 200 - opStructFieldPtrHeadFloat64 opType = 201 - opStructFieldPtrHeadBool opType = 202 - opStructFieldPtrHeadString opType = 203 - opStructFieldPtrHeadBytes opType = 204 - opStructFieldPtrHeadArray opType = 205 - opStructFieldPtrHeadMap opType = 206 - opStructFieldPtrHeadMapLoad opType = 207 - opStructFieldPtrHeadSlice opType = 208 - opStructFieldPtrHeadStruct opType = 209 - opStructFieldPtrHeadMarshalJSON opType = 210 - opStructFieldPtrHeadMarshalText opType = 211 - opStructFieldPtrHeadOmitEmptyInt opType = 212 - opStructFieldPtrHeadOmitEmptyInt8 opType = 213 - opStructFieldPtrHeadOmitEmptyInt16 opType = 214 - opStructFieldPtrHeadOmitEmptyInt32 opType = 215 - opStructFieldPtrHeadOmitEmptyInt64 opType = 216 - opStructFieldPtrHeadOmitEmptyUint opType = 217 - opStructFieldPtrHeadOmitEmptyUint8 opType = 218 - opStructFieldPtrHeadOmitEmptyUint16 opType = 219 - opStructFieldPtrHeadOmitEmptyUint32 opType = 220 - opStructFieldPtrHeadOmitEmptyUint64 opType = 221 - opStructFieldPtrHeadOmitEmptyFloat32 opType = 222 - opStructFieldPtrHeadOmitEmptyFloat64 opType = 223 - opStructFieldPtrHeadOmitEmptyBool opType = 224 - opStructFieldPtrHeadOmitEmptyString opType = 225 - opStructFieldPtrHeadOmitEmptyBytes opType = 226 - opStructFieldPtrHeadOmitEmptyArray opType = 227 - opStructFieldPtrHeadOmitEmptyMap opType = 228 - opStructFieldPtrHeadOmitEmptyMapLoad opType = 229 - opStructFieldPtrHeadOmitEmptySlice opType = 230 - opStructFieldPtrHeadOmitEmptyStruct opType = 231 - opStructFieldPtrHeadOmitEmptyMarshalJSON opType = 232 - opStructFieldPtrHeadOmitEmptyMarshalText opType = 233 - opStructFieldPtrHeadStringTagInt opType = 234 - opStructFieldPtrHeadStringTagInt8 opType = 235 - opStructFieldPtrHeadStringTagInt16 opType = 236 - opStructFieldPtrHeadStringTagInt32 opType = 237 - opStructFieldPtrHeadStringTagInt64 opType = 238 - opStructFieldPtrHeadStringTagUint opType = 239 - opStructFieldPtrHeadStringTagUint8 opType = 240 - opStructFieldPtrHeadStringTagUint16 opType = 241 - opStructFieldPtrHeadStringTagUint32 opType = 242 - opStructFieldPtrHeadStringTagUint64 opType = 243 - opStructFieldPtrHeadStringTagFloat32 opType = 244 - opStructFieldPtrHeadStringTagFloat64 opType = 245 - opStructFieldPtrHeadStringTagBool opType = 246 - opStructFieldPtrHeadStringTagString opType = 247 - opStructFieldPtrHeadStringTagBytes opType = 248 - opStructFieldPtrHeadStringTagArray opType = 249 - opStructFieldPtrHeadStringTagMap opType = 250 - opStructFieldPtrHeadStringTagMapLoad opType = 251 - opStructFieldPtrHeadStringTagSlice opType = 252 - opStructFieldPtrHeadStringTagStruct opType = 253 - opStructFieldPtrHeadStringTagMarshalJSON opType = 254 - opStructFieldPtrHeadStringTagMarshalText opType = 255 - opStructFieldPtrAnonymousHeadInt opType = 256 - opStructFieldPtrAnonymousHeadInt8 opType = 257 - opStructFieldPtrAnonymousHeadInt16 opType = 258 - opStructFieldPtrAnonymousHeadInt32 opType = 259 - opStructFieldPtrAnonymousHeadInt64 opType = 260 - opStructFieldPtrAnonymousHeadUint opType = 261 - opStructFieldPtrAnonymousHeadUint8 opType = 262 - opStructFieldPtrAnonymousHeadUint16 opType = 263 - opStructFieldPtrAnonymousHeadUint32 opType = 264 - opStructFieldPtrAnonymousHeadUint64 opType = 265 - opStructFieldPtrAnonymousHeadFloat32 opType = 266 - opStructFieldPtrAnonymousHeadFloat64 opType = 267 - opStructFieldPtrAnonymousHeadBool opType = 268 - opStructFieldPtrAnonymousHeadString opType = 269 - opStructFieldPtrAnonymousHeadBytes opType = 270 - opStructFieldPtrAnonymousHeadArray opType = 271 - opStructFieldPtrAnonymousHeadMap opType = 272 - opStructFieldPtrAnonymousHeadMapLoad opType = 273 - opStructFieldPtrAnonymousHeadSlice opType = 274 - opStructFieldPtrAnonymousHeadStruct opType = 275 - opStructFieldPtrAnonymousHeadMarshalJSON opType = 276 - opStructFieldPtrAnonymousHeadMarshalText opType = 277 - opStructFieldPtrAnonymousHeadOmitEmptyInt opType = 278 - opStructFieldPtrAnonymousHeadOmitEmptyInt8 opType = 279 - opStructFieldPtrAnonymousHeadOmitEmptyInt16 opType = 280 - opStructFieldPtrAnonymousHeadOmitEmptyInt32 opType = 281 - opStructFieldPtrAnonymousHeadOmitEmptyInt64 opType = 282 - opStructFieldPtrAnonymousHeadOmitEmptyUint opType = 283 - opStructFieldPtrAnonymousHeadOmitEmptyUint8 opType = 284 - opStructFieldPtrAnonymousHeadOmitEmptyUint16 opType = 285 - opStructFieldPtrAnonymousHeadOmitEmptyUint32 opType = 286 - opStructFieldPtrAnonymousHeadOmitEmptyUint64 opType = 287 - opStructFieldPtrAnonymousHeadOmitEmptyFloat32 opType = 288 - opStructFieldPtrAnonymousHeadOmitEmptyFloat64 opType = 289 - opStructFieldPtrAnonymousHeadOmitEmptyBool opType = 290 - opStructFieldPtrAnonymousHeadOmitEmptyString opType = 291 - opStructFieldPtrAnonymousHeadOmitEmptyBytes opType = 292 - opStructFieldPtrAnonymousHeadOmitEmptyArray opType = 293 - opStructFieldPtrAnonymousHeadOmitEmptyMap opType = 294 - opStructFieldPtrAnonymousHeadOmitEmptyMapLoad opType = 295 - opStructFieldPtrAnonymousHeadOmitEmptySlice opType = 296 - opStructFieldPtrAnonymousHeadOmitEmptyStruct opType = 297 - opStructFieldPtrAnonymousHeadOmitEmptyMarshalJSON opType = 298 - opStructFieldPtrAnonymousHeadOmitEmptyMarshalText opType = 299 - opStructFieldPtrAnonymousHeadStringTagInt opType = 300 - opStructFieldPtrAnonymousHeadStringTagInt8 opType = 301 - opStructFieldPtrAnonymousHeadStringTagInt16 opType = 302 - opStructFieldPtrAnonymousHeadStringTagInt32 opType = 303 - opStructFieldPtrAnonymousHeadStringTagInt64 opType = 304 - opStructFieldPtrAnonymousHeadStringTagUint opType = 305 - opStructFieldPtrAnonymousHeadStringTagUint8 opType = 306 - opStructFieldPtrAnonymousHeadStringTagUint16 opType = 307 - opStructFieldPtrAnonymousHeadStringTagUint32 opType = 308 - opStructFieldPtrAnonymousHeadStringTagUint64 opType = 309 - opStructFieldPtrAnonymousHeadStringTagFloat32 opType = 310 - opStructFieldPtrAnonymousHeadStringTagFloat64 opType = 311 - opStructFieldPtrAnonymousHeadStringTagBool opType = 312 - opStructFieldPtrAnonymousHeadStringTagString opType = 313 - opStructFieldPtrAnonymousHeadStringTagBytes opType = 314 - opStructFieldPtrAnonymousHeadStringTagArray opType = 315 - opStructFieldPtrAnonymousHeadStringTagMap opType = 316 - opStructFieldPtrAnonymousHeadStringTagMapLoad opType = 317 - opStructFieldPtrAnonymousHeadStringTagSlice opType = 318 - opStructFieldPtrAnonymousHeadStringTagStruct opType = 319 - opStructFieldPtrAnonymousHeadStringTagMarshalJSON opType = 320 - opStructFieldPtrAnonymousHeadStringTagMarshalText opType = 321 - opStructFieldInt opType = 322 - opStructFieldInt8 opType = 323 - opStructFieldInt16 opType = 324 - opStructFieldInt32 opType = 325 - opStructFieldInt64 opType = 326 - opStructFieldUint opType = 327 - opStructFieldUint8 opType = 328 - opStructFieldUint16 opType = 329 - opStructFieldUint32 opType = 330 - opStructFieldUint64 opType = 331 - opStructFieldFloat32 opType = 332 - opStructFieldFloat64 opType = 333 - opStructFieldBool opType = 334 - opStructFieldString opType = 335 - opStructFieldBytes opType = 336 - opStructFieldArray opType = 337 - opStructFieldMap opType = 338 - opStructFieldMapLoad opType = 339 - opStructFieldSlice opType = 340 - opStructFieldStruct opType = 341 - opStructFieldMarshalJSON opType = 342 - opStructFieldMarshalText opType = 343 - opStructFieldOmitEmptyInt opType = 344 - opStructFieldOmitEmptyInt8 opType = 345 - opStructFieldOmitEmptyInt16 opType = 346 - opStructFieldOmitEmptyInt32 opType = 347 - opStructFieldOmitEmptyInt64 opType = 348 - opStructFieldOmitEmptyUint opType = 349 - opStructFieldOmitEmptyUint8 opType = 350 - opStructFieldOmitEmptyUint16 opType = 351 - opStructFieldOmitEmptyUint32 opType = 352 - opStructFieldOmitEmptyUint64 opType = 353 - opStructFieldOmitEmptyFloat32 opType = 354 - opStructFieldOmitEmptyFloat64 opType = 355 - opStructFieldOmitEmptyBool opType = 356 - opStructFieldOmitEmptyString opType = 357 - opStructFieldOmitEmptyBytes opType = 358 - opStructFieldOmitEmptyArray opType = 359 - opStructFieldOmitEmptyMap opType = 360 - opStructFieldOmitEmptyMapLoad opType = 361 - opStructFieldOmitEmptySlice opType = 362 - opStructFieldOmitEmptyStruct opType = 363 - opStructFieldOmitEmptyMarshalJSON opType = 364 - opStructFieldOmitEmptyMarshalText opType = 365 - opStructFieldStringTagInt opType = 366 - opStructFieldStringTagInt8 opType = 367 - opStructFieldStringTagInt16 opType = 368 - opStructFieldStringTagInt32 opType = 369 - opStructFieldStringTagInt64 opType = 370 - opStructFieldStringTagUint opType = 371 - opStructFieldStringTagUint8 opType = 372 - opStructFieldStringTagUint16 opType = 373 - opStructFieldStringTagUint32 opType = 374 - opStructFieldStringTagUint64 opType = 375 - opStructFieldStringTagFloat32 opType = 376 - opStructFieldStringTagFloat64 opType = 377 - opStructFieldStringTagBool opType = 378 - opStructFieldStringTagString opType = 379 - opStructFieldStringTagBytes opType = 380 - opStructFieldStringTagArray opType = 381 - opStructFieldStringTagMap opType = 382 - opStructFieldStringTagMapLoad opType = 383 - opStructFieldStringTagSlice opType = 384 - opStructFieldStringTagStruct opType = 385 - opStructFieldStringTagMarshalJSON opType = 386 - opStructFieldStringTagMarshalText opType = 387 - opEndIndent opType = 388 - opInterfaceIndent opType = 389 - opPtrIndent opType = 390 - opSliceHeadIndent opType = 391 - opRootSliceHeadIndent opType = 392 - opSliceElemIndent opType = 393 - opRootSliceElemIndent opType = 394 - opSliceEndIndent opType = 395 - opArrayHeadIndent opType = 396 - opArrayElemIndent opType = 397 - opArrayEndIndent opType = 398 - opMapHeadIndent opType = 399 - opMapHeadLoadIndent opType = 400 - opRootMapHeadIndent opType = 401 - opMapKeyIndent opType = 402 - opRootMapKeyIndent opType = 403 - opMapValueIndent opType = 404 - opMapEndIndent opType = 405 - opStructFieldHeadIndent opType = 406 - opStructFieldHeadOmitEmptyIndent opType = 407 - opStructFieldHeadStringTagIndent opType = 408 - opStructFieldAnonymousHeadIndent opType = 409 - opStructFieldAnonymousHeadOmitEmptyIndent opType = 410 - opStructFieldPtrAnonymousHeadOmitEmptyIndent opType = 411 - opStructFieldAnonymousHeadStringTagIndent opType = 412 - opStructFieldPtrAnonymousHeadStringTagIndent opType = 413 - opStructFieldPtrHeadIndent opType = 414 - opStructFieldPtrHeadOmitEmptyIndent opType = 415 - opStructFieldPtrHeadStringTagIndent opType = 416 - opStructFieldPtrAnonymousHeadIndent opType = 417 - opStructFieldIndent opType = 418 - opStructFieldOmitEmptyIndent opType = 419 - opStructFieldStringTagIndent opType = 420 - opStructFieldRecursiveIndent opType = 421 - opStructEndIndent opType = 422 - opStructAnonymousEndIndent opType = 423 - opIntIndent opType = 424 - opInt8Indent opType = 425 - opInt16Indent opType = 426 - opInt32Indent opType = 427 - opInt64Indent opType = 428 - opUintIndent opType = 429 - opUint8Indent opType = 430 - opUint16Indent opType = 431 - opUint32Indent opType = 432 - opUint64Indent opType = 433 - opFloat32Indent opType = 434 - opFloat64Indent opType = 435 - opBoolIndent opType = 436 - opStringIndent opType = 437 - opBytesIndent opType = 438 - opArrayIndent opType = 439 - opMapIndent opType = 440 - opMapLoadIndent opType = 441 - opSliceIndent opType = 442 - opStructIndent opType = 443 - opMarshalJSONIndent opType = 444 - opMarshalTextIndent opType = 445 - opStructFieldHeadIntIndent opType = 446 - opStructFieldHeadInt8Indent opType = 447 - opStructFieldHeadInt16Indent opType = 448 - opStructFieldHeadInt32Indent opType = 449 - opStructFieldHeadInt64Indent opType = 450 - opStructFieldHeadUintIndent opType = 451 - opStructFieldHeadUint8Indent opType = 452 - opStructFieldHeadUint16Indent opType = 453 - opStructFieldHeadUint32Indent opType = 454 - opStructFieldHeadUint64Indent opType = 455 - opStructFieldHeadFloat32Indent opType = 456 - opStructFieldHeadFloat64Indent opType = 457 - opStructFieldHeadBoolIndent opType = 458 - opStructFieldHeadStringIndent opType = 459 - opStructFieldHeadBytesIndent opType = 460 - opStructFieldHeadArrayIndent opType = 461 - opStructFieldHeadMapIndent opType = 462 - opStructFieldHeadMapLoadIndent opType = 463 - opStructFieldHeadSliceIndent opType = 464 - opStructFieldHeadStructIndent opType = 465 - opStructFieldHeadMarshalJSONIndent opType = 466 - opStructFieldHeadMarshalTextIndent opType = 467 - opStructFieldHeadOmitEmptyIntIndent opType = 468 - opStructFieldHeadOmitEmptyInt8Indent opType = 469 - opStructFieldHeadOmitEmptyInt16Indent opType = 470 - opStructFieldHeadOmitEmptyInt32Indent opType = 471 - opStructFieldHeadOmitEmptyInt64Indent opType = 472 - opStructFieldHeadOmitEmptyUintIndent opType = 473 - opStructFieldHeadOmitEmptyUint8Indent opType = 474 - opStructFieldHeadOmitEmptyUint16Indent opType = 475 - opStructFieldHeadOmitEmptyUint32Indent opType = 476 - opStructFieldHeadOmitEmptyUint64Indent opType = 477 - opStructFieldHeadOmitEmptyFloat32Indent opType = 478 - opStructFieldHeadOmitEmptyFloat64Indent opType = 479 - opStructFieldHeadOmitEmptyBoolIndent opType = 480 - opStructFieldHeadOmitEmptyStringIndent opType = 481 - opStructFieldHeadOmitEmptyBytesIndent opType = 482 - opStructFieldHeadOmitEmptyArrayIndent opType = 483 - opStructFieldHeadOmitEmptyMapIndent opType = 484 - opStructFieldHeadOmitEmptyMapLoadIndent opType = 485 - opStructFieldHeadOmitEmptySliceIndent opType = 486 - opStructFieldHeadOmitEmptyStructIndent opType = 487 - opStructFieldHeadOmitEmptyMarshalJSONIndent opType = 488 - opStructFieldHeadOmitEmptyMarshalTextIndent opType = 489 - opStructFieldHeadStringTagIntIndent opType = 490 - opStructFieldHeadStringTagInt8Indent opType = 491 - opStructFieldHeadStringTagInt16Indent opType = 492 - opStructFieldHeadStringTagInt32Indent opType = 493 - opStructFieldHeadStringTagInt64Indent opType = 494 - opStructFieldHeadStringTagUintIndent opType = 495 - opStructFieldHeadStringTagUint8Indent opType = 496 - opStructFieldHeadStringTagUint16Indent opType = 497 - opStructFieldHeadStringTagUint32Indent opType = 498 - opStructFieldHeadStringTagUint64Indent opType = 499 - opStructFieldHeadStringTagFloat32Indent opType = 500 - opStructFieldHeadStringTagFloat64Indent opType = 501 - opStructFieldHeadStringTagBoolIndent opType = 502 - opStructFieldHeadStringTagStringIndent opType = 503 - opStructFieldHeadStringTagBytesIndent opType = 504 - opStructFieldHeadStringTagArrayIndent opType = 505 - opStructFieldHeadStringTagMapIndent opType = 506 - opStructFieldHeadStringTagMapLoadIndent opType = 507 - opStructFieldHeadStringTagSliceIndent opType = 508 - opStructFieldHeadStringTagStructIndent opType = 509 - opStructFieldHeadStringTagMarshalJSONIndent opType = 510 - opStructFieldHeadStringTagMarshalTextIndent opType = 511 - opStructFieldAnonymousHeadIntIndent opType = 512 - opStructFieldAnonymousHeadInt8Indent opType = 513 - opStructFieldAnonymousHeadInt16Indent opType = 514 - opStructFieldAnonymousHeadInt32Indent opType = 515 - opStructFieldAnonymousHeadInt64Indent opType = 516 - opStructFieldAnonymousHeadUintIndent opType = 517 - opStructFieldAnonymousHeadUint8Indent opType = 518 - opStructFieldAnonymousHeadUint16Indent opType = 519 - opStructFieldAnonymousHeadUint32Indent opType = 520 - opStructFieldAnonymousHeadUint64Indent opType = 521 - opStructFieldAnonymousHeadFloat32Indent opType = 522 - opStructFieldAnonymousHeadFloat64Indent opType = 523 - opStructFieldAnonymousHeadBoolIndent opType = 524 - opStructFieldAnonymousHeadStringIndent opType = 525 - opStructFieldAnonymousHeadBytesIndent opType = 526 - opStructFieldAnonymousHeadArrayIndent opType = 527 - opStructFieldAnonymousHeadMapIndent opType = 528 - opStructFieldAnonymousHeadMapLoadIndent opType = 529 - opStructFieldAnonymousHeadSliceIndent opType = 530 - opStructFieldAnonymousHeadStructIndent opType = 531 - opStructFieldAnonymousHeadMarshalJSONIndent opType = 532 - opStructFieldAnonymousHeadMarshalTextIndent opType = 533 - opStructFieldAnonymousHeadOmitEmptyIntIndent opType = 534 - opStructFieldAnonymousHeadOmitEmptyInt8Indent opType = 535 - opStructFieldAnonymousHeadOmitEmptyInt16Indent opType = 536 - opStructFieldAnonymousHeadOmitEmptyInt32Indent opType = 537 - opStructFieldAnonymousHeadOmitEmptyInt64Indent opType = 538 - opStructFieldAnonymousHeadOmitEmptyUintIndent opType = 539 - opStructFieldAnonymousHeadOmitEmptyUint8Indent opType = 540 - opStructFieldAnonymousHeadOmitEmptyUint16Indent opType = 541 - opStructFieldAnonymousHeadOmitEmptyUint32Indent opType = 542 - opStructFieldAnonymousHeadOmitEmptyUint64Indent opType = 543 - opStructFieldAnonymousHeadOmitEmptyFloat32Indent opType = 544 - opStructFieldAnonymousHeadOmitEmptyFloat64Indent opType = 545 - opStructFieldAnonymousHeadOmitEmptyBoolIndent opType = 546 - opStructFieldAnonymousHeadOmitEmptyStringIndent opType = 547 - opStructFieldAnonymousHeadOmitEmptyBytesIndent opType = 548 - opStructFieldAnonymousHeadOmitEmptyArrayIndent opType = 549 - opStructFieldAnonymousHeadOmitEmptyMapIndent opType = 550 - opStructFieldAnonymousHeadOmitEmptyMapLoadIndent opType = 551 - opStructFieldAnonymousHeadOmitEmptySliceIndent opType = 552 - opStructFieldAnonymousHeadOmitEmptyStructIndent opType = 553 - opStructFieldAnonymousHeadOmitEmptyMarshalJSONIndent opType = 554 - opStructFieldAnonymousHeadOmitEmptyMarshalTextIndent opType = 555 - opStructFieldAnonymousHeadStringTagIntIndent opType = 556 - opStructFieldAnonymousHeadStringTagInt8Indent opType = 557 - opStructFieldAnonymousHeadStringTagInt16Indent opType = 558 - opStructFieldAnonymousHeadStringTagInt32Indent opType = 559 - opStructFieldAnonymousHeadStringTagInt64Indent opType = 560 - opStructFieldAnonymousHeadStringTagUintIndent opType = 561 - opStructFieldAnonymousHeadStringTagUint8Indent opType = 562 - opStructFieldAnonymousHeadStringTagUint16Indent opType = 563 - opStructFieldAnonymousHeadStringTagUint32Indent opType = 564 - opStructFieldAnonymousHeadStringTagUint64Indent opType = 565 - opStructFieldAnonymousHeadStringTagFloat32Indent opType = 566 - opStructFieldAnonymousHeadStringTagFloat64Indent opType = 567 - opStructFieldAnonymousHeadStringTagBoolIndent opType = 568 - opStructFieldAnonymousHeadStringTagStringIndent opType = 569 - opStructFieldAnonymousHeadStringTagBytesIndent opType = 570 - opStructFieldAnonymousHeadStringTagArrayIndent opType = 571 - opStructFieldAnonymousHeadStringTagMapIndent opType = 572 - opStructFieldAnonymousHeadStringTagMapLoadIndent opType = 573 - opStructFieldAnonymousHeadStringTagSliceIndent opType = 574 - opStructFieldAnonymousHeadStringTagStructIndent opType = 575 - opStructFieldAnonymousHeadStringTagMarshalJSONIndent opType = 576 - opStructFieldAnonymousHeadStringTagMarshalTextIndent opType = 577 - opStructFieldPtrHeadIntIndent opType = 578 - opStructFieldPtrHeadInt8Indent opType = 579 - opStructFieldPtrHeadInt16Indent opType = 580 - opStructFieldPtrHeadInt32Indent opType = 581 - opStructFieldPtrHeadInt64Indent opType = 582 - opStructFieldPtrHeadUintIndent opType = 583 - opStructFieldPtrHeadUint8Indent opType = 584 - opStructFieldPtrHeadUint16Indent opType = 585 - opStructFieldPtrHeadUint32Indent opType = 586 - opStructFieldPtrHeadUint64Indent opType = 587 - opStructFieldPtrHeadFloat32Indent opType = 588 - opStructFieldPtrHeadFloat64Indent opType = 589 - opStructFieldPtrHeadBoolIndent opType = 590 - opStructFieldPtrHeadStringIndent opType = 591 - opStructFieldPtrHeadBytesIndent opType = 592 - opStructFieldPtrHeadArrayIndent opType = 593 - opStructFieldPtrHeadMapIndent opType = 594 - opStructFieldPtrHeadMapLoadIndent opType = 595 - opStructFieldPtrHeadSliceIndent opType = 596 - opStructFieldPtrHeadStructIndent opType = 597 - opStructFieldPtrHeadMarshalJSONIndent opType = 598 - opStructFieldPtrHeadMarshalTextIndent opType = 599 - opStructFieldPtrHeadOmitEmptyIntIndent opType = 600 - opStructFieldPtrHeadOmitEmptyInt8Indent opType = 601 - opStructFieldPtrHeadOmitEmptyInt16Indent opType = 602 - opStructFieldPtrHeadOmitEmptyInt32Indent opType = 603 - opStructFieldPtrHeadOmitEmptyInt64Indent opType = 604 - opStructFieldPtrHeadOmitEmptyUintIndent opType = 605 - opStructFieldPtrHeadOmitEmptyUint8Indent opType = 606 - opStructFieldPtrHeadOmitEmptyUint16Indent opType = 607 - opStructFieldPtrHeadOmitEmptyUint32Indent opType = 608 - opStructFieldPtrHeadOmitEmptyUint64Indent opType = 609 - opStructFieldPtrHeadOmitEmptyFloat32Indent opType = 610 - opStructFieldPtrHeadOmitEmptyFloat64Indent opType = 611 - opStructFieldPtrHeadOmitEmptyBoolIndent opType = 612 - opStructFieldPtrHeadOmitEmptyStringIndent opType = 613 - opStructFieldPtrHeadOmitEmptyBytesIndent opType = 614 - opStructFieldPtrHeadOmitEmptyArrayIndent opType = 615 - opStructFieldPtrHeadOmitEmptyMapIndent opType = 616 - opStructFieldPtrHeadOmitEmptyMapLoadIndent opType = 617 - opStructFieldPtrHeadOmitEmptySliceIndent opType = 618 - opStructFieldPtrHeadOmitEmptyStructIndent opType = 619 - opStructFieldPtrHeadOmitEmptyMarshalJSONIndent opType = 620 - opStructFieldPtrHeadOmitEmptyMarshalTextIndent opType = 621 - opStructFieldPtrHeadStringTagIntIndent opType = 622 - opStructFieldPtrHeadStringTagInt8Indent opType = 623 - opStructFieldPtrHeadStringTagInt16Indent opType = 624 - opStructFieldPtrHeadStringTagInt32Indent opType = 625 - opStructFieldPtrHeadStringTagInt64Indent opType = 626 - opStructFieldPtrHeadStringTagUintIndent opType = 627 - opStructFieldPtrHeadStringTagUint8Indent opType = 628 - opStructFieldPtrHeadStringTagUint16Indent opType = 629 - opStructFieldPtrHeadStringTagUint32Indent opType = 630 - opStructFieldPtrHeadStringTagUint64Indent opType = 631 - opStructFieldPtrHeadStringTagFloat32Indent opType = 632 - opStructFieldPtrHeadStringTagFloat64Indent opType = 633 - opStructFieldPtrHeadStringTagBoolIndent opType = 634 - opStructFieldPtrHeadStringTagStringIndent opType = 635 - opStructFieldPtrHeadStringTagBytesIndent opType = 636 - opStructFieldPtrHeadStringTagArrayIndent opType = 637 - opStructFieldPtrHeadStringTagMapIndent opType = 638 - opStructFieldPtrHeadStringTagMapLoadIndent opType = 639 - opStructFieldPtrHeadStringTagSliceIndent opType = 640 - opStructFieldPtrHeadStringTagStructIndent opType = 641 - opStructFieldPtrHeadStringTagMarshalJSONIndent opType = 642 - opStructFieldPtrHeadStringTagMarshalTextIndent opType = 643 - opStructFieldPtrAnonymousHeadIntIndent opType = 644 - opStructFieldPtrAnonymousHeadInt8Indent opType = 645 - opStructFieldPtrAnonymousHeadInt16Indent opType = 646 - opStructFieldPtrAnonymousHeadInt32Indent opType = 647 - opStructFieldPtrAnonymousHeadInt64Indent opType = 648 - opStructFieldPtrAnonymousHeadUintIndent opType = 649 - opStructFieldPtrAnonymousHeadUint8Indent opType = 650 - opStructFieldPtrAnonymousHeadUint16Indent opType = 651 - opStructFieldPtrAnonymousHeadUint32Indent opType = 652 - opStructFieldPtrAnonymousHeadUint64Indent opType = 653 - opStructFieldPtrAnonymousHeadFloat32Indent opType = 654 - opStructFieldPtrAnonymousHeadFloat64Indent opType = 655 - opStructFieldPtrAnonymousHeadBoolIndent opType = 656 - opStructFieldPtrAnonymousHeadStringIndent opType = 657 - opStructFieldPtrAnonymousHeadBytesIndent opType = 658 - opStructFieldPtrAnonymousHeadArrayIndent opType = 659 - opStructFieldPtrAnonymousHeadMapIndent opType = 660 - opStructFieldPtrAnonymousHeadMapLoadIndent opType = 661 - opStructFieldPtrAnonymousHeadSliceIndent opType = 662 - opStructFieldPtrAnonymousHeadStructIndent opType = 663 - opStructFieldPtrAnonymousHeadMarshalJSONIndent opType = 664 - opStructFieldPtrAnonymousHeadMarshalTextIndent opType = 665 - opStructFieldPtrAnonymousHeadOmitEmptyIntIndent opType = 666 - opStructFieldPtrAnonymousHeadOmitEmptyInt8Indent opType = 667 - opStructFieldPtrAnonymousHeadOmitEmptyInt16Indent opType = 668 - opStructFieldPtrAnonymousHeadOmitEmptyInt32Indent opType = 669 - opStructFieldPtrAnonymousHeadOmitEmptyInt64Indent opType = 670 - opStructFieldPtrAnonymousHeadOmitEmptyUintIndent opType = 671 - opStructFieldPtrAnonymousHeadOmitEmptyUint8Indent opType = 672 - opStructFieldPtrAnonymousHeadOmitEmptyUint16Indent opType = 673 - opStructFieldPtrAnonymousHeadOmitEmptyUint32Indent opType = 674 - opStructFieldPtrAnonymousHeadOmitEmptyUint64Indent opType = 675 - opStructFieldPtrAnonymousHeadOmitEmptyFloat32Indent opType = 676 - opStructFieldPtrAnonymousHeadOmitEmptyFloat64Indent opType = 677 - opStructFieldPtrAnonymousHeadOmitEmptyBoolIndent opType = 678 - opStructFieldPtrAnonymousHeadOmitEmptyStringIndent opType = 679 - opStructFieldPtrAnonymousHeadOmitEmptyBytesIndent opType = 680 - opStructFieldPtrAnonymousHeadOmitEmptyArrayIndent opType = 681 - opStructFieldPtrAnonymousHeadOmitEmptyMapIndent opType = 682 - opStructFieldPtrAnonymousHeadOmitEmptyMapLoadIndent opType = 683 - opStructFieldPtrAnonymousHeadOmitEmptySliceIndent opType = 684 - opStructFieldPtrAnonymousHeadOmitEmptyStructIndent opType = 685 - opStructFieldPtrAnonymousHeadOmitEmptyMarshalJSONIndent opType = 686 - opStructFieldPtrAnonymousHeadOmitEmptyMarshalTextIndent opType = 687 - opStructFieldPtrAnonymousHeadStringTagIntIndent opType = 688 - opStructFieldPtrAnonymousHeadStringTagInt8Indent opType = 689 - opStructFieldPtrAnonymousHeadStringTagInt16Indent opType = 690 - opStructFieldPtrAnonymousHeadStringTagInt32Indent opType = 691 - opStructFieldPtrAnonymousHeadStringTagInt64Indent opType = 692 - opStructFieldPtrAnonymousHeadStringTagUintIndent opType = 693 - opStructFieldPtrAnonymousHeadStringTagUint8Indent opType = 694 - opStructFieldPtrAnonymousHeadStringTagUint16Indent opType = 695 - opStructFieldPtrAnonymousHeadStringTagUint32Indent opType = 696 - opStructFieldPtrAnonymousHeadStringTagUint64Indent opType = 697 - opStructFieldPtrAnonymousHeadStringTagFloat32Indent opType = 698 - opStructFieldPtrAnonymousHeadStringTagFloat64Indent opType = 699 - opStructFieldPtrAnonymousHeadStringTagBoolIndent opType = 700 - opStructFieldPtrAnonymousHeadStringTagStringIndent opType = 701 - opStructFieldPtrAnonymousHeadStringTagBytesIndent opType = 702 - opStructFieldPtrAnonymousHeadStringTagArrayIndent opType = 703 - opStructFieldPtrAnonymousHeadStringTagMapIndent opType = 704 - opStructFieldPtrAnonymousHeadStringTagMapLoadIndent opType = 705 - opStructFieldPtrAnonymousHeadStringTagSliceIndent opType = 706 - opStructFieldPtrAnonymousHeadStringTagStructIndent opType = 707 - opStructFieldPtrAnonymousHeadStringTagMarshalJSONIndent opType = 708 - opStructFieldPtrAnonymousHeadStringTagMarshalTextIndent opType = 709 - opStructFieldIntIndent opType = 710 - opStructFieldInt8Indent opType = 711 - opStructFieldInt16Indent opType = 712 - opStructFieldInt32Indent opType = 713 - opStructFieldInt64Indent opType = 714 - opStructFieldUintIndent opType = 715 - opStructFieldUint8Indent opType = 716 - opStructFieldUint16Indent opType = 717 - opStructFieldUint32Indent opType = 718 - opStructFieldUint64Indent opType = 719 - opStructFieldFloat32Indent opType = 720 - opStructFieldFloat64Indent opType = 721 - opStructFieldBoolIndent opType = 722 - opStructFieldStringIndent opType = 723 - opStructFieldBytesIndent opType = 724 - opStructFieldArrayIndent opType = 725 - opStructFieldMapIndent opType = 726 - opStructFieldMapLoadIndent opType = 727 - opStructFieldSliceIndent opType = 728 - opStructFieldStructIndent opType = 729 - opStructFieldMarshalJSONIndent opType = 730 - opStructFieldMarshalTextIndent opType = 731 - opStructFieldOmitEmptyIntIndent opType = 732 - opStructFieldOmitEmptyInt8Indent opType = 733 - opStructFieldOmitEmptyInt16Indent opType = 734 - opStructFieldOmitEmptyInt32Indent opType = 735 - opStructFieldOmitEmptyInt64Indent opType = 736 - opStructFieldOmitEmptyUintIndent opType = 737 - opStructFieldOmitEmptyUint8Indent opType = 738 - opStructFieldOmitEmptyUint16Indent opType = 739 - opStructFieldOmitEmptyUint32Indent opType = 740 - opStructFieldOmitEmptyUint64Indent opType = 741 - opStructFieldOmitEmptyFloat32Indent opType = 742 - opStructFieldOmitEmptyFloat64Indent opType = 743 - opStructFieldOmitEmptyBoolIndent opType = 744 - opStructFieldOmitEmptyStringIndent opType = 745 - opStructFieldOmitEmptyBytesIndent opType = 746 - opStructFieldOmitEmptyArrayIndent opType = 747 - opStructFieldOmitEmptyMapIndent opType = 748 - opStructFieldOmitEmptyMapLoadIndent opType = 749 - opStructFieldOmitEmptySliceIndent opType = 750 - opStructFieldOmitEmptyStructIndent opType = 751 - opStructFieldOmitEmptyMarshalJSONIndent opType = 752 - opStructFieldOmitEmptyMarshalTextIndent opType = 753 - opStructFieldStringTagIntIndent opType = 754 - opStructFieldStringTagInt8Indent opType = 755 - opStructFieldStringTagInt16Indent opType = 756 - opStructFieldStringTagInt32Indent opType = 757 - opStructFieldStringTagInt64Indent opType = 758 - opStructFieldStringTagUintIndent opType = 759 - opStructFieldStringTagUint8Indent opType = 760 - opStructFieldStringTagUint16Indent opType = 761 - opStructFieldStringTagUint32Indent opType = 762 - opStructFieldStringTagUint64Indent opType = 763 - opStructFieldStringTagFloat32Indent opType = 764 - opStructFieldStringTagFloat64Indent opType = 765 - opStructFieldStringTagBoolIndent opType = 766 - opStructFieldStringTagStringIndent opType = 767 - opStructFieldStringTagBytesIndent opType = 768 - opStructFieldStringTagArrayIndent opType = 769 - opStructFieldStringTagMapIndent opType = 770 - opStructFieldStringTagMapLoadIndent opType = 771 - opStructFieldStringTagSliceIndent opType = 772 - opStructFieldStringTagStructIndent opType = 773 - opStructFieldStringTagMarshalJSONIndent opType = 774 - opStructFieldStringTagMarshalTextIndent opType = 775 + opInterfaceEnd opType = 2 + opPtr opType = 3 + opSliceHead opType = 4 + opRootSliceHead opType = 5 + opSliceElem opType = 6 + opRootSliceElem opType = 7 + opSliceEnd opType = 8 + opArrayHead opType = 9 + opArrayElem opType = 10 + opArrayEnd opType = 11 + opMapHead opType = 12 + opMapHeadLoad opType = 13 + opRootMapHead opType = 14 + opMapKey opType = 15 + opRootMapKey opType = 16 + opMapValue opType = 17 + opMapEnd opType = 18 + opStructFieldHead opType = 19 + opStructFieldHeadOmitEmpty opType = 20 + opStructFieldHeadStringTag opType = 21 + opStructFieldAnonymousHead opType = 22 + opStructFieldAnonymousHeadOmitEmpty opType = 23 + opStructFieldPtrAnonymousHeadOmitEmpty opType = 24 + opStructFieldAnonymousHeadStringTag opType = 25 + opStructFieldPtrAnonymousHeadStringTag opType = 26 + opStructFieldPtrHead opType = 27 + opStructFieldPtrHeadOmitEmpty opType = 28 + opStructFieldPtrHeadStringTag opType = 29 + opStructFieldPtrAnonymousHead opType = 30 + opStructField opType = 31 + opStructFieldOmitEmpty opType = 32 + opStructFieldStringTag opType = 33 + opStructFieldRecursive opType = 34 + opStructFieldRecursiveEnd opType = 35 + opStructEnd opType = 36 + opStructAnonymousEnd opType = 37 + opInt opType = 38 + opInt8 opType = 39 + opInt16 opType = 40 + opInt32 opType = 41 + opInt64 opType = 42 + opUint opType = 43 + opUint8 opType = 44 + opUint16 opType = 45 + opUint32 opType = 46 + opUint64 opType = 47 + opFloat32 opType = 48 + opFloat64 opType = 49 + opBool opType = 50 + opString opType = 51 + opBytes opType = 52 + opArray opType = 53 + opMap opType = 54 + opMapLoad opType = 55 + opSlice opType = 56 + opStruct opType = 57 + opMarshalJSON opType = 58 + opMarshalText opType = 59 + opStructFieldHeadInt opType = 60 + opStructFieldHeadInt8 opType = 61 + opStructFieldHeadInt16 opType = 62 + opStructFieldHeadInt32 opType = 63 + opStructFieldHeadInt64 opType = 64 + opStructFieldHeadUint opType = 65 + opStructFieldHeadUint8 opType = 66 + opStructFieldHeadUint16 opType = 67 + opStructFieldHeadUint32 opType = 68 + opStructFieldHeadUint64 opType = 69 + opStructFieldHeadFloat32 opType = 70 + opStructFieldHeadFloat64 opType = 71 + opStructFieldHeadBool opType = 72 + opStructFieldHeadString opType = 73 + opStructFieldHeadBytes opType = 74 + opStructFieldHeadArray opType = 75 + opStructFieldHeadMap opType = 76 + opStructFieldHeadMapLoad opType = 77 + opStructFieldHeadSlice opType = 78 + opStructFieldHeadStruct opType = 79 + opStructFieldHeadMarshalJSON opType = 80 + opStructFieldHeadMarshalText opType = 81 + opStructFieldHeadOmitEmptyInt opType = 82 + opStructFieldHeadOmitEmptyInt8 opType = 83 + opStructFieldHeadOmitEmptyInt16 opType = 84 + opStructFieldHeadOmitEmptyInt32 opType = 85 + opStructFieldHeadOmitEmptyInt64 opType = 86 + opStructFieldHeadOmitEmptyUint opType = 87 + opStructFieldHeadOmitEmptyUint8 opType = 88 + opStructFieldHeadOmitEmptyUint16 opType = 89 + opStructFieldHeadOmitEmptyUint32 opType = 90 + opStructFieldHeadOmitEmptyUint64 opType = 91 + opStructFieldHeadOmitEmptyFloat32 opType = 92 + opStructFieldHeadOmitEmptyFloat64 opType = 93 + opStructFieldHeadOmitEmptyBool opType = 94 + opStructFieldHeadOmitEmptyString opType = 95 + opStructFieldHeadOmitEmptyBytes opType = 96 + opStructFieldHeadOmitEmptyArray opType = 97 + opStructFieldHeadOmitEmptyMap opType = 98 + opStructFieldHeadOmitEmptyMapLoad opType = 99 + opStructFieldHeadOmitEmptySlice opType = 100 + opStructFieldHeadOmitEmptyStruct opType = 101 + opStructFieldHeadOmitEmptyMarshalJSON opType = 102 + opStructFieldHeadOmitEmptyMarshalText opType = 103 + opStructFieldHeadStringTagInt opType = 104 + opStructFieldHeadStringTagInt8 opType = 105 + opStructFieldHeadStringTagInt16 opType = 106 + opStructFieldHeadStringTagInt32 opType = 107 + opStructFieldHeadStringTagInt64 opType = 108 + opStructFieldHeadStringTagUint opType = 109 + opStructFieldHeadStringTagUint8 opType = 110 + opStructFieldHeadStringTagUint16 opType = 111 + opStructFieldHeadStringTagUint32 opType = 112 + opStructFieldHeadStringTagUint64 opType = 113 + opStructFieldHeadStringTagFloat32 opType = 114 + opStructFieldHeadStringTagFloat64 opType = 115 + opStructFieldHeadStringTagBool opType = 116 + opStructFieldHeadStringTagString opType = 117 + opStructFieldHeadStringTagBytes opType = 118 + opStructFieldHeadStringTagArray opType = 119 + opStructFieldHeadStringTagMap opType = 120 + opStructFieldHeadStringTagMapLoad opType = 121 + opStructFieldHeadStringTagSlice opType = 122 + opStructFieldHeadStringTagStruct opType = 123 + opStructFieldHeadStringTagMarshalJSON opType = 124 + opStructFieldHeadStringTagMarshalText opType = 125 + opStructFieldAnonymousHeadInt opType = 126 + opStructFieldAnonymousHeadInt8 opType = 127 + opStructFieldAnonymousHeadInt16 opType = 128 + opStructFieldAnonymousHeadInt32 opType = 129 + opStructFieldAnonymousHeadInt64 opType = 130 + opStructFieldAnonymousHeadUint opType = 131 + opStructFieldAnonymousHeadUint8 opType = 132 + opStructFieldAnonymousHeadUint16 opType = 133 + opStructFieldAnonymousHeadUint32 opType = 134 + opStructFieldAnonymousHeadUint64 opType = 135 + opStructFieldAnonymousHeadFloat32 opType = 136 + opStructFieldAnonymousHeadFloat64 opType = 137 + opStructFieldAnonymousHeadBool opType = 138 + opStructFieldAnonymousHeadString opType = 139 + opStructFieldAnonymousHeadBytes opType = 140 + opStructFieldAnonymousHeadArray opType = 141 + opStructFieldAnonymousHeadMap opType = 142 + opStructFieldAnonymousHeadMapLoad opType = 143 + opStructFieldAnonymousHeadSlice opType = 144 + opStructFieldAnonymousHeadStruct opType = 145 + opStructFieldAnonymousHeadMarshalJSON opType = 146 + opStructFieldAnonymousHeadMarshalText opType = 147 + opStructFieldAnonymousHeadOmitEmptyInt opType = 148 + opStructFieldAnonymousHeadOmitEmptyInt8 opType = 149 + opStructFieldAnonymousHeadOmitEmptyInt16 opType = 150 + opStructFieldAnonymousHeadOmitEmptyInt32 opType = 151 + opStructFieldAnonymousHeadOmitEmptyInt64 opType = 152 + opStructFieldAnonymousHeadOmitEmptyUint opType = 153 + opStructFieldAnonymousHeadOmitEmptyUint8 opType = 154 + opStructFieldAnonymousHeadOmitEmptyUint16 opType = 155 + opStructFieldAnonymousHeadOmitEmptyUint32 opType = 156 + opStructFieldAnonymousHeadOmitEmptyUint64 opType = 157 + opStructFieldAnonymousHeadOmitEmptyFloat32 opType = 158 + opStructFieldAnonymousHeadOmitEmptyFloat64 opType = 159 + opStructFieldAnonymousHeadOmitEmptyBool opType = 160 + opStructFieldAnonymousHeadOmitEmptyString opType = 161 + opStructFieldAnonymousHeadOmitEmptyBytes opType = 162 + opStructFieldAnonymousHeadOmitEmptyArray opType = 163 + opStructFieldAnonymousHeadOmitEmptyMap opType = 164 + opStructFieldAnonymousHeadOmitEmptyMapLoad opType = 165 + opStructFieldAnonymousHeadOmitEmptySlice opType = 166 + opStructFieldAnonymousHeadOmitEmptyStruct opType = 167 + opStructFieldAnonymousHeadOmitEmptyMarshalJSON opType = 168 + opStructFieldAnonymousHeadOmitEmptyMarshalText opType = 169 + opStructFieldAnonymousHeadStringTagInt opType = 170 + opStructFieldAnonymousHeadStringTagInt8 opType = 171 + opStructFieldAnonymousHeadStringTagInt16 opType = 172 + opStructFieldAnonymousHeadStringTagInt32 opType = 173 + opStructFieldAnonymousHeadStringTagInt64 opType = 174 + opStructFieldAnonymousHeadStringTagUint opType = 175 + opStructFieldAnonymousHeadStringTagUint8 opType = 176 + opStructFieldAnonymousHeadStringTagUint16 opType = 177 + opStructFieldAnonymousHeadStringTagUint32 opType = 178 + opStructFieldAnonymousHeadStringTagUint64 opType = 179 + opStructFieldAnonymousHeadStringTagFloat32 opType = 180 + opStructFieldAnonymousHeadStringTagFloat64 opType = 181 + opStructFieldAnonymousHeadStringTagBool opType = 182 + opStructFieldAnonymousHeadStringTagString opType = 183 + opStructFieldAnonymousHeadStringTagBytes opType = 184 + opStructFieldAnonymousHeadStringTagArray opType = 185 + opStructFieldAnonymousHeadStringTagMap opType = 186 + opStructFieldAnonymousHeadStringTagMapLoad opType = 187 + opStructFieldAnonymousHeadStringTagSlice opType = 188 + opStructFieldAnonymousHeadStringTagStruct opType = 189 + opStructFieldAnonymousHeadStringTagMarshalJSON opType = 190 + opStructFieldAnonymousHeadStringTagMarshalText opType = 191 + opStructFieldPtrHeadInt opType = 192 + opStructFieldPtrHeadInt8 opType = 193 + opStructFieldPtrHeadInt16 opType = 194 + opStructFieldPtrHeadInt32 opType = 195 + opStructFieldPtrHeadInt64 opType = 196 + opStructFieldPtrHeadUint opType = 197 + opStructFieldPtrHeadUint8 opType = 198 + opStructFieldPtrHeadUint16 opType = 199 + opStructFieldPtrHeadUint32 opType = 200 + opStructFieldPtrHeadUint64 opType = 201 + opStructFieldPtrHeadFloat32 opType = 202 + opStructFieldPtrHeadFloat64 opType = 203 + opStructFieldPtrHeadBool opType = 204 + opStructFieldPtrHeadString opType = 205 + opStructFieldPtrHeadBytes opType = 206 + opStructFieldPtrHeadArray opType = 207 + opStructFieldPtrHeadMap opType = 208 + opStructFieldPtrHeadMapLoad opType = 209 + opStructFieldPtrHeadSlice opType = 210 + opStructFieldPtrHeadStruct opType = 211 + opStructFieldPtrHeadMarshalJSON opType = 212 + opStructFieldPtrHeadMarshalText opType = 213 + opStructFieldPtrHeadOmitEmptyInt opType = 214 + opStructFieldPtrHeadOmitEmptyInt8 opType = 215 + opStructFieldPtrHeadOmitEmptyInt16 opType = 216 + opStructFieldPtrHeadOmitEmptyInt32 opType = 217 + opStructFieldPtrHeadOmitEmptyInt64 opType = 218 + opStructFieldPtrHeadOmitEmptyUint opType = 219 + opStructFieldPtrHeadOmitEmptyUint8 opType = 220 + opStructFieldPtrHeadOmitEmptyUint16 opType = 221 + opStructFieldPtrHeadOmitEmptyUint32 opType = 222 + opStructFieldPtrHeadOmitEmptyUint64 opType = 223 + opStructFieldPtrHeadOmitEmptyFloat32 opType = 224 + opStructFieldPtrHeadOmitEmptyFloat64 opType = 225 + opStructFieldPtrHeadOmitEmptyBool opType = 226 + opStructFieldPtrHeadOmitEmptyString opType = 227 + opStructFieldPtrHeadOmitEmptyBytes opType = 228 + opStructFieldPtrHeadOmitEmptyArray opType = 229 + opStructFieldPtrHeadOmitEmptyMap opType = 230 + opStructFieldPtrHeadOmitEmptyMapLoad opType = 231 + opStructFieldPtrHeadOmitEmptySlice opType = 232 + opStructFieldPtrHeadOmitEmptyStruct opType = 233 + opStructFieldPtrHeadOmitEmptyMarshalJSON opType = 234 + opStructFieldPtrHeadOmitEmptyMarshalText opType = 235 + opStructFieldPtrHeadStringTagInt opType = 236 + opStructFieldPtrHeadStringTagInt8 opType = 237 + opStructFieldPtrHeadStringTagInt16 opType = 238 + opStructFieldPtrHeadStringTagInt32 opType = 239 + opStructFieldPtrHeadStringTagInt64 opType = 240 + opStructFieldPtrHeadStringTagUint opType = 241 + opStructFieldPtrHeadStringTagUint8 opType = 242 + opStructFieldPtrHeadStringTagUint16 opType = 243 + opStructFieldPtrHeadStringTagUint32 opType = 244 + opStructFieldPtrHeadStringTagUint64 opType = 245 + opStructFieldPtrHeadStringTagFloat32 opType = 246 + opStructFieldPtrHeadStringTagFloat64 opType = 247 + opStructFieldPtrHeadStringTagBool opType = 248 + opStructFieldPtrHeadStringTagString opType = 249 + opStructFieldPtrHeadStringTagBytes opType = 250 + opStructFieldPtrHeadStringTagArray opType = 251 + opStructFieldPtrHeadStringTagMap opType = 252 + opStructFieldPtrHeadStringTagMapLoad opType = 253 + opStructFieldPtrHeadStringTagSlice opType = 254 + opStructFieldPtrHeadStringTagStruct opType = 255 + opStructFieldPtrHeadStringTagMarshalJSON opType = 256 + opStructFieldPtrHeadStringTagMarshalText opType = 257 + opStructFieldPtrAnonymousHeadInt opType = 258 + opStructFieldPtrAnonymousHeadInt8 opType = 259 + opStructFieldPtrAnonymousHeadInt16 opType = 260 + opStructFieldPtrAnonymousHeadInt32 opType = 261 + opStructFieldPtrAnonymousHeadInt64 opType = 262 + opStructFieldPtrAnonymousHeadUint opType = 263 + opStructFieldPtrAnonymousHeadUint8 opType = 264 + opStructFieldPtrAnonymousHeadUint16 opType = 265 + opStructFieldPtrAnonymousHeadUint32 opType = 266 + opStructFieldPtrAnonymousHeadUint64 opType = 267 + opStructFieldPtrAnonymousHeadFloat32 opType = 268 + opStructFieldPtrAnonymousHeadFloat64 opType = 269 + opStructFieldPtrAnonymousHeadBool opType = 270 + opStructFieldPtrAnonymousHeadString opType = 271 + opStructFieldPtrAnonymousHeadBytes opType = 272 + opStructFieldPtrAnonymousHeadArray opType = 273 + opStructFieldPtrAnonymousHeadMap opType = 274 + opStructFieldPtrAnonymousHeadMapLoad opType = 275 + opStructFieldPtrAnonymousHeadSlice opType = 276 + opStructFieldPtrAnonymousHeadStruct opType = 277 + opStructFieldPtrAnonymousHeadMarshalJSON opType = 278 + opStructFieldPtrAnonymousHeadMarshalText opType = 279 + opStructFieldPtrAnonymousHeadOmitEmptyInt opType = 280 + opStructFieldPtrAnonymousHeadOmitEmptyInt8 opType = 281 + opStructFieldPtrAnonymousHeadOmitEmptyInt16 opType = 282 + opStructFieldPtrAnonymousHeadOmitEmptyInt32 opType = 283 + opStructFieldPtrAnonymousHeadOmitEmptyInt64 opType = 284 + opStructFieldPtrAnonymousHeadOmitEmptyUint opType = 285 + opStructFieldPtrAnonymousHeadOmitEmptyUint8 opType = 286 + opStructFieldPtrAnonymousHeadOmitEmptyUint16 opType = 287 + opStructFieldPtrAnonymousHeadOmitEmptyUint32 opType = 288 + opStructFieldPtrAnonymousHeadOmitEmptyUint64 opType = 289 + opStructFieldPtrAnonymousHeadOmitEmptyFloat32 opType = 290 + opStructFieldPtrAnonymousHeadOmitEmptyFloat64 opType = 291 + opStructFieldPtrAnonymousHeadOmitEmptyBool opType = 292 + opStructFieldPtrAnonymousHeadOmitEmptyString opType = 293 + opStructFieldPtrAnonymousHeadOmitEmptyBytes opType = 294 + opStructFieldPtrAnonymousHeadOmitEmptyArray opType = 295 + opStructFieldPtrAnonymousHeadOmitEmptyMap opType = 296 + opStructFieldPtrAnonymousHeadOmitEmptyMapLoad opType = 297 + opStructFieldPtrAnonymousHeadOmitEmptySlice opType = 298 + opStructFieldPtrAnonymousHeadOmitEmptyStruct opType = 299 + opStructFieldPtrAnonymousHeadOmitEmptyMarshalJSON opType = 300 + opStructFieldPtrAnonymousHeadOmitEmptyMarshalText opType = 301 + opStructFieldPtrAnonymousHeadStringTagInt opType = 302 + opStructFieldPtrAnonymousHeadStringTagInt8 opType = 303 + opStructFieldPtrAnonymousHeadStringTagInt16 opType = 304 + opStructFieldPtrAnonymousHeadStringTagInt32 opType = 305 + opStructFieldPtrAnonymousHeadStringTagInt64 opType = 306 + opStructFieldPtrAnonymousHeadStringTagUint opType = 307 + opStructFieldPtrAnonymousHeadStringTagUint8 opType = 308 + opStructFieldPtrAnonymousHeadStringTagUint16 opType = 309 + opStructFieldPtrAnonymousHeadStringTagUint32 opType = 310 + opStructFieldPtrAnonymousHeadStringTagUint64 opType = 311 + opStructFieldPtrAnonymousHeadStringTagFloat32 opType = 312 + opStructFieldPtrAnonymousHeadStringTagFloat64 opType = 313 + opStructFieldPtrAnonymousHeadStringTagBool opType = 314 + opStructFieldPtrAnonymousHeadStringTagString opType = 315 + opStructFieldPtrAnonymousHeadStringTagBytes opType = 316 + opStructFieldPtrAnonymousHeadStringTagArray opType = 317 + opStructFieldPtrAnonymousHeadStringTagMap opType = 318 + opStructFieldPtrAnonymousHeadStringTagMapLoad opType = 319 + opStructFieldPtrAnonymousHeadStringTagSlice opType = 320 + opStructFieldPtrAnonymousHeadStringTagStruct opType = 321 + opStructFieldPtrAnonymousHeadStringTagMarshalJSON opType = 322 + opStructFieldPtrAnonymousHeadStringTagMarshalText opType = 323 + opStructFieldInt opType = 324 + opStructFieldInt8 opType = 325 + opStructFieldInt16 opType = 326 + opStructFieldInt32 opType = 327 + opStructFieldInt64 opType = 328 + opStructFieldUint opType = 329 + opStructFieldUint8 opType = 330 + opStructFieldUint16 opType = 331 + opStructFieldUint32 opType = 332 + opStructFieldUint64 opType = 333 + opStructFieldFloat32 opType = 334 + opStructFieldFloat64 opType = 335 + opStructFieldBool opType = 336 + opStructFieldString opType = 337 + opStructFieldBytes opType = 338 + opStructFieldArray opType = 339 + opStructFieldMap opType = 340 + opStructFieldMapLoad opType = 341 + opStructFieldSlice opType = 342 + opStructFieldStruct opType = 343 + opStructFieldMarshalJSON opType = 344 + opStructFieldMarshalText opType = 345 + opStructFieldOmitEmptyInt opType = 346 + opStructFieldOmitEmptyInt8 opType = 347 + opStructFieldOmitEmptyInt16 opType = 348 + opStructFieldOmitEmptyInt32 opType = 349 + opStructFieldOmitEmptyInt64 opType = 350 + opStructFieldOmitEmptyUint opType = 351 + opStructFieldOmitEmptyUint8 opType = 352 + opStructFieldOmitEmptyUint16 opType = 353 + opStructFieldOmitEmptyUint32 opType = 354 + opStructFieldOmitEmptyUint64 opType = 355 + opStructFieldOmitEmptyFloat32 opType = 356 + opStructFieldOmitEmptyFloat64 opType = 357 + opStructFieldOmitEmptyBool opType = 358 + opStructFieldOmitEmptyString opType = 359 + opStructFieldOmitEmptyBytes opType = 360 + opStructFieldOmitEmptyArray opType = 361 + opStructFieldOmitEmptyMap opType = 362 + opStructFieldOmitEmptyMapLoad opType = 363 + opStructFieldOmitEmptySlice opType = 364 + opStructFieldOmitEmptyStruct opType = 365 + opStructFieldOmitEmptyMarshalJSON opType = 366 + opStructFieldOmitEmptyMarshalText opType = 367 + opStructFieldStringTagInt opType = 368 + opStructFieldStringTagInt8 opType = 369 + opStructFieldStringTagInt16 opType = 370 + opStructFieldStringTagInt32 opType = 371 + opStructFieldStringTagInt64 opType = 372 + opStructFieldStringTagUint opType = 373 + opStructFieldStringTagUint8 opType = 374 + opStructFieldStringTagUint16 opType = 375 + opStructFieldStringTagUint32 opType = 376 + opStructFieldStringTagUint64 opType = 377 + opStructFieldStringTagFloat32 opType = 378 + opStructFieldStringTagFloat64 opType = 379 + opStructFieldStringTagBool opType = 380 + opStructFieldStringTagString opType = 381 + opStructFieldStringTagBytes opType = 382 + opStructFieldStringTagArray opType = 383 + opStructFieldStringTagMap opType = 384 + opStructFieldStringTagMapLoad opType = 385 + opStructFieldStringTagSlice opType = 386 + opStructFieldStringTagStruct opType = 387 + opStructFieldStringTagMarshalJSON opType = 388 + opStructFieldStringTagMarshalText opType = 389 + opEndIndent opType = 390 + opInterfaceIndent opType = 391 + opInterfaceEndIndent opType = 392 + opPtrIndent opType = 393 + opSliceHeadIndent opType = 394 + opRootSliceHeadIndent opType = 395 + opSliceElemIndent opType = 396 + opRootSliceElemIndent opType = 397 + opSliceEndIndent opType = 398 + opArrayHeadIndent opType = 399 + opArrayElemIndent opType = 400 + opArrayEndIndent opType = 401 + opMapHeadIndent opType = 402 + opMapHeadLoadIndent opType = 403 + opRootMapHeadIndent opType = 404 + opMapKeyIndent opType = 405 + opRootMapKeyIndent opType = 406 + opMapValueIndent opType = 407 + opMapEndIndent opType = 408 + opStructFieldHeadIndent opType = 409 + opStructFieldHeadOmitEmptyIndent opType = 410 + opStructFieldHeadStringTagIndent opType = 411 + opStructFieldAnonymousHeadIndent opType = 412 + opStructFieldAnonymousHeadOmitEmptyIndent opType = 413 + opStructFieldPtrAnonymousHeadOmitEmptyIndent opType = 414 + opStructFieldAnonymousHeadStringTagIndent opType = 415 + opStructFieldPtrAnonymousHeadStringTagIndent opType = 416 + opStructFieldPtrHeadIndent opType = 417 + opStructFieldPtrHeadOmitEmptyIndent opType = 418 + opStructFieldPtrHeadStringTagIndent opType = 419 + opStructFieldPtrAnonymousHeadIndent opType = 420 + opStructFieldIndent opType = 421 + opStructFieldOmitEmptyIndent opType = 422 + opStructFieldStringTagIndent opType = 423 + opStructFieldRecursiveIndent opType = 424 + opStructFieldRecursiveEndIndent opType = 425 + opStructEndIndent opType = 426 + opStructAnonymousEndIndent opType = 427 + opIntIndent opType = 428 + opInt8Indent opType = 429 + opInt16Indent opType = 430 + opInt32Indent opType = 431 + opInt64Indent opType = 432 + opUintIndent opType = 433 + opUint8Indent opType = 434 + opUint16Indent opType = 435 + opUint32Indent opType = 436 + opUint64Indent opType = 437 + opFloat32Indent opType = 438 + opFloat64Indent opType = 439 + opBoolIndent opType = 440 + opStringIndent opType = 441 + opBytesIndent opType = 442 + opArrayIndent opType = 443 + opMapIndent opType = 444 + opMapLoadIndent opType = 445 + opSliceIndent opType = 446 + opStructIndent opType = 447 + opMarshalJSONIndent opType = 448 + opMarshalTextIndent opType = 449 + opStructFieldHeadIntIndent opType = 450 + opStructFieldHeadInt8Indent opType = 451 + opStructFieldHeadInt16Indent opType = 452 + opStructFieldHeadInt32Indent opType = 453 + opStructFieldHeadInt64Indent opType = 454 + opStructFieldHeadUintIndent opType = 455 + opStructFieldHeadUint8Indent opType = 456 + opStructFieldHeadUint16Indent opType = 457 + opStructFieldHeadUint32Indent opType = 458 + opStructFieldHeadUint64Indent opType = 459 + opStructFieldHeadFloat32Indent opType = 460 + opStructFieldHeadFloat64Indent opType = 461 + opStructFieldHeadBoolIndent opType = 462 + opStructFieldHeadStringIndent opType = 463 + opStructFieldHeadBytesIndent opType = 464 + opStructFieldHeadArrayIndent opType = 465 + opStructFieldHeadMapIndent opType = 466 + opStructFieldHeadMapLoadIndent opType = 467 + opStructFieldHeadSliceIndent opType = 468 + opStructFieldHeadStructIndent opType = 469 + opStructFieldHeadMarshalJSONIndent opType = 470 + opStructFieldHeadMarshalTextIndent opType = 471 + opStructFieldHeadOmitEmptyIntIndent opType = 472 + opStructFieldHeadOmitEmptyInt8Indent opType = 473 + opStructFieldHeadOmitEmptyInt16Indent opType = 474 + opStructFieldHeadOmitEmptyInt32Indent opType = 475 + opStructFieldHeadOmitEmptyInt64Indent opType = 476 + opStructFieldHeadOmitEmptyUintIndent opType = 477 + opStructFieldHeadOmitEmptyUint8Indent opType = 478 + opStructFieldHeadOmitEmptyUint16Indent opType = 479 + opStructFieldHeadOmitEmptyUint32Indent opType = 480 + opStructFieldHeadOmitEmptyUint64Indent opType = 481 + opStructFieldHeadOmitEmptyFloat32Indent opType = 482 + opStructFieldHeadOmitEmptyFloat64Indent opType = 483 + opStructFieldHeadOmitEmptyBoolIndent opType = 484 + opStructFieldHeadOmitEmptyStringIndent opType = 485 + opStructFieldHeadOmitEmptyBytesIndent opType = 486 + opStructFieldHeadOmitEmptyArrayIndent opType = 487 + opStructFieldHeadOmitEmptyMapIndent opType = 488 + opStructFieldHeadOmitEmptyMapLoadIndent opType = 489 + opStructFieldHeadOmitEmptySliceIndent opType = 490 + opStructFieldHeadOmitEmptyStructIndent opType = 491 + opStructFieldHeadOmitEmptyMarshalJSONIndent opType = 492 + opStructFieldHeadOmitEmptyMarshalTextIndent opType = 493 + opStructFieldHeadStringTagIntIndent opType = 494 + opStructFieldHeadStringTagInt8Indent opType = 495 + opStructFieldHeadStringTagInt16Indent opType = 496 + opStructFieldHeadStringTagInt32Indent opType = 497 + opStructFieldHeadStringTagInt64Indent opType = 498 + opStructFieldHeadStringTagUintIndent opType = 499 + opStructFieldHeadStringTagUint8Indent opType = 500 + opStructFieldHeadStringTagUint16Indent opType = 501 + opStructFieldHeadStringTagUint32Indent opType = 502 + opStructFieldHeadStringTagUint64Indent opType = 503 + opStructFieldHeadStringTagFloat32Indent opType = 504 + opStructFieldHeadStringTagFloat64Indent opType = 505 + opStructFieldHeadStringTagBoolIndent opType = 506 + opStructFieldHeadStringTagStringIndent opType = 507 + opStructFieldHeadStringTagBytesIndent opType = 508 + opStructFieldHeadStringTagArrayIndent opType = 509 + opStructFieldHeadStringTagMapIndent opType = 510 + opStructFieldHeadStringTagMapLoadIndent opType = 511 + opStructFieldHeadStringTagSliceIndent opType = 512 + opStructFieldHeadStringTagStructIndent opType = 513 + opStructFieldHeadStringTagMarshalJSONIndent opType = 514 + opStructFieldHeadStringTagMarshalTextIndent opType = 515 + opStructFieldAnonymousHeadIntIndent opType = 516 + opStructFieldAnonymousHeadInt8Indent opType = 517 + opStructFieldAnonymousHeadInt16Indent opType = 518 + opStructFieldAnonymousHeadInt32Indent opType = 519 + opStructFieldAnonymousHeadInt64Indent opType = 520 + opStructFieldAnonymousHeadUintIndent opType = 521 + opStructFieldAnonymousHeadUint8Indent opType = 522 + opStructFieldAnonymousHeadUint16Indent opType = 523 + opStructFieldAnonymousHeadUint32Indent opType = 524 + opStructFieldAnonymousHeadUint64Indent opType = 525 + opStructFieldAnonymousHeadFloat32Indent opType = 526 + opStructFieldAnonymousHeadFloat64Indent opType = 527 + opStructFieldAnonymousHeadBoolIndent opType = 528 + opStructFieldAnonymousHeadStringIndent opType = 529 + opStructFieldAnonymousHeadBytesIndent opType = 530 + opStructFieldAnonymousHeadArrayIndent opType = 531 + opStructFieldAnonymousHeadMapIndent opType = 532 + opStructFieldAnonymousHeadMapLoadIndent opType = 533 + opStructFieldAnonymousHeadSliceIndent opType = 534 + opStructFieldAnonymousHeadStructIndent opType = 535 + opStructFieldAnonymousHeadMarshalJSONIndent opType = 536 + opStructFieldAnonymousHeadMarshalTextIndent opType = 537 + opStructFieldAnonymousHeadOmitEmptyIntIndent opType = 538 + opStructFieldAnonymousHeadOmitEmptyInt8Indent opType = 539 + opStructFieldAnonymousHeadOmitEmptyInt16Indent opType = 540 + opStructFieldAnonymousHeadOmitEmptyInt32Indent opType = 541 + opStructFieldAnonymousHeadOmitEmptyInt64Indent opType = 542 + opStructFieldAnonymousHeadOmitEmptyUintIndent opType = 543 + opStructFieldAnonymousHeadOmitEmptyUint8Indent opType = 544 + opStructFieldAnonymousHeadOmitEmptyUint16Indent opType = 545 + opStructFieldAnonymousHeadOmitEmptyUint32Indent opType = 546 + opStructFieldAnonymousHeadOmitEmptyUint64Indent opType = 547 + opStructFieldAnonymousHeadOmitEmptyFloat32Indent opType = 548 + opStructFieldAnonymousHeadOmitEmptyFloat64Indent opType = 549 + opStructFieldAnonymousHeadOmitEmptyBoolIndent opType = 550 + opStructFieldAnonymousHeadOmitEmptyStringIndent opType = 551 + opStructFieldAnonymousHeadOmitEmptyBytesIndent opType = 552 + opStructFieldAnonymousHeadOmitEmptyArrayIndent opType = 553 + opStructFieldAnonymousHeadOmitEmptyMapIndent opType = 554 + opStructFieldAnonymousHeadOmitEmptyMapLoadIndent opType = 555 + opStructFieldAnonymousHeadOmitEmptySliceIndent opType = 556 + opStructFieldAnonymousHeadOmitEmptyStructIndent opType = 557 + opStructFieldAnonymousHeadOmitEmptyMarshalJSONIndent opType = 558 + opStructFieldAnonymousHeadOmitEmptyMarshalTextIndent opType = 559 + opStructFieldAnonymousHeadStringTagIntIndent opType = 560 + opStructFieldAnonymousHeadStringTagInt8Indent opType = 561 + opStructFieldAnonymousHeadStringTagInt16Indent opType = 562 + opStructFieldAnonymousHeadStringTagInt32Indent opType = 563 + opStructFieldAnonymousHeadStringTagInt64Indent opType = 564 + opStructFieldAnonymousHeadStringTagUintIndent opType = 565 + opStructFieldAnonymousHeadStringTagUint8Indent opType = 566 + opStructFieldAnonymousHeadStringTagUint16Indent opType = 567 + opStructFieldAnonymousHeadStringTagUint32Indent opType = 568 + opStructFieldAnonymousHeadStringTagUint64Indent opType = 569 + opStructFieldAnonymousHeadStringTagFloat32Indent opType = 570 + opStructFieldAnonymousHeadStringTagFloat64Indent opType = 571 + opStructFieldAnonymousHeadStringTagBoolIndent opType = 572 + opStructFieldAnonymousHeadStringTagStringIndent opType = 573 + opStructFieldAnonymousHeadStringTagBytesIndent opType = 574 + opStructFieldAnonymousHeadStringTagArrayIndent opType = 575 + opStructFieldAnonymousHeadStringTagMapIndent opType = 576 + opStructFieldAnonymousHeadStringTagMapLoadIndent opType = 577 + opStructFieldAnonymousHeadStringTagSliceIndent opType = 578 + opStructFieldAnonymousHeadStringTagStructIndent opType = 579 + opStructFieldAnonymousHeadStringTagMarshalJSONIndent opType = 580 + opStructFieldAnonymousHeadStringTagMarshalTextIndent opType = 581 + opStructFieldPtrHeadIntIndent opType = 582 + opStructFieldPtrHeadInt8Indent opType = 583 + opStructFieldPtrHeadInt16Indent opType = 584 + opStructFieldPtrHeadInt32Indent opType = 585 + opStructFieldPtrHeadInt64Indent opType = 586 + opStructFieldPtrHeadUintIndent opType = 587 + opStructFieldPtrHeadUint8Indent opType = 588 + opStructFieldPtrHeadUint16Indent opType = 589 + opStructFieldPtrHeadUint32Indent opType = 590 + opStructFieldPtrHeadUint64Indent opType = 591 + opStructFieldPtrHeadFloat32Indent opType = 592 + opStructFieldPtrHeadFloat64Indent opType = 593 + opStructFieldPtrHeadBoolIndent opType = 594 + opStructFieldPtrHeadStringIndent opType = 595 + opStructFieldPtrHeadBytesIndent opType = 596 + opStructFieldPtrHeadArrayIndent opType = 597 + opStructFieldPtrHeadMapIndent opType = 598 + opStructFieldPtrHeadMapLoadIndent opType = 599 + opStructFieldPtrHeadSliceIndent opType = 600 + opStructFieldPtrHeadStructIndent opType = 601 + opStructFieldPtrHeadMarshalJSONIndent opType = 602 + opStructFieldPtrHeadMarshalTextIndent opType = 603 + opStructFieldPtrHeadOmitEmptyIntIndent opType = 604 + opStructFieldPtrHeadOmitEmptyInt8Indent opType = 605 + opStructFieldPtrHeadOmitEmptyInt16Indent opType = 606 + opStructFieldPtrHeadOmitEmptyInt32Indent opType = 607 + opStructFieldPtrHeadOmitEmptyInt64Indent opType = 608 + opStructFieldPtrHeadOmitEmptyUintIndent opType = 609 + opStructFieldPtrHeadOmitEmptyUint8Indent opType = 610 + opStructFieldPtrHeadOmitEmptyUint16Indent opType = 611 + opStructFieldPtrHeadOmitEmptyUint32Indent opType = 612 + opStructFieldPtrHeadOmitEmptyUint64Indent opType = 613 + opStructFieldPtrHeadOmitEmptyFloat32Indent opType = 614 + opStructFieldPtrHeadOmitEmptyFloat64Indent opType = 615 + opStructFieldPtrHeadOmitEmptyBoolIndent opType = 616 + opStructFieldPtrHeadOmitEmptyStringIndent opType = 617 + opStructFieldPtrHeadOmitEmptyBytesIndent opType = 618 + opStructFieldPtrHeadOmitEmptyArrayIndent opType = 619 + opStructFieldPtrHeadOmitEmptyMapIndent opType = 620 + opStructFieldPtrHeadOmitEmptyMapLoadIndent opType = 621 + opStructFieldPtrHeadOmitEmptySliceIndent opType = 622 + opStructFieldPtrHeadOmitEmptyStructIndent opType = 623 + opStructFieldPtrHeadOmitEmptyMarshalJSONIndent opType = 624 + opStructFieldPtrHeadOmitEmptyMarshalTextIndent opType = 625 + opStructFieldPtrHeadStringTagIntIndent opType = 626 + opStructFieldPtrHeadStringTagInt8Indent opType = 627 + opStructFieldPtrHeadStringTagInt16Indent opType = 628 + opStructFieldPtrHeadStringTagInt32Indent opType = 629 + opStructFieldPtrHeadStringTagInt64Indent opType = 630 + opStructFieldPtrHeadStringTagUintIndent opType = 631 + opStructFieldPtrHeadStringTagUint8Indent opType = 632 + opStructFieldPtrHeadStringTagUint16Indent opType = 633 + opStructFieldPtrHeadStringTagUint32Indent opType = 634 + opStructFieldPtrHeadStringTagUint64Indent opType = 635 + opStructFieldPtrHeadStringTagFloat32Indent opType = 636 + opStructFieldPtrHeadStringTagFloat64Indent opType = 637 + opStructFieldPtrHeadStringTagBoolIndent opType = 638 + opStructFieldPtrHeadStringTagStringIndent opType = 639 + opStructFieldPtrHeadStringTagBytesIndent opType = 640 + opStructFieldPtrHeadStringTagArrayIndent opType = 641 + opStructFieldPtrHeadStringTagMapIndent opType = 642 + opStructFieldPtrHeadStringTagMapLoadIndent opType = 643 + opStructFieldPtrHeadStringTagSliceIndent opType = 644 + opStructFieldPtrHeadStringTagStructIndent opType = 645 + opStructFieldPtrHeadStringTagMarshalJSONIndent opType = 646 + opStructFieldPtrHeadStringTagMarshalTextIndent opType = 647 + opStructFieldPtrAnonymousHeadIntIndent opType = 648 + opStructFieldPtrAnonymousHeadInt8Indent opType = 649 + opStructFieldPtrAnonymousHeadInt16Indent opType = 650 + opStructFieldPtrAnonymousHeadInt32Indent opType = 651 + opStructFieldPtrAnonymousHeadInt64Indent opType = 652 + opStructFieldPtrAnonymousHeadUintIndent opType = 653 + opStructFieldPtrAnonymousHeadUint8Indent opType = 654 + opStructFieldPtrAnonymousHeadUint16Indent opType = 655 + opStructFieldPtrAnonymousHeadUint32Indent opType = 656 + opStructFieldPtrAnonymousHeadUint64Indent opType = 657 + opStructFieldPtrAnonymousHeadFloat32Indent opType = 658 + opStructFieldPtrAnonymousHeadFloat64Indent opType = 659 + opStructFieldPtrAnonymousHeadBoolIndent opType = 660 + opStructFieldPtrAnonymousHeadStringIndent opType = 661 + opStructFieldPtrAnonymousHeadBytesIndent opType = 662 + opStructFieldPtrAnonymousHeadArrayIndent opType = 663 + opStructFieldPtrAnonymousHeadMapIndent opType = 664 + opStructFieldPtrAnonymousHeadMapLoadIndent opType = 665 + opStructFieldPtrAnonymousHeadSliceIndent opType = 666 + opStructFieldPtrAnonymousHeadStructIndent opType = 667 + opStructFieldPtrAnonymousHeadMarshalJSONIndent opType = 668 + opStructFieldPtrAnonymousHeadMarshalTextIndent opType = 669 + opStructFieldPtrAnonymousHeadOmitEmptyIntIndent opType = 670 + opStructFieldPtrAnonymousHeadOmitEmptyInt8Indent opType = 671 + opStructFieldPtrAnonymousHeadOmitEmptyInt16Indent opType = 672 + opStructFieldPtrAnonymousHeadOmitEmptyInt32Indent opType = 673 + opStructFieldPtrAnonymousHeadOmitEmptyInt64Indent opType = 674 + opStructFieldPtrAnonymousHeadOmitEmptyUintIndent opType = 675 + opStructFieldPtrAnonymousHeadOmitEmptyUint8Indent opType = 676 + opStructFieldPtrAnonymousHeadOmitEmptyUint16Indent opType = 677 + opStructFieldPtrAnonymousHeadOmitEmptyUint32Indent opType = 678 + opStructFieldPtrAnonymousHeadOmitEmptyUint64Indent opType = 679 + opStructFieldPtrAnonymousHeadOmitEmptyFloat32Indent opType = 680 + opStructFieldPtrAnonymousHeadOmitEmptyFloat64Indent opType = 681 + opStructFieldPtrAnonymousHeadOmitEmptyBoolIndent opType = 682 + opStructFieldPtrAnonymousHeadOmitEmptyStringIndent opType = 683 + opStructFieldPtrAnonymousHeadOmitEmptyBytesIndent opType = 684 + opStructFieldPtrAnonymousHeadOmitEmptyArrayIndent opType = 685 + opStructFieldPtrAnonymousHeadOmitEmptyMapIndent opType = 686 + opStructFieldPtrAnonymousHeadOmitEmptyMapLoadIndent opType = 687 + opStructFieldPtrAnonymousHeadOmitEmptySliceIndent opType = 688 + opStructFieldPtrAnonymousHeadOmitEmptyStructIndent opType = 689 + opStructFieldPtrAnonymousHeadOmitEmptyMarshalJSONIndent opType = 690 + opStructFieldPtrAnonymousHeadOmitEmptyMarshalTextIndent opType = 691 + opStructFieldPtrAnonymousHeadStringTagIntIndent opType = 692 + opStructFieldPtrAnonymousHeadStringTagInt8Indent opType = 693 + opStructFieldPtrAnonymousHeadStringTagInt16Indent opType = 694 + opStructFieldPtrAnonymousHeadStringTagInt32Indent opType = 695 + opStructFieldPtrAnonymousHeadStringTagInt64Indent opType = 696 + opStructFieldPtrAnonymousHeadStringTagUintIndent opType = 697 + opStructFieldPtrAnonymousHeadStringTagUint8Indent opType = 698 + opStructFieldPtrAnonymousHeadStringTagUint16Indent opType = 699 + opStructFieldPtrAnonymousHeadStringTagUint32Indent opType = 700 + opStructFieldPtrAnonymousHeadStringTagUint64Indent opType = 701 + opStructFieldPtrAnonymousHeadStringTagFloat32Indent opType = 702 + opStructFieldPtrAnonymousHeadStringTagFloat64Indent opType = 703 + opStructFieldPtrAnonymousHeadStringTagBoolIndent opType = 704 + opStructFieldPtrAnonymousHeadStringTagStringIndent opType = 705 + opStructFieldPtrAnonymousHeadStringTagBytesIndent opType = 706 + opStructFieldPtrAnonymousHeadStringTagArrayIndent opType = 707 + opStructFieldPtrAnonymousHeadStringTagMapIndent opType = 708 + opStructFieldPtrAnonymousHeadStringTagMapLoadIndent opType = 709 + opStructFieldPtrAnonymousHeadStringTagSliceIndent opType = 710 + opStructFieldPtrAnonymousHeadStringTagStructIndent opType = 711 + opStructFieldPtrAnonymousHeadStringTagMarshalJSONIndent opType = 712 + opStructFieldPtrAnonymousHeadStringTagMarshalTextIndent opType = 713 + opStructFieldIntIndent opType = 714 + opStructFieldInt8Indent opType = 715 + opStructFieldInt16Indent opType = 716 + opStructFieldInt32Indent opType = 717 + opStructFieldInt64Indent opType = 718 + opStructFieldUintIndent opType = 719 + opStructFieldUint8Indent opType = 720 + opStructFieldUint16Indent opType = 721 + opStructFieldUint32Indent opType = 722 + opStructFieldUint64Indent opType = 723 + opStructFieldFloat32Indent opType = 724 + opStructFieldFloat64Indent opType = 725 + opStructFieldBoolIndent opType = 726 + opStructFieldStringIndent opType = 727 + opStructFieldBytesIndent opType = 728 + opStructFieldArrayIndent opType = 729 + opStructFieldMapIndent opType = 730 + opStructFieldMapLoadIndent opType = 731 + opStructFieldSliceIndent opType = 732 + opStructFieldStructIndent opType = 733 + opStructFieldMarshalJSONIndent opType = 734 + opStructFieldMarshalTextIndent opType = 735 + opStructFieldOmitEmptyIntIndent opType = 736 + opStructFieldOmitEmptyInt8Indent opType = 737 + opStructFieldOmitEmptyInt16Indent opType = 738 + opStructFieldOmitEmptyInt32Indent opType = 739 + opStructFieldOmitEmptyInt64Indent opType = 740 + opStructFieldOmitEmptyUintIndent opType = 741 + opStructFieldOmitEmptyUint8Indent opType = 742 + opStructFieldOmitEmptyUint16Indent opType = 743 + opStructFieldOmitEmptyUint32Indent opType = 744 + opStructFieldOmitEmptyUint64Indent opType = 745 + opStructFieldOmitEmptyFloat32Indent opType = 746 + opStructFieldOmitEmptyFloat64Indent opType = 747 + opStructFieldOmitEmptyBoolIndent opType = 748 + opStructFieldOmitEmptyStringIndent opType = 749 + opStructFieldOmitEmptyBytesIndent opType = 750 + opStructFieldOmitEmptyArrayIndent opType = 751 + opStructFieldOmitEmptyMapIndent opType = 752 + opStructFieldOmitEmptyMapLoadIndent opType = 753 + opStructFieldOmitEmptySliceIndent opType = 754 + opStructFieldOmitEmptyStructIndent opType = 755 + opStructFieldOmitEmptyMarshalJSONIndent opType = 756 + opStructFieldOmitEmptyMarshalTextIndent opType = 757 + opStructFieldStringTagIntIndent opType = 758 + opStructFieldStringTagInt8Indent opType = 759 + opStructFieldStringTagInt16Indent opType = 760 + opStructFieldStringTagInt32Indent opType = 761 + opStructFieldStringTagInt64Indent opType = 762 + opStructFieldStringTagUintIndent opType = 763 + opStructFieldStringTagUint8Indent opType = 764 + opStructFieldStringTagUint16Indent opType = 765 + opStructFieldStringTagUint32Indent opType = 766 + opStructFieldStringTagUint64Indent opType = 767 + opStructFieldStringTagFloat32Indent opType = 768 + opStructFieldStringTagFloat64Indent opType = 769 + opStructFieldStringTagBoolIndent opType = 770 + opStructFieldStringTagStringIndent opType = 771 + opStructFieldStringTagBytesIndent opType = 772 + opStructFieldStringTagArrayIndent opType = 773 + opStructFieldStringTagMapIndent opType = 774 + opStructFieldStringTagMapLoadIndent opType = 775 + opStructFieldStringTagSliceIndent opType = 776 + opStructFieldStringTagStructIndent opType = 777 + opStructFieldStringTagMarshalJSONIndent opType = 778 + opStructFieldStringTagMarshalTextIndent opType = 779 ) func (t opType) String() string { @@ -803,6 +807,8 @@ func (t opType) String() string { return "End" case opInterface: return "Interface" + case opInterfaceEnd: + return "InterfaceEnd" case opPtr: return "Ptr" case opSliceHead: @@ -867,6 +873,8 @@ func (t opType) String() string { return "StructFieldStringTag" case opStructFieldRecursive: return "StructFieldRecursive" + case opStructFieldRecursiveEnd: + return "StructFieldRecursiveEnd" case opStructEnd: return "StructEnd" case opStructAnonymousEnd: @@ -1579,6 +1587,8 @@ func (t opType) String() string { return "EndIndent" case opInterfaceIndent: return "InterfaceIndent" + case opInterfaceEndIndent: + return "InterfaceEndIndent" case opPtrIndent: return "PtrIndent" case opSliceHeadIndent: @@ -1643,6 +1653,8 @@ func (t opType) String() string { return "StructFieldStringTagIndent" case opStructFieldRecursiveIndent: return "StructFieldRecursiveIndent" + case opStructFieldRecursiveEndIndent: + return "StructFieldRecursiveEndIndent" case opStructEndIndent: return "StructEndIndent" case opStructAnonymousEndIndent: @@ -2361,6 +2373,8 @@ func (t opType) codeType() codeType { return codeOp case opInterface: return codeOp + case opInterfaceEnd: + return codeOp case opPtr: return codeOp case opSliceHead: @@ -2425,6 +2439,8 @@ func (t opType) codeType() codeType { return codeStructField case opStructFieldRecursive: return codeStructFieldRecursive + case opStructFieldRecursiveEnd: + return codeOp case opStructEnd: return codeStructField case opStructAnonymousEnd: @@ -3137,6 +3153,8 @@ func (t opType) codeType() codeType { return codeOp case opInterfaceIndent: return codeOp + case opInterfaceEndIndent: + return codeOp case opPtrIndent: return codeOp case opSliceHeadIndent: @@ -3201,6 +3219,8 @@ func (t opType) codeType() codeType { return codeStructField case opStructFieldRecursiveIndent: return codeStructFieldRecursive + case opStructFieldRecursiveEndIndent: + return codeOp case opStructEndIndent: return codeStructField case opStructAnonymousEndIndent: @@ -3919,6 +3939,8 @@ func (t opType) toIndent() opType { return opEndIndent case opInterface: return opInterfaceIndent + case opInterfaceEnd: + return opInterfaceEndIndent case opPtr: return opPtrIndent case opSliceHead: @@ -3983,6 +4005,8 @@ func (t opType) toIndent() opType { return opStructFieldStringTagIndent case opStructFieldRecursive: return opStructFieldRecursiveIndent + case opStructFieldRecursiveEnd: + return opStructFieldRecursiveEndIndent case opStructEnd: return opStructEndIndent case opStructAnonymousEnd: @@ -4695,6 +4719,8 @@ func (t opType) toIndent() opType { return opEndIndent case opInterfaceIndent: return opInterfaceIndent + case opInterfaceEndIndent: + return opInterfaceEndIndent case opPtrIndent: return opPtrIndent case opSliceHeadIndent: @@ -4759,6 +4785,8 @@ func (t opType) toIndent() opType { return opStructFieldStringTagIndent case opStructFieldRecursiveIndent: return opStructFieldRecursiveIndent + case opStructFieldRecursiveEndIndent: + return opStructFieldRecursiveEndIndent case opStructEndIndent: return opStructEndIndent case opStructAnonymousEndIndent: diff --git a/encode_vm.go b/encode_vm.go index 7126476..29ddb30 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -11,49 +11,63 @@ import ( "unsafe" ) -func (e *Encoder) run(code *opcode) error { +const startDetectingCyclesAfter = 1000 + +func load(base uintptr, idx uintptr) uintptr { + return *(*uintptr)(unsafe.Pointer(base + idx)) +} + +func store(base uintptr, idx uintptr, p uintptr) { + *(*uintptr)(unsafe.Pointer(base + idx)) = p +} + +func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { + recursiveLevel := 0 seenPtr := map[uintptr]struct{}{} + ptrOffset := uintptr(0) + ctxptr := ctx.ptr() + for { switch code.op { case opPtr: - ptr := code.ptr + ptr := load(ctxptr, code.idx) code = code.next - code.ptr = e.ptrToPtr(ptr) + store(ctxptr, code.idx, e.ptrToPtr(ptr)) case opInt: - e.encodeInt(e.ptrToInt(code.ptr)) + e.encodeInt(e.ptrToInt(load(ctxptr, code.idx))) code = code.next case opInt8: - e.encodeInt8(e.ptrToInt8(code.ptr)) + e.encodeInt8(e.ptrToInt8(load(ctxptr, code.idx))) code = code.next case opInt16: - e.encodeInt16(e.ptrToInt16(code.ptr)) + e.encodeInt16(e.ptrToInt16(load(ctxptr, code.idx))) code = code.next case opInt32: - e.encodeInt32(e.ptrToInt32(code.ptr)) + e.encodeInt32(e.ptrToInt32(load(ctxptr, code.idx))) code = code.next case opInt64: - e.encodeInt64(e.ptrToInt64(code.ptr)) + e.encodeInt64(e.ptrToInt64(load(ctxptr, code.idx))) code = code.next case opUint: - e.encodeUint(e.ptrToUint(code.ptr)) + e.encodeUint(e.ptrToUint(load(ctxptr, code.idx))) code = code.next case opUint8: - e.encodeUint8(e.ptrToUint8(code.ptr)) + e.encodeUint8(e.ptrToUint8(load(ctxptr, code.idx))) code = code.next case opUint16: - e.encodeUint16(e.ptrToUint16(code.ptr)) + e.encodeUint16(e.ptrToUint16(load(ctxptr, code.idx))) code = code.next case opUint32: - e.encodeUint32(e.ptrToUint32(code.ptr)) + e.encodeUint32(e.ptrToUint32(load(ctxptr, code.idx))) code = code.next case opUint64: - e.encodeUint64(e.ptrToUint64(code.ptr)) + e.encodeUint64(e.ptrToUint64(load(ctxptr, code.idx))) code = code.next case opFloat32: - e.encodeFloat32(e.ptrToFloat32(code.ptr)) + e.encodeFloat32(e.ptrToFloat32(load(ctxptr, code.idx))) code = code.next case opFloat64: - v := e.ptrToFloat64(code.ptr) + v := e.ptrToFloat64(load(ctxptr, code.idx)) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), @@ -63,18 +77,18 @@ func (e *Encoder) run(code *opcode) error { e.encodeFloat64(v) code = code.next case opString: - e.encodeString(e.ptrToString(code.ptr)) + e.encodeString(e.ptrToString(load(ctxptr, code.idx))) code = code.next case opBool: - e.encodeBool(e.ptrToBool(code.ptr)) + e.encodeBool(e.ptrToBool(load(ctxptr, code.idx))) code = code.next case opBytes: - ptr := code.ptr + ptr := load(ctxptr, code.idx) header := (*reflect.SliceHeader)(unsafe.Pointer(ptr)) if ptr == 0 || header.Data == 0 { e.encodeNull() } else { - b := e.ptrToBytes(code.ptr) + b := e.ptrToBytes(ptr) encodedLen := base64.StdEncoding.EncodedLen(len(b)) e.encodeByte('"') buf := make([]byte, encodedLen) @@ -84,10 +98,9 @@ func (e *Encoder) run(code *opcode) error { } code = code.next case opInterface: - ifaceCode := code.toInterfaceCode() - ptr := ifaceCode.ptr + ptr := load(ctxptr, code.idx) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ - typ: ifaceCode.typ, + typ: code.typ, ptr: unsafe.Pointer(ptr), })) if _, exists := seenPtr[ptr]; exists { @@ -100,7 +113,7 @@ func (e *Encoder) run(code *opcode) error { rv := reflect.ValueOf(v) if rv.IsNil() { e.encodeNull() - code = ifaceCode.next + code = code.next break } vv := rv.Interface() @@ -109,26 +122,65 @@ func (e *Encoder) run(code *opcode) error { if typ.Kind() == reflect.Ptr { typ = typ.Elem() } - e.indent = ifaceCode.indent var c *opcode if typ.Kind() == reflect.Map { - code, err := e.compileMap(typ, false, ifaceCode.root, e.enabledIndent) + code, err := e.compileMap(&encodeCompileContext{ + typ: typ, + root: code.root, + withIndent: e.enabledIndent, + indent: code.indent, + }, false) if err != nil { return err } c = code } else { - code, err := e.compile(typ, ifaceCode.root, e.enabledIndent) + code, err := e.compile(&encodeCompileContext{ + typ: typ, + root: code.root, + withIndent: e.enabledIndent, + indent: code.indent, + }) if err != nil { return err } c = code } - c.ptr = uintptr(header.ptr) - c.beforeLastCode().next = code.next + + beforeLastCode := c.beforeLastCode() + lastCode := beforeLastCode.next + lastCode.idx = beforeLastCode.idx + uintptrSize + totalLength := uintptr(code.totalLength()) + nextTotalLength := uintptr(c.totalLength()) + curlen := uintptr(len(ctx.ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.ptrs = append(ctx.ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, 0, uintptr(header.ptr)) + store(ctxptr, lastCode.idx, oldOffset) + + // link lastCode ( opInterfaceEnd ) => code.next + lastCode.op = opInterfaceEnd + lastCode.next = code.next + code = c + recursiveLevel++ + case opInterfaceEnd: + recursiveLevel-- + // restore ctxptr + offset := load(ctxptr, code.idx) + ctxptr = ctx.ptr() + offset + ptrOffset = offset + code = code.next case opMarshalJSON: - ptr := code.ptr + ptr := load(ctxptr, code.idx) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(ptr), @@ -164,7 +216,7 @@ func (e *Encoder) run(code *opcode) error { e.encodeBytes(buf.Bytes()) code = code.next case opMarshalText: - ptr := code.ptr + ptr := load(ctxptr, code.idx) isPtr := code.typ.Kind() == reflect.Ptr p := unsafe.Pointer(ptr) if p == nil { @@ -190,193 +242,211 @@ func (e *Encoder) run(code *opcode) error { } code = code.next case opSliceHead: - p := code.ptr - headerCode := code.toSliceHeaderCode() + p := load(ctxptr, code.idx) header := (*reflect.SliceHeader)(unsafe.Pointer(p)) if p == 0 || header.Data == 0 { e.encodeNull() - code = headerCode.end.next + code = code.end.next } else { e.encodeByte('[') - headerCode.elem.set(header) + store(ctxptr, code.elemIdx, 0) + store(ctxptr, code.length, uintptr(header.Len)) + store(ctxptr, code.idx, header.Data) if header.Len > 0 { code = code.next - code.ptr = header.Data + store(ctxptr, code.idx, header.Data) } else { e.encodeByte(']') - code = headerCode.end.next + code = code.end.next } } case opSliceElem: - c := code.toSliceElemCode() - c.idx++ - if c.idx < c.len { + idx := load(ctxptr, code.elemIdx) + length := load(ctxptr, code.length) + idx++ + if idx < length { e.encodeByte(',') + store(ctxptr, code.elemIdx, idx) + data := load(ctxptr, code.headIdx) + size := code.size code = code.next - code.ptr = c.data + c.idx*c.size + store(ctxptr, code.idx, data+idx*size) } else { e.encodeByte(']') - code = c.end.next + code = code.end.next } case opSliceHeadIndent: - p := code.ptr - headerCode := code.toSliceHeaderCode() + p := load(ctxptr, code.idx) if p == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = headerCode.end.next + code = code.end.next } else { header := (*reflect.SliceHeader)(unsafe.Pointer(p)) - headerCode.elem.set(header) + store(ctxptr, code.elemIdx, 0) + store(ctxptr, code.length, uintptr(header.Len)) + store(ctxptr, code.idx, header.Data) if header.Len > 0 { e.encodeBytes([]byte{'[', '\n'}) e.encodeIndent(code.indent + 1) code = code.next - code.ptr = header.Data + store(ctxptr, code.idx, header.Data) } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'[', ']'}) - code = headerCode.end.next + code = code.end.next } } case opRootSliceHeadIndent: - p := code.ptr - headerCode := code.toSliceHeaderCode() + p := load(ctxptr, code.idx) if p == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = headerCode.end.next + code = code.end.next } else { header := (*reflect.SliceHeader)(unsafe.Pointer(p)) - headerCode.elem.set(header) + store(ctxptr, code.elemIdx, 0) + store(ctxptr, code.length, uintptr(header.Len)) + store(ctxptr, code.idx, header.Data) if header.Len > 0 { e.encodeBytes([]byte{'[', '\n'}) e.encodeIndent(code.indent + 1) code = code.next - code.ptr = header.Data + store(ctxptr, code.idx, header.Data) } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'[', ']'}) - code = headerCode.end.next + code = code.end.next } } case opSliceElemIndent: - c := code.toSliceElemCode() - c.idx++ - if c.idx < c.len { + idx := load(ctxptr, code.elemIdx) + length := load(ctxptr, code.length) + idx++ + if idx < length { e.encodeBytes([]byte{',', '\n'}) e.encodeIndent(code.indent + 1) + store(ctxptr, code.elemIdx, idx) + data := load(ctxptr, code.headIdx) + size := code.size code = code.next - code.ptr = c.data + c.idx*c.size + store(ctxptr, code.idx, data+idx*size) } else { e.encodeByte('\n') e.encodeIndent(code.indent) e.encodeByte(']') - code = c.end.next + code = code.end.next } case opRootSliceElemIndent: - c := code.toSliceElemCode() - c.idx++ - if c.idx < c.len { + idx := load(ctxptr, code.elemIdx) + length := load(ctxptr, code.length) + idx++ + if idx < length { e.encodeBytes([]byte{',', '\n'}) e.encodeIndent(code.indent + 1) + store(ctxptr, code.elemIdx, idx) code = code.next - code.ptr = c.data + c.idx*c.size + data := load(ctxptr, code.headIdx) + store(ctxptr, code.idx, data+idx*code.size) } else { e.encodeByte('\n') e.encodeIndent(code.indent) e.encodeByte(']') - code = c.end.next + code = code.end.next } case opArrayHead: - p := code.ptr - headerCode := code.toArrayHeaderCode() + p := load(ctxptr, code.idx) if p == 0 { e.encodeNull() - code = headerCode.end.next + code = code.end.next } else { e.encodeByte('[') - if headerCode.len > 0 { + if code.length > 0 { + store(ctxptr, code.elemIdx, 0) code = code.next - code.ptr = p - headerCode.elem.ptr = p + store(ctxptr, code.idx, p) } else { e.encodeByte(']') - code = headerCode.end.next + code = code.end.next } } case opArrayElem: - c := code.toArrayElemCode() - c.idx++ - if c.idx < c.len { + idx := load(ctxptr, code.elemIdx) + idx++ + if idx < code.length { e.encodeByte(',') + store(ctxptr, code.elemIdx, idx) + p := load(ctxptr, code.headIdx) + size := code.size code = code.next - code.ptr = c.ptr + c.idx*c.size + store(ctxptr, code.idx, p+idx*size) } else { e.encodeByte(']') - code = c.end.next + code = code.end.next } case opArrayHeadIndent: - p := code.ptr - headerCode := code.toArrayHeaderCode() + p := load(ctxptr, code.idx) if p == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = headerCode.end.next + code = code.end.next } else { e.encodeBytes([]byte{'[', '\n'}) - if headerCode.len > 0 { + if code.length > 0 { e.encodeIndent(code.indent + 1) + store(ctxptr, code.elemIdx, 0) code = code.next - code.ptr = p - headerCode.elem.ptr = p + store(ctxptr, code.idx, p) } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{']', '\n'}) - code = headerCode.end.next + code = code.end.next } } case opArrayElemIndent: - c := code.toArrayElemCode() - c.idx++ - if c.idx < c.len { + idx := load(ctxptr, code.elemIdx) + idx++ + if idx < code.length { e.encodeBytes([]byte{',', '\n'}) e.encodeIndent(code.indent + 1) + store(ctxptr, code.elemIdx, idx) + p := load(ctxptr, code.headIdx) + size := code.size code = code.next - code.ptr = c.ptr + c.idx*c.size + store(ctxptr, code.idx, p+idx*size) } else { e.encodeByte('\n') e.encodeIndent(code.indent) e.encodeBytes([]byte{']', '\n'}) - code = c.end.next + code = code.end.next } case opMapHead: - ptr := code.ptr - mapHeadCode := code.toMapHeadCode() + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = mapHeadCode.end.next + code = code.end.next } else { e.encodeByte('{') mlen := maplen(unsafe.Pointer(ptr)) if mlen > 0 { iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) - mapHeadCode.key.set(mlen, iter) - mapHeadCode.value.set(iter) + ctx.keepRefs = append(ctx.keepRefs, iter) + store(ctxptr, code.elemIdx, 0) + store(ctxptr, code.length, uintptr(mlen)) + store(ctxptr, code.mapIter, uintptr(iter)) key := mapiterkey(iter) - code.next.ptr = uintptr(key) + store(ctxptr, code.next.idx, uintptr(key)) code = code.next } else { e.encodeByte('}') - code = mapHeadCode.end.next + code = code.end.next } } case opMapHeadLoad: - ptr := code.ptr - mapHeadCode := code.toMapHeadCode() + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = mapHeadCode.end.next + code = code.end.next } else { // load pointer ptr = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(ptr))) @@ -384,66 +454,71 @@ func (e *Encoder) run(code *opcode) error { mlen := maplen(unsafe.Pointer(ptr)) if mlen > 0 { iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) - mapHeadCode.key.set(mlen, iter) - mapHeadCode.value.set(iter) + ctx.keepRefs = append(ctx.keepRefs, iter) + store(ctxptr, code.elemIdx, 0) + store(ctxptr, code.length, uintptr(mlen)) + store(ctxptr, code.mapIter, uintptr(iter)) key := mapiterkey(iter) - code.next.ptr = uintptr(key) + store(ctxptr, code.next.idx, uintptr(key)) code = code.next } else { e.encodeByte('}') - code = mapHeadCode.end.next + code = code.end.next } } case opMapKey: - c := code.toMapKeyCode() - c.idx++ - if c.idx < c.len { + idx := load(ctxptr, code.elemIdx) + length := load(ctxptr, code.length) + idx++ + if idx < length { e.encodeByte(',') - key := mapiterkey(c.iter) - c.next.ptr = uintptr(key) - code = c.next + iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + store(ctxptr, code.elemIdx, idx) + key := mapiterkey(iter) + store(ctxptr, code.next.idx, uintptr(key)) + code = code.next } else { e.encodeByte('}') - code = c.end.next + code = code.end.next } case opMapValue: e.encodeByte(':') - c := code.toMapValueCode() - value := mapitervalue(c.iter) - c.next.ptr = uintptr(value) - mapiternext(c.iter) - code = c.next + iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + value := mapitervalue(iter) + store(ctxptr, code.next.idx, uintptr(value)) + mapiternext(iter) + code = code.next case opMapHeadIndent: - ptr := code.ptr - mapHeadCode := code.toMapHeadCode() + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = mapHeadCode.end.next + code = code.end.next } else { mlen := maplen(unsafe.Pointer(ptr)) if mlen > 0 { e.encodeBytes([]byte{'{', '\n'}) iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) - mapHeadCode.key.set(mlen, iter) - mapHeadCode.value.set(iter) + ctx.keepRefs = append(ctx.keepRefs, iter) + store(ctxptr, code.elemIdx, 0) + store(ctxptr, code.length, uintptr(mlen)) + store(ctxptr, code.mapIter, uintptr(iter)) key := mapiterkey(iter) - code.next.ptr = uintptr(key) + store(ctxptr, code.next.idx, uintptr(key)) code = code.next e.encodeIndent(code.indent) } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '}'}) - code = mapHeadCode.end.next + code = code.end.next } } case opMapHeadLoadIndent: - ptr := code.ptr - mapHeadCode := code.toMapHeadCode() + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = mapHeadCode.end.next + code = code.end.next } else { // load pointer ptr = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(ptr))) @@ -451,519 +526,528 @@ func (e *Encoder) run(code *opcode) error { if mlen > 0 { e.encodeBytes([]byte{'{', '\n'}) iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) - mapHeadCode.key.set(mlen, iter) - mapHeadCode.value.set(iter) + ctx.keepRefs = append(ctx.keepRefs, iter) + store(ctxptr, code.elemIdx, 0) + store(ctxptr, code.length, uintptr(mlen)) + store(ctxptr, code.mapIter, uintptr(iter)) key := mapiterkey(iter) - code.next.ptr = uintptr(key) + store(ctxptr, code.next.idx, uintptr(key)) code = code.next e.encodeIndent(code.indent) } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '}'}) - code = mapHeadCode.end.next + code = code.end.next } } case opRootMapHeadIndent: - ptr := code.ptr - mapHeadCode := code.toMapHeadCode() + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = mapHeadCode.end.next + code = code.end.next } else { mlen := maplen(unsafe.Pointer(ptr)) if mlen > 0 { e.encodeBytes([]byte{'{', '\n'}) iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) - mapHeadCode.key.set(mlen, iter) - mapHeadCode.value.set(iter) + ctx.keepRefs = append(ctx.keepRefs, iter) + store(ctxptr, code.elemIdx, 0) + store(ctxptr, code.length, uintptr(mlen)) + store(ctxptr, code.mapIter, uintptr(iter)) key := mapiterkey(iter) - code.next.ptr = uintptr(key) + store(ctxptr, code.next.idx, uintptr(key)) code = code.next e.encodeIndent(code.indent) } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '}'}) - code = mapHeadCode.end.next + code = code.end.next } } case opMapKeyIndent: - c := code.toMapKeyCode() - c.idx++ - if c.idx < c.len { + idx := load(ctxptr, code.elemIdx) + length := load(ctxptr, code.length) + idx++ + if idx < length { e.encodeBytes([]byte{',', '\n'}) e.encodeIndent(code.indent) - key := mapiterkey(c.iter) - c.next.ptr = uintptr(key) - code = c.next + store(ctxptr, code.elemIdx, idx) + iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + key := mapiterkey(iter) + store(ctxptr, code.next.idx, uintptr(key)) + code = code.next } else { e.encodeByte('\n') e.encodeIndent(code.indent - 1) e.encodeByte('}') - code = c.end.next + code = code.end.next } case opRootMapKeyIndent: - c := code.toMapKeyCode() - c.idx++ - if c.idx < c.len { + idx := load(ctxptr, code.elemIdx) + length := load(ctxptr, code.length) + idx++ + if idx < length { e.encodeBytes([]byte{',', '\n'}) e.encodeIndent(code.indent) - key := mapiterkey(c.iter) - c.next.ptr = uintptr(key) - code = c.next + store(ctxptr, code.elemIdx, idx) + iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + key := mapiterkey(iter) + store(ctxptr, code.next.idx, uintptr(key)) + code = code.next } else { e.encodeByte('\n') e.encodeIndent(code.indent - 1) e.encodeByte('}') - code = c.end.next + code = code.end.next } case opMapValueIndent: e.encodeBytes([]byte{':', ' '}) - c := code.toMapValueCode() - value := mapitervalue(c.iter) - c.next.ptr = uintptr(value) - mapiternext(c.iter) - code = c.next + iter := unsafe.Pointer(load(ctxptr, code.mapIter)) + value := mapitervalue(iter) + store(ctxptr, code.next.idx, uintptr(value)) + mapiternext(iter) + code = code.next case opStructFieldRecursive: - recursive := code.toRecursiveCode() - if recursive.seenPtr != 0 && recursive.seenPtr == recursive.ptr { - v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ - typ: code.typ, - ptr: unsafe.Pointer(recursive.ptr), - })) - return &UnsupportedValueError{ - Value: reflect.ValueOf(v), - Str: fmt.Sprintf("encountered a cycle via %s", code.typ), + ptr := load(ctxptr, code.idx) + if ptr != 0 { + if recursiveLevel > startDetectingCyclesAfter { + if _, exists := seenPtr[ptr]; exists { + v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ + typ: code.typ, + ptr: unsafe.Pointer(ptr), + })) + return &UnsupportedValueError{ + Value: reflect.ValueOf(v), + Str: fmt.Sprintf("encountered a cycle via %s", code.typ), + } + } } } - recursive.seenPtr = recursive.ptr - if err := e.run(newRecursiveCode(recursive)); err != nil { - return err + seenPtr[ptr] = struct{}{} + c := code.jmp.code + c.end.next = newEndOp(&encodeCompileContext{}) + c.op = c.op.ptrHeadToHead() + + beforeLastCode := c.end + lastCode := beforeLastCode.next + + lastCode.idx = beforeLastCode.idx + uintptrSize + lastCode.elemIdx = lastCode.idx + uintptrSize + + // extend length to alloc slot for elemIdx + totalLength := uintptr(code.totalLength() + 1) + nextTotalLength := uintptr(c.totalLength() + 1) + + curlen := uintptr(len(ctx.ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.ptrs = append(ctx.ptrs, make([]uintptr, newLen-curlen)...) } - code = recursive.next + ctxptr = ctx.ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, 0, ptr) + store(ctxptr, lastCode.idx, oldOffset) + store(ctxptr, lastCode.elemIdx, uintptr(unsafe.Pointer(code.next))) + + // link lastCode ( opStructFieldRecursiveEnd ) => code.next + lastCode.op = opStructFieldRecursiveEnd + code = c + recursiveLevel++ + case opStructFieldRecursiveEnd: + recursiveLevel-- + + // Since the pointer addresses of root code and code.jmp.code may be common, + // `opStructFieldRecursive` processing may replace `opEnd` of root code with `opRecursiveEnd`. + // At that time, `recursiveLevel` becomes -1, so return here as normal processing. + if recursiveLevel < 0 { + return nil + } + // restore ctxptr + offset := load(ctxptr, code.idx) + code = (*opcode)(unsafe.Pointer(load(ctxptr, code.elemIdx))) + ctxptr = ctx.ptr() + offset + ptrOffset = offset case opStructFieldPtrHead: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHead: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHead { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - if !field.anonymousKey { - e.encodeBytes(field.key) + if !code.anonymousKey { + e.encodeBytes(code.key) } - code = field.next - code.ptr = ptr + field.offset - field.nextField.ptr = ptr + p := ptr + code.offset + code = code.next + store(ctxptr, code.idx, p) } case opStructFieldAnonymousHead: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - code = field.next - code.ptr = ptr - field.nextField.ptr = ptr + code = code.next + store(ctxptr, code.idx, ptr) } case opStructFieldPtrHeadInt: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt(e.ptrToInt(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt(e.ptrToInt(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeInt(e.ptrToInt(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt(e.ptrToInt(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt8: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt8 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt8(e.ptrToInt8(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt8(e.ptrToInt8(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt8: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeInt8(e.ptrToInt8(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt8(e.ptrToInt8(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt16: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt16 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt16(e.ptrToInt16(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt16(e.ptrToInt16(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt16: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeInt16(e.ptrToInt16(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt16(e.ptrToInt16(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt32: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt32 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt32(e.ptrToInt32(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt32(e.ptrToInt32(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt32: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeInt32(e.ptrToInt32(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt32(e.ptrToInt32(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt64: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt64 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt64(e.ptrToInt64(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt64(e.ptrToInt64(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt64: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeInt64(e.ptrToInt64(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeInt64(e.ptrToInt64(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint(e.ptrToUint(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint(e.ptrToUint(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeUint(e.ptrToUint(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint(e.ptrToUint(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint8: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint8 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint8(e.ptrToUint8(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint8(e.ptrToUint8(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint8: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeUint8(e.ptrToUint8(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint8(e.ptrToUint8(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint16: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint16 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint16(e.ptrToUint16(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint16(e.ptrToUint16(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint16: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeUint16(e.ptrToUint16(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint16(e.ptrToUint16(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint32: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint32 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint32(e.ptrToUint32(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint32(e.ptrToUint32(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint32: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeUint32(e.ptrToUint32(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint32(e.ptrToUint32(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint64: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint64 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint64(e.ptrToUint64(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint64(e.ptrToUint64(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint64: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeUint64(e.ptrToUint64(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeUint64(e.ptrToUint64(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadFloat32: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadFloat32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadFloat32 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeFloat32(e.ptrToFloat32(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadFloat32: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadFloat32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeFloat32(e.ptrToFloat32(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadFloat64: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadFloat64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadFloat64 { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { - v := e.ptrToFloat64(ptr + field.offset) + v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), @@ -971,232 +1055,210 @@ func (e *Encoder) run(code *opcode) error { } } e.encodeByte('{') - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeFloat64(v) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrAnonymousHeadFloat64: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadFloat64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - v := e.ptrToFloat64(ptr + field.offset) + v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeFloat64(v) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadString: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadString: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadString { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(e.ptrToString(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeString(e.ptrToString(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadString: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadString: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeString(e.ptrToString(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeString(e.ptrToString(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadBool: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadBool: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadBool { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeBool(e.ptrToBool(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeBool(e.ptrToBool(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadBool: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadBool: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - e.encodeBool(e.ptrToBool(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeBytes(code.key) + e.encodeBool(e.ptrToBool(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadBytes: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadBytes: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadBytes { e.encodeNull() } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - s := base64.StdEncoding.EncodeToString(e.ptrToBytes(ptr + field.offset)) + e.encodeBytes(code.key) + s := base64.StdEncoding.EncodeToString(e.ptrToBytes(ptr + code.offset)) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrAnonymousHeadBytes: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadBytes: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) - s := base64.StdEncoding.EncodeToString(e.ptrToBytes(code.ptr + field.offset)) + e.encodeBytes(code.key) + s := base64.StdEncoding.EncodeToString(e.ptrToBytes(ptr + code.offset)) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadArray: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadArray: - c := code.toStructFieldCode() - ptr := c.ptr + c.offset + ptr := load(ctxptr, code.idx) + code.offset if ptr == 0 { if code.op == opStructFieldPtrHeadArray { e.encodeNull() } else { e.encodeBytes([]byte{'[', ']'}) } - code = c.end + code = code.end } else { e.encodeByte('{') - if !c.anonymousKey { - e.encodeBytes(c.key) + if !code.anonymousKey { + e.encodeBytes(code.key) } - code = c.next - code.ptr = ptr - c.nextField.ptr = ptr + code = code.next + store(ctxptr, code.idx, ptr) } case opStructFieldPtrAnonymousHeadArray: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadArray: - c := code.toStructFieldCode() - ptr := c.ptr + c.offset + ptr := load(ctxptr, code.idx) + code.offset if ptr == 0 { - code = c.end + code = code.end } else { - e.encodeBytes(c.key) - code.ptr = ptr - c.nextField.ptr = ptr - code = c.next + e.encodeBytes(code.key) + store(ctxptr, code.idx, ptr) + code = code.next } case opStructFieldPtrHeadSlice: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadSlice: - c := code.toStructFieldCode() - ptr := c.ptr + c.offset - if ptr == 0 { + ptr := load(ctxptr, code.idx) + p := ptr + code.offset + if p == 0 { if code.op == opStructFieldPtrHeadSlice { e.encodeNull() } else { e.encodeBytes([]byte{'[', ']'}) } - code = c.end + code = code.end } else { e.encodeByte('{') - if !c.anonymousKey { - e.encodeBytes(c.key) + if !code.anonymousKey { + e.encodeBytes(code.key) } - code = c.next - code.ptr = ptr - c.nextField.ptr = ptr + code = code.next + store(ctxptr, code.idx, p) } case opStructFieldPtrAnonymousHeadSlice: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadSlice: - c := code.toStructFieldCode() - ptr := c.ptr + c.offset - if ptr == 0 { - code = c.end + ptr := load(ctxptr, code.idx) + p := ptr + code.offset + if p == 0 { + code = code.end } else { - e.encodeBytes(c.key) - code.ptr = ptr - c.nextField.ptr = ptr - code = c.next + e.encodeBytes(code.key) + store(ctxptr, code.idx, p) + code = code.next } case opStructFieldPtrHeadMarshalJSON: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadMarshalJSON: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) + e.encodeBytes(code.key) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr + field.offset), + ptr: unsafe.Pointer(ptr + code.offset), })) rv := reflect.ValueOf(v) if rv.Type().Kind() == reflect.Interface && rv.IsNil() { e.encodeNull() - code = field.end + code = code.end break } b, err := rv.Interface().(Marshaler).MarshalJSON() @@ -1217,27 +1279,25 @@ func (e *Encoder) run(code *opcode) error { return err } e.encodeBytes(buf.Bytes()) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrAnonymousHeadMarshalJSON: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadMarshalJSON: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr + field.offset), + ptr: unsafe.Pointer(ptr + code.offset), })) rv := reflect.ValueOf(v) if rv.Type().Kind() == reflect.Interface && rv.IsNil() { e.encodeNull() - code = field.end + code = code.end break } b, err := rv.Interface().(Marshaler).MarshalJSON() @@ -1258,29 +1318,27 @@ func (e *Encoder) run(code *opcode) error { return err } e.encodeBytes(buf.Bytes()) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadMarshalText: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadMarshalText: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) + e.encodeBytes(code.key) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr + field.offset), + ptr: unsafe.Pointer(ptr + code.offset), })) rv := reflect.ValueOf(v) if rv.Type().Kind() == reflect.Interface && rv.IsNil() { e.encodeNull() - code = field.end + code = code.end break } bytes, err := rv.Interface().(encoding.TextMarshaler).MarshalText() @@ -1291,27 +1349,25 @@ func (e *Encoder) run(code *opcode) error { } } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrAnonymousHeadMarshalText: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadMarshalText: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end + code = code.end } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr + field.offset), + ptr: unsafe.Pointer(ptr + code.offset), })) rv := reflect.ValueOf(v) if rv.Type().Kind() == reflect.Interface && rv.IsNil() { e.encodeNull() - code = field.end + code = code.end break } bytes, err := rv.Interface().(encoding.TextMarshaler).MarshalText() @@ -1322,44 +1378,40 @@ func (e *Encoder) run(code *opcode) error { } } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next - } else if field.next == field.end { + code = code.end.next + } else if code.next == code.end { // not exists fields e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '}'}) - code = field.next - code.ptr = ptr - field.nextField.ptr = ptr + code = code.next + store(ctxptr, code.idx, ptr) } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - code = field.next - code.ptr = ptr - field.nextField.ptr = ptr + code = code.next + store(ctxptr, code.idx, ptr) } case opStructFieldPtrHeadIntIndent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadIntIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadIntIndent { e.encodeIndent(code.indent) @@ -1367,225 +1419,203 @@ func (e *Encoder) run(code *opcode) error { } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeInt(e.ptrToInt(ptr + field.offset)) - field.nextField.ptr = ptr - code = field.next + e.encodeInt(e.ptrToInt(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt8Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt8Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt8(e.ptrToInt8(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadInt16Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt16Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt16(e.ptrToInt16(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadInt32Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt32Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt32(e.ptrToInt32(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadInt64Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt64Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt64(e.ptrToInt64(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadUintIndent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUintIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint(e.ptrToUint(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadUint8Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint8Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint8(e.ptrToUint8(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadUint16Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint16Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint16(e.ptrToUint16(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadUint32Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint32Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint32(e.ptrToUint32(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadUint64Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint64Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint64(e.ptrToUint64(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadFloat32Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadFloat32Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeFloat32(e.ptrToFloat32(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadFloat64Indent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadFloat64Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { v := e.ptrToFloat64(ptr) if math.IsInf(v, 0) || math.IsNaN(v) { @@ -1597,619 +1627,588 @@ func (e *Encoder) run(code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeFloat64(v) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadStringIndent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadStringIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeString(e.ptrToString(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadBoolIndent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadBoolIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeBool(e.ptrToBool(ptr)) - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadBytesIndent: - code.ptr = e.ptrToPtr(code.ptr) + store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadBytesIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end + code = code.end } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString(e.ptrToBytes(ptr)) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') - field.nextField.ptr = ptr - code = field.next + code = code.next } case opStructFieldPtrHeadOmitEmpty: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmpty: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - p := ptr + field.offset + p := ptr + code.offset if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) - code = field.next - code.ptr = p + e.encodeBytes(code.key) + code = code.next + store(ctxptr, code.idx, p) } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmpty: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmpty: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - p := ptr + field.offset + p := ptr + code.offset if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) - code = field.next - code.ptr = p + e.encodeBytes(code.key) + code = code.next + store(ctxptr, code.idx, p) } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyInt: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyInt: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToInt(ptr + field.offset) + v := e.ptrToInt(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrAnonymousHeadOmitEmptyInt: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToInt(ptr + field.offset) + v := e.ptrToInt(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyInt8: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyInt8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToInt8(ptr + field.offset) + v := e.ptrToInt8(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt8(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyInt8: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToInt8(ptr + field.offset) + v := e.ptrToInt8(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt8(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyInt16: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyInt16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToInt16(ptr + field.offset) + v := e.ptrToInt16(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt16(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrAnonymousHeadOmitEmptyInt16: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToInt16(ptr + field.offset) + v := e.ptrToInt16(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt16(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyInt32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyInt32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToInt32(ptr + field.offset) + v := e.ptrToInt32(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt32(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrAnonymousHeadOmitEmptyInt32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToInt32(ptr + field.offset) + v := e.ptrToInt32(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt32(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyInt64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyInt64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToInt64(ptr + field.offset) + v := e.ptrToInt64(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt64(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyInt64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToInt64(ptr + field.offset) + v := e.ptrToInt64(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeInt64(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyUint: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUint: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToUint(ptr + field.offset) + v := e.ptrToUint(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyUint: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToUint(ptr + field.offset) + v := e.ptrToUint(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyUint8: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUint8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToUint8(ptr + field.offset) + v := e.ptrToUint8(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint8(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyUint8: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToUint8(ptr + field.offset) + v := e.ptrToUint8(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint8(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyUint16: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUint16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToUint16(ptr + field.offset) + v := e.ptrToUint16(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint16(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrAnonymousHeadOmitEmptyUint16: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToUint16(ptr + field.offset) + v := e.ptrToUint16(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint16(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyUint32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUint32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToUint32(ptr + field.offset) + v := e.ptrToUint32(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint32(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyUint32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToUint32(ptr + field.offset) + v := e.ptrToUint32(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint32(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyUint64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUint64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToUint64(ptr + field.offset) + v := e.ptrToUint64(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint64(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrAnonymousHeadOmitEmptyUint64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToUint64(ptr + field.offset) + v := e.ptrToUint64(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeUint64(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyFloat32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyFloat32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToFloat32(ptr + field.offset) + v := e.ptrToFloat32(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeFloat32(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyFloat32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyFloat32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToFloat32(ptr + field.offset) + v := e.ptrToFloat32(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeFloat32(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyFloat64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyFloat64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToFloat64(ptr + field.offset) + v := e.ptrToFloat64(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ @@ -2217,26 +2216,25 @@ func (e *Encoder) run(code *opcode) error { Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeFloat64(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrAnonymousHeadOmitEmptyFloat64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyFloat64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToFloat64(ptr + field.offset) + v := e.ptrToFloat64(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ @@ -2244,167 +2242,160 @@ func (e *Encoder) run(code *opcode) error { Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeFloat64(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyString: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyString: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToString(ptr + field.offset) + v := e.ptrToString(ptr + code.offset) if v == "" { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyString: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyString: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToString(ptr + field.offset) + v := e.ptrToString(ptr + code.offset) if v == "" { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyBool: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyBool: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToBool(ptr + field.offset) + v := e.ptrToBool(ptr + code.offset) if !v { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeBool(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyBool: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyBool: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToBool(ptr + field.offset) + v := e.ptrToBool(ptr + code.offset) if !v { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeBool(v) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyBytes: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyBytes: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToBytes(ptr + field.offset) + v := e.ptrToBytes(ptr + code.offset) if len(v) == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) s := base64.StdEncoding.EncodeToString(v) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyBytes: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyBytes: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToBytes(ptr + field.offset) + v := e.ptrToBytes(ptr + code.offset) if len(v) == 0 { - code = field.nextField + code = code.nextField } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) s := base64.StdEncoding.EncodeToString(v) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyMarshalJSON: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyMarshalJSON: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - p := unsafe.Pointer(ptr + field.offset) + p := unsafe.Pointer(ptr + code.offset) isPtr := code.typ.Kind() == reflect.Ptr if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { - code = field.nextField + code = code.nextField } else { v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) b, err := v.(Marshaler).MarshalJSON() @@ -2421,34 +2412,33 @@ func (e *Encoder) run(code *opcode) error { 0, ) } - code = field.nextField + code = code.nextField } else { var buf bytes.Buffer if err := compact(&buf, b, true); err != nil { return err } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeBytes(buf.Bytes()) - code = field.next + code = code.next } } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyMarshalJSON: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyMarshalJSON: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - p := unsafe.Pointer(ptr + field.offset) + p := unsafe.Pointer(ptr + code.offset) isPtr := code.typ.Kind() == reflect.Ptr if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { - code = field.nextField + code = code.nextField } else { v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) b, err := v.(Marshaler).MarshalJSON() @@ -2465,36 +2455,35 @@ func (e *Encoder) run(code *opcode) error { 0, ) } - code = field.nextField + code = code.nextField } else { var buf bytes.Buffer if err := compact(&buf, b, true); err != nil { return err } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeBytes(buf.Bytes()) - code = field.next + code = code.next } } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyMarshalText: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyMarshalText: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - p := unsafe.Pointer(ptr + field.offset) + p := unsafe.Pointer(ptr + code.offset) isPtr := code.typ.Kind() == reflect.Ptr if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { - code = field.nextField + code = code.nextField } else { v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) bytes, err := v.(encoding.TextMarshaler).MarshalText() @@ -2504,27 +2493,26 @@ func (e *Encoder) run(code *opcode) error { Err: err, } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadOmitEmptyMarshalText: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadOmitEmptyMarshalText: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - p := unsafe.Pointer(ptr + field.offset) + p := unsafe.Pointer(ptr + code.offset) isPtr := code.typ.Kind() == reflect.Ptr if p == nil || (!isPtr && *(*unsafe.Pointer)(p) == nil) { - code = field.nextField + code = code.nextField } else { v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) bytes, err := v.(encoding.TextMarshaler).MarshalText() @@ -2534,354 +2522,341 @@ func (e *Encoder) run(code *opcode) error { Err: err, } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadOmitEmptyIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - p := ptr + field.offset + p := ptr + code.offset if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - code = field.next - code.ptr = p + code = code.next + store(ctxptr, code.idx, p) } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyIntIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyIntIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToInt(ptr + field.offset) + v := e.ptrToInt(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyInt8Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyInt8Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToInt8(ptr + field.offset) + v := e.ptrToInt8(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt8(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyInt16Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyInt16Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToInt16(ptr + field.offset) + v := e.ptrToInt16(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt16(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyInt32Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyInt32Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToInt32(ptr + field.offset) + v := e.ptrToInt32(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt32(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyInt64Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyInt64Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToInt64(ptr + field.offset) + v := e.ptrToInt64(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt64(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyUintIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUintIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToUint(ptr + field.offset) + v := e.ptrToUint(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyUint8Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUint8Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToUint8(ptr + field.offset) + v := e.ptrToUint8(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint8(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyUint16Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUint16Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToUint16(ptr + field.offset) + v := e.ptrToUint16(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint16(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyUint32Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUint32Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToUint32(ptr + field.offset) + v := e.ptrToUint32(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint32(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyUint64Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyUint64Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToUint64(ptr + field.offset) + v := e.ptrToUint64(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint64(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyFloat32Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyFloat32Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToFloat32(ptr + field.offset) + v := e.ptrToFloat32(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeFloat32(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyFloat64Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyFloat64Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToFloat64(ptr + field.offset) + v := e.ptrToFloat64(ptr + code.offset) if v == 0 { - code = field.nextField + code = code.nextField } else { if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ @@ -2890,680 +2865,644 @@ func (e *Encoder) run(code *opcode) error { } } e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeFloat64(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyStringIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyStringIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToString(ptr + field.offset) + v := e.ptrToString(ptr + code.offset) if v == "" { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeString(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyBoolIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyBoolIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToBool(ptr + field.offset) + v := e.ptrToBool(ptr + code.offset) if !v { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeBool(v) - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadOmitEmptyBytesIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadOmitEmptyBytesIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToBytes(ptr + field.offset) + v := e.ptrToBytes(ptr + code.offset) if len(v) == 0 { - code = field.nextField + code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString(v) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') - code = field.next + code = code.next } - field.nextField.ptr = field.ptr } case opStructFieldPtrHeadStringTag: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTag: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - p := ptr + field.offset - e.encodeBytes(field.key) - code = field.next - code.ptr = p - field.nextField.ptr = ptr + p := ptr + code.offset + e.encodeBytes(code.key) + code = code.next + store(ctxptr, code.idx, p) } case opStructFieldPtrAnonymousHeadStringTag: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTag: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - code = field.next - code.ptr = ptr + field.offset - field.nextField.ptr = ptr + e.encodeBytes(code.key) + code = code.next + store(ctxptr, code.idx, ptr+code.offset) } case opStructFieldPtrHeadStringTagInt: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagInt: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagInt: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt8: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagInt8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt8: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagInt8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt16: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagInt16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt16: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagInt16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagInt32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagInt32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagInt64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagInt64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUint: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagUint: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint8: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUint8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint8: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagUint8: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint16: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUint16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint16: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagUint16: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUint32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagUint32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUint64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagUint64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagFloat32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagFloat32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagFloat32: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagFloat32: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagFloat64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagFloat64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - v := e.ptrToFloat64(ptr + field.offset) + v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(fmt.Sprint(v)) - code = field.next - field.nextField.ptr = ptr + code = code.next } case opStructFieldPtrAnonymousHeadStringTagFloat64: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagFloat64: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - v := e.ptrToFloat64(ptr + field.offset) + v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(fmt.Sprint(v)) - code = field.next - field.nextField.ptr = ptr + code = code.next } case opStructFieldPtrHeadStringTagString: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagString: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(strconv.Quote(e.ptrToString(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagString: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagString: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(strconv.Quote(e.ptrToString(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagBool: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagBool: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToBool(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagBool: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagBool: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - e.encodeString(fmt.Sprint(e.ptrToBool(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagBytes: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagBytes: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(field.key) + e.encodeBytes(code.key) s := base64.StdEncoding.EncodeToString( - e.ptrToBytes(ptr + field.offset), + e.ptrToBytes(ptr + code.offset), ) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') - code = field.next - field.nextField.ptr = ptr + code = code.next } case opStructFieldPtrAnonymousHeadStringTagBytes: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagBytes: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) + e.encodeBytes(code.key) s := base64.StdEncoding.EncodeToString( - e.ptrToBytes(ptr + field.offset), + e.ptrToBytes(ptr + code.offset), ) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') - code = field.next - field.nextField.ptr = ptr + code = code.next } case opStructFieldPtrHeadStringTagMarshalJSON: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagMarshalJSON: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - p := unsafe.Pointer(ptr + field.offset) + p := unsafe.Pointer(ptr + code.offset) isPtr := code.typ.Kind() == reflect.Ptr v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) b, err := v.(Marshaler).MarshalJSON() @@ -3580,31 +3519,30 @@ func (e *Encoder) run(code *opcode) error { 0, ) } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeBytes([]byte{'"', '"'}) - code = field.nextField + code = code.nextField } else { var buf bytes.Buffer if err := compact(&buf, b, true); err != nil { return err } e.encodeString(buf.String()) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrAnonymousHeadStringTagMarshalJSON: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagMarshalJSON: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - p := unsafe.Pointer(ptr + field.offset) + p := unsafe.Pointer(ptr + code.offset) isPtr := code.typ.Kind() == reflect.Ptr v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) b, err := v.(Marshaler).MarshalJSON() @@ -3621,34 +3559,33 @@ func (e *Encoder) run(code *opcode) error { 0, ) } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeBytes([]byte{'"', '"'}) - code = field.nextField + code = code.nextField } else { var buf bytes.Buffer if err := compact(&buf, b, true); err != nil { return err } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(buf.String()) - code = field.next + code = code.next } - field.nextField.ptr = ptr } case opStructFieldPtrHeadStringTagMarshalText: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagMarshalText: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeByte('{') - p := unsafe.Pointer(ptr + field.offset) + p := unsafe.Pointer(ptr + code.offset) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -3657,23 +3594,22 @@ func (e *Encoder) run(code *opcode) error { Err: err, } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - code = field.next - field.nextField.ptr = ptr + code = code.next } case opStructFieldPtrAnonymousHeadStringTagMarshalText: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldAnonymousHeadStringTagMarshalText: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - p := unsafe.Pointer(ptr + field.offset) + p := unsafe.Pointer(ptr + code.offset) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{typ: code.typ, ptr: p})) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -3682,279 +3618,266 @@ func (e *Encoder) run(code *opcode) error { Err: err, } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - code = field.next - field.nextField.ptr = ptr + code = code.next } case opStructFieldPtrHeadStringTagIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) - p := ptr + field.offset + p := ptr + code.offset e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - code = field.next - code.ptr = p - field.nextField.ptr = field.ptr + code = code.next + store(ctxptr, code.idx, p) } case opStructFieldPtrHeadStringTagIntIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagIntIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt8Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagInt8Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt16Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagInt16Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt32Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagInt32Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt64Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagInt64Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUintIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUintIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint8Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUint8Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint16Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUint16Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint32Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUint32Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint64Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagUint64Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagFloat32Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagFloat32Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagFloat64Indent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagFloat64Indent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) - v := e.ptrToFloat64(ptr + field.offset) + v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), @@ -3962,198 +3885,181 @@ func (e *Encoder) run(code *opcode) error { } } e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeString(fmt.Sprint(v)) - code = field.next - field.nextField.ptr = ptr + code = code.next } case opStructFieldPtrHeadStringTagStringIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagStringIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(strconv.Quote(e.ptrToString(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagBoolIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagBoolIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToBool(ptr + field.offset))) - code = field.next - field.nextField.ptr = ptr + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagBytesIndent: - if code.ptr != 0 { - code.ptr = e.ptrToPtr(code.ptr) + ptr := load(ctxptr, code.idx) + if ptr != 0 { + store(ctxptr, code.idx, e.ptrToPtr(ptr)) } fallthrough case opStructFieldHeadStringTagBytesIndent: - field := code.toStructFieldCode() - ptr := field.ptr + ptr := load(ctxptr, code.idx) if ptr == 0 { e.encodeIndent(code.indent) e.encodeNull() - code = field.end.next + code = code.end.next } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString( - e.ptrToBytes(ptr + field.offset), + e.ptrToBytes(ptr + code.offset), ) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') - code = field.next - field.nextField.ptr = ptr + code = code.next } case opStructField: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - if !c.anonymousKey { - e.encodeBytes(c.key) + if !code.anonymousKey { + e.encodeBytes(code.key) } + ptr := load(ctxptr, code.headIdx) + code.offset code = code.next - code.ptr = c.ptr + c.offset - c.nextField.ptr = c.ptr + store(ctxptr, code.idx, ptr) case opStructFieldInt: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeInt(e.ptrToInt(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeInt(e.ptrToInt(ptr + code.offset)) code = code.next case opStructFieldInt8: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeInt8(e.ptrToInt8(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeInt8(e.ptrToInt8(ptr + code.offset)) code = code.next case opStructFieldInt16: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeInt16(e.ptrToInt16(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeInt16(e.ptrToInt16(ptr + code.offset)) code = code.next case opStructFieldInt32: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeInt32(e.ptrToInt32(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeInt32(e.ptrToInt32(ptr + code.offset)) code = code.next case opStructFieldInt64: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeInt64(e.ptrToInt64(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeInt64(e.ptrToInt64(ptr + code.offset)) code = code.next case opStructFieldUint: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeUint(e.ptrToUint(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeUint(e.ptrToUint(ptr + code.offset)) code = code.next case opStructFieldUint8: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeUint8(e.ptrToUint8(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeUint8(e.ptrToUint8(ptr + code.offset)) code = code.next case opStructFieldUint16: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeUint16(e.ptrToUint16(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeUint16(e.ptrToUint16(ptr + code.offset)) code = code.next case opStructFieldUint32: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeUint32(e.ptrToUint32(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeUint32(e.ptrToUint32(ptr + code.offset)) code = code.next case opStructFieldUint64: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeUint64(e.ptrToUint64(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeUint64(e.ptrToUint64(ptr + code.offset)) code = code.next case opStructFieldFloat32: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeFloat32(e.ptrToFloat32(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) code = code.next case opStructFieldFloat64: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - v := e.ptrToFloat64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), @@ -4166,28 +4072,25 @@ func (e *Encoder) run(code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeString(e.ptrToString(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeString(e.ptrToString(ptr + code.offset)) code = code.next case opStructFieldBool: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - e.encodeBool(e.ptrToBool(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + e.encodeBool(e.ptrToBool(ptr + code.offset)) code = code.next case opStructFieldBytes: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - s := base64.StdEncoding.EncodeToString(e.ptrToBytes(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + s := base64.StdEncoding.EncodeToString(e.ptrToBytes(ptr + code.offset)) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') @@ -4196,13 +4099,12 @@ func (e *Encoder) run(code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - ptr := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) b, err := v.(Marshaler).MarshalJSON() if err != nil { @@ -4221,13 +4123,12 @@ func (e *Encoder) run(code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr - e.encodeBytes(c.key) - ptr := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + e.encodeBytes(code.key) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -4242,188 +4143,177 @@ func (e *Encoder) run(code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset code = code.next - code.ptr = c.ptr + c.offset - e.encodeBytes(c.key) + store(ctxptr, code.idx, p) case opStructFieldSlice: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - c.nextField.ptr = c.ptr + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset code = code.next - code.ptr = c.ptr + c.offset - e.encodeBytes(c.key) + store(ctxptr, code.idx, p) case opStructFieldMap: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - e.encodeBytes(c.key) + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset code = code.next - code.ptr = c.ptr + c.offset - c.nextField.ptr = c.ptr + store(ctxptr, code.idx, p) case opStructFieldMapLoad: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - e.encodeBytes(c.key) + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset code = code.next - code.ptr = c.ptr + c.offset - c.nextField.ptr = c.ptr + store(ctxptr, code.idx, p) case opStructFieldStruct: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - e.encodeBytes(c.key) + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset code = code.next - code.ptr = c.ptr + c.offset - c.nextField.ptr = c.ptr + store(ctxptr, code.idx, p) case opStructFieldIndent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset code = code.next - code.ptr = c.ptr + c.offset - c.nextField.ptr = c.ptr + store(ctxptr, code.idx, p) case opStructFieldIntIndent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeInt(e.ptrToInt(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt(e.ptrToInt(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldInt8Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeInt8(e.ptrToInt8(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt8(e.ptrToInt8(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldInt16Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeInt16(e.ptrToInt16(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt16(e.ptrToInt16(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldInt32Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeInt32(e.ptrToInt32(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt32(e.ptrToInt32(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldInt64Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeInt64(e.ptrToInt64(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt64(e.ptrToInt64(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldUintIndent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeUint(e.ptrToUint(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint(e.ptrToUint(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldUint8Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeUint8(e.ptrToUint8(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint8(e.ptrToUint8(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldUint16Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeUint16(e.ptrToUint16(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint16(e.ptrToUint16(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldUint32Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeUint32(e.ptrToUint32(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint32(e.ptrToUint32(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldUint64Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeUint64(e.ptrToUint64(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint64(e.ptrToUint64(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldFloat32Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeFloat32(e.ptrToFloat32(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldFloat64Indent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - v := e.ptrToFloat64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), @@ -4432,55 +4322,51 @@ func (e *Encoder) run(code *opcode) error { } e.encodeFloat64(v) code = code.next - c.nextField.ptr = c.ptr case opStructFieldStringIndent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(e.ptrToString(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeString(e.ptrToString(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldBoolIndent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeBool(e.ptrToBool(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBool(e.ptrToBool(ptr + code.offset)) code = code.next - c.nextField.ptr = c.ptr case opStructFieldBytesIndent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - s := base64.StdEncoding.EncodeToString(e.ptrToBytes(c.ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + s := base64.StdEncoding.EncodeToString(e.ptrToBytes(ptr + code.offset)) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') code = code.next - c.nextField.ptr = c.ptr case opStructFieldMarshalJSONIndent: - c := code.toStructFieldCode() if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeByte(',') } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - ptr := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) b, err := v.(Marshaler).MarshalJSON() if err != nil { @@ -4495,261 +4381,242 @@ func (e *Encoder) run(code *opcode) error { } e.encodeBytes(buf.Bytes()) code = code.next - c.nextField.ptr = c.ptr case opStructFieldArrayIndent: if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - c := code.toStructFieldCode() - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset header := (*reflect.SliceHeader)(unsafe.Pointer(p)) if p == 0 || header.Data == 0 { e.encodeNull() - code = c.nextField + code = code.nextField } else { code = code.next } - c.nextField.ptr = c.ptr case opStructFieldSliceIndent: if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - c := code.toStructFieldCode() - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset header := (*reflect.SliceHeader)(unsafe.Pointer(p)) if p == 0 || header.Data == 0 { e.encodeNull() - code = c.nextField + code = code.nextField } else { code = code.next } - c.nextField.ptr = c.ptr case opStructFieldMapIndent: if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - c := code.toStructFieldCode() - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if p == 0 { e.encodeNull() - code = c.nextField + code = code.nextField } else { mlen := maplen(unsafe.Pointer(p)) if mlen == 0 { e.encodeBytes([]byte{'{', '}'}) mapCode := code.next - mapHeadCode := mapCode.toMapHeadCode() - code = mapHeadCode.end.next + code = mapCode.end.next } else { code = code.next } } - c.nextField.ptr = c.ptr case opStructFieldMapLoadIndent: if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - c := code.toStructFieldCode() - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if p == 0 { e.encodeNull() - code = c.nextField + code = code.nextField } else { p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p))) mlen := maplen(unsafe.Pointer(p)) if mlen == 0 { e.encodeBytes([]byte{'{', '}'}) - code = c.nextField + code = code.nextField } else { code = code.next } } - c.nextField.ptr = c.ptr case opStructFieldStructIndent: if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - c := code.toStructFieldCode() - p := c.ptr + c.offset - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') if p == 0 { e.encodeBytes([]byte{'{', '}'}) - code = c.nextField + code = code.nextField } else { - headCode := c.next.toStructFieldCode() + headCode := code.next if headCode.next == headCode.end { // not exists fields e.encodeBytes([]byte{'{', '}'}) - code = c.nextField + code = code.nextField } else { code = code.next - code.ptr = p + store(ctxptr, code.idx, p) } } - c.nextField.ptr = c.ptr case opStructFieldOmitEmpty: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) code = code.next - code.ptr = p + store(ctxptr, code.idx, p) } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptyInt: - c := code.toStructFieldCode() - v := e.ptrToInt(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeInt(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyInt8: - c := code.toStructFieldCode() - v := e.ptrToInt8(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt8(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeInt8(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyInt16: - c := code.toStructFieldCode() - v := e.ptrToInt16(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt16(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeInt16(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyInt32: - c := code.toStructFieldCode() - v := e.ptrToInt32(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt32(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeInt32(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyInt64: - c := code.toStructFieldCode() - v := e.ptrToInt64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt64(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeInt64(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUint: - c := code.toStructFieldCode() - v := e.ptrToUint(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeUint(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUint8: - c := code.toStructFieldCode() - v := e.ptrToUint8(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint8(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeUint8(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUint16: - c := code.toStructFieldCode() - v := e.ptrToUint16(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint16(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeUint16(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUint32: - c := code.toStructFieldCode() - v := e.ptrToUint32(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint32(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeUint32(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUint64: - c := code.toStructFieldCode() - v := e.ptrToUint64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint64(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeUint64(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyFloat32: - c := code.toStructFieldCode() - v := e.ptrToFloat32(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToFloat32(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeFloat32(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyFloat64: - c := code.toStructFieldCode() - v := e.ptrToFloat64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToFloat64(ptr + code.offset) if v != 0 { if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ @@ -4760,56 +4627,52 @@ func (e *Encoder) run(code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeFloat64(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyString: - c := code.toStructFieldCode() - v := e.ptrToString(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToString(ptr + code.offset) if v != "" { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeString(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyBool: - c := code.toStructFieldCode() - v := e.ptrToBool(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToBool(ptr + code.offset) if v { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeBool(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyBytes: - c := code.toStructFieldCode() - v := e.ptrToBytes(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToBytes(ptr + code.offset) if len(v) > 0 { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) s := base64.StdEncoding.EncodeToString(v) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyMarshalJSON: - c := code.toStructFieldCode() - ptr := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) if v != nil { b, err := v.(Marshaler).MarshalJSON() @@ -4826,18 +4689,17 @@ func (e *Encoder) run(code *opcode) error { e.encodeBytes(buf.Bytes()) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyMarshalText: - c := code.toStructFieldCode() - ptr := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) if v != nil { v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -4849,42 +4711,39 @@ func (e *Encoder) run(code *opcode) error { e.encodeString(*(*string)(unsafe.Pointer(&bytes))) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyArray: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset header := (*reflect.SliceHeader)(unsafe.Pointer(p)) if p == 0 || header.Data == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } code = code.next } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptySlice: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset header := (*reflect.SliceHeader)(unsafe.Pointer(p)) if p == 0 || header.Data == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } code = code.next } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptyMap: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if p == 0 { - code = c.nextField + code = code.nextField } else { mlen := maplen(unsafe.Pointer(p)) if mlen == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') @@ -4892,17 +4751,16 @@ func (e *Encoder) run(code *opcode) error { code = code.next } } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptyMapLoad: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if p == 0 { - code = c.nextField + code = code.nextField } else { p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p))) mlen := maplen(unsafe.Pointer(p)) if mlen == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') @@ -4910,180 +4768,167 @@ func (e *Encoder) run(code *opcode) error { code = code.next } } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptyIndent: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') code = code.next - code.ptr = p + store(ctxptr, code.idx, p) } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptyIntIndent: - c := code.toStructFieldCode() - v := e.ptrToInt(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyInt8Indent: - c := code.toStructFieldCode() - v := e.ptrToInt8(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt8(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt8(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyInt16Indent: - c := code.toStructFieldCode() - v := e.ptrToInt16(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt16(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt16(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyInt32Indent: - c := code.toStructFieldCode() - v := e.ptrToInt32(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt32(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt32(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyInt64Indent: - c := code.toStructFieldCode() - v := e.ptrToInt64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToInt64(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeInt64(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUintIndent: - c := code.toStructFieldCode() - v := e.ptrToUint(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUint8Indent: - c := code.toStructFieldCode() - v := e.ptrToUint8(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint8(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint8(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUint16Indent: - c := code.toStructFieldCode() - v := e.ptrToUint16(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint16(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint16(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUint32Indent: - c := code.toStructFieldCode() - v := e.ptrToUint32(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint32(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint32(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyUint64Indent: - c := code.toStructFieldCode() - v := e.ptrToUint64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToUint64(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeUint64(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyFloat32Indent: - c := code.toStructFieldCode() - v := e.ptrToFloat32(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToFloat32(ptr + code.offset) if v != 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeFloat32(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyFloat64Indent: - c := code.toStructFieldCode() - v := e.ptrToFloat64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToFloat64(ptr + code.offset) if v != 0 { if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ @@ -5094,50 +4939,47 @@ func (e *Encoder) run(code *opcode) error { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeFloat64(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyStringIndent: - c := code.toStructFieldCode() - v := e.ptrToString(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToString(ptr + code.offset) if v != "" { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeString(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyBoolIndent: - c := code.toStructFieldCode() - v := e.ptrToBool(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToBool(ptr + code.offset) if v { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeBool(v) } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyBytesIndent: - c := code.toStructFieldCode() - v := e.ptrToBytes(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToBytes(ptr + code.offset) if len(v) > 0 { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString(v) e.encodeByte('"') @@ -5145,215 +4987,197 @@ func (e *Encoder) run(code *opcode) error { e.encodeByte('"') } code = code.next - code.ptr = c.ptr case opStructFieldOmitEmptyArrayIndent: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset header := (*reflect.SliceHeader)(unsafe.Pointer(p)) if p == 0 || header.Data == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') code = code.next } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptySliceIndent: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset header := (*reflect.SliceHeader)(unsafe.Pointer(p)) if p == 0 || header.Data == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') code = code.next } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptyMapIndent: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if p == 0 { - code = c.nextField + code = code.nextField } else { mlen := maplen(unsafe.Pointer(p)) if mlen == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') code = code.next } } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptyMapLoadIndent: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if p == 0 { - code = c.nextField + code = code.nextField } else { p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p))) mlen := maplen(unsafe.Pointer(p)) if mlen == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') code = code.next } } - c.nextField.ptr = c.ptr case opStructFieldOmitEmptyStructIndent: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if p == 0 { - code = c.nextField + code = code.nextField } else { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - headCode := c.next.toStructFieldCode() + headCode := code.next if headCode.next == headCode.end { // not exists fields e.encodeBytes([]byte{'{', '}'}) - code = c.nextField + code = code.nextField } else { code = code.next - code.ptr = p + store(ctxptr, code.idx, p) } } - c.nextField.ptr = c.ptr case opStructFieldStringTag: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) code = code.next - code.ptr = p - c.nextField.ptr = c.ptr + store(ctxptr, code.idx, p) case opStructFieldStringTagInt: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagInt8: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt8(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagInt16: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt16(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagInt32: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt32(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagInt64: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt64(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUint: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUint8: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint8(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUint16: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint16(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUint32: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint32(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUint64: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint64(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagFloat32: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToFloat32(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagFloat64: - c := code.toStructFieldCode() - v := e.ptrToFloat64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), @@ -5363,47 +5187,43 @@ func (e *Encoder) run(code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeString(fmt.Sprint(v)) code = code.next - code.ptr = c.ptr case opStructFieldStringTagString: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(strconv.Quote(e.ptrToString(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagBool: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToBool(c.ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagBytes: - c := code.toStructFieldCode() - v := e.ptrToBytes(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToBytes(ptr + code.offset) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) s := base64.StdEncoding.EncodeToString(v) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') code = code.next - code.ptr = c.ptr case opStructFieldStringTagMarshalJSON: - c := code.toStructFieldCode() - ptr := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) b, err := v.(Marshaler).MarshalJSON() if err != nil { @@ -5418,13 +5238,12 @@ func (e *Encoder) run(code *opcode) error { } e.encodeString(buf.String()) code = code.next - code.ptr = c.ptr case opStructFieldStringTagMarshalText: - c := code.toStructFieldCode() - ptr := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -5435,143 +5254,130 @@ func (e *Encoder) run(code *opcode) error { } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagIndent: - c := code.toStructFieldCode() - p := c.ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') code = code.next - code.ptr = p - c.nextField.ptr = c.ptr + store(ctxptr, code.idx, p) case opStructFieldStringTagIntIndent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagInt8Indent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt8(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagInt16Indent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt16(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagInt32Indent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt32(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagInt64Indent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToInt64(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUintIndent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUint8Indent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint8(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUint16Indent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint16(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUint32Indent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint32(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagUint64Indent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToUint64(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagFloat32Indent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToFloat32(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagFloat64Indent: - c := code.toStructFieldCode() - v := e.ptrToFloat64(c.ptr + c.offset) + ptr := load(ctxptr, code.headIdx) + v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ Value: reflect.ValueOf(v), @@ -5581,66 +5387,62 @@ func (e *Encoder) run(code *opcode) error { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeString(fmt.Sprint(v)) code = code.next - code.ptr = c.ptr case opStructFieldStringTagStringIndent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') var b bytes.Buffer enc := NewEncoder(&b) - enc.encodeString(e.ptrToString(c.ptr + c.offset)) + enc.encodeString(e.ptrToString(ptr + code.offset)) e.encodeString(string(enc.buf)) enc.release() code = code.next - code.ptr = c.ptr case opStructFieldStringTagBoolIndent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - e.encodeString(fmt.Sprint(e.ptrToBool(c.ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) code = code.next - code.ptr = c.ptr case opStructFieldStringTagBytesIndent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString( - e.ptrToBytes(c.ptr + c.offset), + e.ptrToBytes(ptr + code.offset), ) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') code = code.next - code.ptr = c.ptr case opStructFieldStringTagMarshalJSONIndent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - ptr := c.ptr + c.offset + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) b, err := v.(Marshaler).MarshalJSON() if err != nil { @@ -5655,19 +5457,18 @@ func (e *Encoder) run(code *opcode) error { } e.encodeString(buf.String()) code = code.next - c.nextField.ptr = c.ptr case opStructFieldStringTagMarshalTextIndent: - c := code.toStructFieldCode() + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - e.encodeIndent(c.indent) - e.encodeBytes(c.key) + e.encodeIndent(code.indent) + e.encodeBytes(code.key) e.encodeByte(' ') - ptr := c.ptr + c.offset + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, - ptr: unsafe.Pointer(ptr), + ptr: unsafe.Pointer(p), })) bytes, err := v.(encoding.TextMarshaler).MarshalText() if err != nil { @@ -5678,7 +5479,6 @@ func (e *Encoder) run(code *opcode) error { } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) code = code.next - c.nextField.ptr = c.ptr case opStructEnd: e.encodeByte('}') code = code.next diff --git a/json_test.go b/json_test.go index 3831777..f3a066c 100644 --- a/json_test.go +++ b/json_test.go @@ -121,7 +121,6 @@ func TestIndent(t *testing.T) { } // Tests of a large random structure. - func TestCompactBig(t *testing.T) { initBig() var buf bytes.Buffer @@ -221,7 +220,9 @@ func trim(b []byte) []byte { // Generate a random JSON object. -var jsonBig []byte +var ( + jsonBig []byte +) func initBig() { if len(jsonBig) > 0 {