Add optimized code

This commit is contained in:
Masaaki Goshima 2020-04-30 11:56:56 +09:00
parent 40544f1ea2
commit 95b2194742
4 changed files with 492 additions and 38 deletions

View File

@ -163,6 +163,10 @@ func (e *Encoder) encodeBool(v bool) {
e.buf = strconv.AppendBool(e.buf, v) e.buf = strconv.AppendBool(e.buf, v)
} }
func (e *Encoder) encodeBytes(b []byte) {
e.buf = append(e.buf, b...)
}
func (e *Encoder) encodeString(s string) { func (e *Encoder) encodeString(s string) {
b := *(*[]byte)(unsafe.Pointer(&s)) b := *(*[]byte)(unsafe.Pointer(&s))
e.buf = append(e.buf, b...) e.buf = append(e.buf, b...)

View File

@ -53,22 +53,50 @@ func (e *Encoder) compileOp(typ *rtype) (*opcode, error) {
return nil, xerrors.Errorf("failed to encode type %s: %w", typ.String(), ErrUnsupportedType) return nil, xerrors.Errorf("failed to encode type %s: %w", typ.String(), ErrUnsupportedType)
} }
func (e *Encoder) compilePtrOp(typ *rtype) (*opcode, error) { func (e *Encoder) optimizeStructFieldPtrHead(typ *rtype, code *opcode) *opcode {
code, err := e.compileOp(typ.Elem())
if err != nil {
return nil, err
}
switch code.op { switch code.op {
case opStructFieldHead: case opStructFieldHead:
code.op = opStructFieldPtrHead code.op = opStructFieldPtrHead
case opStructFieldHeadInt: case opStructFieldHeadInt:
code.op = opStructFieldPtrHeadInt code.op = opStructFieldPtrHeadInt
case opStructFieldHeadInt8:
code.op = opStructFieldPtrHeadInt8
case opStructFieldHeadInt16:
code.op = opStructFieldPtrHeadInt16
case opStructFieldHeadInt32:
code.op = opStructFieldPtrHeadInt32
case opStructFieldHeadInt64:
code.op = opStructFieldPtrHeadInt64
case opStructFieldHeadUint:
code.op = opStructFieldPtrHeadUint
case opStructFieldHeadUint8:
code.op = opStructFieldPtrHeadUint8
case opStructFieldHeadUint16:
code.op = opStructFieldPtrHeadUint16
case opStructFieldHeadUint32:
code.op = opStructFieldPtrHeadUint32
case opStructFieldHeadUint64:
code.op = opStructFieldPtrHeadUint64
case opStructFieldHeadFloat32:
code.op = opStructFieldPtrHeadFloat32
case opStructFieldHeadFloat64:
code.op = opStructFieldPtrHeadFloat64
case opStructFieldHeadString: case opStructFieldHeadString:
code.op = opStructFieldPtrHeadString code.op = opStructFieldPtrHeadString
case opStructFieldHeadBool:
code.op = opStructFieldPtrHeadBool
default: default:
return newOpCode(opPtr, typ, code), nil return newOpCode(opPtr, typ, code)
} }
return code, nil return code
}
func (e *Encoder) compilePtrOp(typ *rtype) (*opcode, error) {
code, err := e.compileOp(typ.Elem())
if err != nil {
return nil, err
}
return e.optimizeStructFieldPtrHead(typ, code), nil
} }
func (e *Encoder) compileIntOp(typ *rtype) (*opcode, error) { func (e *Encoder) compileIntOp(typ *rtype) (*opcode, error) {
@ -154,9 +182,9 @@ func (e *Encoder) compileSliceOp(typ *rtype) (*opcode, error) {
} }
func (e *Encoder) compileStructOp(typ *rtype) (*opcode, error) { func (e *Encoder) compileStructOp(typ *rtype) (*opcode, error) {
// header => firstField => structField => end // header => code => structField => code => end
// ^ | // ^ |
// |________| // |__________|
fieldNum := typ.NumField() fieldNum := typ.NumField()
fieldIdx := 0 fieldIdx := 0
var ( var (
@ -183,47 +211,86 @@ func (e *Encoder) compileStructOp(typ *rtype) (*opcode, error) {
return nil, err return nil, err
} }
key := fmt.Sprintf(`"%s":`, keyName) key := fmt.Sprintf(`"%s":`, keyName)
if fieldIdx == 0 {
fieldCode := &structFieldCode{ fieldCode := &structFieldCode{
opcodeHeader: &opcodeHeader{ opcodeHeader: &opcodeHeader{
op: opStructFieldHead,
typ: fieldType, typ: fieldType,
next: valueCode, next: valueCode,
}, },
key: key, key: []byte(key),
offset: field.Offset, offset: field.Offset,
} }
if fieldIdx == 0 {
fieldCode.op = opStructFieldHead
head = fieldCode head = fieldCode
code = (*opcode)(unsafe.Pointer(fieldCode)) code = (*opcode)(unsafe.Pointer(fieldCode))
prevField = fieldCode prevField = fieldCode
switch valueCode.op { switch valueCode.op {
case opInt: case opInt:
fieldCode.op = opStructFieldHeadInt fieldCode.op = opStructFieldHeadInt
case opInt8:
fieldCode.op = opStructFieldHeadInt8
case opInt16:
fieldCode.op = opStructFieldHeadInt16
case opInt32:
fieldCode.op = opStructFieldHeadInt32
case opInt64:
fieldCode.op = opStructFieldHeadInt64
case opUint:
fieldCode.op = opStructFieldHeadUint
case opUint8:
fieldCode.op = opStructFieldHeadUint8
case opUint16:
fieldCode.op = opStructFieldHeadUint16
case opUint32:
fieldCode.op = opStructFieldHeadUint32
case opUint64:
fieldCode.op = opStructFieldHeadUint64
case opFloat32:
fieldCode.op = opStructFieldHeadFloat32
case opFloat64:
fieldCode.op = opStructFieldHeadFloat64
case opString: case opString:
fieldCode.op = opStructFieldHeadString fieldCode.op = opStructFieldHeadString
case opBool:
fieldCode.op = opStructFieldHeadBool
default: default:
code = valueCode.beforeLastCode() code = valueCode.beforeLastCode()
} }
} else { } else {
fieldCode := &structFieldCode{ fieldCode.op = opStructField
opcodeHeader: &opcodeHeader{
op: opStructField,
typ: fieldType,
next: valueCode,
},
key: key,
offset: field.Offset,
}
code.next = (*opcode)(unsafe.Pointer(fieldCode)) code.next = (*opcode)(unsafe.Pointer(fieldCode))
prevField.nextField = (*opcode)(unsafe.Pointer(fieldCode)) prevField.nextField = (*opcode)(unsafe.Pointer(fieldCode))
prevField = fieldCode prevField = fieldCode
code = (*opcode)(unsafe.Pointer(fieldCode))
switch valueCode.op { switch valueCode.op {
case opInt: case opInt:
fieldCode.op = opStructFieldInt fieldCode.op = opStructFieldInt
code = (*opcode)(unsafe.Pointer(fieldCode)) case opInt8:
fieldCode.op = opStructFieldInt8
case opInt16:
fieldCode.op = opStructFieldInt16
case opInt32:
fieldCode.op = opStructFieldInt32
case opInt64:
fieldCode.op = opStructFieldInt64
case opUint:
fieldCode.op = opStructFieldUint
case opUint8:
fieldCode.op = opStructFieldUint8
case opUint16:
fieldCode.op = opStructFieldUint16
case opUint32:
fieldCode.op = opStructFieldUint32
case opUint64:
fieldCode.op = opStructFieldUint64
case opFloat32:
fieldCode.op = opStructFieldFloat32
case opFloat64:
fieldCode.op = opStructFieldFloat64
case opString: case opString:
fieldCode.op = opStructFieldString fieldCode.op = opStructFieldString
code = (*opcode)(unsafe.Pointer(fieldCode)) case opBool:
fieldCode.op = opStructFieldBool
default: default:
code = valueCode.beforeLastCode() code = valueCode.beforeLastCode()
} }

View File

@ -31,13 +31,49 @@ const (
opSliceEnd opSliceEnd
opStructFieldHead opStructFieldHead
opStructFieldHeadInt opStructFieldHeadInt
opStructFieldHeadInt8
opStructFieldHeadInt16
opStructFieldHeadInt32
opStructFieldHeadInt64
opStructFieldHeadUint
opStructFieldHeadUint8
opStructFieldHeadUint16
opStructFieldHeadUint32
opStructFieldHeadUint64
opStructFieldHeadFloat32
opStructFieldHeadFloat64
opStructFieldHeadString opStructFieldHeadString
opStructFieldHeadBool
opStructFieldPtrHead opStructFieldPtrHead
opStructFieldPtrHeadInt opStructFieldPtrHeadInt
opStructFieldPtrHeadInt8
opStructFieldPtrHeadInt16
opStructFieldPtrHeadInt32
opStructFieldPtrHeadInt64
opStructFieldPtrHeadUint
opStructFieldPtrHeadUint8
opStructFieldPtrHeadUint16
opStructFieldPtrHeadUint32
opStructFieldPtrHeadUint64
opStructFieldPtrHeadFloat32
opStructFieldPtrHeadFloat64
opStructFieldPtrHeadString opStructFieldPtrHeadString
opStructFieldPtrHeadBool
opStructField opStructField
opStructFieldInt opStructFieldInt
opStructFieldInt8
opStructFieldInt16
opStructFieldInt32
opStructFieldInt64
opStructFieldUint
opStructFieldUint8
opStructFieldUint16
opStructFieldUint32
opStructFieldUint64
opStructFieldFloat32
opStructFieldFloat64
opStructFieldString opStructFieldString
opStructFieldBool
opStructEnd opStructEnd
) )
@ -85,20 +121,92 @@ func (t opType) String() string {
return "STRUCT_FIELD_HEAD" return "STRUCT_FIELD_HEAD"
case opStructFieldHeadInt: case opStructFieldHeadInt:
return "STRUCT_FIELD_HEAD_INT" return "STRUCT_FIELD_HEAD_INT"
case opStructFieldHeadInt8:
return "STRUCT_FIELD_HEAD_INT8"
case opStructFieldHeadInt16:
return "STRUCT_FIELD_HEAD_INT16"
case opStructFieldHeadInt32:
return "STRUCT_FIELD_HEAD_INT32"
case opStructFieldHeadInt64:
return "STRUCT_FIELD_HEAD_INT64"
case opStructFieldHeadUint:
return "STRUCT_FIELD_HEAD_UINT"
case opStructFieldHeadUint8:
return "STRUCT_FIELD_HEAD_UINT8"
case opStructFieldHeadUint16:
return "STRUCT_FIELD_HEAD_UINT16"
case opStructFieldHeadUint32:
return "STRUCT_FIELD_HEAD_UINT32"
case opStructFieldHeadUint64:
return "STRUCT_FIELD_HEAD_UINT64"
case opStructFieldHeadFloat32:
return "STRUCT_FIELD_HEAD_FLOAT32"
case opStructFieldHeadFloat64:
return "STRUCT_FIELD_HEAD_FLOAT64"
case opStructFieldHeadString: case opStructFieldHeadString:
return "STRUCT_FIELD_HEAD_STRING" return "STRUCT_FIELD_HEAD_STRING"
case opStructFieldHeadBool:
return "STRUCT_FIELD_HEAD_BOOL"
case opStructFieldPtrHead: case opStructFieldPtrHead:
return "STRUCT_FIELD_PTR_HEAD" return "STRUCT_FIELD_PTR_HEAD"
case opStructFieldPtrHeadInt: case opStructFieldPtrHeadInt:
return "STRUCT_FIELD_PTR_HEAD_INT" return "STRUCT_FIELD_PTR_HEAD_INT"
case opStructFieldPtrHeadInt8:
return "STRUCT_FIELD_PTR_HEAD_INT8"
case opStructFieldPtrHeadInt16:
return "STRUCT_FIELD_PTR_HEAD_INT16"
case opStructFieldPtrHeadInt32:
return "STRUCT_FIELD_PTR_HEAD_INT32"
case opStructFieldPtrHeadInt64:
return "STRUCT_FIELD_PTR_HEAD_INT64"
case opStructFieldPtrHeadUint:
return "STRUCT_FIELD_PTR_HEAD_UINT"
case opStructFieldPtrHeadUint8:
return "STRUCT_FIELD_PTR_HEAD_UINT8"
case opStructFieldPtrHeadUint16:
return "STRUCT_FIELD_PTR_HEAD_UINT16"
case opStructFieldPtrHeadUint32:
return "STRUCT_FIELD_PTR_HEAD_UINT32"
case opStructFieldPtrHeadUint64:
return "STRUCT_FIELD_PTR_HEAD_UINT64"
case opStructFieldPtrHeadFloat32:
return "STRUCT_FIELD_PTR_HEAD_FLOAT32"
case opStructFieldPtrHeadFloat64:
return "STRUCT_FIELD_PTR_HEAD_FLOAT64"
case opStructFieldPtrHeadString: case opStructFieldPtrHeadString:
return "STRUCT_FIELD_PTR_HEAD_STRING" return "STRUCT_FIELD_PTR_HEAD_STRING"
case opStructFieldPtrHeadBool:
return "STRUCT_FIELD_PTR_HEAD_BOOL"
case opStructField: case opStructField:
return "STRUCT_FIELD" return "STRUCT_FIELD"
case opStructFieldInt: case opStructFieldInt:
return "STRUCT_FIELD_INT" return "STRUCT_FIELD_INT"
case opStructFieldInt8:
return "STRUCT_FIELD_INT8"
case opStructFieldInt16:
return "STRUCT_FIELD_INT16"
case opStructFieldInt32:
return "STRUCT_FIELD_INT32"
case opStructFieldInt64:
return "STRUCT_FIELD_INT64"
case opStructFieldUint:
return "STRUCT_FIELD_UINT"
case opStructFieldUint8:
return "STRUCT_FIELD_UINT8"
case opStructFieldUint16:
return "STRUCT_FIELD_UINT16"
case opStructFieldUint32:
return "STRUCT_FIELD_UINT32"
case opStructFieldUint64:
return "STRUCT_FIELD_UINT64"
case opStructFieldFloat32:
return "STRUCT_FIELD_FLOAT32"
case opStructFieldFloat64:
return "STRUCT_FIELD_FLOAT64"
case opStructFieldString: case opStructFieldString:
return "STRUCT_FIELD_STRING" return "STRUCT_FIELD_STRING"
case opStructFieldBool:
return "STRUCT_FIELD_BOOL"
case opStructEnd: case opStructEnd:
return "STRUCT_END" return "STRUCT_END"
} }
@ -192,7 +300,6 @@ type sliceElemCode struct {
len uintptr len uintptr
size uintptr size uintptr
data uintptr data uintptr
elem *sliceElemCode // first => elem
end *opcode end *opcode
} }
@ -204,7 +311,7 @@ func (c *sliceElemCode) set(header *reflect.SliceHeader) {
type structFieldCode struct { type structFieldCode struct {
*opcodeHeader *opcodeHeader
key string key []byte
offset uintptr offset uintptr
nextField *opcode nextField *opcode
end *opcode end *opcode

View File

@ -98,7 +98,7 @@ func (e *Encoder) run(code *opcode) error {
code = field.end code = field.end
} else { } else {
e.encodeByte('{') e.encodeByte('{')
e.encodeString(field.key) e.encodeBytes(field.key)
code = field.next code = field.next
code.ptr = field.ptr + field.offset code.ptr = field.ptr + field.offset
field.nextField.ptr = field.ptr field.nextField.ptr = field.ptr
@ -114,11 +114,187 @@ func (e *Encoder) run(code *opcode) error {
code = field.end code = field.end
} else { } else {
e.encodeByte('{') e.encodeByte('{')
e.encodeString(field.key) e.encodeBytes(field.key)
e.encodeInt(e.ptrToInt(field.ptr + field.offset)) e.encodeInt(e.ptrToInt(field.ptr + field.offset))
field.nextField.ptr = field.ptr field.nextField.ptr = field.ptr
code = field.next code = field.next
} }
case opStructFieldPtrHeadInt8:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadInt8:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeInt8(e.ptrToInt8(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadInt16:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadInt16:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeInt16(e.ptrToInt16(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadInt32:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadInt32:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeInt32(e.ptrToInt32(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadInt64:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadInt64:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeInt64(e.ptrToInt64(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadUint:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadUint:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeUint(e.ptrToUint(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadUint8:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadUint8:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeUint8(e.ptrToUint8(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadUint16:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadUint16:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeUint16(e.ptrToUint16(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadUint32:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadUint32:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeUint32(e.ptrToUint32(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadUint64:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadUint64:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeUint64(e.ptrToUint64(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadFloat32:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadFloat32:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeFloat32(e.ptrToFloat32(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadFloat64:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadFloat64:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeFloat64(e.ptrToFloat64(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructFieldPtrHeadString: case opStructFieldPtrHeadString:
code.ptr = e.ptrToPtr(code.ptr) code.ptr = e.ptrToPtr(code.ptr)
fallthrough fallthrough
@ -130,15 +306,31 @@ func (e *Encoder) run(code *opcode) error {
code = field.end code = field.end
} else { } else {
e.encodeByte('{') e.encodeByte('{')
e.encodeString(field.key) e.encodeBytes(field.key)
e.encodeEscapedString(e.ptrToString(field.ptr + field.offset)) e.encodeEscapedString(e.ptrToString(field.ptr + field.offset))
field.nextField.ptr = field.ptr field.nextField.ptr = field.ptr
code = field.next code = field.next
} }
case opStructFieldPtrHeadBool:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadBool:
field := code.toStructFieldCode()
ptr := field.ptr
if ptr == 0 {
e.encodeString("null")
code = field.end
} else {
e.encodeByte('{')
e.encodeBytes(field.key)
e.encodeBool(e.ptrToBool(field.ptr + field.offset))
field.nextField.ptr = field.ptr
code = field.next
}
case opStructField: case opStructField:
e.encodeByte(',') e.encodeByte(',')
c := code.toStructFieldCode() c := code.toStructFieldCode()
e.encodeString(c.key) e.encodeBytes(c.key)
code = code.next code = code.next
code.ptr = c.ptr + c.offset code.ptr = c.ptr + c.offset
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
@ -146,16 +338,100 @@ func (e *Encoder) run(code *opcode) error {
e.encodeByte(',') e.encodeByte(',')
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeString(c.key) e.encodeBytes(c.key)
e.encodeInt(e.ptrToInt(c.ptr + c.offset)) e.encodeInt(e.ptrToInt(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldInt8:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeInt8(e.ptrToInt8(c.ptr + c.offset))
code = code.next
case opStructFieldInt16:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeInt16(e.ptrToInt16(c.ptr + c.offset))
code = code.next
case opStructFieldInt32:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeInt32(e.ptrToInt32(c.ptr + c.offset))
code = code.next
case opStructFieldInt64:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeInt64(e.ptrToInt64(c.ptr + c.offset))
code = code.next
case opStructFieldUint:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeUint(e.ptrToUint(c.ptr + c.offset))
code = code.next
case opStructFieldUint8:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeUint8(e.ptrToUint8(c.ptr + c.offset))
code = code.next
case opStructFieldUint16:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeUint16(e.ptrToUint16(c.ptr + c.offset))
code = code.next
case opStructFieldUint32:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeUint32(e.ptrToUint32(c.ptr + c.offset))
code = code.next
case opStructFieldUint64:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeUint64(e.ptrToUint64(c.ptr + c.offset))
code = code.next
case opStructFieldFloat32:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeFloat32(e.ptrToFloat32(c.ptr + c.offset))
code = code.next
case opStructFieldFloat64:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeFloat64(e.ptrToFloat64(c.ptr + c.offset))
code = code.next
case opStructFieldString: case opStructFieldString:
e.encodeByte(',') e.encodeByte(',')
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeString(c.key) e.encodeBytes(c.key)
e.encodeEscapedString(e.ptrToString(c.ptr + c.offset)) e.encodeEscapedString(e.ptrToString(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldBool:
e.encodeByte(',')
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
e.encodeBytes(c.key)
e.encodeBool(e.ptrToBool(c.ptr + c.offset))
code = code.next
case opStructEnd: case opStructEnd:
e.encodeByte('}') e.encodeByte('}')
code = code.next code = code.next