forked from mirror/go-json
refactor
This commit is contained in:
parent
79dba78e41
commit
de62a395f4
|
@ -32,6 +32,10 @@ func (o Opcodes) Last() *Opcode {
|
||||||
return o[len(o)-1]
|
return o[len(o)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o Opcodes) Add(codes ...*Opcode) Opcodes {
|
||||||
|
return append(o, codes...)
|
||||||
|
}
|
||||||
|
|
||||||
type CodeType2 int
|
type CodeType2 int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -237,7 +241,7 @@ func (c *SliceCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
codes.Last().Next = elemCode
|
codes.Last().Next = elemCode
|
||||||
elemCode.Next = codes.First()
|
elemCode.Next = codes.First()
|
||||||
elemCode.End = end
|
elemCode.End = end
|
||||||
return append(append(Opcodes{header}, codes...), elemCode, end)
|
return Opcodes{header}.Add(codes...).Add(elemCode).Add(end)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArrayCode struct {
|
type ArrayCode struct {
|
||||||
|
@ -275,7 +279,7 @@ func (c *ArrayCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
elemCode.Next = codes.First()
|
elemCode.Next = codes.First()
|
||||||
elemCode.End = end
|
elemCode.End = end
|
||||||
|
|
||||||
return append(append(Opcodes{header}, codes...), elemCode, end)
|
return Opcodes{header}.Add(codes...).Add(elemCode).Add(end)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MapCode struct {
|
type MapCode struct {
|
||||||
|
@ -317,7 +321,7 @@ func (c *MapCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
header.End = end
|
header.End = end
|
||||||
key.End = end
|
key.End = end
|
||||||
value.End = end
|
value.End = end
|
||||||
return append(append(append(append(append(Opcodes{header}, keyCodes...), value), valueCodes...), key), end)
|
return Opcodes{header}.Add(keyCodes...).Add(value).Add(valueCodes...).Add(key).Add(end)
|
||||||
}
|
}
|
||||||
|
|
||||||
type StructCode struct {
|
type StructCode struct {
|
||||||
|
@ -397,11 +401,11 @@ func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
} else {
|
} else {
|
||||||
firstField.End = endField
|
firstField.End = endField
|
||||||
}
|
}
|
||||||
codes = append(codes, fieldCodes...)
|
codes = codes.Add(fieldCodes...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
prevField = c.lastFieldCode(field, firstField)
|
prevField = c.lastFieldCode(field, firstField)
|
||||||
codes = append(codes, fieldCodes...)
|
codes = codes.Add(fieldCodes...)
|
||||||
}
|
}
|
||||||
if len(codes) == 0 {
|
if len(codes) == 0 {
|
||||||
head := &Opcode{
|
head := &Opcode{
|
||||||
|
@ -421,7 +425,7 @@ func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
head.NextField = end
|
head.NextField = end
|
||||||
head.Next = end
|
head.Next = end
|
||||||
head.End = end
|
head.End = end
|
||||||
codes = append(codes, head, end)
|
codes = codes.Add(head, end)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
}
|
}
|
||||||
ctx = ctx.decIndent()
|
ctx = ctx.decIndent()
|
||||||
|
@ -468,7 +472,7 @@ func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevField = firstField
|
prevField = firstField
|
||||||
codes = append(codes, fieldCodes...)
|
codes = codes.Add(fieldCodes...)
|
||||||
}
|
}
|
||||||
return codes
|
return codes
|
||||||
}
|
}
|
||||||
|
@ -552,7 +556,7 @@ func (c *StructFieldCode) headerOpcodes(ctx *compileContext, field *Opcode, valu
|
||||||
fieldCodes := Opcodes{field}
|
fieldCodes := Opcodes{field}
|
||||||
if op.IsMultipleOpHead() {
|
if op.IsMultipleOpHead() {
|
||||||
field.Next = value
|
field.Next = value
|
||||||
fieldCodes = append(fieldCodes, valueCodes...)
|
fieldCodes = fieldCodes.Add(valueCodes...)
|
||||||
} else {
|
} else {
|
||||||
ctx.decIndex()
|
ctx.decIndex()
|
||||||
}
|
}
|
||||||
|
@ -569,7 +573,7 @@ func (c *StructFieldCode) fieldOpcodes(ctx *compileContext, field *Opcode, value
|
||||||
fieldCodes := Opcodes{field}
|
fieldCodes := Opcodes{field}
|
||||||
if op.IsMultipleOpField() {
|
if op.IsMultipleOpField() {
|
||||||
field.Next = value
|
field.Next = value
|
||||||
fieldCodes = append(fieldCodes, valueCodes...)
|
fieldCodes = fieldCodes.Add(valueCodes...)
|
||||||
} else {
|
} else {
|
||||||
ctx.decIndex()
|
ctx.decIndex()
|
||||||
}
|
}
|
||||||
|
@ -585,8 +589,8 @@ func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) O
|
||||||
}
|
}
|
||||||
codes.Last().Next = end
|
codes.Last().Next = end
|
||||||
codes.First().NextField = end
|
codes.First().NextField = end
|
||||||
codes = append(codes, end)
|
codes = codes.Add(end)
|
||||||
ctx.incIndex()
|
ctx.incOpcodeIndex()
|
||||||
return codes
|
return codes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,7 +687,7 @@ func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField, i
|
||||||
|
|
||||||
func isEnableStructEndOptimizationType(typ CodeType2) bool {
|
func isEnableStructEndOptimizationType(typ CodeType2) bool {
|
||||||
switch typ {
|
switch typ {
|
||||||
case CodeTypeInt, CodeTypeUint, CodeTypeFloat, CodeTypeString, CodeTypeBool:
|
case CodeTypeInt, CodeTypeUint, CodeTypeFloat, CodeTypeString, CodeTypeBool, CodeTypeBytes:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -59,17 +59,19 @@ func compileToGetCodeSetSlowPath(typeptr uintptr) (*OpcodeSet, error) {
|
||||||
// noescape trick for header.typ ( reflect.*rtype )
|
// noescape trick for header.typ ( reflect.*rtype )
|
||||||
copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
|
copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
|
||||||
|
|
||||||
noescapeKeyCode, err := compileHead(&compileContext{
|
noescapeKeyCode, err := compile(&compileContext{
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
escapeKeyCode, err := compileHead(&compileContext{
|
escapeKeyCode, err := compile(&compileContext{
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
escapeKey: true,
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
|
escapeKey: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -94,7 +96,7 @@ func compileToGetCodeSetSlowPath(typeptr uintptr) (*OpcodeSet, error) {
|
||||||
return codeSet, nil
|
return codeSet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileHead(ctx *compileContext) (*Opcode, error) {
|
func compile(ctx *compileContext) (*Opcode, error) {
|
||||||
code, err := type2code(ctx)
|
code, err := type2code(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -21,23 +21,21 @@ func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) {
|
||||||
// noescape trick for header.typ ( reflect.*rtype )
|
// noescape trick for header.typ ( reflect.*rtype )
|
||||||
copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
|
copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
|
||||||
|
|
||||||
noescapeKeyCode, err := compileHead(&compileContext{
|
noescapeKeyCode, err := compile(&compileContext{
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
structTypeToCode: map[uintptr]*StructCode{},
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
structTypeToCodes: map[uintptr]Opcodes{},
|
recursiveCodes: &Opcodes{},
|
||||||
recursiveCodes: &Opcodes{},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
escapeKeyCode, err := compileHead(&compileContext{
|
escapeKeyCode, err := compile(&compileContext{
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
structTypeToCode: map[uintptr]*StructCode{},
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
structTypeToCodes: map[uintptr]Opcodes{},
|
recursiveCodes: &Opcodes{},
|
||||||
recursiveCodes: &Opcodes{},
|
escapeKey: true,
|
||||||
escapeKey: true,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -27,23 +27,21 @@ func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) {
|
||||||
// noescape trick for header.typ ( reflect.*rtype )
|
// noescape trick for header.typ ( reflect.*rtype )
|
||||||
copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
|
copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
|
||||||
|
|
||||||
noescapeKeyCode, err := compileHead(&compileContext{
|
noescapeKeyCode, err := compile(&compileContext{
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
structTypeToCode: map[uintptr]*StructCode{},
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
structTypeToCodes: map[uintptr]Opcodes{},
|
recursiveCodes: &Opcodes{},
|
||||||
recursiveCodes: &Opcodes{},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
escapeKeyCode, err := compileHead(&compileContext{
|
escapeKeyCode, err := compile(&compileContext{
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
structTypeToCode: map[uintptr]*StructCode{},
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
structTypeToCodes: map[uintptr]Opcodes{},
|
recursiveCodes: &Opcodes{},
|
||||||
recursiveCodes: &Opcodes{},
|
escapeKey: true,
|
||||||
escapeKey: true,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -9,31 +9,29 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type compileContext struct {
|
type compileContext struct {
|
||||||
typ *runtime.Type
|
typ *runtime.Type
|
||||||
opcodeIndex uint32
|
opcodeIndex uint32
|
||||||
ptrIndex int
|
ptrIndex int
|
||||||
indent uint32
|
indent uint32
|
||||||
escapeKey bool
|
escapeKey bool
|
||||||
structTypeToCompiledCode map[uintptr]*CompiledCode
|
structTypeToCode map[uintptr]*StructCode
|
||||||
structTypeToCode map[uintptr]*StructCode
|
structTypeToCodes map[uintptr]Opcodes
|
||||||
structTypeToCodes map[uintptr]Opcodes
|
recursiveCodes *Opcodes
|
||||||
recursiveCodes *Opcodes
|
|
||||||
|
|
||||||
parent *compileContext
|
parent *compileContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *compileContext) context() *compileContext {
|
func (c *compileContext) context() *compileContext {
|
||||||
return &compileContext{
|
return &compileContext{
|
||||||
typ: c.typ,
|
typ: c.typ,
|
||||||
opcodeIndex: c.opcodeIndex,
|
opcodeIndex: c.opcodeIndex,
|
||||||
ptrIndex: c.ptrIndex,
|
ptrIndex: c.ptrIndex,
|
||||||
indent: c.indent,
|
indent: c.indent,
|
||||||
escapeKey: c.escapeKey,
|
escapeKey: c.escapeKey,
|
||||||
structTypeToCompiledCode: c.structTypeToCompiledCode,
|
structTypeToCode: c.structTypeToCode,
|
||||||
structTypeToCode: c.structTypeToCode,
|
structTypeToCodes: c.structTypeToCodes,
|
||||||
structTypeToCodes: c.structTypeToCodes,
|
recursiveCodes: c.recursiveCodes,
|
||||||
recursiveCodes: c.recursiveCodes,
|
parent: c,
|
||||||
parent: c,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ func TestOpcodeSize(t *testing.T) {
|
||||||
if uintptrSize == 8 {
|
if uintptrSize == 8 {
|
||||||
size := unsafe.Sizeof(encoder.Opcode{})
|
size := unsafe.Sizeof(encoder.Opcode{})
|
||||||
if size != 120 {
|
if size != 120 {
|
||||||
t.Fatalf("unexpected opcode size: expected 128bytes but got %dbytes", size)
|
t.Fatalf("unexpected opcode size: expected 120bytes but got %dbytes", size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue