diff --git a/encode.go b/encode.go index 556bd57..e9f2c48 100644 --- a/encode.go +++ b/encode.go @@ -195,16 +195,16 @@ func (e *Encoder) encode(v interface{}) error { if err != nil { return err } - codeLength := code.length() + codeLength := code.totalLength() codeSet := &opcodeSet{ codeIndent: sync.Pool{ New: func() interface{} { - return copyOpcode(codeIndent) + return codeIndent }, }, code: sync.Pool{ New: func() interface{} { - return copyOpcode(code) + return code }, }, ctx: sync.Pool{ diff --git a/encode_compile.go b/encode_compile.go index eb98048..ff1124e 100644 --- a/encode_compile.go +++ b/encode_compile.go @@ -265,17 +265,7 @@ func (e *Encoder) compileBytes(ctx *encodeCompileContext) (*opcode, error) { } func (e *Encoder) compileInterface(ctx *encodeCompileContext) (*opcode, error) { - code := (*opcode)(unsafe.Pointer(&interfaceCode{ - opcodeHeader: &opcodeHeader{ - op: opInterface, - typ: ctx.typ, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - next: newEndOp(ctx), - }, - root: ctx.root, - })) + code := newInterfaceCode(ctx) ctx.incOpcodeIndex() return code, nil } @@ -406,8 +396,8 @@ func (e *Encoder) compileMap(ctx *encodeCompileContext, withLoad bool) (*opcode, ctx = ctx.decIndent() - header.key = key - header.value = value + header.mapKey = key + header.mapValue = value end := newOpCode(ctx, opMapEnd) ctx.incOpcodeIndex() @@ -586,20 +576,10 @@ func (e *Encoder) optimizeStructField(op opType, tag *structTag, withIndent bool return fieldType } -func (e *Encoder) recursiveCode(ctx *encodeCompileContext, code *compiledCode) *opcode { - c := (*opcode)(unsafe.Pointer(&recursiveCode{ - opcodeHeader: &opcodeHeader{ - op: opStructFieldRecursive, - typ: ctx.typ, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - next: newEndOp(ctx), - }, - jmp: code, - })) +func (e *Encoder) recursiveCode(ctx *encodeCompileContext, jmp *compiledCode) *opcode { + code := newRecursiveCode(ctx, jmp) ctx.incOpcodeIndex() - return c + return code } func (e *Encoder) compiledCode(ctx *encodeCompileContext) *opcode { @@ -617,7 +597,7 @@ func (e *Encoder) compiledCode(ctx *encodeCompileContext) *opcode { return nil } -func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *structFieldCode, valueCode *opcode, tag *structTag) *opcode { +func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode { fieldCode.indent-- op := e.optimizeStructHeader(valueCode.op, tag, ctx.withIndent) fieldCode.op = op @@ -654,7 +634,7 @@ func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *structField return (*opcode)(unsafe.Pointer(fieldCode)) } -func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *structFieldCode, valueCode *opcode, tag *structTag) *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, ctx.withIndent) fieldCode.op = op @@ -691,7 +671,7 @@ func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *structFieldC return code } -func (e *Encoder) isNotExistsField(head *structFieldCode) bool { +func (e *Encoder) isNotExistsField(head *opcode) bool { if head == nil { return false } @@ -713,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 @@ -726,7 +706,7 @@ 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++ { @@ -738,21 +718,21 @@ func (e *Encoder) optimizeAnonymousFields(head *structFieldCode) { } } 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() @@ -777,7 +757,7 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, value break } prevAnonymousField = f - f = f.nextField.toStructFieldCode() + f = f.nextField continue } @@ -787,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...) } } @@ -795,7 +775,7 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, value break } prevAnonymousField = f - f = f.nextField.toStructFieldCode() + f = f.nextField } return anonymousFields } @@ -869,9 +849,9 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode, fieldNum := typ.NumField() fieldIdx := 0 var ( - head *structFieldCode + head *opcode code *opcode - prevField *structFieldCode + prevField *opcode ) ctx = ctx.incIndent() tags := structTags{} @@ -903,7 +883,7 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode, } 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...) } } @@ -919,14 +899,12 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode, } } key := fmt.Sprintf(`"%s":`, tag.key) - fieldCode := &structFieldCode{ - opcodeHeader: &opcodeHeader{ - typ: valueCode.typ, - displayIdx: fieldOpcodeIndex, - idx: uintptr(fieldOpcodeIndex) * 8, - next: valueCode, - indent: ctx.indent, - }, + fieldCode := &opcode{ + typ: valueCode.typ, + displayIdx: fieldOpcodeIndex, + idx: opcodeOffset(fieldOpcodeIndex), + next: valueCode, + indent: ctx.indent, anonymousKey: field.Anonymous, key: []byte(key), isTaggedKey: tag.isTaggedKey, @@ -948,36 +926,32 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode, } ctx = ctx.decIndent() - structEndCode := (*opcode)(unsafe.Pointer(&structFieldCode{ - opcodeHeader: &opcodeHeader{ - op: opStructEnd, - typ: nil, - indent: ctx.indent, - next: newEndOp(ctx), - }, - })) + structEndCode := &opcode{ + op: opStructEnd, + typ: nil, + indent: ctx.indent, + next: newEndOp(ctx), + } // no struct field if head == nil { - head = &structFieldCode{ - opcodeHeader: &opcodeHeader{ - op: opStructFieldHead, - typ: typ, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - }, - nextField: structEndCode, + head = &opcode{ + op: opStructFieldHead, + typ: typ, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.opcodeIndex), + indent: ctx.indent, + nextField: structEndCode, } ctx.incOpcodeIndex() if ctx.withIndent { head.op = opStructFieldHeadIndent } - code = (*opcode)(unsafe.Pointer(head)) + code = head } structEndCode.displayIdx = ctx.opcodeIndex - structEndCode.idx = uintptr(ctx.opcodeIndex) * 8 + structEndCode.idx = opcodeOffset(ctx.opcodeIndex) ctx.incOpcodeIndex() if ctx.withIndent { diff --git a/encode_context.go b/encode_context.go index ec30d68..a36ddec 100644 --- a/encode_context.go +++ b/encode_context.go @@ -10,6 +10,7 @@ type encodeCompileContext struct { withIndent bool root bool opcodeIndex int + ptrIndex int indent int parent *encodeCompileContext @@ -21,6 +22,7 @@ func (c *encodeCompileContext) context() *encodeCompileContext { withIndent: c.withIndent, root: c.root, opcodeIndex: c.opcodeIndex, + ptrIndex: c.ptrIndex, indent: c.indent, parent: c, } @@ -46,6 +48,7 @@ func (c *encodeCompileContext) decIndent() *encodeCompileContext { func (c *encodeCompileContext) incOpcodeIndex() { c.opcodeIndex++ + c.ptrIndex++ if c.parent != nil { c.parent.incOpcodeIndex() } @@ -53,6 +56,7 @@ func (c *encodeCompileContext) incOpcodeIndex() { func (c *encodeCompileContext) decOpcodeIndex() { c.opcodeIndex-- + c.ptrIndex-- if c.parent != nil { c.parent.decOpcodeIndex() } diff --git a/encode_opcode.go b/encode_opcode.go index 7cc4ae9..bc1fe9f 100644 --- a/encode_opcode.go +++ b/encode_opcode.go @@ -2,54 +2,56 @@ 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 - displayIdx int - idx uintptr - indent int - next *opcode -} - -func (h *opcodeHeader) copy(codeMap map[uintptr]*opcode) *opcodeHeader { - return &opcodeHeader{ - op: h.op, - typ: h.typ, - displayIdx: h.displayIdx, - idx: h.idx, - 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(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: ctx.typ, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - next: next, - }, + op: op, + typ: ctx.typ, + displayIdx: ctx.opcodeIndex, + indent: ctx.indent, + idx: opcodeOffset(ctx.opcodeIndex), + next: next, } } @@ -62,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 } @@ -79,17 +77,13 @@ func (c *opcode) beforeLastCode() *opcode { return nil } -func (c *opcode) length() int { +func (c *opcode) totalLength() int { var idx int for code := c; code.op != opEnd; { idx = code.displayIdx switch code.op.codeType() { - case codeArrayElem: - code = code.toArrayElemCode().end - case codeSliceElem: - code = code.toSliceElemCode().end - case codeMapKey: - code = code.toMapKeyCode().end + case codeArrayElem, codeSliceElem, codeMapKey: + code = code.end default: code = code.next } @@ -102,310 +96,86 @@ func (c *opcode) decOpcodeIndex() { code.displayIdx-- code.idx -= 8 switch code.op.codeType() { - case codeArrayElem: - code = code.toArrayElemCode().end - case codeSliceElem: - code = code.toSliceElemCode().end - case codeMapKey: - code = code.toMapKeyCode().end + case codeArrayElem, codeSliceElem, codeMapKey: + code = code.end default: code = code.next } } } -func (c *opcode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil - } - 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 +func (c *opcode) dumpElem(code *opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([headIdx:%d][elemIdx:%d][length:%d][size:%d])`, + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.headIdx, + code.elemIdx, + code.length, + code.size, + ) +} - code.opcodeHeader = c.opcodeHeader.copy(codeMap) - } - return code +func (c *opcode) dumpField(code *opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([key:%s][offset:%d][headIdx:%d])`, + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.displayKey, + code.offset, + code.headIdx, + ) +} + +func (c *opcode) dumpKey(code *opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([elemIdx:%d][length:%d][mapIter:%d])`, + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + code.elemIdx, + code.length, + code.mapIter, + ) } 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("[%d]%s%s ( %p )", code.displayIdx, indent, code.op, unsafe.Pointer(code))) - code = code.toArrayElemCode().end - case codeSliceElem: - codes = append(codes, fmt.Sprintf("[%d]%s%s ( %p )", code.displayIdx, indent, code.op, unsafe.Pointer(code))) - code = code.toSliceElemCode().end + case codeArrayElem, codeSliceElem: + codes = append(codes, c.dumpElem(code)) + code = code.end case codeMapKey: - codes = append(codes, fmt.Sprintf("[%d]%s%s ( %p )", code.displayIdx, indent, code.op, unsafe.Pointer(code))) - code = code.toMapKeyCode().end + codes = append(codes, c.dumpKey(code)) + code = code.end case codeStructField: - sf := code.toStructFieldCode() - key := sf.displayKey - offset := sf.offset - codes = append(codes, fmt.Sprintf("[%d]%s%s [%s:%d] ( %p )", code.displayIdx, indent, code.op, key, offset, unsafe.Pointer(code))) + codes = append(codes, c.dumpField(code)) code = code.next default: - codes = append(codes, fmt.Sprintf("[%d]%s%s ( %p )", code.displayIdx, indent, code.op, unsafe.Pointer(code))) + codes = append(codes, fmt.Sprintf( + "[%d]%s%s", + code.displayIdx, + strings.Repeat("-", code.indent), + code.op, + )) 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(ctx *encodeCompileContext) *sliceHeaderCode { - return &sliceHeaderCode{ - opcodeHeader: &opcodeHeader{ - op: opSliceHead, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - }, - } -} - -func newSliceElemCode(ctx *encodeCompileContext, size uintptr) *sliceElemCode { - return &sliceElemCode{ - opcodeHeader: &opcodeHeader{ - op: opSliceElem, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - }, - size: size, - } -} - -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(ctx *encodeCompileContext, alen int) *arrayHeaderCode { - return &arrayHeaderCode{ - opcodeHeader: &opcodeHeader{ - op: opArrayHead, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - }, - len: uintptr(alen), - } -} - -func newArrayElemCode(ctx *encodeCompileContext, alen int, size uintptr) *arrayElemCode { - return &arrayElemCode{ - opcodeHeader: &opcodeHeader{ - op: opArrayElem, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - }, - len: uintptr(alen), - size: size, - } -} - -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 } @@ -419,213 +189,108 @@ func linkPrevToNextField(prev, cur *structFieldCode) { } } -func (c *structFieldCode) toOpcode() *opcode { - return (*opcode)(unsafe.Pointer(c)) +func newSliceHeaderCode(ctx *encodeCompileContext) *opcode { + return &opcode{ + op: opSliceHead, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.opcodeIndex), + indent: ctx.indent, + } } -func (c *structFieldCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil +func newSliceElemCode(ctx *encodeCompileContext, size uintptr) *opcode { + return &opcode{ + op: opSliceElem, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.opcodeIndex), + 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 { + return &opcode{ + op: opArrayHead, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.opcodeIndex), + indent: ctx.indent, + length: uintptr(alen), + } } -func (c *mapHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode { - if c == nil { - return nil +func newArrayElemCode(ctx *encodeCompileContext, alen int, size uintptr) *opcode { + return &opcode{ + op: opArrayElem, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.opcodeIndex), + length: uintptr(alen), + 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(ctx *encodeCompileContext, withLoad bool) *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: ctx.typ, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - }, + return &opcode{ + op: op, + typ: ctx.typ, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.opcodeIndex), + indent: ctx.indent, } } -func newMapKeyCode(ctx *encodeCompileContext) *mapKeyCode { - return &mapKeyCode{ - opcodeHeader: &opcodeHeader{ - op: opMapKey, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - }, +func newMapKeyCode(ctx *encodeCompileContext) *opcode { + return &opcode{ + op: opMapKey, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.opcodeIndex), + indent: ctx.indent, } } -func newMapValueCode(ctx *encodeCompileContext) *mapValueCode { - return &mapValueCode{ - opcodeHeader: &opcodeHeader{ - op: opMapValue, - displayIdx: ctx.opcodeIndex, - idx: uintptr(ctx.opcodeIndex) * 8, - indent: ctx.indent, - }, +func newMapValueCode(ctx *encodeCompileContext) *opcode { + return &opcode{ + op: opMapValue, + displayIdx: ctx.opcodeIndex, + idx: opcodeOffset(ctx.opcodeIndex), + 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.opcodeIndex), + indent: ctx.indent, + next: newEndOp(ctx), + root: ctx.root, + } } -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.opcodeIndex), + 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 newRecursiveCode(recursive *recursiveCode) *opcode { +//code := copyOpcode(recursive.jmp.code) +//head := (*structFieldCode)(unsafe.Pointer(code)) +//head.end.next = newEndOp(&encodeCompileContext{}) -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(&encodeCompileContext{}) - - code.op = code.op.ptrHeadToHead() - return code -} +//code.op = code.op.ptrHeadToHead() +// return code +//} diff --git a/encode_vm.go b/encode_vm.go index e873ae8..409a60c 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -92,10 +92,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } code = code.next case opInterface: - ifaceCode := code.toInterfaceCode() - ptr := load(ctxptr, ifaceCode.idx) + 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 { @@ -108,7 +107,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c rv := reflect.ValueOf(v) if rv.IsNil() { e.encodeNull() - code = ifaceCode.next + code = code.next break } vv := rv.Interface() @@ -121,9 +120,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c if typ.Kind() == reflect.Map { code, err := e.compileMap(&encodeCompileContext{ typ: typ, - root: ifaceCode.root, + root: code.root, withIndent: e.enabledIndent, - indent: ifaceCode.indent, + indent: code.indent, }, false) if err != nil { return err @@ -132,9 +131,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { code, err := e.compile(&encodeCompileContext{ typ: typ, - root: ifaceCode.root, + root: code.root, withIndent: e.enabledIndent, - indent: ifaceCode.indent, + indent: code.indent, }) if err != nil { return err @@ -142,13 +141,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c c = code } ctx := &encodeRuntimeContext{ - ptrs: make([]uintptr, c.length()), + ptrs: make([]uintptr, c.totalLength()), } ctx.init(uintptr(header.ptr)) if err := e.run(ctx, seenPtr, c); err != nil { return err } - code = ifaceCode.next + code = code.next case opMarshalJSON: ptr := load(ctxptr, code.idx) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ @@ -213,43 +212,48 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c code = code.next case opSliceHead: p := load(ctxptr, code.idx) - headerCode := code.toSliceHeaderCode() 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 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) code = code.next - store(ctxptr, code.idx, c.data+c.idx*c.size) + data := load(ctxptr, code.headIdx) + store(ctxptr, code.idx, data+idx*code.size) } else { e.encodeByte(']') - code = c.end.next + code = code.end.next } case opSliceHeadIndent: p := load(ctxptr, code.idx) - headerCode := code.toSliceHeaderCode() 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) @@ -258,19 +262,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'[', ']'}) - code = headerCode.end.next + code = code.end.next } } case opRootSliceHeadIndent: p := load(ctxptr, code.idx) - headerCode := code.toSliceHeaderCode() 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) @@ -279,128 +284,131 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } 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) code = code.next - store(ctxptr, code.idx, 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 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 - store(ctxptr, code.idx, 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 := load(ctxptr, code.idx) - headerCode := code.toArrayHeaderCode() if p == 0 { e.encodeNull() - code = headerCode.end.next + code = code.end.next } else { e.encodeByte('[') - if headerCode.len > 0 { + if code.length > 0 { code = code.next store(ctxptr, code.idx, p) - store(ctxptr, headerCode.elem.opcodeHeader.idx, p) } else { e.encodeByte(']') - code = headerCode.end.next + code = code.end.next } } case opArrayElem: - c := code.toArrayElemCode() - c.idx++ - p := load(ctxptr, c.opcodeHeader.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) code = code.next - store(ctxptr, code.idx, p+c.idx*c.size) + store(ctxptr, code.idx, p+idx*code.size) } else { e.encodeByte(']') - code = c.end.next + code = code.end.next } case opArrayHeadIndent: p := load(ctxptr, code.idx) - headerCode := code.toArrayHeaderCode() 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) code = code.next store(ctxptr, code.idx, p) - store(ctxptr, headerCode.elem.opcodeHeader.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++ - p := load(ctxptr, c.opcodeHeader.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) code = code.next - store(ctxptr, code.idx, p+c.idx*c.size) + store(ctxptr, code.idx, p+idx*code.size) } else { e.encodeByte('\n') e.encodeIndent(code.indent) e.encodeBytes([]byte{']', '\n'}) - code = c.end.next + code = code.end.next } case opMapHead: ptr := load(ctxptr, code.idx) - mapHeadCode := code.toMapHeadCode() 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) + store(ctxptr, code.mapKey.length, uintptr(mlen)) + store(ctxptr, code.mapKey.mapIter, uintptr(iter)) + store(ctxptr, code.mapValue.mapIter, uintptr(iter)) key := mapiterkey(iter) store(ctxptr, code.next.idx, uintptr(key)) code = code.next } else { e.encodeByte('}') - code = mapHeadCode.end.next + code = code.end.next } } case opMapHeadLoad: ptr := load(ctxptr, code.idx) - mapHeadCode := code.toMapHeadCode() if ptr == 0 { e.encodeNull() - code = mapHeadCode.end.next + code = code.end.next } else { // load pointer ptr = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(ptr))) @@ -408,49 +416,53 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c mlen := maplen(unsafe.Pointer(ptr)) if mlen > 0 { iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) - mapHeadCode.key.set(mlen, iter) - mapHeadCode.value.set(iter) + store(ctxptr, code.mapKey.length, uintptr(mlen)) + store(ctxptr, code.mapKey.mapIter, uintptr(iter)) + store(ctxptr, code.mapValue.mapIter, uintptr(iter)) key := mapiterkey(iter) 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) - store(ctxptr, c.next.idx, 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) - store(ctxptr, c.next.idx, 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 := load(ctxptr, code.idx) - mapHeadCode := code.toMapHeadCode() 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) + store(ctxptr, code.mapKey.length, uintptr(mlen)) + store(ctxptr, code.mapKey.mapIter, uintptr(iter)) + store(ctxptr, code.mapValue.mapIter, uintptr(iter)) key := mapiterkey(iter) store(ctxptr, code.next.idx, uintptr(key)) code = code.next @@ -458,16 +470,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '}'}) - code = mapHeadCode.end.next + code = code.end.next } } case opMapHeadLoadIndent: ptr := load(ctxptr, code.idx) - mapHeadCode := code.toMapHeadCode() 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))) @@ -475,8 +486,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c if mlen > 0 { e.encodeBytes([]byte{'{', '\n'}) iter := mapiterinit(code.typ, unsafe.Pointer(ptr)) - mapHeadCode.key.set(mlen, iter) - mapHeadCode.value.set(iter) + store(ctxptr, code.mapKey.length, uintptr(mlen)) + store(ctxptr, code.mapKey.mapIter, uintptr(iter)) + store(ctxptr, code.mapValue.mapIter, uintptr(iter)) key := mapiterkey(iter) store(ctxptr, code.next.idx, uintptr(key)) code = code.next @@ -484,23 +496,23 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '}'}) - code = mapHeadCode.end.next + code = code.end.next } } case opRootMapHeadIndent: ptr := load(ctxptr, code.idx) - mapHeadCode := code.toMapHeadCode() 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) + store(ctxptr, code.mapKey.length, uintptr(mlen)) + store(ctxptr, code.mapKey.mapIter, uintptr(iter)) + store(ctxptr, code.mapValue.mapIter, uintptr(iter)) key := mapiterkey(iter) store(ctxptr, code.next.idx, uintptr(key)) code = code.next @@ -508,69 +520,77 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } 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) - store(ctxptr, c.next.idx, 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) - store(ctxptr, c.next.idx, 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) - store(ctxptr, c.next.idx, 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() ptr := load(ctxptr, code.idx) - if recursive.seenPtr != 0 && recursive.seenPtr == ptr { - 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), + if ptr != 0 { + 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 = ptr - recursiveCode := newRecursiveCode(recursive) + c := *(code.jmp.code) ctx := &encodeRuntimeContext{ - ptrs: make([]uintptr, recursiveCode.length()), + ptrs: make([]uintptr, c.totalLength()), } ctx.init(ptr) - if err := e.run(ctx, seenPtr, recursiveCode); err != nil { + c.end.next = newEndOp(&encodeCompileContext{}) + c.op = c.op.ptrHeadToHead() + if err := e.run(ctx, seenPtr, &c); err != nil { return err } - code = recursive.next + code = code.next case opStructFieldPtrHead: ptr := load(ctxptr, code.idx) if ptr != 0 { @@ -578,7 +598,6 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHead: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHead { @@ -586,31 +605,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } 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 - store(ctxptr, code.idx, ptr+field.offset) - store(ctxptr, field.nextField.idx, ptr) + code = code.next + store(ctxptr, code.idx, ptr+code.offset) } case opStructFieldAnonymousHead: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - code = field.next + code = code.next store(ctxptr, code.idx, ptr) - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadInt: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt { @@ -618,33 +633,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt(e.ptrToInt(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt(e.ptrToInt(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt(e.ptrToInt(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt8: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt8: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt8 { @@ -652,33 +663,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt8(e.ptrToInt8(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt8(e.ptrToInt8(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt8: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt8: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt8(e.ptrToInt8(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt16: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt16: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt16 { @@ -686,33 +693,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt16(e.ptrToInt16(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt16(e.ptrToInt16(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt16: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt16: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt16(e.ptrToInt16(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt32: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt32: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt32 { @@ -720,33 +723,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt32(e.ptrToInt32(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt32(e.ptrToInt32(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt32: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt32: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt32(e.ptrToInt32(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt64: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt64: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadInt64 { @@ -754,33 +753,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeInt64(e.ptrToInt64(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt64(e.ptrToInt64(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadInt64: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadInt64: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeInt64(e.ptrToInt64(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint { @@ -788,33 +783,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint(e.ptrToUint(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint(e.ptrToUint(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint(e.ptrToUint(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint8: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint8: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint8 { @@ -822,33 +813,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint8(e.ptrToUint8(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint8(e.ptrToUint8(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint8: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint8: - field := code.toStructFieldCode() - ptr := load(ctxptr, field.idx) + 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint8(e.ptrToUint8(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint16: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint16: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint16 { @@ -856,33 +843,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint16(e.ptrToUint16(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint16(e.ptrToUint16(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint16: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint16: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint16(e.ptrToUint16(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint32: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint32: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint32 { @@ -890,33 +873,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint32(e.ptrToUint32(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint32(e.ptrToUint32(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint32: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint32: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint32(e.ptrToUint32(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadUint64: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint64: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadUint64 { @@ -924,33 +903,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeUint64(e.ptrToUint64(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint64(e.ptrToUint64(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadUint64: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadUint64: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeUint64(e.ptrToUint64(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadFloat32: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadFloat32: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadFloat32 { @@ -958,33 +933,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeFloat32(e.ptrToFloat32(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadFloat32: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadFloat32: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadFloat64: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadFloat64: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadFloat64 { @@ -992,9 +963,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } 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), @@ -1002,37 +973,33 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } } e.encodeByte('{') - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeFloat64(v) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrAnonymousHeadFloat64: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadFloat64: - field := code.toStructFieldCode() 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) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadString: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadString: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadString { @@ -1040,33 +1007,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeString(e.ptrToString(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeString(e.ptrToString(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadString: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadString: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeString(e.ptrToString(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadBool: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadBool: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadBool { @@ -1074,33 +1037,29 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } else { e.encodeBytes([]byte{'{', '}'}) } - code = field.end + code = code.end } else { e.encodeByte('{') - e.encodeBytes(field.key) - e.encodeBool(e.ptrToBool(ptr + field.offset)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeBool(e.ptrToBool(ptr + code.offset)) + code = code.next } case opStructFieldPtrAnonymousHeadBool: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadBool: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeBytes(code.key) + e.encodeBool(e.ptrToBool(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadBytes: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadBytes: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadBytes { @@ -1108,128 +1067,116 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } 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('"') - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrAnonymousHeadBytes: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadBytes: - field := code.toStructFieldCode() 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(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('"') - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadArray: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadArray: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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 = code.next store(ctxptr, code.idx, ptr) - store(ctxptr, c.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadArray: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadArray: - c := code.toStructFieldCode() - ptr := load(ctxptr, code.idx) + c.offset + ptr := load(ctxptr, code.idx) + code.offset if ptr == 0 { - code = c.end + code = code.end } else { - e.encodeBytes(c.key) + e.encodeBytes(code.key) store(ctxptr, code.idx, ptr) - store(ctxptr, c.nextField.idx, ptr) - code = c.next + code = code.next } case opStructFieldPtrHeadSlice: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadSlice: - c := code.toStructFieldCode() ptr := load(ctxptr, code.idx) - p := ptr + c.offset + 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 = code.next store(ctxptr, code.idx, p) - store(ctxptr, c.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadSlice: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadSlice: - c := code.toStructFieldCode() ptr := load(ctxptr, code.idx) - p := ptr + c.offset + p := ptr + code.offset if p == 0 { - code = c.end + code = code.end } else { - e.encodeBytes(c.key) + e.encodeBytes(code.key) store(ctxptr, code.idx, p) - store(ctxptr, c.nextField.idx, ptr) - code = c.next + code = code.next } case opStructFieldPtrHeadMarshalJSON: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadMarshalJSON: - field := code.toStructFieldCode() 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() @@ -1250,27 +1197,25 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c return err } e.encodeBytes(buf.Bytes()) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrAnonymousHeadMarshalJSON: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadMarshalJSON: - field := code.toStructFieldCode() 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() @@ -1291,29 +1236,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c return err } e.encodeBytes(buf.Bytes()) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadMarshalText: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadMarshalText: - field := code.toStructFieldCode() 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() @@ -1324,27 +1267,25 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrAnonymousHeadMarshalText: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldAnonymousHeadMarshalText: - field := code.toStructFieldCode() 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() @@ -1355,8 +1296,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadIndent: ptr := load(ctxptr, code.idx) @@ -1365,34 +1305,30 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadIndent: - field := code.toStructFieldCode() 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 = code.next store(ctxptr, code.idx, ptr) - store(ctxptr, field.nextField.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 = code.next store(ctxptr, code.idx, ptr) - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadIntIndent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadIntIndent: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { if code.op == opStructFieldPtrHeadIntIndent { @@ -1401,225 +1337,203 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + e.encodeInt(e.ptrToInt(ptr + code.offset)) + code = code.next } case opStructFieldPtrHeadInt8Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt8Indent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadInt16Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt16Indent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadInt32Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt32Indent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadInt64Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadInt64Indent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadUintIndent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUintIndent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadUint8Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint8Indent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadUint16Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint16Indent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadUint32Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint32Indent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadUint64Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadUint64Indent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadFloat32Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadFloat32Indent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadFloat64Indent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadFloat64Indent: - field := code.toStructFieldCode() 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) { @@ -1631,74 +1545,67 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c 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) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadStringIndent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadStringIndent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadBoolIndent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadBoolIndent: - field := code.toStructFieldCode() 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)) - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadBytesIndent: store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx))) fallthrough case opStructFieldHeadBytesIndent: - field := code.toStructFieldCode() 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('"') - store(ctxptr, field.nextField.idx, ptr) - code = field.next + code = code.next } case opStructFieldPtrHeadOmitEmpty: ptr := load(ctxptr, code.idx) @@ -1707,22 +1614,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmpty: - field := code.toStructFieldCode() 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 + e.encodeBytes(code.key) + code = code.next store(ctxptr, code.idx, p) } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmpty: ptr := load(ctxptr, code.idx) @@ -1731,20 +1636,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmpty: - field := code.toStructFieldCode() 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 + e.encodeBytes(code.key) + code = code.next store(ctxptr, code.idx, p) } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyInt: ptr := load(ctxptr, code.idx) @@ -1753,22 +1656,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyInt: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyInt: ptr := load(ctxptr, code.idx) @@ -1777,20 +1678,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyInt8: ptr := load(ctxptr, code.idx) @@ -1799,22 +1698,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyInt8: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyInt8: ptr := load(ctxptr, code.idx) @@ -1823,20 +1720,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt8: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyInt16: ptr := load(ctxptr, code.idx) @@ -1845,22 +1740,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyInt16: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyInt16: ptr := load(ctxptr, code.idx) @@ -1869,20 +1762,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt16: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyInt32: ptr := load(ctxptr, code.idx) @@ -1891,22 +1782,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyInt32: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyInt32: ptr := load(ctxptr, code.idx) @@ -1915,20 +1804,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt32: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyInt64: ptr := load(ctxptr, code.idx) @@ -1937,22 +1824,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyInt64: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyInt64: ptr := load(ctxptr, code.idx) @@ -1961,20 +1846,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyInt64: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUint: ptr := load(ctxptr, code.idx) @@ -1983,22 +1866,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUint: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyUint: ptr := load(ctxptr, code.idx) @@ -2007,20 +1888,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUint8: ptr := load(ctxptr, code.idx) @@ -2029,22 +1908,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUint8: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyUint8: ptr := load(ctxptr, code.idx) @@ -2053,20 +1930,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint8: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUint16: ptr := load(ctxptr, code.idx) @@ -2075,22 +1950,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUint16: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyUint16: ptr := load(ctxptr, code.idx) @@ -2099,20 +1972,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint16: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUint32: ptr := load(ctxptr, code.idx) @@ -2121,22 +1992,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUint32: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyUint32: ptr := load(ctxptr, code.idx) @@ -2145,20 +2014,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint32: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUint64: ptr := load(ctxptr, code.idx) @@ -2167,22 +2034,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUint64: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyUint64: ptr := load(ctxptr, code.idx) @@ -2191,20 +2056,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyUint64: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyFloat32: ptr := load(ctxptr, code.idx) @@ -2213,22 +2076,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyFloat32: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyFloat32: ptr := load(ctxptr, code.idx) @@ -2237,20 +2098,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyFloat32: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyFloat64: ptr := load(ctxptr, code.idx) @@ -2259,16 +2118,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyFloat64: - field := code.toStructFieldCode() 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{ @@ -2276,11 +2134,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeFloat64(v) - code = field.next + code = code.next } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyFloat64: ptr := load(ctxptr, code.idx) @@ -2289,14 +2146,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyFloat64: - field := code.toStructFieldCode() 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{ @@ -2304,11 +2160,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeFloat64(v) - code = field.next + code = code.next } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyString: ptr := load(ctxptr, code.idx) @@ -2317,22 +2172,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyString: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyString: ptr := load(ctxptr, code.idx) @@ -2341,20 +2194,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyString: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyBool: ptr := load(ctxptr, code.idx) @@ -2363,22 +2214,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyBool: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyBool: ptr := load(ctxptr, code.idx) @@ -2387,20 +2236,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyBool: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyBytes: ptr := load(ctxptr, code.idx) @@ -2409,25 +2256,23 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyBytes: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyBytes: ptr := load(ctxptr, code.idx) @@ -2436,23 +2281,21 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyBytes: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyMarshalJSON: ptr := load(ctxptr, code.idx) @@ -2461,17 +2304,16 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyMarshalJSON: - field := code.toStructFieldCode() 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() @@ -2488,18 +2330,17 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c 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 } } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyMarshalJSON: ptr := load(ctxptr, code.idx) @@ -2508,15 +2349,14 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyMarshalJSON: - field := code.toStructFieldCode() 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() @@ -2533,18 +2373,17 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c 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 } } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyMarshalText: ptr := load(ctxptr, code.idx) @@ -2553,17 +2392,16 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyMarshalText: - field := code.toStructFieldCode() 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() @@ -2573,11 +2411,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c Err: err, } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - code = field.next + code = code.next } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadOmitEmptyMarshalText: ptr := load(ctxptr, code.idx) @@ -2586,15 +2423,14 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadOmitEmptyMarshalText: - field := code.toStructFieldCode() 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() @@ -2604,11 +2440,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c Err: err, } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - code = field.next + code = code.next } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyIndent: ptr := load(ctxptr, code.idx) @@ -2617,26 +2452,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyIndent: - field := code.toStructFieldCode() 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 = code.next store(ctxptr, code.idx, p) } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyIntIndent: ptr := load(ctxptr, code.idx) @@ -2645,26 +2478,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyIntIndent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyInt8Indent: ptr := load(ctxptr, code.idx) @@ -2673,26 +2504,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyInt8Indent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyInt16Indent: ptr := load(ctxptr, code.idx) @@ -2701,26 +2530,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyInt16Indent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyInt32Indent: ptr := load(ctxptr, code.idx) @@ -2729,26 +2556,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyInt32Indent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyInt64Indent: ptr := load(ctxptr, code.idx) @@ -2757,26 +2582,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyInt64Indent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUintIndent: ptr := load(ctxptr, code.idx) @@ -2785,26 +2608,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUintIndent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUint8Indent: ptr := load(ctxptr, code.idx) @@ -2813,26 +2634,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUint8Indent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUint16Indent: ptr := load(ctxptr, code.idx) @@ -2841,26 +2660,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUint16Indent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUint32Indent: ptr := load(ctxptr, code.idx) @@ -2869,26 +2686,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUint32Indent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyUint64Indent: ptr := load(ctxptr, code.idx) @@ -2897,26 +2712,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyUint64Indent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyFloat32Indent: ptr := load(ctxptr, code.idx) @@ -2925,26 +2738,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyFloat32Indent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyFloat64Indent: ptr := load(ctxptr, code.idx) @@ -2953,18 +2764,17 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyFloat64Indent: - field := code.toStructFieldCode() 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{ @@ -2973,12 +2783,11 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } } e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeFloat64(v) - code = field.next + code = code.next } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyStringIndent: ptr := load(ctxptr, code.idx) @@ -2987,26 +2796,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyStringIndent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyBoolIndent: ptr := load(ctxptr, code.idx) @@ -3015,26 +2822,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyBoolIndent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadOmitEmptyBytesIndent: ptr := load(ctxptr, code.idx) @@ -3043,29 +2848,27 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadOmitEmptyBytesIndent: - field := code.toStructFieldCode() 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadStringTag: ptr := load(ctxptr, code.idx) @@ -3074,18 +2877,16 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTag: - field := code.toStructFieldCode() 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 + p := ptr + code.offset + e.encodeBytes(code.key) + code = code.next store(ctxptr, code.idx, p) - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadStringTag: ptr := load(ctxptr, code.idx) @@ -3094,15 +2895,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTag: - field := code.toStructFieldCode() ptr := load(ctxptr, code.idx) if ptr == 0 { - code = field.end.next + code = code.end.next } else { - e.encodeBytes(field.key) - code = field.next - store(ctxptr, code.idx, ptr+field.offset) - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + code = code.next + store(ctxptr, code.idx, ptr+code.offset) } case opStructFieldPtrHeadStringTagInt: ptr := load(ctxptr, code.idx) @@ -3111,17 +2910,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagInt: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt: ptr := load(ctxptr, code.idx) @@ -3130,15 +2927,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagInt: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt8: ptr := load(ctxptr, code.idx) @@ -3147,17 +2942,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagInt8: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt8: ptr := load(ctxptr, code.idx) @@ -3166,15 +2959,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagInt8: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt16: ptr := load(ctxptr, code.idx) @@ -3183,17 +2974,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagInt16: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt16: ptr := load(ctxptr, code.idx) @@ -3202,15 +2991,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagInt16: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt32: ptr := load(ctxptr, code.idx) @@ -3219,17 +3006,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagInt32: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt32: ptr := load(ctxptr, code.idx) @@ -3238,15 +3023,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagInt32: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt64: ptr := load(ctxptr, code.idx) @@ -3255,17 +3038,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagInt64: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagInt64: ptr := load(ctxptr, code.idx) @@ -3274,15 +3055,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagInt64: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint: ptr := load(ctxptr, code.idx) @@ -3291,17 +3070,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUint: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint: ptr := load(ctxptr, code.idx) @@ -3310,15 +3087,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagUint: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint8: ptr := load(ctxptr, code.idx) @@ -3327,17 +3102,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUint8: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint8: ptr := load(ctxptr, code.idx) @@ -3346,15 +3119,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagUint8: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint16: ptr := load(ctxptr, code.idx) @@ -3363,17 +3134,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUint16: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint16: ptr := load(ctxptr, code.idx) @@ -3382,15 +3151,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagUint16: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint32: ptr := load(ctxptr, code.idx) @@ -3399,17 +3166,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUint32: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint32: ptr := load(ctxptr, code.idx) @@ -3418,15 +3183,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagUint32: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint64: ptr := load(ctxptr, code.idx) @@ -3435,17 +3198,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUint64: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagUint64: ptr := load(ctxptr, code.idx) @@ -3454,15 +3215,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagUint64: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagFloat32: ptr := load(ctxptr, code.idx) @@ -3471,17 +3230,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagFloat32: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagFloat32: ptr := load(ctxptr, code.idx) @@ -3490,15 +3247,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagFloat32: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagFloat64: ptr := load(ctxptr, code.idx) @@ -3507,24 +3262,22 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagFloat64: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagFloat64: ptr := load(ctxptr, code.idx) @@ -3533,22 +3286,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagFloat64: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + code = code.next } case opStructFieldPtrHeadStringTagString: ptr := load(ctxptr, code.idx) @@ -3557,17 +3308,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagString: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagString: ptr := load(ctxptr, code.idx) @@ -3576,15 +3325,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagString: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagBool: ptr := load(ctxptr, code.idx) @@ -3593,17 +3340,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagBool: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagBool: ptr := load(ctxptr, code.idx) @@ -3612,15 +3357,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagBool: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagBytes: ptr := load(ctxptr, code.idx) @@ -3629,22 +3372,20 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagBytes: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagBytes: ptr := load(ctxptr, code.idx) @@ -3653,20 +3394,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagBytes: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + code = code.next } case opStructFieldPtrHeadStringTagMarshalJSON: ptr := load(ctxptr, code.idx) @@ -3675,14 +3414,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagMarshalJSON: - field := code.toStructFieldCode() 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() @@ -3699,18 +3437,17 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrAnonymousHeadStringTagMarshalJSON: ptr := load(ctxptr, code.idx) @@ -3719,12 +3456,11 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagMarshalJSON: - field := code.toStructFieldCode() 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() @@ -3741,19 +3477,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c 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 } - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadStringTagMarshalText: ptr := load(ctxptr, code.idx) @@ -3762,14 +3497,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagMarshalText: - field := code.toStructFieldCode() 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 { @@ -3778,10 +3512,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c Err: err, } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - code = field.next - store(ctxptr, field.nextField.idx, ptr) + code = code.next } case opStructFieldPtrAnonymousHeadStringTagMarshalText: ptr := load(ctxptr, code.idx) @@ -3790,12 +3523,11 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldAnonymousHeadStringTagMarshalText: - field := code.toStructFieldCode() 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 { @@ -3804,10 +3536,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c Err: err, } } - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) - code = field.next - store(ctxptr, field.nextField.idx, ptr) + code = code.next } case opStructFieldPtrHeadStringTagIndent: ptr := load(ctxptr, code.idx) @@ -3816,21 +3547,19 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagIndent: - field := code.toStructFieldCode() 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 = code.next store(ctxptr, code.idx, p) - store(ctxptr, field.nextField.idx, ptr) } case opStructFieldPtrHeadStringTagIntIndent: ptr := load(ctxptr, code.idx) @@ -3839,20 +3568,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagIntIndent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt8Indent: ptr := load(ctxptr, code.idx) @@ -3861,20 +3588,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagInt8Indent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt16Indent: ptr := load(ctxptr, code.idx) @@ -3883,20 +3608,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagInt16Indent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt32Indent: ptr := load(ctxptr, code.idx) @@ -3905,20 +3628,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagInt32Indent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagInt64Indent: ptr := load(ctxptr, code.idx) @@ -3927,20 +3648,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagInt64Indent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUintIndent: ptr := load(ctxptr, code.idx) @@ -3949,20 +3668,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUintIndent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint8Indent: ptr := load(ctxptr, code.idx) @@ -3971,20 +3688,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUint8Indent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint16Indent: ptr := load(ctxptr, code.idx) @@ -3993,20 +3708,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUint16Indent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint32Indent: ptr := load(ctxptr, code.idx) @@ -4015,20 +3728,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUint32Indent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagUint64Indent: ptr := load(ctxptr, code.idx) @@ -4037,20 +3748,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagUint64Indent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagFloat32Indent: ptr := load(ctxptr, code.idx) @@ -4059,20 +3768,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagFloat32Indent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagFloat64Indent: ptr := load(ctxptr, code.idx) @@ -4081,15 +3788,14 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagFloat64Indent: - field := code.toStructFieldCode() 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), @@ -4097,11 +3803,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } } e.encodeIndent(code.indent + 1) - e.encodeBytes(field.key) + e.encodeBytes(code.key) e.encodeByte(' ') e.encodeString(fmt.Sprint(v)) - code = field.next - store(ctxptr, field.nextField.idx, ptr) + code = code.next } case opStructFieldPtrHeadStringTagStringIndent: ptr := load(ctxptr, code.idx) @@ -4110,20 +3815,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagStringIndent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagBoolIndent: ptr := load(ctxptr, code.idx) @@ -4132,20 +3835,18 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagBoolIndent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, ptr) + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) + code = code.next } case opStructFieldPtrHeadStringTagBytesIndent: ptr := load(ctxptr, code.idx) @@ -4154,157 +3855,129 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } fallthrough case opStructFieldHeadStringTagBytesIndent: - field := code.toStructFieldCode() 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 - store(ctxptr, field.nextField.idx, 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 - ptr := load(ctxptr, c.idx) - store(ctxptr, code.idx, ptr+c.offset) - store(ctxptr, c.nextField.idx, ptr) + store(ctxptr, code.idx, ptr) case opStructFieldInt: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeInt(e.ptrToInt(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeInt8(e.ptrToInt8(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeInt16(e.ptrToInt16(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeInt32(e.ptrToInt32(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeInt64(e.ptrToInt64(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeUint(e.ptrToUint(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeUint8(e.ptrToUint8(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeUint16(e.ptrToUint16(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeUint32(e.ptrToUint32(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeUint64(e.ptrToUint64(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeFloat32(e.ptrToFloat32(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - v := e.ptrToFloat64(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), @@ -4317,31 +3990,25 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeString(e.ptrToString(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - e.encodeBool(e.ptrToBool(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() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - s := base64.StdEncoding.EncodeToString(e.ptrToBytes(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('"') @@ -4350,11 +4017,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - p := 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(p), @@ -4376,11 +4041,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) - e.encodeBytes(c.key) - p := 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(p), @@ -4398,206 +4061,171 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) code = code.next - store(ctxptr, code.idx, ptr+c.offset) - e.encodeBytes(c.key) + store(ctxptr, code.idx, ptr+code.offset) case opStructFieldSlice: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - store(ctxptr, c.nextField.idx, ptr) + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) code = code.next - store(ctxptr, code.idx, ptr+c.offset) - e.encodeBytes(c.key) + store(ctxptr, code.idx, ptr+code.offset) case opStructFieldMap: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - e.encodeBytes(c.key) + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) code = code.next - store(ctxptr, code.idx, ptr+c.offset) - store(ctxptr, c.nextField.idx, ptr) + store(ctxptr, code.idx, ptr+code.offset) case opStructFieldMapLoad: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - e.encodeBytes(c.key) + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) code = code.next - store(ctxptr, code.idx, ptr+c.offset) - store(ctxptr, c.nextField.idx, ptr) + store(ctxptr, code.idx, ptr+code.offset) case opStructFieldStruct: if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - e.encodeBytes(c.key) + e.encodeBytes(code.key) + ptr := load(ctxptr, code.headIdx) code = code.next - store(ctxptr, code.idx, ptr+c.offset) - store(ctxptr, c.nextField.idx, ptr) + store(ctxptr, code.idx, ptr+code.offset) 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) code = code.next - ptr := load(ctxptr, c.idx) - store(ctxptr, code.idx, ptr+c.offset) - store(ctxptr, c.nextField.idx, ptr) + store(ctxptr, code.idx, ptr+code.offset) 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeInt(e.ptrToInt(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt(e.ptrToInt(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeInt8(e.ptrToInt8(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt8(e.ptrToInt8(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeInt16(e.ptrToInt16(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt16(e.ptrToInt16(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeInt32(e.ptrToInt32(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt32(e.ptrToInt32(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeInt64(e.ptrToInt64(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeInt64(e.ptrToInt64(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeUint(e.ptrToUint(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint(e.ptrToUint(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeUint8(e.ptrToUint8(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint8(e.ptrToUint8(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeUint16(e.ptrToUint16(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint16(e.ptrToUint16(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeUint32(e.ptrToUint32(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint32(e.ptrToUint32(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeUint64(e.ptrToUint64(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeUint64(e.ptrToUint64(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeFloat32(e.ptrToFloat32(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - v := e.ptrToFloat64(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), @@ -4606,56 +4234,48 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } e.encodeFloat64(v) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeString(e.ptrToString(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeString(e.ptrToString(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - e.encodeBool(e.ptrToBool(ptr + c.offset)) + ptr := load(ctxptr, code.headIdx) + e.encodeBool(e.ptrToBool(ptr + code.offset)) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - s := base64.StdEncoding.EncodeToString(e.ptrToBytes(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 - store(ctxptr, c.nextField.idx, 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 := load(ctxptr, c.idx) - p := ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(p), @@ -4673,279 +4293,242 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } e.encodeBytes(buf.Bytes()) code = code.next - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - p := 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 } - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - p := 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 } - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - p := 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 } } - store(ctxptr, c.nextField.idx, 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(' ') - ptr := load(ctxptr, c.idx) - p := 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 } } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldStructIndent: if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { e.encodeBytes([]byte{',', '\n'}) } - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 store(ctxptr, code.idx, p) } } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmpty: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 store(ctxptr, code.idx, p) } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptyInt: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyInt8: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt8(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyInt16: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt16(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyInt32: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt32(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyInt64: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt64(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUint: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUint8: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint8(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUint16: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint16(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUint32: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint32(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUint64: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint64(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyFloat32: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToFloat32(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyFloat64: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToFloat64(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{ @@ -4956,57 +4539,49 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) + e.encodeBytes(code.key) e.encodeFloat64(v) } code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyString: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToString(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyBool: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToBool(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyBytes: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToBytes(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyMarshalJSON: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(p), @@ -5026,11 +4601,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c e.encodeBytes(buf.Bytes()) } code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyMarshalText: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(p), @@ -5050,45 +4623,39 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c e.encodeString(*(*string)(unsafe.Pointer(&bytes))) } code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyArray: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptySlice: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptyMap: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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(',') @@ -5096,18 +4663,16 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c code = code.next } } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptyMapLoad: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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(',') @@ -5115,193 +4680,167 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c code = code.next } } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptyIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 store(ctxptr, code.idx, p) } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptyIntIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyInt8Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt8(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyInt16Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt16(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyInt32Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt32(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyInt64Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToInt64(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUintIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUint8Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint8(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUint16Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint16(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUint32Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint32(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyUint64Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToUint64(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyFloat32Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToFloat32(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyFloat64Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToFloat64(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{ @@ -5312,53 +4851,47 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c 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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyStringIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToString(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyBoolIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToBool(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 - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyBytesIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToBytes(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('"') @@ -5366,233 +4899,197 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c e.encodeByte('"') } code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldOmitEmptyArrayIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptySliceIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptyMapIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 } } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptyMapLoadIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 } } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldOmitEmptyStructIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 store(ctxptr, code.idx, p) } } - store(ctxptr, c.nextField.idx, ptr) case opStructFieldStringTag: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 store(ctxptr, code.idx, p) - store(ctxptr, c.nextField.idx, ptr) case opStructFieldStringTagInt: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagInt8: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagInt16: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagInt32: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagInt64: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUint: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUint8: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUint16: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUint32: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUint64: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagFloat32: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagFloat64: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToFloat64(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), @@ -5602,48 +5099,40 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c 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 - store(ctxptr, code.idx, ptr) case opStructFieldStringTagString: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(strconv.Quote(e.ptrToString(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagBool: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + ptr := load(ctxptr, code.headIdx) if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(c.key) - e.encodeString(fmt.Sprint(e.ptrToBool(ptr + c.offset))) + e.encodeBytes(code.key) + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagBytes: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToBytes(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 - store(ctxptr, code.idx, ptr) case opStructFieldStringTagMarshalJSON: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(p), @@ -5661,11 +5150,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } e.encodeString(buf.String()) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagMarshalText: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := ptr + c.offset + ptr := load(ctxptr, code.headIdx) + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(p), @@ -5679,156 +5166,130 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - p := 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 store(ctxptr, code.idx, p) - store(ctxptr, c.nextField.idx, ptr) case opStructFieldStringTagIntIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagInt8Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagInt16Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagInt32Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagInt64Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUintIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUint8Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUint16Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUint32Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagUint64Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagFloat32Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagFloat64Indent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) - v := e.ptrToFloat64(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), @@ -5838,67 +5299,59 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c 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 - store(ctxptr, code.idx, ptr) case opStructFieldStringTagStringIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset)) + enc.encodeString(e.ptrToString(ptr + code.offset)) e.encodeString(string(enc.buf)) enc.release() code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagBoolIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset))) + e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagBytesIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(ptr + c.offset), + e.ptrToBytes(ptr + code.offset), ) e.encodeByte('"') e.encodeBytes(*(*[]byte)(unsafe.Pointer(&s))) e.encodeByte('"') code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagMarshalJSONIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(' ') - p := ptr + c.offset + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(p), @@ -5916,17 +5369,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } e.encodeString(buf.String()) code = code.next - store(ctxptr, code.idx, ptr) case opStructFieldStringTagMarshalTextIndent: - c := code.toStructFieldCode() - ptr := load(ctxptr, c.idx) + 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(' ') - p := ptr + c.offset + p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(p), @@ -5940,7 +5391,6 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, seenPtr map[uintptr]struct{}, c } e.encodeString(*(*string)(unsafe.Pointer(&bytes))) code = code.next - store(ctxptr, c.nextField.idx, ptr) case opStructEnd: e.encodeByte('}') code = code.next