mirror of https://github.com/goccy/go-json.git
Refactor indent parameter
This commit is contained in:
parent
7dcadbd6ce
commit
e508ad41ba
|
@ -19,7 +19,6 @@ type Encoder struct {
|
||||||
enabledHTMLEscape bool
|
enabledHTMLEscape bool
|
||||||
prefix []byte
|
prefix []byte
|
||||||
indentStr []byte
|
indentStr []byte
|
||||||
indent int
|
|
||||||
structTypeToCompiledCode map[uintptr]*compiledCode
|
structTypeToCompiledCode map[uintptr]*compiledCode
|
||||||
structTypeToCompiledIndentCode map[uintptr]*compiledCode
|
structTypeToCompiledIndentCode map[uintptr]*compiledCode
|
||||||
}
|
}
|
||||||
|
@ -123,7 +122,6 @@ func (e *Encoder) release() {
|
||||||
|
|
||||||
func (e *Encoder) reset() {
|
func (e *Encoder) reset() {
|
||||||
e.buf = e.buf[:0]
|
e.buf = e.buf[:0]
|
||||||
e.indent = 0
|
|
||||||
e.enabledHTMLEscape = true
|
e.enabledHTMLEscape = true
|
||||||
e.enabledIndent = false
|
e.enabledIndent = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,13 @@ func (e *Encoder) compileHead(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
typ := ctx.typ
|
typ := ctx.typ
|
||||||
switch {
|
switch {
|
||||||
case typ.Implements(marshalJSONType):
|
case typ.Implements(marshalJSONType):
|
||||||
return newOpCode(opMarshalJSON, typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opMarshalJSON), nil
|
||||||
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
||||||
return newOpCode(opMarshalJSON, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalJSON), nil
|
||||||
case typ.Implements(marshalTextType):
|
case typ.Implements(marshalTextType):
|
||||||
return newOpCode(opMarshalText, typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opMarshalText), nil
|
||||||
case rtype_ptrTo(typ).Implements(marshalTextType):
|
case rtype_ptrTo(typ).Implements(marshalTextType):
|
||||||
return newOpCode(opMarshalText, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalText), nil
|
||||||
}
|
}
|
||||||
isPtr := false
|
isPtr := false
|
||||||
if typ.Kind() == reflect.Ptr {
|
if typ.Kind() == reflect.Ptr {
|
||||||
|
@ -49,13 +49,13 @@ func (e *Encoder) compile(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
typ := ctx.typ
|
typ := ctx.typ
|
||||||
switch {
|
switch {
|
||||||
case typ.Implements(marshalJSONType):
|
case typ.Implements(marshalJSONType):
|
||||||
return newOpCode(opMarshalJSON, typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opMarshalJSON), nil
|
||||||
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
||||||
return newOpCode(opMarshalJSON, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalJSON), nil
|
||||||
case typ.Implements(marshalTextType):
|
case typ.Implements(marshalTextType):
|
||||||
return newOpCode(opMarshalText, typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opMarshalText), nil
|
||||||
case rtype_ptrTo(typ).Implements(marshalTextType):
|
case rtype_ptrTo(typ).Implements(marshalTextType):
|
||||||
return newOpCode(opMarshalText, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalText), nil
|
||||||
}
|
}
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
|
@ -112,13 +112,13 @@ func (e *Encoder) compileKey(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
typ := ctx.typ
|
typ := ctx.typ
|
||||||
switch {
|
switch {
|
||||||
case typ.Implements(marshalJSONType):
|
case typ.Implements(marshalJSONType):
|
||||||
return newOpCode(opMarshalJSON, typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opMarshalJSON), nil
|
||||||
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
||||||
return newOpCode(opMarshalJSON, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalJSON), nil
|
||||||
case typ.Implements(marshalTextType):
|
case typ.Implements(marshalTextType):
|
||||||
return newOpCode(opMarshalText, typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opMarshalText), nil
|
||||||
case rtype_ptrTo(typ).Implements(marshalTextType):
|
case rtype_ptrTo(typ).Implements(marshalTextType):
|
||||||
return newOpCode(opMarshalText, rtype_ptrTo(typ), e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalText), nil
|
||||||
}
|
}
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
|
@ -132,13 +132,12 @@ func (e *Encoder) compileKey(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) optimizeStructFieldPtrHead(ctx *encodeCompileContext, code *opcode) *opcode {
|
func (e *Encoder) optimizeStructFieldPtrHead(ctx *encodeCompileContext, code *opcode) *opcode {
|
||||||
typ := ctx.typ
|
|
||||||
ptrHeadOp := code.op.headToPtrHead()
|
ptrHeadOp := code.op.headToPtrHead()
|
||||||
if code.op != ptrHeadOp {
|
if code.op != ptrHeadOp {
|
||||||
code.op = ptrHeadOp
|
code.op = ptrHeadOp
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
return newOpCode(opPtr, typ, e.indent, code)
|
return newOpCodeWithNext(ctx, opPtr, code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compilePtr(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compilePtr(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
|
@ -150,63 +149,63 @@ func (e *Encoder) compilePtr(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opInt, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opInt), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt8(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt8(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opInt8, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opInt8), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt16(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt16(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opInt16, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opInt16), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt32(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt32(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opInt32, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opInt32), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt64(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt64(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opInt64, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opInt64), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opUint, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opUint), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint8(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint8(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opUint8, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opUint8), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint16(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint16(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opUint16, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opUint16), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint32(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint32(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opUint32, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opUint32), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint64(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint64(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opUint64, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opUint64), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileFloat32(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileFloat32(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opFloat32, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opFloat32), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileFloat64(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileFloat64(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opFloat64, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opFloat64), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileString(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileString(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opString, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opString), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileBool(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileBool(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opBool, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opBool), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileBytes(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileBytes(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(opBytes, ctx.typ, e.indent, newEndOp(e.indent)), nil
|
return newOpCode(ctx, opBytes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInterface(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInterface(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
|
@ -214,8 +213,8 @@ func (e *Encoder) compileInterface(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opInterface,
|
op: opInterface,
|
||||||
typ: ctx.typ,
|
typ: ctx.typ,
|
||||||
indent: e.indent,
|
indent: ctx.indent,
|
||||||
next: newEndOp(e.indent),
|
next: newEndOp(ctx),
|
||||||
},
|
},
|
||||||
root: ctx.root,
|
root: ctx.root,
|
||||||
})), nil
|
})), nil
|
||||||
|
@ -226,10 +225,7 @@ func (e *Encoder) compileSlice(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
elem := ctx.typ.Elem()
|
elem := ctx.typ.Elem()
|
||||||
size := elem.Size()
|
size := elem.Size()
|
||||||
|
|
||||||
e.indent++
|
code, err := e.compile(ctx.withType(ctx.typ.Elem()).incIndent())
|
||||||
code, err := e.compile(ctx.withType(ctx.typ.Elem()))
|
|
||||||
e.indent--
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -238,15 +234,15 @@ func (e *Encoder) compileSlice(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
// ^ |
|
// ^ |
|
||||||
// |________|
|
// |________|
|
||||||
|
|
||||||
header := newSliceHeaderCode(e.indent)
|
header := newSliceHeaderCode(ctx.indent)
|
||||||
elemCode := &sliceElemCode{
|
elemCode := &sliceElemCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opSliceElem,
|
op: opSliceElem,
|
||||||
indent: e.indent,
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
size: size,
|
size: size,
|
||||||
}
|
}
|
||||||
end := newOpCode(opSliceEnd, nil, e.indent, newEndOp(e.indent))
|
end := newOpCode(ctx, opSliceEnd)
|
||||||
if ctx.withIndent {
|
if ctx.withIndent {
|
||||||
if ctx.root {
|
if ctx.root {
|
||||||
header.op = opRootSliceHeadIndent
|
header.op = opRootSliceHeadIndent
|
||||||
|
@ -274,10 +270,7 @@ func (e *Encoder) compileArray(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
alen := typ.Len()
|
alen := typ.Len()
|
||||||
size := elem.Size()
|
size := elem.Size()
|
||||||
|
|
||||||
e.indent++
|
code, err := e.compile(ctx.withType(elem).incIndent())
|
||||||
code, err := e.compile(ctx.withType(elem))
|
|
||||||
e.indent--
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -285,7 +278,7 @@ func (e *Encoder) compileArray(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
// ^ |
|
// ^ |
|
||||||
// |________|
|
// |________|
|
||||||
|
|
||||||
header := newArrayHeaderCode(e.indent, alen)
|
header := newArrayHeaderCode(ctx.indent, alen)
|
||||||
elemCode := &arrayElemCode{
|
elemCode := &arrayElemCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opArrayElem,
|
op: opArrayElem,
|
||||||
|
@ -293,7 +286,7 @@ func (e *Encoder) compileArray(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
len: uintptr(alen),
|
len: uintptr(alen),
|
||||||
size: size,
|
size: size,
|
||||||
}
|
}
|
||||||
end := newOpCode(opArrayEnd, nil, e.indent, newEndOp(e.indent))
|
end := newOpCode(ctx, opArrayEnd)
|
||||||
|
|
||||||
if ctx.withIndent {
|
if ctx.withIndent {
|
||||||
header.op = opArrayHeadIndent
|
header.op = opArrayHeadIndent
|
||||||
|
@ -330,7 +323,7 @@ func (e *Encoder) compileMap(ctx *encodeCompileContext, withLoad bool) (*opcode,
|
||||||
// header => code => value => code => key => code => value => code => end
|
// header => code => value => code => key => code => value => code => end
|
||||||
// ^ |
|
// ^ |
|
||||||
// |_______________________|
|
// |_______________________|
|
||||||
e.indent++
|
ctx = ctx.incIndent()
|
||||||
typ := ctx.typ
|
typ := ctx.typ
|
||||||
keyType := ctx.typ.Key()
|
keyType := ctx.typ.Key()
|
||||||
keyCode, err := e.compileKey(ctx.withType(keyType))
|
keyCode, err := e.compileKey(ctx.withType(keyType))
|
||||||
|
@ -343,15 +336,15 @@ func (e *Encoder) compileMap(ctx *encodeCompileContext, withLoad bool) (*opcode,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
key := newMapKeyCode(e.indent)
|
key := newMapKeyCode(ctx.indent)
|
||||||
value := newMapValueCode(e.indent)
|
value := newMapValueCode(ctx.indent)
|
||||||
|
|
||||||
e.indent--
|
ctx = ctx.decIndent()
|
||||||
|
|
||||||
header := newMapHeaderCode(typ, withLoad, e.indent)
|
header := newMapHeaderCode(typ, withLoad, ctx.indent)
|
||||||
header.key = key
|
header.key = key
|
||||||
header.value = value
|
header.value = value
|
||||||
end := newOpCode(opMapEnd, nil, e.indent, newEndOp(e.indent))
|
end := newOpCode(ctx, opMapEnd)
|
||||||
|
|
||||||
if ctx.withIndent {
|
if ctx.withIndent {
|
||||||
if header.op == opMapHead {
|
if header.op == opMapHead {
|
||||||
|
@ -533,8 +526,8 @@ func (e *Encoder) recursiveCode(ctx *encodeCompileContext, code *compiledCode) *
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opStructFieldRecursive,
|
op: opStructFieldRecursive,
|
||||||
typ: ctx.typ,
|
typ: ctx.typ,
|
||||||
indent: e.indent,
|
indent: ctx.indent,
|
||||||
next: newEndOp(e.indent),
|
next: newEndOp(ctx),
|
||||||
},
|
},
|
||||||
jmp: code,
|
jmp: code,
|
||||||
}))
|
}))
|
||||||
|
@ -793,7 +786,7 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
code *opcode
|
code *opcode
|
||||||
prevField *structFieldCode
|
prevField *structFieldCode
|
||||||
)
|
)
|
||||||
e.indent++
|
ctx = ctx.incIndent()
|
||||||
tags := structTags{}
|
tags := structTags{}
|
||||||
anonymousFields := map[string][]structFieldPair{}
|
anonymousFields := map[string][]structFieldPair{}
|
||||||
for i := 0; i < fieldNum; i++ {
|
for i := 0; i < fieldNum; i++ {
|
||||||
|
@ -839,7 +832,7 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
typ: valueCode.typ,
|
typ: valueCode.typ,
|
||||||
next: valueCode,
|
next: valueCode,
|
||||||
indent: e.indent,
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
anonymousKey: field.Anonymous,
|
anonymousKey: field.Anonymous,
|
||||||
key: []byte(key),
|
key: []byte(key),
|
||||||
|
@ -860,16 +853,16 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
}
|
}
|
||||||
fieldIdx++
|
fieldIdx++
|
||||||
}
|
}
|
||||||
e.indent--
|
ctx = ctx.decIndent()
|
||||||
|
|
||||||
structEndCode := (*opcode)(unsafe.Pointer(&structFieldCode{
|
structEndCode := (*opcode)(unsafe.Pointer(&structFieldCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opStructEnd,
|
op: opStructEnd,
|
||||||
typ: nil,
|
typ: nil,
|
||||||
indent: e.indent,
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
structEndCode.next = newEndOp(e.indent)
|
structEndCode.next = newEndOp(ctx)
|
||||||
if ctx.withIndent {
|
if ctx.withIndent {
|
||||||
structEndCode.op = opStructEndIndent
|
structEndCode.op = opStructEndIndent
|
||||||
}
|
}
|
||||||
|
@ -884,7 +877,7 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opStructFieldHead,
|
op: opStructFieldHead,
|
||||||
typ: typ,
|
typ: typ,
|
||||||
indent: e.indent,
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
nextField: structEndCode,
|
nextField: structEndCode,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
type encodeCompileContext struct {
|
||||||
|
typ *rtype
|
||||||
|
withIndent bool
|
||||||
|
root bool
|
||||||
|
opcodeIndex int
|
||||||
|
indent int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *encodeCompileContext) context() *encodeCompileContext {
|
||||||
|
return &encodeCompileContext{
|
||||||
|
typ: c.typ,
|
||||||
|
withIndent: c.withIndent,
|
||||||
|
root: c.root,
|
||||||
|
opcodeIndex: c.opcodeIndex,
|
||||||
|
indent: c.indent,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *encodeCompileContext) withType(typ *rtype) *encodeCompileContext {
|
||||||
|
ctx := c.context()
|
||||||
|
ctx.typ = typ
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *encodeCompileContext) incIndent() *encodeCompileContext {
|
||||||
|
ctx := c.context()
|
||||||
|
ctx.indent++
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *encodeCompileContext) decIndent() *encodeCompileContext {
|
||||||
|
ctx := c.context()
|
||||||
|
ctx.indent--
|
||||||
|
return ctx
|
||||||
|
}
|
|
@ -34,19 +34,30 @@ type opcode struct {
|
||||||
*opcodeHeader
|
*opcodeHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOpCode(op opType, typ *rtype, indent int, next *opcode) *opcode {
|
func newOpCode(ctx *encodeCompileContext, op opType) *opcode {
|
||||||
return &opcode{
|
return &opcode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: op,
|
op: op,
|
||||||
typ: typ,
|
typ: ctx.typ,
|
||||||
indent: indent,
|
indent: ctx.indent,
|
||||||
|
next: newEndOp(ctx),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode {
|
||||||
|
return &opcode{
|
||||||
|
opcodeHeader: &opcodeHeader{
|
||||||
|
op: op,
|
||||||
|
typ: ctx.typ,
|
||||||
|
indent: ctx.indent,
|
||||||
next: next,
|
next: next,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newEndOp(indent int) *opcode {
|
func newEndOp(ctx *encodeCompileContext) *opcode {
|
||||||
return newOpCode(opEnd, nil, indent, nil)
|
return newOpCodeWithNext(ctx, opEnd, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *opcode) beforeLastCode() *opcode {
|
func (c *opcode) beforeLastCode() *opcode {
|
||||||
|
@ -547,7 +558,7 @@ func (c *recursiveCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
func newRecursiveCode(recursive *recursiveCode) *opcode {
|
func newRecursiveCode(recursive *recursiveCode) *opcode {
|
||||||
code := copyOpcode(recursive.jmp.code)
|
code := copyOpcode(recursive.jmp.code)
|
||||||
head := (*structFieldCode)(unsafe.Pointer(code))
|
head := (*structFieldCode)(unsafe.Pointer(code))
|
||||||
head.end.next = newEndOp(0)
|
head.end.next = newEndOp(&encodeCompileContext{})
|
||||||
code.ptr = recursive.ptr
|
code.ptr = recursive.ptr
|
||||||
|
|
||||||
code.op = code.op.ptrHeadToHead()
|
code.op = code.op.ptrHeadToHead()
|
||||||
|
|
|
@ -109,13 +109,13 @@ func (e *Encoder) run(code *opcode) error {
|
||||||
if typ.Kind() == reflect.Ptr {
|
if typ.Kind() == reflect.Ptr {
|
||||||
typ = typ.Elem()
|
typ = typ.Elem()
|
||||||
}
|
}
|
||||||
e.indent = ifaceCode.indent
|
|
||||||
var c *opcode
|
var c *opcode
|
||||||
if typ.Kind() == reflect.Map {
|
if typ.Kind() == reflect.Map {
|
||||||
code, err := e.compileMap(&encodeCompileContext{
|
code, err := e.compileMap(&encodeCompileContext{
|
||||||
typ: typ,
|
typ: typ,
|
||||||
root: ifaceCode.root,
|
root: ifaceCode.root,
|
||||||
withIndent: e.enabledIndent,
|
withIndent: e.enabledIndent,
|
||||||
|
indent: ifaceCode.indent,
|
||||||
}, false)
|
}, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -126,6 +126,7 @@ func (e *Encoder) run(code *opcode) error {
|
||||||
typ: typ,
|
typ: typ,
|
||||||
root: ifaceCode.root,
|
root: ifaceCode.root,
|
||||||
withIndent: e.enabledIndent,
|
withIndent: e.enabledIndent,
|
||||||
|
indent: ifaceCode.indent,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in New Issue