forked from mirror/go-json
Support multiple pointer
This commit is contained in:
parent
7e55f41a59
commit
6c3382dc4e
|
@ -18,18 +18,24 @@ type opType struct {
|
|||
}
|
||||
|
||||
type headType struct {
|
||||
Head string
|
||||
PtrHead string
|
||||
AnonymousHead string
|
||||
AnonymousPtrHead string
|
||||
OmitEmptyHead string
|
||||
OmitEmptyPtrHead string
|
||||
AnonymousOmitEmptyHead string
|
||||
AnonymousOmitEmptyPtrHead string
|
||||
StringTagHead string
|
||||
StringTagPtrHead string
|
||||
AnonymousStringTagHead string
|
||||
AnonymousStringTagPtrHead string
|
||||
Head string
|
||||
PtrHead string
|
||||
NPtrHead string
|
||||
AnonymousHead string
|
||||
AnonymousPtrHead string
|
||||
AnonymousNPtrHead string
|
||||
OmitEmptyHead string
|
||||
OmitEmptyPtrHead string
|
||||
OmitEmptyNPtrHead string
|
||||
AnonymousOmitEmptyHead string
|
||||
AnonymousOmitEmptyPtrHead string
|
||||
AnonymousOmitEmptyNPtrHead string
|
||||
StringTagHead string
|
||||
StringTagPtrHead string
|
||||
StringTagNPtrHead string
|
||||
AnonymousStringTagHead string
|
||||
AnonymousStringTagPtrHead string
|
||||
AnonymousStringTagNPtrHead string
|
||||
}
|
||||
|
||||
type fieldType struct {
|
||||
|
@ -108,6 +114,26 @@ func (t opType) headToPtrHead() opType {
|
|||
return t
|
||||
}
|
||||
|
||||
func (t opType) headToNPtrHead() opType {
|
||||
switch t {
|
||||
{{- range $type := .HeadTypes }}
|
||||
case op{{ $type.Head }}:
|
||||
return op{{ $type.NPtrHead }}
|
||||
case op{{ $type.AnonymousHead }}:
|
||||
return op{{ $type.AnonymousNPtrHead }}
|
||||
case op{{ $type.OmitEmptyHead }}:
|
||||
return op{{ $type.OmitEmptyNPtrHead }}
|
||||
case op{{ $type.AnonymousOmitEmptyHead }}:
|
||||
return op{{ $type.AnonymousOmitEmptyNPtrHead }}
|
||||
case op{{ $type.StringTagHead }}:
|
||||
return op{{ $type.StringTagNPtrHead }}
|
||||
case op{{ $type.AnonymousStringTagHead }}:
|
||||
return op{{ $type.AnonymousStringTagNPtrHead }}
|
||||
{{- end }}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (t opType) headToAnonymousHead() opType {
|
||||
switch t {
|
||||
{{- range $type := .HeadTypes }}
|
||||
|
@ -155,17 +181,17 @@ func (t opType) headToStringTagHead() opType {
|
|||
func (t opType) ptrHeadToHead() opType {
|
||||
switch t {
|
||||
{{- range $type := .HeadTypes }}
|
||||
case op{{ $type.PtrHead }}:
|
||||
case op{{ $type.PtrHead }}, op{{ $type.NPtrHead }}:
|
||||
return op{{ $type.Head }}
|
||||
case op{{ $type.AnonymousPtrHead }}:
|
||||
case op{{ $type.AnonymousPtrHead }}, op{{ $type.AnonymousNPtrHead }}:
|
||||
return op{{ $type.AnonymousHead }}
|
||||
case op{{ $type.OmitEmptyPtrHead }}:
|
||||
case op{{ $type.OmitEmptyPtrHead }}, op{{ $type.OmitEmptyNPtrHead }}:
|
||||
return op{{ $type.OmitEmptyHead }}
|
||||
case op{{ $type.AnonymousOmitEmptyPtrHead }}:
|
||||
case op{{ $type.AnonymousOmitEmptyPtrHead }}, op{{ $type.AnonymousOmitEmptyNPtrHead }}:
|
||||
return op{{ $type.AnonymousOmitEmptyHead }}
|
||||
case op{{ $type.StringTagPtrHead }}:
|
||||
case op{{ $type.StringTagPtrHead }}, op{{ $type.StringTagNPtrHead }}:
|
||||
return op{{ $type.StringTagHead }}
|
||||
case op{{ $type.AnonymousStringTagPtrHead }}:
|
||||
case op{{ $type.AnonymousStringTagPtrHead }}, op{{ $type.AnonymousStringTagNPtrHead }}:
|
||||
return op{{ $type.AnonymousStringTagHead }}
|
||||
{{- end }}
|
||||
}
|
||||
|
@ -216,6 +242,12 @@ func (t opType) fieldToStringTagField() opType {
|
|||
"array", "map", "mapLoad", "slice", "struct", "MarshalJSON", "MarshalText", "recursive",
|
||||
"intString", "int8String", "int16String", "int32String", "int64String",
|
||||
"uintString", "uint8String", "uint16String", "uint32String", "uint64String",
|
||||
"intPtr", "int8Ptr", "int16Ptr", "int32Ptr", "int64Ptr",
|
||||
"uintPtr", "uint8Ptr", "uint16Ptr", "uint32Ptr", "uint64Ptr",
|
||||
"float32Ptr", "float64Ptr", "boolPtr", "stringPtr", "bytesPtr",
|
||||
"intNPtr", "int8NPtr", "int16NPtr", "int32NPtr", "int64NPtr",
|
||||
"uintNPtr", "uint8NPtr", "uint16NPtr", "uint32NPtr", "uint64NPtr",
|
||||
"float32NPtr", "float64NPtr", "boolNPtr", "stringNPtr", "bytesNPtr",
|
||||
}
|
||||
primitiveTypesUpper := []string{}
|
||||
for _, typ := range primitiveTypes {
|
||||
|
@ -226,6 +258,7 @@ func (t opType) fieldToStringTagField() opType {
|
|||
{"Interface", "InterfaceIndent", "Op"},
|
||||
{"InterfaceEnd", "InterfaceEndIndent", "Op"},
|
||||
{"Ptr", "PtrIndent", "Op"},
|
||||
{"NPtr", "NPtrIndent", "Op"},
|
||||
{"SliceHead", "SliceHeadIndent", "SliceHead"},
|
||||
{"RootSliceHead", "RootSliceHeadIndent", "SliceHead"},
|
||||
{"SliceElem", "SliceElemIndent", "SliceElem"},
|
||||
|
@ -245,12 +278,18 @@ func (t opType) fieldToStringTagField() opType {
|
|||
{"StructFieldAnonymousHead", "StructFieldAnonymousHeadIndent", "StructField"},
|
||||
{"StructFieldAnonymousHeadOmitEmpty", "StructFieldAnonymousHeadOmitEmptyIndent", "StructField"},
|
||||
{"StructFieldPtrAnonymousHeadOmitEmpty", "StructFieldPtrAnonymousHeadOmitEmptyIndent", "StructField"},
|
||||
{"StructFieldNPtrAnonymousHeadOmitEmpty", "StructFieldNPtrAnonymousHeadOmitEmptyIndent", "StructField"},
|
||||
{"StructFieldAnonymousHeadStringTag", "StructFieldAnonymousHeadStringTagIndent", "StructField"},
|
||||
{"StructFieldPtrAnonymousHeadStringTag", "StructFieldPtrAnonymousHeadStringTagIndent", "StructField"},
|
||||
{"StructFieldNPtrAnonymousHeadStringTag", "StructFieldNPtrAnonymousHeadStringTagIndent", "StructField"},
|
||||
{"StructFieldPtrHead", "StructFieldPtrHeadIndent", "StructField"},
|
||||
{"StructFieldPtrHeadOmitEmpty", "StructFieldPtrHeadOmitEmptyIndent", "StructField"},
|
||||
{"StructFieldPtrHeadStringTag", "StructFieldPtrHeadStringTagIndent", "StructField"},
|
||||
{"StructFieldPtrAnonymousHead", "StructFieldPtrAnonymousHeadIndent", "StructField"},
|
||||
{"StructFieldNPtrHead", "StructFieldNPtrHeadIndent", "StructField"},
|
||||
{"StructFieldNPtrHeadOmitEmpty", "StructFieldNPtrHeadOmitEmptyIndent", "StructField"},
|
||||
{"StructFieldNPtrHeadStringTag", "StructFieldNPtrHeadStringTagIndent", "StructField"},
|
||||
{"StructFieldNPtrAnonymousHead", "StructFieldNPtrAnonymousHeadIndent", "StructField"},
|
||||
{"StructField", "StructFieldIndent", "StructField"},
|
||||
{"StructFieldOmitEmpty", "StructFieldOmitEmptyIndent", "StructField"},
|
||||
{"StructFieldStringTag", "StructFieldStringTagIndent", "StructField"},
|
||||
|
@ -278,8 +317,15 @@ func (t opType) fieldToStringTagField() opType {
|
|||
"StructFieldPtrAnonymousHead",
|
||||
"StructFieldPtrAnonymousHeadOmitEmpty",
|
||||
"StructFieldPtrAnonymousHeadStringTag",
|
||||
"StructFieldNPtrHead",
|
||||
"StructFieldNPtrHeadOmitEmpty",
|
||||
"StructFieldNPtrHeadStringTag",
|
||||
"StructFieldNPtrAnonymousHead",
|
||||
"StructFieldNPtrAnonymousHeadOmitEmpty",
|
||||
"StructFieldNPtrAnonymousHeadStringTag",
|
||||
"StructField",
|
||||
"StructFieldPtr",
|
||||
//"StructFieldPtr",
|
||||
//"StructFieldNPtr",
|
||||
"StructFieldOmitEmpty",
|
||||
"StructFieldStringTag",
|
||||
} {
|
||||
|
@ -299,50 +345,68 @@ func (t opType) fieldToStringTagField() opType {
|
|||
})
|
||||
}
|
||||
base := headType{
|
||||
Head: "StructFieldHead",
|
||||
PtrHead: "StructFieldPtrHead",
|
||||
AnonymousHead: "StructFieldAnonymousHead",
|
||||
AnonymousPtrHead: "StructFieldPtrAnonymousHead",
|
||||
OmitEmptyHead: "StructFieldHeadOmitEmpty",
|
||||
OmitEmptyPtrHead: "StructFieldPtrHeadOmitEmpty",
|
||||
StringTagHead: "StructFieldHeadStringTag",
|
||||
StringTagPtrHead: "StructFieldPtrHeadStringTag",
|
||||
AnonymousOmitEmptyHead: "StructFieldAnonymousHeadOmitEmpty",
|
||||
AnonymousOmitEmptyPtrHead: "StructFieldPtrAnonymousHeadOmitEmpty",
|
||||
AnonymousStringTagHead: "StructFieldAnonymousHeadStringTag",
|
||||
AnonymousStringTagPtrHead: "StructFieldPtrAnonymousHeadStringTag",
|
||||
Head: "StructFieldHead",
|
||||
PtrHead: "StructFieldPtrHead",
|
||||
NPtrHead: "StructFieldNPtrHead",
|
||||
AnonymousHead: "StructFieldAnonymousHead",
|
||||
AnonymousPtrHead: "StructFieldPtrAnonymousHead",
|
||||
AnonymousNPtrHead: "StructFieldNPtrAnonymousHead",
|
||||
OmitEmptyHead: "StructFieldHeadOmitEmpty",
|
||||
OmitEmptyPtrHead: "StructFieldPtrHeadOmitEmpty",
|
||||
OmitEmptyNPtrHead: "StructFieldNPtrHeadOmitEmpty",
|
||||
StringTagHead: "StructFieldHeadStringTag",
|
||||
StringTagPtrHead: "StructFieldPtrHeadStringTag",
|
||||
StringTagNPtrHead: "StructFieldNPtrHeadStringTag",
|
||||
AnonymousOmitEmptyHead: "StructFieldAnonymousHeadOmitEmpty",
|
||||
AnonymousOmitEmptyPtrHead: "StructFieldPtrAnonymousHeadOmitEmpty",
|
||||
AnonymousOmitEmptyNPtrHead: "StructFieldNPtrAnonymousHeadOmitEmpty",
|
||||
AnonymousStringTagHead: "StructFieldAnonymousHeadStringTag",
|
||||
AnonymousStringTagPtrHead: "StructFieldPtrAnonymousHeadStringTag",
|
||||
AnonymousStringTagNPtrHead: "StructFieldNPtrAnonymousHeadStringTag",
|
||||
}
|
||||
headTypes := []headType{base}
|
||||
for _, prim := range primitiveTypesUpper {
|
||||
headTypes = append(headTypes, headType{
|
||||
Head: fmt.Sprintf("%s%s", base.Head, prim),
|
||||
PtrHead: fmt.Sprintf("%s%s", base.PtrHead, prim),
|
||||
AnonymousHead: fmt.Sprintf("%s%s", base.AnonymousHead, prim),
|
||||
AnonymousPtrHead: fmt.Sprintf("%s%s", base.AnonymousPtrHead, prim),
|
||||
OmitEmptyHead: fmt.Sprintf("%s%s", base.OmitEmptyHead, prim),
|
||||
OmitEmptyPtrHead: fmt.Sprintf("%s%s", base.OmitEmptyPtrHead, prim),
|
||||
AnonymousOmitEmptyHead: fmt.Sprintf("%s%s", base.AnonymousOmitEmptyHead, prim),
|
||||
AnonymousOmitEmptyPtrHead: fmt.Sprintf("%s%s", base.AnonymousOmitEmptyPtrHead, prim),
|
||||
StringTagHead: fmt.Sprintf("%s%s", base.StringTagHead, prim),
|
||||
StringTagPtrHead: fmt.Sprintf("%s%s", base.StringTagPtrHead, prim),
|
||||
AnonymousStringTagHead: fmt.Sprintf("%s%s", base.AnonymousStringTagHead, prim),
|
||||
AnonymousStringTagPtrHead: fmt.Sprintf("%s%s", base.AnonymousStringTagPtrHead, prim),
|
||||
Head: fmt.Sprintf("%s%s", base.Head, prim),
|
||||
PtrHead: fmt.Sprintf("%s%s", base.PtrHead, prim),
|
||||
NPtrHead: fmt.Sprintf("%s%s", base.NPtrHead, prim),
|
||||
AnonymousHead: fmt.Sprintf("%s%s", base.AnonymousHead, prim),
|
||||
AnonymousPtrHead: fmt.Sprintf("%s%s", base.AnonymousPtrHead, prim),
|
||||
AnonymousNPtrHead: fmt.Sprintf("%s%s", base.AnonymousNPtrHead, prim),
|
||||
OmitEmptyHead: fmt.Sprintf("%s%s", base.OmitEmptyHead, prim),
|
||||
OmitEmptyPtrHead: fmt.Sprintf("%s%s", base.OmitEmptyPtrHead, prim),
|
||||
OmitEmptyNPtrHead: fmt.Sprintf("%s%s", base.OmitEmptyNPtrHead, prim),
|
||||
AnonymousOmitEmptyHead: fmt.Sprintf("%s%s", base.AnonymousOmitEmptyHead, prim),
|
||||
AnonymousOmitEmptyPtrHead: fmt.Sprintf("%s%s", base.AnonymousOmitEmptyPtrHead, prim),
|
||||
AnonymousOmitEmptyNPtrHead: fmt.Sprintf("%s%s", base.AnonymousOmitEmptyNPtrHead, prim),
|
||||
StringTagHead: fmt.Sprintf("%s%s", base.StringTagHead, prim),
|
||||
StringTagPtrHead: fmt.Sprintf("%s%s", base.StringTagPtrHead, prim),
|
||||
StringTagNPtrHead: fmt.Sprintf("%s%s", base.StringTagNPtrHead, prim),
|
||||
AnonymousStringTagHead: fmt.Sprintf("%s%s", base.AnonymousStringTagHead, prim),
|
||||
AnonymousStringTagPtrHead: fmt.Sprintf("%s%s", base.AnonymousStringTagPtrHead, prim),
|
||||
AnonymousStringTagNPtrHead: fmt.Sprintf("%s%s", base.AnonymousStringTagNPtrHead, prim),
|
||||
})
|
||||
}
|
||||
for _, typ := range headTypes {
|
||||
headTypes = append(headTypes, headType{
|
||||
Head: fmt.Sprintf("%sIndent", typ.Head),
|
||||
PtrHead: fmt.Sprintf("%sIndent", typ.PtrHead),
|
||||
AnonymousHead: fmt.Sprintf("%sIndent", typ.AnonymousHead),
|
||||
AnonymousPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousPtrHead),
|
||||
OmitEmptyHead: fmt.Sprintf("%sIndent", typ.OmitEmptyHead),
|
||||
OmitEmptyPtrHead: fmt.Sprintf("%sIndent", typ.OmitEmptyPtrHead),
|
||||
AnonymousOmitEmptyHead: fmt.Sprintf("%sIndent", typ.AnonymousOmitEmptyHead),
|
||||
AnonymousOmitEmptyPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousOmitEmptyPtrHead),
|
||||
StringTagHead: fmt.Sprintf("%sIndent", typ.StringTagHead),
|
||||
StringTagPtrHead: fmt.Sprintf("%sIndent", typ.StringTagPtrHead),
|
||||
AnonymousStringTagHead: fmt.Sprintf("%sIndent", typ.AnonymousStringTagHead),
|
||||
AnonymousStringTagPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousStringTagPtrHead),
|
||||
Head: fmt.Sprintf("%sIndent", typ.Head),
|
||||
PtrHead: fmt.Sprintf("%sIndent", typ.PtrHead),
|
||||
NPtrHead: fmt.Sprintf("%sIndent", typ.NPtrHead),
|
||||
AnonymousHead: fmt.Sprintf("%sIndent", typ.AnonymousHead),
|
||||
AnonymousPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousPtrHead),
|
||||
AnonymousNPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousNPtrHead),
|
||||
OmitEmptyHead: fmt.Sprintf("%sIndent", typ.OmitEmptyHead),
|
||||
OmitEmptyPtrHead: fmt.Sprintf("%sIndent", typ.OmitEmptyPtrHead),
|
||||
OmitEmptyNPtrHead: fmt.Sprintf("%sIndent", typ.OmitEmptyNPtrHead),
|
||||
AnonymousOmitEmptyHead: fmt.Sprintf("%sIndent", typ.AnonymousOmitEmptyHead),
|
||||
AnonymousOmitEmptyPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousOmitEmptyPtrHead),
|
||||
AnonymousOmitEmptyNPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousOmitEmptyNPtrHead),
|
||||
StringTagHead: fmt.Sprintf("%sIndent", typ.StringTagHead),
|
||||
StringTagPtrHead: fmt.Sprintf("%sIndent", typ.StringTagPtrHead),
|
||||
StringTagNPtrHead: fmt.Sprintf("%sIndent", typ.StringTagNPtrHead),
|
||||
AnonymousStringTagHead: fmt.Sprintf("%sIndent", typ.AnonymousStringTagHead),
|
||||
AnonymousStringTagPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousStringTagPtrHead),
|
||||
AnonymousStringTagNPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousStringTagNPtrHead),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -508,8 +508,84 @@ func (e *Encoder) compileMap(ctx *encodeCompileContext, withLoad bool) (*opcode,
|
|||
return (*opcode)(unsafe.Pointer(header)), nil
|
||||
}
|
||||
|
||||
func (e *Encoder) typeToHeaderType(op opType) opType {
|
||||
switch op {
|
||||
func (e *Encoder) typeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
|
||||
switch code.op {
|
||||
case opPtr:
|
||||
ptrNum := 1
|
||||
c := code
|
||||
ctx.decIndex()
|
||||
for {
|
||||
if code.next.op == opPtr {
|
||||
ptrNum++
|
||||
code = code.next
|
||||
ctx.decIndex()
|
||||
}
|
||||
break
|
||||
}
|
||||
c.ptrNum = ptrNum
|
||||
if ptrNum > 1 {
|
||||
switch code.next.op {
|
||||
case opInt:
|
||||
return opStructFieldHeadIntNPtr
|
||||
case opInt8:
|
||||
return opStructFieldHeadInt8NPtr
|
||||
case opInt16:
|
||||
return opStructFieldHeadInt16NPtr
|
||||
case opInt32:
|
||||
return opStructFieldHeadInt32NPtr
|
||||
case opInt64:
|
||||
return opStructFieldHeadInt64NPtr
|
||||
case opUint:
|
||||
return opStructFieldHeadUintNPtr
|
||||
case opUint8:
|
||||
return opStructFieldHeadUint8NPtr
|
||||
case opUint16:
|
||||
return opStructFieldHeadUint16NPtr
|
||||
case opUint32:
|
||||
return opStructFieldHeadUint32NPtr
|
||||
case opUint64:
|
||||
return opStructFieldHeadUint64NPtr
|
||||
case opFloat32:
|
||||
return opStructFieldHeadFloat32NPtr
|
||||
case opFloat64:
|
||||
return opStructFieldHeadFloat64NPtr
|
||||
case opString:
|
||||
return opStructFieldHeadStringNPtr
|
||||
case opBool:
|
||||
return opStructFieldHeadBoolNPtr
|
||||
}
|
||||
} else {
|
||||
switch code.next.op {
|
||||
case opInt:
|
||||
return opStructFieldHeadIntPtr
|
||||
case opInt8:
|
||||
return opStructFieldHeadInt8Ptr
|
||||
case opInt16:
|
||||
return opStructFieldHeadInt16Ptr
|
||||
case opInt32:
|
||||
return opStructFieldHeadInt32Ptr
|
||||
case opInt64:
|
||||
return opStructFieldHeadInt64Ptr
|
||||
case opUint:
|
||||
return opStructFieldHeadUintPtr
|
||||
case opUint8:
|
||||
return opStructFieldHeadUint8Ptr
|
||||
case opUint16:
|
||||
return opStructFieldHeadUint16Ptr
|
||||
case opUint32:
|
||||
return opStructFieldHeadUint32Ptr
|
||||
case opUint64:
|
||||
return opStructFieldHeadUint64Ptr
|
||||
case opFloat32:
|
||||
return opStructFieldHeadFloat32Ptr
|
||||
case opFloat64:
|
||||
return opStructFieldHeadFloat64Ptr
|
||||
case opString:
|
||||
return opStructFieldHeadStringPtr
|
||||
case opBool:
|
||||
return opStructFieldHeadBoolPtr
|
||||
}
|
||||
}
|
||||
case opInt:
|
||||
return opStructFieldHeadInt
|
||||
case opIntIndent:
|
||||
|
@ -598,38 +674,83 @@ func (e *Encoder) typeToHeaderType(op opType) opType {
|
|||
return opStructFieldHead
|
||||
}
|
||||
|
||||
func (e *Encoder) typeToFieldType(code *opcode) opType {
|
||||
func (e *Encoder) typeToFieldType(ctx *encodeCompileContext, code *opcode) opType {
|
||||
switch code.op {
|
||||
case opPtr:
|
||||
switch code.next.op {
|
||||
case opInt:
|
||||
return opStructFieldPtrInt
|
||||
case opInt8:
|
||||
return opStructFieldPtrInt8
|
||||
case opInt16:
|
||||
return opStructFieldPtrInt16
|
||||
case opInt32:
|
||||
return opStructFieldPtrInt32
|
||||
case opInt64:
|
||||
return opStructFieldPtrInt64
|
||||
case opUint:
|
||||
return opStructFieldPtrUint
|
||||
case opUint8:
|
||||
return opStructFieldPtrUint8
|
||||
case opUint16:
|
||||
return opStructFieldPtrUint16
|
||||
case opUint32:
|
||||
return opStructFieldPtrUint32
|
||||
case opUint64:
|
||||
return opStructFieldPtrUint64
|
||||
case opFloat32:
|
||||
return opStructFieldPtrFloat32
|
||||
case opFloat64:
|
||||
return opStructFieldPtrFloat64
|
||||
case opString:
|
||||
return opStructFieldPtrString
|
||||
case opBool:
|
||||
return opStructFieldPtrBool
|
||||
ptrNum := 1
|
||||
ctx.decIndex()
|
||||
c := code
|
||||
for {
|
||||
if code.next.op == opPtr {
|
||||
ptrNum++
|
||||
code = code.next
|
||||
ctx.decIndex()
|
||||
}
|
||||
break
|
||||
}
|
||||
c.ptrNum = ptrNum
|
||||
if ptrNum > 1 {
|
||||
switch code.next.op {
|
||||
case opInt:
|
||||
return opStructFieldIntNPtr
|
||||
case opInt8:
|
||||
return opStructFieldInt8NPtr
|
||||
case opInt16:
|
||||
return opStructFieldInt16NPtr
|
||||
case opInt32:
|
||||
return opStructFieldInt32NPtr
|
||||
case opInt64:
|
||||
return opStructFieldInt64NPtr
|
||||
case opUint:
|
||||
return opStructFieldUintNPtr
|
||||
case opUint8:
|
||||
return opStructFieldUint8NPtr
|
||||
case opUint16:
|
||||
return opStructFieldUint16NPtr
|
||||
case opUint32:
|
||||
return opStructFieldUint32NPtr
|
||||
case opUint64:
|
||||
return opStructFieldUint64NPtr
|
||||
case opFloat32:
|
||||
return opStructFieldFloat32NPtr
|
||||
case opFloat64:
|
||||
return opStructFieldFloat64NPtr
|
||||
case opString:
|
||||
return opStructFieldStringNPtr
|
||||
case opBool:
|
||||
return opStructFieldBoolNPtr
|
||||
}
|
||||
} else {
|
||||
switch code.next.op {
|
||||
case opInt:
|
||||
return opStructFieldIntPtr
|
||||
case opInt8:
|
||||
return opStructFieldInt8Ptr
|
||||
case opInt16:
|
||||
return opStructFieldInt16Ptr
|
||||
case opInt32:
|
||||
return opStructFieldInt32Ptr
|
||||
case opInt64:
|
||||
return opStructFieldInt64Ptr
|
||||
case opUint:
|
||||
return opStructFieldUintPtr
|
||||
case opUint8:
|
||||
return opStructFieldUint8Ptr
|
||||
case opUint16:
|
||||
return opStructFieldUint16Ptr
|
||||
case opUint32:
|
||||
return opStructFieldUint32Ptr
|
||||
case opUint64:
|
||||
return opStructFieldUint64Ptr
|
||||
case opFloat32:
|
||||
return opStructFieldFloat32Ptr
|
||||
case opFloat64:
|
||||
return opStructFieldFloat64Ptr
|
||||
case opString:
|
||||
return opStructFieldStringPtr
|
||||
case opBool:
|
||||
return opStructFieldBoolPtr
|
||||
}
|
||||
}
|
||||
case opInt:
|
||||
return opStructFieldInt
|
||||
|
@ -719,8 +840,8 @@ func (e *Encoder) typeToFieldType(code *opcode) opType {
|
|||
return opStructField
|
||||
}
|
||||
|
||||
func (e *Encoder) optimizeStructHeader(op opType, tag *structTag, withIndent bool) opType {
|
||||
headType := e.typeToHeaderType(op)
|
||||
func (e *Encoder) optimizeStructHeader(ctx *encodeCompileContext, code *opcode, tag *structTag, withIndent bool) opType {
|
||||
headType := e.typeToHeaderType(ctx, code)
|
||||
switch {
|
||||
case tag.isOmitEmpty:
|
||||
headType = headType.headToOmitEmptyHead()
|
||||
|
@ -733,8 +854,8 @@ func (e *Encoder) optimizeStructHeader(op opType, tag *structTag, withIndent boo
|
|||
return headType
|
||||
}
|
||||
|
||||
func (e *Encoder) optimizeStructField(code *opcode, tag *structTag, withIndent bool) opType {
|
||||
fieldType := e.typeToFieldType(code)
|
||||
func (e *Encoder) optimizeStructField(ctx *encodeCompileContext, code *opcode, tag *structTag, withIndent bool) opType {
|
||||
fieldType := e.typeToFieldType(ctx, code)
|
||||
switch {
|
||||
case tag.isOmitEmpty:
|
||||
fieldType = fieldType.fieldToOmitEmptyField()
|
||||
|
@ -770,8 +891,9 @@ func (e *Encoder) compiledCode(ctx *encodeCompileContext) *opcode {
|
|||
|
||||
func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode {
|
||||
fieldCode.indent--
|
||||
op := e.optimizeStructHeader(valueCode.op, tag, ctx.withIndent)
|
||||
op := e.optimizeStructHeader(ctx, valueCode, tag, ctx.withIndent)
|
||||
fieldCode.op = op
|
||||
fieldCode.ptrNum = valueCode.ptrNum
|
||||
switch op {
|
||||
case opStructFieldHead,
|
||||
opStructFieldHeadSlice,
|
||||
|
@ -807,8 +929,9 @@ func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, val
|
|||
|
||||
func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode {
|
||||
code := (*opcode)(unsafe.Pointer(fieldCode))
|
||||
op := e.optimizeStructField(valueCode, tag, ctx.withIndent)
|
||||
op := e.optimizeStructField(ctx, valueCode, tag, ctx.withIndent)
|
||||
fieldCode.op = op
|
||||
fieldCode.ptrNum = valueCode.ptrNum
|
||||
switch op {
|
||||
case opStructField,
|
||||
opStructFieldSlice,
|
||||
|
|
|
@ -14,6 +14,7 @@ type opcode struct {
|
|||
displayIdx int // opcode index
|
||||
key []byte // struct field key
|
||||
escapedKey []byte // struct field key ( HTML escaped )
|
||||
ptrNum int // pointer number: e.g. double pointer is 2.
|
||||
displayKey string // key text to display
|
||||
isTaggedKey bool // whether tagged key
|
||||
anonymousKey bool // whether anonymous key
|
||||
|
@ -85,6 +86,7 @@ func (c *opcode) copy(codeMap map[uintptr]*opcode) *opcode {
|
|||
key: c.key,
|
||||
escapedKey: c.escapedKey,
|
||||
displayKey: c.displayKey,
|
||||
ptrNum: c.ptrNum,
|
||||
isTaggedKey: c.isTaggedKey,
|
||||
anonymousKey: c.anonymousKey,
|
||||
root: c.root,
|
||||
|
|
19942
encode_optype.go
19942
encode_optype.go
File diff suppressed because it is too large
Load Diff
83
encode_vm.go
83
encode_vm.go
|
@ -54,7 +54,6 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
var seenPtr map[uintptr]struct{}
|
||||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.ptr()
|
||||
|
||||
for {
|
||||
switch code.op {
|
||||
default:
|
||||
|
@ -1169,6 +1168,43 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = encodeComma(b)
|
||||
code = code.next
|
||||
}
|
||||
case opStructFieldHeadIntPtr:
|
||||
p := load(ctxptr, code.idx)
|
||||
if p == 0 {
|
||||
b = encodeNull(b)
|
||||
} else {
|
||||
b = append(b, '{')
|
||||
b = e.encodeKey(b, code)
|
||||
p = e.ptrToPtr(p)
|
||||
if p == 0 {
|
||||
b = encodeNull(b)
|
||||
} else {
|
||||
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
||||
}
|
||||
}
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldHeadIntNPtr:
|
||||
p := load(ctxptr, code.idx)
|
||||
if p == 0 {
|
||||
b = encodeNull(b)
|
||||
} else {
|
||||
b = append(b, '{')
|
||||
b = e.encodeKey(b, code)
|
||||
for i := 0; i < code.ptrNum; i++ {
|
||||
if p == 0 {
|
||||
break
|
||||
}
|
||||
p = e.ptrToPtr(p)
|
||||
}
|
||||
if p == 0 {
|
||||
b = encodeNull(b)
|
||||
} else {
|
||||
b = appendInt(b, int64(e.ptrToInt(p+code.offset)))
|
||||
}
|
||||
}
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrAnonymousHeadInt:
|
||||
store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
|
||||
fallthrough
|
||||
|
@ -4738,7 +4774,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
ptr := load(ctxptr, code.headIdx) + code.offset
|
||||
code = code.next
|
||||
store(ctxptr, code.idx, ptr)
|
||||
case opStructFieldPtrInt:
|
||||
case opStructFieldIntPtr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4749,13 +4785,30 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
}
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldIntNPtr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
for i := 0; i < code.ptrNum-1; i++ {
|
||||
if p == 0 {
|
||||
break
|
||||
}
|
||||
p = e.ptrToPtr(p)
|
||||
}
|
||||
if p == 0 {
|
||||
b = encodeNull(b)
|
||||
} else {
|
||||
b = appendInt(b, int64(e.ptrToInt(p)))
|
||||
}
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldInt:
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
b = e.encodeKey(b, code)
|
||||
b = appendInt(b, int64(e.ptrToInt(ptr+code.offset)))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrInt8:
|
||||
case opStructFieldInt8Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4772,7 +4825,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = appendInt(b, int64(e.ptrToInt8(ptr+code.offset)))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrInt16:
|
||||
case opStructFieldInt16Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4789,7 +4842,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = appendInt(b, int64(e.ptrToInt16(ptr+code.offset)))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrInt32:
|
||||
case opStructFieldInt32Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4806,7 +4859,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = appendInt(b, int64(e.ptrToInt32(ptr+code.offset)))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrInt64:
|
||||
case opStructFieldInt64Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4823,7 +4876,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = appendInt(b, e.ptrToInt64(ptr+code.offset))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrUint:
|
||||
case opStructFieldUintPtr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4840,7 +4893,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = appendUint(b, uint64(e.ptrToUint(ptr+code.offset)))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrUint8:
|
||||
case opStructFieldUint8Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4857,7 +4910,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = appendUint(b, uint64(e.ptrToUint8(ptr+code.offset)))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrUint16:
|
||||
case opStructFieldUint16Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4874,7 +4927,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = appendUint(b, uint64(e.ptrToUint16(ptr+code.offset)))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrUint32:
|
||||
case opStructFieldUint32Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4891,7 +4944,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = appendUint(b, uint64(e.ptrToUint32(ptr+code.offset)))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrUint64:
|
||||
case opStructFieldUint64Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4908,7 +4961,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = appendUint(b, e.ptrToUint64(ptr+code.offset))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrFloat32:
|
||||
case opStructFieldFloat32Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4925,7 +4978,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = encodeFloat32(b, e.ptrToFloat32(ptr+code.offset))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrFloat64:
|
||||
case opStructFieldFloat64Ptr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4952,7 +5005,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = encodeFloat64(b, v)
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrString:
|
||||
case opStructFieldStringPtr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
@ -4969,7 +5022,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
b = e.encodeString(b, e.ptrToString(ptr+code.offset))
|
||||
b = encodeComma(b)
|
||||
code = code.next
|
||||
case opStructFieldPtrBool:
|
||||
case opStructFieldBoolPtr:
|
||||
b = e.encodeKey(b, code)
|
||||
ptr := load(ctxptr, code.headIdx)
|
||||
p := e.ptrToPtr(ptr + code.offset)
|
||||
|
|
Loading…
Reference in New Issue