forked from mirror/go-json
Add optimized code
This commit is contained in:
parent
40544f1ea2
commit
95b2194742
|
@ -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...)
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
111
encode_opcode.go
111
encode_opcode.go
|
@ -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
|
||||||
|
|
288
encode_vm.go
288
encode_vm.go
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue