forked from mirror/go-json
Add opcodeIndex to opcode
This commit is contained in:
parent
e508ad41ba
commit
a9e2386e42
|
@ -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(ctx, opMarshalJSON), nil
|
return e.compileMarshalJSON(ctx)
|
||||||
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
||||||
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalJSON), nil
|
return e.compileMarshalJSONPtr(ctx)
|
||||||
case typ.Implements(marshalTextType):
|
case typ.Implements(marshalTextType):
|
||||||
return newOpCode(ctx, opMarshalText), nil
|
return e.compileMarshalText(ctx)
|
||||||
case rtype_ptrTo(typ).Implements(marshalTextType):
|
case rtype_ptrTo(typ).Implements(marshalTextType):
|
||||||
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalText), nil
|
return e.compileMarshalTextPtr(ctx)
|
||||||
}
|
}
|
||||||
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(ctx, opMarshalJSON), nil
|
return e.compileMarshalJSON(ctx)
|
||||||
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
||||||
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalJSON), nil
|
return e.compileMarshalJSONPtr(ctx)
|
||||||
case typ.Implements(marshalTextType):
|
case typ.Implements(marshalTextType):
|
||||||
return newOpCode(ctx, opMarshalText), nil
|
return e.compileMarshalText(ctx)
|
||||||
case rtype_ptrTo(typ).Implements(marshalTextType):
|
case rtype_ptrTo(typ).Implements(marshalTextType):
|
||||||
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalText), nil
|
return e.compileMarshalTextPtr(ctx)
|
||||||
}
|
}
|
||||||
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(ctx, opMarshalJSON), nil
|
return e.compileMarshalJSON(ctx)
|
||||||
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
case rtype_ptrTo(typ).Implements(marshalJSONType):
|
||||||
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalJSON), nil
|
return e.compileMarshalJSONPtr(ctx)
|
||||||
case typ.Implements(marshalTextType):
|
case typ.Implements(marshalTextType):
|
||||||
return newOpCode(ctx, opMarshalText), nil
|
return e.compileMarshalText(ctx)
|
||||||
case rtype_ptrTo(typ).Implements(marshalTextType):
|
case rtype_ptrTo(typ).Implements(marshalTextType):
|
||||||
return newOpCode(ctx.withType(rtype_ptrTo(typ)), opMarshalText), nil
|
return e.compileMarshalTextPtr(ctx)
|
||||||
}
|
}
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
|
@ -131,93 +131,152 @@ func (e *Encoder) compileKey(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return nil, &UnsupportedTypeError{Type: rtype2type(typ)}
|
return nil, &UnsupportedTypeError{Type: rtype2type(typ)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) optimizeStructFieldPtrHead(ctx *encodeCompileContext, code *opcode) *opcode {
|
|
||||||
ptrHeadOp := code.op.headToPtrHead()
|
|
||||||
if code.op != ptrHeadOp {
|
|
||||||
code.op = ptrHeadOp
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
return newOpCodeWithNext(ctx, opPtr, code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Encoder) compilePtr(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compilePtr(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
|
ptrOpcodeIndex := ctx.opcodeIndex
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
code, err := e.compile(ctx.withType(ctx.typ.Elem()))
|
code, err := e.compile(ctx.withType(ctx.typ.Elem()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return e.optimizeStructFieldPtrHead(ctx, code), nil
|
ptrHeadOp := code.op.headToPtrHead()
|
||||||
|
if code.op != ptrHeadOp {
|
||||||
|
code.op = ptrHeadOp
|
||||||
|
code.decOpcodeIndex()
|
||||||
|
ctx.decOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
|
}
|
||||||
|
c := ctx.context()
|
||||||
|
c.opcodeIndex = ptrOpcodeIndex
|
||||||
|
return newOpCodeWithNext(c, opPtr, code), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) compileMarshalJSON(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
|
code := newOpCode(ctx, opMarshalJSON)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) compileMarshalJSONPtr(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
|
code := newOpCode(ctx.withType(rtype_ptrTo(ctx.typ)), opMarshalJSON)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) compileMarshalText(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
|
code := newOpCode(ctx, opMarshalText)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) compileMarshalTextPtr(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
|
code := newOpCode(ctx.withType(rtype_ptrTo(ctx.typ)), opMarshalText)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opInt), nil
|
code := newOpCode(ctx, opInt)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt8(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt8(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opInt8), nil
|
code := newOpCode(ctx, opInt8)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt16(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt16(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opInt16), nil
|
code := newOpCode(ctx, opInt16)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt32(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt32(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opInt32), nil
|
code := newOpCode(ctx, opInt32)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt64(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInt64(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opInt64), nil
|
code := newOpCode(ctx, opInt64)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opUint), nil
|
code := newOpCode(ctx, opUint)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint8(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint8(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opUint8), nil
|
code := newOpCode(ctx, opUint8)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint16(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint16(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opUint16), nil
|
code := newOpCode(ctx, opUint16)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint32(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint32(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opUint32), nil
|
code := newOpCode(ctx, opUint32)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileUint64(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileUint64(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opUint64), nil
|
code := newOpCode(ctx, opUint64)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileFloat32(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileFloat32(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opFloat32), nil
|
code := newOpCode(ctx, opFloat32)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileFloat64(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileFloat64(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opFloat64), nil
|
code := newOpCode(ctx, opFloat64)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileString(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileString(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opString), nil
|
code := newOpCode(ctx, opString)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileBool(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileBool(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opBool), nil
|
code := newOpCode(ctx, opBool)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileBytes(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileBytes(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return newOpCode(ctx, opBytes), nil
|
code := newOpCode(ctx, opBytes)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInterface(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileInterface(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
return (*opcode)(unsafe.Pointer(&interfaceCode{
|
code := (*opcode)(unsafe.Pointer(&interfaceCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opInterface,
|
op: opInterface,
|
||||||
typ: ctx.typ,
|
typ: ctx.typ,
|
||||||
|
idx: ctx.opcodeIndex,
|
||||||
indent: ctx.indent,
|
indent: ctx.indent,
|
||||||
next: newEndOp(ctx),
|
next: newEndOp(ctx),
|
||||||
},
|
},
|
||||||
root: ctx.root,
|
root: ctx.root,
|
||||||
})), nil
|
}))
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileSlice(ctx *encodeCompileContext) (*opcode, error) {
|
func (e *Encoder) compileSlice(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
|
@ -225,6 +284,9 @@ func (e *Encoder) compileSlice(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
elem := ctx.typ.Elem()
|
elem := ctx.typ.Elem()
|
||||||
size := elem.Size()
|
size := elem.Size()
|
||||||
|
|
||||||
|
header := newSliceHeaderCode(ctx)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
|
||||||
code, err := e.compile(ctx.withType(ctx.typ.Elem()).incIndent())
|
code, err := e.compile(ctx.withType(ctx.typ.Elem()).incIndent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -234,15 +296,11 @@ func (e *Encoder) compileSlice(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
// ^ |
|
// ^ |
|
||||||
// |________|
|
// |________|
|
||||||
|
|
||||||
header := newSliceHeaderCode(ctx.indent)
|
elemCode := newSliceElemCode(ctx, size)
|
||||||
elemCode := &sliceElemCode{
|
ctx.incOpcodeIndex()
|
||||||
opcodeHeader: &opcodeHeader{
|
|
||||||
op: opSliceElem,
|
|
||||||
indent: ctx.indent,
|
|
||||||
},
|
|
||||||
size: size,
|
|
||||||
}
|
|
||||||
end := newOpCode(ctx, opSliceEnd)
|
end := newOpCode(ctx, opSliceEnd)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
if ctx.withIndent {
|
if ctx.withIndent {
|
||||||
if ctx.root {
|
if ctx.root {
|
||||||
header.op = opRootSliceHeadIndent
|
header.op = opRootSliceHeadIndent
|
||||||
|
@ -270,6 +328,9 @@ func (e *Encoder) compileArray(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
alen := typ.Len()
|
alen := typ.Len()
|
||||||
size := elem.Size()
|
size := elem.Size()
|
||||||
|
|
||||||
|
header := newArrayHeaderCode(ctx, alen)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
|
||||||
code, err := e.compile(ctx.withType(elem).incIndent())
|
code, err := e.compile(ctx.withType(elem).incIndent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -278,15 +339,11 @@ func (e *Encoder) compileArray(ctx *encodeCompileContext) (*opcode, error) {
|
||||||
// ^ |
|
// ^ |
|
||||||
// |________|
|
// |________|
|
||||||
|
|
||||||
header := newArrayHeaderCode(ctx.indent, alen)
|
elemCode := newArrayElemCode(ctx, alen, size)
|
||||||
elemCode := &arrayElemCode{
|
ctx.incOpcodeIndex()
|
||||||
opcodeHeader: &opcodeHeader{
|
|
||||||
op: opArrayElem,
|
|
||||||
},
|
|
||||||
len: uintptr(alen),
|
|
||||||
size: size,
|
|
||||||
}
|
|
||||||
end := newOpCode(ctx, opArrayEnd)
|
end := newOpCode(ctx, opArrayEnd)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
|
||||||
if ctx.withIndent {
|
if ctx.withIndent {
|
||||||
header.op = opArrayHeadIndent
|
header.op = opArrayHeadIndent
|
||||||
|
@ -324,27 +381,34 @@ func (e *Encoder) compileMap(ctx *encodeCompileContext, withLoad bool) (*opcode,
|
||||||
// ^ |
|
// ^ |
|
||||||
// |_______________________|
|
// |_______________________|
|
||||||
ctx = ctx.incIndent()
|
ctx = ctx.incIndent()
|
||||||
|
header := newMapHeaderCode(ctx, withLoad)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
|
||||||
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))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value := newMapValueCode(ctx)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
|
||||||
valueType := typ.Elem()
|
valueType := typ.Elem()
|
||||||
valueCode, err := e.compile(ctx.withType(valueType))
|
valueCode, err := e.compile(ctx.withType(valueType))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
key := newMapKeyCode(ctx.indent)
|
key := newMapKeyCode(ctx)
|
||||||
value := newMapValueCode(ctx.indent)
|
ctx.incOpcodeIndex()
|
||||||
|
|
||||||
ctx = ctx.decIndent()
|
ctx = ctx.decIndent()
|
||||||
|
|
||||||
header := newMapHeaderCode(typ, withLoad, ctx.indent)
|
|
||||||
header.key = key
|
header.key = key
|
||||||
header.value = value
|
header.value = value
|
||||||
end := newOpCode(ctx, opMapEnd)
|
end := newOpCode(ctx, opMapEnd)
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
|
||||||
if ctx.withIndent {
|
if ctx.withIndent {
|
||||||
if header.op == opMapHead {
|
if header.op == opMapHead {
|
||||||
|
@ -522,15 +586,18 @@ func (e *Encoder) optimizeStructField(op opType, tag *structTag, withIndent bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) recursiveCode(ctx *encodeCompileContext, code *compiledCode) *opcode {
|
func (e *Encoder) recursiveCode(ctx *encodeCompileContext, code *compiledCode) *opcode {
|
||||||
return (*opcode)(unsafe.Pointer(&recursiveCode{
|
c := (*opcode)(unsafe.Pointer(&recursiveCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opStructFieldRecursive,
|
op: opStructFieldRecursive,
|
||||||
typ: ctx.typ,
|
typ: ctx.typ,
|
||||||
|
idx: ctx.opcodeIndex,
|
||||||
indent: ctx.indent,
|
indent: ctx.indent,
|
||||||
next: newEndOp(ctx),
|
next: newEndOp(ctx),
|
||||||
},
|
},
|
||||||
jmp: code,
|
jmp: code,
|
||||||
}))
|
}))
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) compiledCode(ctx *encodeCompileContext) *opcode {
|
func (e *Encoder) compiledCode(ctx *encodeCompileContext) *opcode {
|
||||||
|
@ -548,9 +615,9 @@ func (e *Encoder) compiledCode(ctx *encodeCompileContext) *opcode {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, tag *structTag, withIndent bool) *opcode {
|
func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *structFieldCode, valueCode *opcode, tag *structTag) *opcode {
|
||||||
fieldCode.indent--
|
fieldCode.indent--
|
||||||
op := e.optimizeStructHeader(valueCode.op, tag, withIndent)
|
op := e.optimizeStructHeader(valueCode.op, tag, ctx.withIndent)
|
||||||
fieldCode.op = op
|
fieldCode.op = op
|
||||||
switch op {
|
switch op {
|
||||||
case opStructFieldHead,
|
case opStructFieldHead,
|
||||||
|
@ -581,12 +648,13 @@ func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, ta
|
||||||
opStructFieldHeadStringTagIndent:
|
opStructFieldHeadStringTagIndent:
|
||||||
return valueCode.beforeLastCode()
|
return valueCode.beforeLastCode()
|
||||||
}
|
}
|
||||||
|
ctx.decOpcodeIndex()
|
||||||
return (*opcode)(unsafe.Pointer(fieldCode))
|
return (*opcode)(unsafe.Pointer(fieldCode))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) structField(fieldCode *structFieldCode, valueCode *opcode, tag *structTag, withIndent bool) *opcode {
|
func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *structFieldCode, valueCode *opcode, tag *structTag) *opcode {
|
||||||
code := (*opcode)(unsafe.Pointer(fieldCode))
|
code := (*opcode)(unsafe.Pointer(fieldCode))
|
||||||
op := e.optimizeStructField(valueCode.op, tag, withIndent)
|
op := e.optimizeStructField(valueCode.op, tag, ctx.withIndent)
|
||||||
fieldCode.op = op
|
fieldCode.op = op
|
||||||
switch op {
|
switch op {
|
||||||
case opStructField,
|
case opStructField,
|
||||||
|
@ -617,6 +685,7 @@ func (e *Encoder) structField(fieldCode *structFieldCode, valueCode *opcode, tag
|
||||||
opStructFieldStringTagIndent:
|
opStructFieldStringTagIndent:
|
||||||
return valueCode.beforeLastCode()
|
return valueCode.beforeLastCode()
|
||||||
}
|
}
|
||||||
|
ctx.decOpcodeIndex()
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,6 +726,10 @@ func (e *Encoder) optimizeAnonymousFields(head *structFieldCode) {
|
||||||
if codeType == codeStructField {
|
if codeType == codeStructField {
|
||||||
if e.isNotExistsField(code.next.toStructFieldCode()) {
|
if e.isNotExistsField(code.next.toStructFieldCode()) {
|
||||||
code.next = code.nextField
|
code.next = code.nextField
|
||||||
|
diff := code.next.idx - code.idx
|
||||||
|
for i := 0; i < diff; i++ {
|
||||||
|
code.next.decOpcodeIndex()
|
||||||
|
}
|
||||||
linkPrevToNextField(prev, code)
|
linkPrevToNextField(prev, code)
|
||||||
code = prev
|
code = prev
|
||||||
}
|
}
|
||||||
|
@ -690,6 +763,10 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, value
|
||||||
} else if f.op == opStructEnd {
|
} else if f.op == opStructEnd {
|
||||||
f.op = opStructAnonymousEnd
|
f.op = opStructAnonymousEnd
|
||||||
} else if existsKey {
|
} else if existsKey {
|
||||||
|
diff := f.nextField.idx - f.idx
|
||||||
|
for i := 0; i < diff; i++ {
|
||||||
|
f.nextField.decOpcodeIndex()
|
||||||
|
}
|
||||||
linkPrevToNextField(prevAnonymousField, f)
|
linkPrevToNextField(prevAnonymousField, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,6 +814,10 @@ func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]s
|
||||||
// head operation
|
// head operation
|
||||||
fieldPair.curField.op = opStructFieldAnonymousHead
|
fieldPair.curField.op = opStructFieldAnonymousHead
|
||||||
} else {
|
} else {
|
||||||
|
diff := fieldPair.curField.nextField.idx - fieldPair.curField.idx
|
||||||
|
for i := 0; i < diff; i++ {
|
||||||
|
fieldPair.curField.nextField.decOpcodeIndex()
|
||||||
|
}
|
||||||
linkPrevToNextField(fieldPair.prevField, fieldPair.curField)
|
linkPrevToNextField(fieldPair.prevField, fieldPair.curField)
|
||||||
}
|
}
|
||||||
fieldPair.linked = true
|
fieldPair.linked = true
|
||||||
|
@ -750,6 +831,10 @@ func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]s
|
||||||
// head operation
|
// head operation
|
||||||
fieldPair.curField.op = opStructFieldAnonymousHead
|
fieldPair.curField.op = opStructFieldAnonymousHead
|
||||||
} else {
|
} else {
|
||||||
|
diff := fieldPair.curField.nextField.idx - fieldPair.curField.idx
|
||||||
|
for i := 0; i < diff; i++ {
|
||||||
|
fieldPair.curField.nextField.decOpcodeIndex()
|
||||||
|
}
|
||||||
linkPrevToNextField(fieldPair.prevField, fieldPair.curField)
|
linkPrevToNextField(fieldPair.prevField, fieldPair.curField)
|
||||||
}
|
}
|
||||||
fieldPair.linked = true
|
fieldPair.linked = true
|
||||||
|
@ -808,10 +893,13 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
fieldType = rtype_ptrTo(fieldType)
|
fieldType = rtype_ptrTo(fieldType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fieldOpcodeIndex := ctx.opcodeIndex
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
valueCode, err := e.compile(ctx.withType(fieldType))
|
valueCode, err := e.compile(ctx.withType(fieldType))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if field.Anonymous {
|
if field.Anonymous {
|
||||||
for k, v := range e.anonymousStructFieldPairMap(typ, tags, valueCode.toStructFieldCode()) {
|
for k, v := range e.anonymousStructFieldPairMap(typ, tags, valueCode.toStructFieldCode()) {
|
||||||
anonymousFields[k] = append(anonymousFields[k], v...)
|
anonymousFields[k] = append(anonymousFields[k], v...)
|
||||||
|
@ -825,12 +913,14 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
opUint, opUint8, opUint16, opUint32, opUint64,
|
opUint, opUint8, opUint16, opUint32, opUint64,
|
||||||
opFloat32, opFloat64, opBool, opString, opBytes:
|
opFloat32, opFloat64, opBool, opString, opBytes:
|
||||||
valueCode = valueCode.next
|
valueCode = valueCode.next
|
||||||
|
ctx.decOpcodeIndex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key := fmt.Sprintf(`"%s":`, tag.key)
|
key := fmt.Sprintf(`"%s":`, tag.key)
|
||||||
fieldCode := &structFieldCode{
|
fieldCode := &structFieldCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
typ: valueCode.typ,
|
typ: valueCode.typ,
|
||||||
|
idx: fieldOpcodeIndex,
|
||||||
next: valueCode,
|
next: valueCode,
|
||||||
indent: ctx.indent,
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
|
@ -841,13 +931,13 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
offset: field.Offset,
|
offset: field.Offset,
|
||||||
}
|
}
|
||||||
if fieldIdx == 0 {
|
if fieldIdx == 0 {
|
||||||
code = e.structHeader(fieldCode, valueCode, tag, ctx.withIndent)
|
code = e.structHeader(ctx, fieldCode, valueCode, tag)
|
||||||
head = fieldCode
|
head = fieldCode
|
||||||
prevField = fieldCode
|
prevField = fieldCode
|
||||||
} else {
|
} else {
|
||||||
fcode := (*opcode)(unsafe.Pointer(fieldCode))
|
fcode := (*opcode)(unsafe.Pointer(fieldCode))
|
||||||
code.next = fcode
|
code.next = fcode
|
||||||
code = e.structField(fieldCode, valueCode, tag, ctx.withIndent)
|
code = e.structField(ctx, fieldCode, valueCode, tag)
|
||||||
prevField.nextField = fcode
|
prevField.nextField = fcode
|
||||||
prevField = fieldCode
|
prevField = fieldCode
|
||||||
}
|
}
|
||||||
|
@ -860,9 +950,31 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
op: opStructEnd,
|
op: opStructEnd,
|
||||||
typ: nil,
|
typ: nil,
|
||||||
indent: ctx.indent,
|
indent: ctx.indent,
|
||||||
|
next: newEndOp(ctx),
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
structEndCode.next = newEndOp(ctx)
|
|
||||||
|
// no struct field
|
||||||
|
if head == nil {
|
||||||
|
head = &structFieldCode{
|
||||||
|
opcodeHeader: &opcodeHeader{
|
||||||
|
op: opStructFieldHead,
|
||||||
|
typ: typ,
|
||||||
|
idx: ctx.opcodeIndex,
|
||||||
|
indent: ctx.indent,
|
||||||
|
},
|
||||||
|
nextField: structEndCode,
|
||||||
|
}
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
if ctx.withIndent {
|
||||||
|
head.op = opStructFieldHeadIndent
|
||||||
|
}
|
||||||
|
code = (*opcode)(unsafe.Pointer(head))
|
||||||
|
}
|
||||||
|
|
||||||
|
structEndCode.idx = ctx.opcodeIndex
|
||||||
|
ctx.incOpcodeIndex()
|
||||||
|
|
||||||
if ctx.withIndent {
|
if ctx.withIndent {
|
||||||
structEndCode.op = opStructEndIndent
|
structEndCode.op = opStructEndIndent
|
||||||
}
|
}
|
||||||
|
@ -871,21 +983,6 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
prevField.nextField = structEndCode
|
prevField.nextField = structEndCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// no struct field
|
|
||||||
if head == nil {
|
|
||||||
head = &structFieldCode{
|
|
||||||
opcodeHeader: &opcodeHeader{
|
|
||||||
op: opStructFieldHead,
|
|
||||||
typ: typ,
|
|
||||||
indent: ctx.indent,
|
|
||||||
},
|
|
||||||
nextField: structEndCode,
|
|
||||||
}
|
|
||||||
if ctx.withIndent {
|
|
||||||
head.op = opStructFieldHeadIndent
|
|
||||||
}
|
|
||||||
code = (*opcode)(unsafe.Pointer(head))
|
|
||||||
}
|
|
||||||
head.end = structEndCode
|
head.end = structEndCode
|
||||||
code.next = structEndCode
|
code.next = structEndCode
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ type encodeCompileContext struct {
|
||||||
root bool
|
root bool
|
||||||
opcodeIndex int
|
opcodeIndex int
|
||||||
indent int
|
indent int
|
||||||
|
|
||||||
|
parent *encodeCompileContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *encodeCompileContext) context() *encodeCompileContext {
|
func (c *encodeCompileContext) context() *encodeCompileContext {
|
||||||
|
@ -15,6 +17,7 @@ func (c *encodeCompileContext) context() *encodeCompileContext {
|
||||||
root: c.root,
|
root: c.root,
|
||||||
opcodeIndex: c.opcodeIndex,
|
opcodeIndex: c.opcodeIndex,
|
||||||
indent: c.indent,
|
indent: c.indent,
|
||||||
|
parent: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,3 +38,17 @@ func (c *encodeCompileContext) decIndent() *encodeCompileContext {
|
||||||
ctx.indent--
|
ctx.indent--
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *encodeCompileContext) incOpcodeIndex() {
|
||||||
|
c.opcodeIndex++
|
||||||
|
if c.parent != nil {
|
||||||
|
c.parent.incOpcodeIndex()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *encodeCompileContext) decOpcodeIndex() {
|
||||||
|
c.opcodeIndex--
|
||||||
|
if c.parent != nil {
|
||||||
|
c.parent.decOpcodeIndex()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ func copyOpcode(code *opcode) *opcode {
|
||||||
type opcodeHeader struct {
|
type opcodeHeader struct {
|
||||||
op opType
|
op opType
|
||||||
typ *rtype
|
typ *rtype
|
||||||
|
idx int
|
||||||
ptr uintptr
|
ptr uintptr
|
||||||
indent int
|
indent int
|
||||||
next *opcode
|
next *opcode
|
||||||
|
@ -24,6 +25,7 @@ func (h *opcodeHeader) copy(codeMap map[uintptr]*opcode) *opcodeHeader {
|
||||||
return &opcodeHeader{
|
return &opcodeHeader{
|
||||||
op: h.op,
|
op: h.op,
|
||||||
typ: h.typ,
|
typ: h.typ,
|
||||||
|
idx: h.idx,
|
||||||
ptr: h.ptr,
|
ptr: h.ptr,
|
||||||
indent: h.indent,
|
indent: h.indent,
|
||||||
next: h.next.copy(codeMap),
|
next: h.next.copy(codeMap),
|
||||||
|
@ -35,14 +37,7 @@ type opcode struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOpCode(ctx *encodeCompileContext, op opType) *opcode {
|
func newOpCode(ctx *encodeCompileContext, op opType) *opcode {
|
||||||
return &opcode{
|
return newOpCodeWithNext(ctx, op, newEndOp(ctx))
|
||||||
opcodeHeader: &opcodeHeader{
|
|
||||||
op: op,
|
|
||||||
typ: ctx.typ,
|
|
||||||
indent: ctx.indent,
|
|
||||||
next: newEndOp(ctx),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode {
|
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode {
|
||||||
|
@ -50,6 +45,7 @@ func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opco
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: op,
|
op: op,
|
||||||
typ: ctx.typ,
|
typ: ctx.typ,
|
||||||
|
idx: ctx.opcodeIndex,
|
||||||
indent: ctx.indent,
|
indent: ctx.indent,
|
||||||
next: next,
|
next: next,
|
||||||
},
|
},
|
||||||
|
@ -82,6 +78,22 @@ func (c *opcode) beforeLastCode() *opcode {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *opcode) decOpcodeIndex() {
|
||||||
|
for code := c; code.op != opEnd; {
|
||||||
|
code.idx--
|
||||||
|
switch code.op.codeType() {
|
||||||
|
case codeArrayElem:
|
||||||
|
code = code.toArrayElemCode().end
|
||||||
|
case codeSliceElem:
|
||||||
|
code = code.toSliceElemCode().end
|
||||||
|
case codeMapKey:
|
||||||
|
code = code.toMapKeyCode().end
|
||||||
|
default:
|
||||||
|
code = code.next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *opcode) copy(codeMap map[uintptr]*opcode) *opcode {
|
func (c *opcode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -125,22 +137,22 @@ func (c *opcode) dump() string {
|
||||||
indent := strings.Repeat(" ", code.indent)
|
indent := strings.Repeat(" ", code.indent)
|
||||||
switch code.op.codeType() {
|
switch code.op.codeType() {
|
||||||
case codeArrayElem:
|
case codeArrayElem:
|
||||||
codes = append(codes, fmt.Sprintf("%s%s ( %p )", indent, code.op, unsafe.Pointer(code)))
|
codes = append(codes, fmt.Sprintf("[%d]%s%s ( %p )", code.idx, indent, code.op, unsafe.Pointer(code)))
|
||||||
code = code.toArrayElemCode().end
|
code = code.toArrayElemCode().end
|
||||||
case codeSliceElem:
|
case codeSliceElem:
|
||||||
codes = append(codes, fmt.Sprintf("%s%s ( %p )", indent, code.op, unsafe.Pointer(code)))
|
codes = append(codes, fmt.Sprintf("[%d]%s%s ( %p )", code.idx, indent, code.op, unsafe.Pointer(code)))
|
||||||
code = code.toSliceElemCode().end
|
code = code.toSliceElemCode().end
|
||||||
case codeMapKey:
|
case codeMapKey:
|
||||||
codes = append(codes, fmt.Sprintf("%s%s ( %p )", indent, code.op, unsafe.Pointer(code)))
|
codes = append(codes, fmt.Sprintf("[%d]%s%s ( %p )", code.idx, indent, code.op, unsafe.Pointer(code)))
|
||||||
code = code.toMapKeyCode().end
|
code = code.toMapKeyCode().end
|
||||||
case codeStructField:
|
case codeStructField:
|
||||||
sf := code.toStructFieldCode()
|
sf := code.toStructFieldCode()
|
||||||
key := sf.displayKey
|
key := sf.displayKey
|
||||||
offset := sf.offset
|
offset := sf.offset
|
||||||
codes = append(codes, fmt.Sprintf("%s%s [%s:%d] ( %p )", indent, code.op, key, offset, unsafe.Pointer(code)))
|
codes = append(codes, fmt.Sprintf("[%d]%s%s [%s:%d] ( %p )", code.idx, indent, code.op, key, offset, unsafe.Pointer(code)))
|
||||||
code = code.next
|
code = code.next
|
||||||
default:
|
default:
|
||||||
codes = append(codes, fmt.Sprintf("%s%s ( %p )", indent, code.op, unsafe.Pointer(code)))
|
codes = append(codes, fmt.Sprintf("[%d]%s%s ( %p )", code.idx, indent, code.op, unsafe.Pointer(code)))
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,15 +205,27 @@ type sliceHeaderCode struct {
|
||||||
end *opcode
|
end *opcode
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSliceHeaderCode(indent int) *sliceHeaderCode {
|
func newSliceHeaderCode(ctx *encodeCompileContext) *sliceHeaderCode {
|
||||||
return &sliceHeaderCode{
|
return &sliceHeaderCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opSliceHead,
|
op: opSliceHead,
|
||||||
indent: indent,
|
idx: ctx.opcodeIndex,
|
||||||
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newSliceElemCode(ctx *encodeCompileContext, size uintptr) *sliceElemCode {
|
||||||
|
return &sliceElemCode{
|
||||||
|
opcodeHeader: &opcodeHeader{
|
||||||
|
op: opSliceElem,
|
||||||
|
idx: ctx.opcodeIndex,
|
||||||
|
indent: ctx.indent,
|
||||||
|
},
|
||||||
|
size: size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *sliceHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
func (c *sliceHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -264,16 +288,28 @@ type arrayHeaderCode struct {
|
||||||
end *opcode
|
end *opcode
|
||||||
}
|
}
|
||||||
|
|
||||||
func newArrayHeaderCode(indent, alen int) *arrayHeaderCode {
|
func newArrayHeaderCode(ctx *encodeCompileContext, alen int) *arrayHeaderCode {
|
||||||
return &arrayHeaderCode{
|
return &arrayHeaderCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opArrayHead,
|
op: opArrayHead,
|
||||||
indent: indent,
|
idx: ctx.opcodeIndex,
|
||||||
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
len: uintptr(alen),
|
len: uintptr(alen),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newArrayElemCode(ctx *encodeCompileContext, alen int, size uintptr) *arrayElemCode {
|
||||||
|
return &arrayElemCode{
|
||||||
|
opcodeHeader: &opcodeHeader{
|
||||||
|
op: opArrayElem,
|
||||||
|
idx: ctx.opcodeIndex,
|
||||||
|
},
|
||||||
|
len: uintptr(alen),
|
||||||
|
size: size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *arrayHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
func (c *arrayHeaderCode) copy(codeMap map[uintptr]*opcode) *opcode {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -475,7 +511,7 @@ func (c *mapValueCode) set(iter unsafe.Pointer) {
|
||||||
c.iter = iter
|
c.iter = iter
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMapHeaderCode(typ *rtype, withLoad bool, indent int) *mapHeaderCode {
|
func newMapHeaderCode(ctx *encodeCompileContext, withLoad bool) *mapHeaderCode {
|
||||||
var op opType
|
var op opType
|
||||||
if withLoad {
|
if withLoad {
|
||||||
op = opMapHeadLoad
|
op = opMapHeadLoad
|
||||||
|
@ -485,26 +521,29 @@ func newMapHeaderCode(typ *rtype, withLoad bool, indent int) *mapHeaderCode {
|
||||||
return &mapHeaderCode{
|
return &mapHeaderCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: op,
|
op: op,
|
||||||
typ: typ,
|
typ: ctx.typ,
|
||||||
indent: indent,
|
idx: ctx.opcodeIndex,
|
||||||
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMapKeyCode(indent int) *mapKeyCode {
|
func newMapKeyCode(ctx *encodeCompileContext) *mapKeyCode {
|
||||||
return &mapKeyCode{
|
return &mapKeyCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opMapKey,
|
op: opMapKey,
|
||||||
indent: indent,
|
idx: ctx.opcodeIndex,
|
||||||
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMapValueCode(indent int) *mapValueCode {
|
func newMapValueCode(ctx *encodeCompileContext) *mapValueCode {
|
||||||
return &mapValueCode{
|
return &mapValueCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
op: opMapValue,
|
op: opMapValue,
|
||||||
indent: indent,
|
idx: ctx.opcodeIndex,
|
||||||
|
indent: ctx.indent,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue