Add special operation for opStructFieldHead and opStructField

This commit is contained in:
Masaaki Goshima 2020-08-24 01:50:18 +09:00
parent 93ce3f8bd2
commit 9ba13f68ff
2 changed files with 459 additions and 0 deletions

View File

@ -435,6 +435,26 @@ func (e *Encoder) typeToHeaderType(op opType) opType {
return opStructFieldHeadString return opStructFieldHeadString
case opBool: case opBool:
return opStructFieldHeadBool return opStructFieldHeadBool
case opMapHead:
return opStructFieldHeadMap
case opMapHeadLoad:
return opStructFieldHeadMapLoad
case opMapHeadIndent:
return opStructFieldHeadMapIndent
case opMapHeadLoadIndent:
return opStructFieldHeadMapLoadIndent
case opArrayHead:
return opStructFieldHeadArray
case opArrayHeadIndent:
return opStructFieldHeadArrayIndent
case opSliceHead:
return opStructFieldHeadSlice
case opSliceHeadIndent:
return opStructFieldHeadSliceIndent
case opStructFieldHead:
return opStructFieldHeadStruct
case opStructFieldHeadIndent:
return opStructFieldHeadStructIndent
case opMarshalJSON: case opMarshalJSON:
return opStructFieldHeadMarshalJSON return opStructFieldHeadMarshalJSON
case opMarshalText: case opMarshalText:
@ -473,6 +493,26 @@ func (e *Encoder) typeToFieldType(op opType) opType {
return opStructFieldString return opStructFieldString
case opBool: case opBool:
return opStructFieldBool return opStructFieldBool
case opMapHead:
return opStructFieldMap
case opMapHeadLoad:
return opStructFieldMapLoad
case opMapHeadIndent:
return opStructFieldMapIndent
case opMapHeadLoadIndent:
return opStructFieldMapLoadIndent
case opArrayHead:
return opStructFieldArray
case opArrayHeadIndent:
return opStructFieldArrayIndent
case opSliceHead:
return opStructFieldSlice
case opSliceHeadIndent:
return opStructFieldSliceIndent
case opStructFieldHead:
return opStructFieldStruct
case opStructFieldHeadIndent:
return opStructFieldStructIndent
case opMarshalJSON: case opMarshalJSON:
return opStructFieldMarshalJSON return opStructFieldMarshalJSON
case opMarshalText: case opMarshalText:
@ -541,10 +581,30 @@ func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, ta
fieldCode.op = op fieldCode.op = op
switch op { switch op {
case opStructFieldHead, case opStructFieldHead,
opStructFieldHeadSlice,
opStructFieldHeadArray,
opStructFieldHeadMap,
opStructFieldHeadMapLoad,
opStructFieldHeadStruct,
opStructFieldHeadOmitEmpty, opStructFieldHeadOmitEmpty,
opStructFieldHeadOmitEmptySlice,
opStructFieldHeadOmitEmptyArray,
opStructFieldHeadOmitEmptyMap,
opStructFieldHeadOmitEmptyMapLoad,
opStructFieldHeadOmitEmptyStruct,
opStructFieldHeadStringTag, opStructFieldHeadStringTag,
opStructFieldHeadIndent, opStructFieldHeadIndent,
opStructFieldHeadSliceIndent,
opStructFieldHeadArrayIndent,
opStructFieldHeadMapIndent,
opStructFieldHeadMapLoadIndent,
opStructFieldHeadStructIndent,
opStructFieldHeadOmitEmptyIndent, opStructFieldHeadOmitEmptyIndent,
opStructFieldHeadOmitEmptySliceIndent,
opStructFieldHeadOmitEmptyArrayIndent,
opStructFieldHeadOmitEmptyMapIndent,
opStructFieldHeadOmitEmptyMapLoadIndent,
opStructFieldHeadOmitEmptyStructIndent,
opStructFieldHeadStringTagIndent: opStructFieldHeadStringTagIndent:
return valueCode.beforeLastCode() return valueCode.beforeLastCode()
} }
@ -557,10 +617,30 @@ func (e *Encoder) structField(fieldCode *structFieldCode, valueCode *opcode, tag
fieldCode.op = op fieldCode.op = op
switch op { switch op {
case opStructField, case opStructField,
opStructFieldSlice,
opStructFieldArray,
opStructFieldMap,
opStructFieldMapLoad,
opStructFieldStruct,
opStructFieldOmitEmpty, opStructFieldOmitEmpty,
opStructFieldOmitEmptySlice,
opStructFieldOmitEmptyArray,
opStructFieldOmitEmptyMap,
opStructFieldOmitEmptyMapLoad,
opStructFieldOmitEmptyStruct,
opStructFieldStringTag, opStructFieldStringTag,
opStructFieldIndent, opStructFieldIndent,
opStructFieldSliceIndent,
opStructFieldArrayIndent,
opStructFieldMapIndent,
opStructFieldMapLoadIndent,
opStructFieldStructIndent,
opStructFieldOmitEmptyIndent, opStructFieldOmitEmptyIndent,
opStructFieldOmitEmptySliceIndent,
opStructFieldOmitEmptyArrayIndent,
opStructFieldOmitEmptyMapIndent,
opStructFieldOmitEmptyMapLoadIndent,
opStructFieldOmitEmptyStructIndent,
opStructFieldStringTagIndent: opStructFieldStringTagIndent:
return valueCode.beforeLastCode() return valueCode.beforeLastCode()
} }

View File

@ -1093,6 +1093,78 @@ func (e *Encoder) run(code *opcode) error {
field.nextField.ptr = ptr field.nextField.ptr = ptr
code = field.next code = field.next
} }
case opStructFieldPtrHeadArray:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadArray:
c := code.toStructFieldCode()
ptr := c.ptr + c.offset
if ptr == 0 {
if code.op == opStructFieldPtrHeadArray {
e.encodeNull()
} else {
e.encodeBytes([]byte{'[', ']'})
}
code = c.end
} else {
e.encodeByte('{')
if !c.anonymousKey {
e.encodeBytes(c.key)
}
code = c.next
code.ptr = ptr
c.nextField.ptr = ptr
}
case opStructFieldPtrAnonymousHeadArray:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldAnonymousHeadArray:
c := code.toStructFieldCode()
ptr := c.ptr + c.offset
if ptr == 0 {
code = c.end
} else {
e.encodeBytes(c.key)
code.ptr = ptr
c.nextField.ptr = ptr
code = c.next
}
case opStructFieldPtrHeadSlice:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldHeadSlice:
c := code.toStructFieldCode()
ptr := c.ptr + c.offset
if ptr == 0 {
if code.op == opStructFieldPtrHeadSlice {
e.encodeNull()
} else {
e.encodeBytes([]byte{'[', ']'})
}
code = c.end
} else {
e.encodeByte('{')
if !c.anonymousKey {
e.encodeBytes(c.key)
}
code = c.next
code.ptr = ptr
c.nextField.ptr = ptr
}
case opStructFieldPtrAnonymousHeadSlice:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
case opStructFieldAnonymousHeadSlice:
c := code.toStructFieldCode()
ptr := c.ptr + c.offset
if ptr == 0 {
code = c.end
} else {
e.encodeBytes(c.key)
code.ptr = ptr
c.nextField.ptr = ptr
code = c.next
}
case opStructFieldPtrHeadMarshalJSON: case opStructFieldPtrHeadMarshalJSON:
code.ptr = e.ptrToPtr(code.ptr) code.ptr = e.ptrToPtr(code.ptr)
fallthrough fallthrough
@ -4150,6 +4222,51 @@ func (e *Encoder) run(code *opcode) error {
} }
e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeString(*(*string)(unsafe.Pointer(&bytes)))
code = code.next code = code.next
case opStructFieldArray:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',')
}
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
code = code.next
code.ptr = c.ptr + c.offset
e.encodeBytes(c.key)
case opStructFieldSlice:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',')
}
c := code.toStructFieldCode()
c.nextField.ptr = c.ptr
code = code.next
code.ptr = c.ptr + c.offset
e.encodeBytes(c.key)
case opStructFieldMap:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',')
}
c := code.toStructFieldCode()
e.encodeBytes(c.key)
code = code.next
code.ptr = c.ptr + c.offset
c.nextField.ptr = c.ptr
case opStructFieldMapLoad:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',')
}
c := code.toStructFieldCode()
e.encodeBytes(c.key)
code = code.next
code.ptr = c.ptr + c.offset
c.nextField.ptr = c.ptr
case opStructFieldStruct:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',')
}
c := code.toStructFieldCode()
e.encodeBytes(c.key)
code = code.next
code.ptr = c.ptr + c.offset
c.nextField.ptr = c.ptr
case opStructFieldIndent: case opStructFieldIndent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' { if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
@ -4363,6 +4480,111 @@ func (e *Encoder) run(code *opcode) error {
e.encodeBytes(buf.Bytes()) e.encodeBytes(buf.Bytes())
code = code.next code = code.next
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldArrayIndent:
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
c := code.toStructFieldCode()
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
p := c.ptr + c.offset
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
if p == 0 || header.Data == 0 {
e.encodeNull()
code = c.nextField
} else {
code = code.next
}
c.nextField.ptr = c.ptr
case opStructFieldSliceIndent:
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
c := code.toStructFieldCode()
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
p := c.ptr + c.offset
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
if p == 0 || header.Data == 0 {
e.encodeNull()
code = c.nextField
} else {
code = code.next
}
c.nextField.ptr = c.ptr
case opStructFieldMapIndent:
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
c := code.toStructFieldCode()
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
p := c.ptr + c.offset
if p == 0 {
e.encodeNull()
code = c.nextField
} else {
mlen := maplen(unsafe.Pointer(p))
if mlen == 0 {
e.encodeBytes([]byte{'{', '}'})
mapCode := code.next
mapHeadCode := mapCode.toMapHeadCode()
code = mapHeadCode.end.next
} else {
code = code.next
}
}
c.nextField.ptr = c.ptr
case opStructFieldMapLoadIndent:
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
c := code.toStructFieldCode()
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
p := c.ptr + c.offset
if p == 0 {
e.encodeNull()
code = c.nextField
} else {
p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p)))
mlen := maplen(unsafe.Pointer(p))
if mlen == 0 {
e.encodeBytes([]byte{'{', '}'})
code = c.nextField
} else {
code = code.next
}
}
c.nextField.ptr = c.ptr
case opStructFieldStructIndent:
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
c := code.toStructFieldCode()
p := c.ptr + c.offset
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
if p == 0 {
e.encodeBytes([]byte{'{', '}'})
code = c.nextField
} else {
headCode := c.next.toStructFieldCode()
if headCode.next == headCode.end {
// not exists fields
e.encodeBytes([]byte{'{', '}'})
code = c.nextField
} else {
code = code.next
code.ptr = p
}
}
c.nextField.ptr = c.ptr
case opStructFieldOmitEmpty: case opStructFieldOmitEmpty:
c := code.toStructFieldCode() c := code.toStructFieldCode()
p := c.ptr + c.offset p := c.ptr + c.offset
@ -4612,6 +4834,67 @@ func (e *Encoder) run(code *opcode) error {
} }
code = code.next code = code.next
code.ptr = c.ptr code.ptr = c.ptr
case opStructFieldOmitEmptyArray:
c := code.toStructFieldCode()
p := c.ptr + c.offset
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
if p == 0 || header.Data == 0 {
code = c.nextField
} else {
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',')
}
code = code.next
}
c.nextField.ptr = c.ptr
case opStructFieldOmitEmptySlice:
c := code.toStructFieldCode()
p := c.ptr + c.offset
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
if p == 0 || header.Data == 0 {
code = c.nextField
} else {
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',')
}
code = code.next
}
c.nextField.ptr = c.ptr
case opStructFieldOmitEmptyMap:
c := code.toStructFieldCode()
p := c.ptr + c.offset
if p == 0 {
code = c.nextField
} else {
mlen := maplen(unsafe.Pointer(p))
if mlen == 0 {
code = c.nextField
} else {
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',')
}
code = code.next
}
}
c.nextField.ptr = c.ptr
case opStructFieldOmitEmptyMapLoad:
c := code.toStructFieldCode()
p := c.ptr + c.offset
if p == 0 {
code = c.nextField
} else {
p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p)))
mlen := maplen(unsafe.Pointer(p))
if mlen == 0 {
code = c.nextField
} else {
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',')
}
code = code.next
}
}
c.nextField.ptr = c.ptr
case opStructFieldOmitEmptyIndent: case opStructFieldOmitEmptyIndent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
p := c.ptr + c.offset p := c.ptr + c.offset
@ -4847,6 +5130,102 @@ func (e *Encoder) run(code *opcode) error {
} }
code = code.next code = code.next
code.ptr = c.ptr code.ptr = c.ptr
case opStructFieldOmitEmptyArrayIndent:
c := code.toStructFieldCode()
p := c.ptr + c.offset
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
if p == 0 || header.Data == 0 {
code = c.nextField
} else {
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
code = code.next
}
c.nextField.ptr = c.ptr
case opStructFieldOmitEmptySliceIndent:
c := code.toStructFieldCode()
p := c.ptr + c.offset
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
if p == 0 || header.Data == 0 {
code = c.nextField
} else {
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
code = code.next
}
c.nextField.ptr = c.ptr
case opStructFieldOmitEmptyMapIndent:
c := code.toStructFieldCode()
p := c.ptr + c.offset
if p == 0 {
code = c.nextField
} else {
mlen := maplen(unsafe.Pointer(p))
if mlen == 0 {
code = c.nextField
} else {
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
code = code.next
}
}
c.nextField.ptr = c.ptr
case opStructFieldOmitEmptyMapLoadIndent:
c := code.toStructFieldCode()
p := c.ptr + c.offset
if p == 0 {
code = c.nextField
} else {
p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p)))
mlen := maplen(unsafe.Pointer(p))
if mlen == 0 {
code = c.nextField
} else {
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
code = code.next
}
}
c.nextField.ptr = c.ptr
case opStructFieldOmitEmptyStructIndent:
c := code.toStructFieldCode()
p := c.ptr + c.offset
if p == 0 {
code = c.nextField
} else {
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent)
e.encodeBytes(c.key)
e.encodeByte(' ')
headCode := c.next.toStructFieldCode()
if headCode.next == headCode.end {
// not exists fields
e.encodeBytes([]byte{'{', '}'})
code = c.nextField
} else {
code = code.next
code.ptr = p
}
}
c.nextField.ptr = c.ptr
case opStructFieldStringTag: case opStructFieldStringTag:
c := code.toStructFieldCode() c := code.toStructFieldCode()
p := c.ptr + c.offset p := c.ptr + c.offset