go-json/encode_opcode.go

452 lines
8.9 KiB
Go
Raw Normal View History

2020-04-29 18:31:50 +03:00
package json
import (
"fmt"
"reflect"
"strings"
"unsafe"
)
type opType int
const (
opEnd opType = iota
opInt
opInt8
opInt16
opInt32
opInt64
opUint
opUint8
opUint16
opUint32
opUint64
opFloat32
opFloat64
opString
opBool
opInterface
2020-04-29 18:31:50 +03:00
opPtr
opSliceHead
opSliceElem
opSliceEnd
opArrayHead
opArrayElem
opArrayEnd
opMapHead
opMapKey
opMapValue
opMapEnd
2020-04-29 19:44:48 +03:00
opStructFieldHead
opStructFieldHeadInt
2020-04-30 05:56:56 +03:00
opStructFieldHeadInt8
opStructFieldHeadInt16
opStructFieldHeadInt32
opStructFieldHeadInt64
opStructFieldHeadUint
opStructFieldHeadUint8
opStructFieldHeadUint16
opStructFieldHeadUint32
opStructFieldHeadUint64
opStructFieldHeadFloat32
opStructFieldHeadFloat64
2020-04-29 19:44:48 +03:00
opStructFieldHeadString
2020-04-30 05:56:56 +03:00
opStructFieldHeadBool
2020-04-29 19:44:48 +03:00
opStructFieldPtrHead
opStructFieldPtrHeadInt
2020-04-30 05:56:56 +03:00
opStructFieldPtrHeadInt8
opStructFieldPtrHeadInt16
opStructFieldPtrHeadInt32
opStructFieldPtrHeadInt64
opStructFieldPtrHeadUint
opStructFieldPtrHeadUint8
opStructFieldPtrHeadUint16
opStructFieldPtrHeadUint32
opStructFieldPtrHeadUint64
opStructFieldPtrHeadFloat32
opStructFieldPtrHeadFloat64
2020-04-29 19:44:48 +03:00
opStructFieldPtrHeadString
2020-04-30 05:56:56 +03:00
opStructFieldPtrHeadBool
2020-04-29 18:31:50 +03:00
opStructField
opStructFieldInt
2020-04-30 05:56:56 +03:00
opStructFieldInt8
opStructFieldInt16
opStructFieldInt32
opStructFieldInt64
opStructFieldUint
opStructFieldUint8
opStructFieldUint16
opStructFieldUint32
opStructFieldUint64
opStructFieldFloat32
opStructFieldFloat64
2020-04-29 18:31:50 +03:00
opStructFieldString
2020-04-30 05:56:56 +03:00
opStructFieldBool
2020-04-29 18:31:50 +03:00
opStructEnd
)
func (t opType) String() string {
switch t {
case opEnd:
return "END"
case opInt:
return "INT"
case opInt8:
return "INT8"
case opInt16:
return "INT16"
case opInt32:
return "INT32"
case opInt64:
return "INT64"
case opUint:
return "UINT"
case opUint8:
return "UINT8"
case opUint16:
return "UINT16"
case opUint32:
return "UINT32"
case opUint64:
return "UINT64"
case opFloat32:
return "FLOAT32"
case opFloat64:
return "FLOAT64"
case opString:
return "STRING"
case opBool:
return "BOOL"
case opInterface:
return "INTERFACE"
2020-04-29 18:31:50 +03:00
case opPtr:
return "PTR"
case opSliceHead:
return "SLICE_HEAD"
case opSliceElem:
return "SLICE_ELEM"
case opSliceEnd:
return "SLICE_END"
case opArrayHead:
return "ARRAY_HEAD"
case opArrayElem:
return "ARRAY_ELEM"
case opArrayEnd:
return "ARRAY_END"
case opMapHead:
return "MAP_HEAD"
case opMapKey:
return "MAP_KEY"
case opMapValue:
return "MAP_VALUE"
case opMapEnd:
return "MAP_END"
2020-04-29 19:44:48 +03:00
case opStructFieldHead:
return "STRUCT_FIELD_HEAD"
case opStructFieldHeadInt:
return "STRUCT_FIELD_HEAD_INT"
2020-04-30 05:56:56 +03:00
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"
2020-04-29 19:44:48 +03:00
case opStructFieldHeadString:
return "STRUCT_FIELD_HEAD_STRING"
2020-04-30 05:56:56 +03:00
case opStructFieldHeadBool:
return "STRUCT_FIELD_HEAD_BOOL"
2020-04-29 19:44:48 +03:00
case opStructFieldPtrHead:
return "STRUCT_FIELD_PTR_HEAD"
case opStructFieldPtrHeadInt:
return "STRUCT_FIELD_PTR_HEAD_INT"
2020-04-30 05:56:56 +03:00
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"
2020-04-29 19:44:48 +03:00
case opStructFieldPtrHeadString:
return "STRUCT_FIELD_PTR_HEAD_STRING"
2020-04-30 05:56:56 +03:00
case opStructFieldPtrHeadBool:
return "STRUCT_FIELD_PTR_HEAD_BOOL"
2020-04-29 18:31:50 +03:00
case opStructField:
return "STRUCT_FIELD"
case opStructFieldInt:
return "STRUCT_FIELD_INT"
2020-04-30 05:56:56 +03:00
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"
2020-04-29 18:31:50 +03:00
case opStructFieldString:
return "STRUCT_FIELD_STRING"
2020-04-30 05:56:56 +03:00
case opStructFieldBool:
return "STRUCT_FIELD_BOOL"
2020-04-29 18:31:50 +03:00
case opStructEnd:
return "STRUCT_END"
}
return ""
}
type opcodeHeader struct {
op opType
typ *rtype
ptr uintptr
next *opcode
}
type opcode struct {
*opcodeHeader
}
func newOpCode(op opType, typ *rtype, next *opcode) *opcode {
return &opcode{
opcodeHeader: &opcodeHeader{
op: op,
typ: typ,
next: next,
},
}
}
func newEndOp() *opcode {
return newOpCode(opEnd, nil, nil)
}
func (c *opcode) beforeLastCode() *opcode {
code := c
for {
var nextCode *opcode
switch code.op {
case opArrayElem:
nextCode = code.toArrayElemCode().end
case opSliceElem:
2020-04-29 18:31:50 +03:00
nextCode = code.toSliceElemCode().end
case opMapKey:
nextCode = code.toMapKeyCode().end
default:
2020-04-29 18:31:50 +03:00
nextCode = code.next
}
if nextCode.op == opEnd {
return code
}
code = nextCode
}
return nil
}
func (c *opcode) dump() string {
codes := []string{}
for code := c; code.op != opEnd; {
codes = append(codes, fmt.Sprintf("%s", code.op))
switch code.op {
case opArrayElem:
code = code.toArrayElemCode().end
case opSliceElem:
2020-04-29 18:31:50 +03:00
code = code.toSliceElemCode().end
case opMapKey:
code = code.toMapKeyCode().end
default:
2020-04-29 18:31:50 +03:00
code = code.next
}
}
return strings.Join(codes, "\n")
}
2020-04-29 19:44:48 +03:00
func (c *opcode) toSliceHeaderCode() *sliceHeaderCode {
return (*sliceHeaderCode)(unsafe.Pointer(c))
2020-04-29 18:31:50 +03:00
}
2020-04-29 19:44:48 +03:00
func (c *opcode) toSliceElemCode() *sliceElemCode {
return (*sliceElemCode)(unsafe.Pointer(c))
2020-04-29 18:31:50 +03:00
}
func (c *opcode) toArrayHeaderCode() *arrayHeaderCode {
return (*arrayHeaderCode)(unsafe.Pointer(c))
}
func (c *opcode) toArrayElemCode() *arrayElemCode {
return (*arrayElemCode)(unsafe.Pointer(c))
}
2020-04-29 18:31:50 +03:00
func (c *opcode) toStructFieldCode() *structFieldCode {
return (*structFieldCode)(unsafe.Pointer(c))
}
func (c *opcode) toMapHeadCode() *mapHeaderCode {
return (*mapHeaderCode)(unsafe.Pointer(c))
}
func (c *opcode) toMapKeyCode() *mapKeyCode {
return (*mapKeyCode)(unsafe.Pointer(c))
}
func (c *opcode) toMapValueCode() *mapValueCode {
return (*mapValueCode)(unsafe.Pointer(c))
}
2020-04-29 19:44:48 +03:00
type sliceHeaderCode struct {
*opcodeHeader
elem *sliceElemCode
end *opcode
}
func newSliceHeaderCode() *sliceHeaderCode {
return &sliceHeaderCode{
opcodeHeader: &opcodeHeader{
op: opSliceHead,
},
}
}
2020-04-29 18:31:50 +03:00
type sliceElemCode struct {
*opcodeHeader
idx uintptr
len uintptr
size uintptr
data uintptr
end *opcode
}
func (c *sliceElemCode) set(header *reflect.SliceHeader) {
c.idx = uintptr(0)
c.len = uintptr(header.Len)
c.data = header.Data
}
type arrayHeaderCode struct {
*opcodeHeader
len uintptr
elem *arrayElemCode
end *opcode
}
func newArrayHeaderCode(alen int) *arrayHeaderCode {
return &arrayHeaderCode{
opcodeHeader: &opcodeHeader{
op: opArrayHead,
},
len: uintptr(alen),
}
}
type arrayElemCode struct {
*opcodeHeader
idx uintptr
len uintptr
size uintptr
end *opcode
}
2020-04-29 18:31:50 +03:00
type structFieldCode struct {
*opcodeHeader
2020-04-30 05:56:56 +03:00
key []byte
2020-04-29 18:31:50 +03:00
offset uintptr
nextField *opcode
2020-04-29 19:44:48 +03:00
end *opcode
2020-04-29 18:31:50 +03:00
}
type mapHeaderCode struct {
*opcodeHeader
key *mapKeyCode
value *mapValueCode
end *opcode
}
type mapKeyCode struct {
*opcodeHeader
idx int
len int
iter unsafe.Pointer
end *opcode
}
func (c *mapKeyCode) set(len int, iter unsafe.Pointer) {
c.idx = 0
c.len = len
c.iter = iter
}
type mapValueCode struct {
*opcodeHeader
iter unsafe.Pointer
}
func (c *mapValueCode) set(iter unsafe.Pointer) {
c.iter = iter
}
func newMapHeaderCode(typ *rtype) *mapHeaderCode {
return &mapHeaderCode{
opcodeHeader: &opcodeHeader{
op: opMapHead,
typ: typ,
},
}
}
func newMapKeyCode() *mapKeyCode {
return &mapKeyCode{
opcodeHeader: &opcodeHeader{
op: opMapKey,
},
}
}
func newMapValueCode() *mapValueCode {
return &mapValueCode{
opcodeHeader: &opcodeHeader{
op: opMapValue,
},
}
}