Merge pull request #50 from goccy/feature/fix-pointer-fields

Fix encoding of pointer fields ( primitive type )
This commit is contained in:
Masaaki Goshima 2020-09-17 21:54:03 +09:00 committed by GitHub
commit d373a4b7d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 3731 additions and 524 deletions

View File

@ -277,6 +277,7 @@ func (t opType) fieldToStringTagField() opType {
"StructFieldPtrAnonymousHeadOmitEmpty", "StructFieldPtrAnonymousHeadOmitEmpty",
"StructFieldPtrAnonymousHeadStringTag", "StructFieldPtrAnonymousHeadStringTag",
"StructField", "StructField",
"StructFieldPtr",
"StructFieldOmitEmpty", "StructFieldOmitEmpty",
"StructFieldStringTag", "StructFieldStringTag",
} { } {

View File

@ -28,11 +28,13 @@ func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
func (d *mapDecoder) setKey(buf []byte, cursor int64, key interface{}) (int64, error) { func (d *mapDecoder) setKey(buf []byte, cursor int64, key interface{}) (int64, error) {
header := (*interfaceHeader)(unsafe.Pointer(&key)) header := (*interfaceHeader)(unsafe.Pointer(&key))
d.dummy = header
return d.keyDecoder.decode(buf, cursor, uintptr(header.ptr)) return d.keyDecoder.decode(buf, cursor, uintptr(header.ptr))
} }
func (d *mapDecoder) setValue(buf []byte, cursor int64, key interface{}) (int64, error) { func (d *mapDecoder) setValue(buf []byte, cursor int64, key interface{}) (int64, error) {
header := (*interfaceHeader)(unsafe.Pointer(&key)) header := (*interfaceHeader)(unsafe.Pointer(&key))
d.dummy = header
return d.valueDecoder.decode(buf, cursor, uintptr(header.ptr)) return d.valueDecoder.decode(buf, cursor, uintptr(header.ptr))
} }

File diff suppressed because it is too large Load Diff

View File

@ -481,8 +481,39 @@ func (e *Encoder) typeToHeaderType(op opType) opType {
return opStructFieldHead return opStructFieldHead
} }
func (e *Encoder) typeToFieldType(op opType) opType { func (e *Encoder) typeToFieldType(code *opcode) opType {
switch op { 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
}
case opInt: case opInt:
return opStructFieldInt return opStructFieldInt
case opInt8: case opInt8:
@ -553,8 +584,8 @@ func (e *Encoder) optimizeStructHeader(op opType, tag *structTag, withIndent boo
return headType return headType
} }
func (e *Encoder) optimizeStructField(op opType, tag *structTag, withIndent bool) opType { func (e *Encoder) optimizeStructField(code *opcode, tag *structTag, withIndent bool) opType {
fieldType := e.typeToFieldType(op) fieldType := e.typeToFieldType(code)
switch { switch {
case tag.isOmitEmpty: case tag.isOmitEmpty:
fieldType = fieldType.fieldToOmitEmptyField() fieldType = fieldType.fieldToOmitEmptyField()
@ -627,7 +658,7 @@ func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, val
func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode { func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode {
code := (*opcode)(unsafe.Pointer(fieldCode)) code := (*opcode)(unsafe.Pointer(fieldCode))
op := e.optimizeStructField(valueCode.op, tag, ctx.withIndent) op := e.optimizeStructField(valueCode, tag, ctx.withIndent)
fieldCode.op = op fieldCode.op = op
switch op { switch op {
case opStructField, case opStructField,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,19 +15,19 @@ import (
type Size int type Size int
const ( const (
Unrecognized Size = iota unrecognized Size = iota
Small small
Large large
) )
func (s *Size) UnmarshalText(text []byte) error { func (s *Size) UnmarshalText(text []byte) error {
switch strings.ToLower(string(text)) { switch strings.ToLower(string(text)) {
default: default:
*s = Unrecognized *s = unrecognized
case "small": case "small":
*s = Small *s = small
case "large": case "large":
*s = Large *s = large
} }
return nil return nil
} }
@ -37,9 +37,9 @@ func (s Size) MarshalText() ([]byte, error) {
switch s { switch s {
default: default:
name = "unrecognized" name = "unrecognized"
case Small: case small:
name = "small" name = "small"
case Large: case large:
name = "large" name = "large"
} }
return []byte(name), nil return []byte(name), nil
@ -58,7 +58,7 @@ func Example_textMarshalJSON() {
} }
fmt.Printf("Inventory Counts:\n* Small: %d\n* Large: %d\n* Unrecognized: %d\n", fmt.Printf("Inventory Counts:\n* Small: %d\n* Large: %d\n* Unrecognized: %d\n",
counts[Small], counts[Large], counts[Unrecognized]) counts[small], counts[large], counts[unrecognized])
// Output: // Output:
// Inventory Counts: // Inventory Counts: