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

View File

@ -1093,6 +1093,78 @@ func (e *Encoder) run(code *opcode) error {
field.nextField.ptr = ptr
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:
code.ptr = e.ptrToPtr(code.ptr)
fallthrough
@ -4150,6 +4222,51 @@ func (e *Encoder) run(code *opcode) error {
}
e.encodeString(*(*string)(unsafe.Pointer(&bytes)))
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:
c := code.toStructFieldCode()
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())
code = code.next
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:
c := code.toStructFieldCode()
p := c.ptr + c.offset
@ -4612,6 +4834,67 @@ func (e *Encoder) run(code *opcode) error {
}
code = code.next
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:
c := code.toStructFieldCode()
p := c.ptr + c.offset
@ -4847,6 +5130,102 @@ func (e *Encoder) run(code *opcode) error {
}
code = code.next
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:
c := code.toStructFieldCode()
p := c.ptr + c.offset