This commit is contained in:
Masaaki Goshima 2021-11-27 19:34:06 +09:00
parent 79dba78e41
commit de62a395f4
No known key found for this signature in database
GPG Key ID: 6A53785055537153
6 changed files with 66 additions and 66 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,
} }
} }

View File

@ -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)
} }
} }
} }