Compare commits

...

6 Commits

Author SHA1 Message Date
Masaaki Goshima 02fb2b9de7 Revert "Refactor HeadInt operation"
This reverts commit fbfaea2c88.
2021-02-23 16:10:57 +09:00
Masaaki Goshima 8aded2b62d Add NPtr operation 2021-02-23 16:07:04 +09:00
Masaaki Goshima 52b2bf1089 Fix encoding of slice type 2021-02-23 16:05:16 +09:00
Masaaki Goshima ae68eaf96b Add pointer operation 2021-02-23 15:57:32 +09:00
Masaaki Goshima c8f6acaa2b Refactor ptr operation 2021-02-23 15:32:33 +09:00
Masaaki Goshima fbfaea2c88 Refactor HeadInt operation 2021-02-22 17:15:48 +09:00
7 changed files with 852 additions and 114 deletions

View File

@ -6,6 +6,7 @@ import (
) )
func intptr(v int) *int { return &v } func intptr(v int) *int { return &v }
func intptr3(v int) ***int { vv := &v; vvv := &vv; return &vvv }
func int8ptr(v int8) *int8 { return &v } func int8ptr(v int8) *int8 { return &v }
func int16ptr(v int16) *int16 { return &v } func int16ptr(v int16) *int16 { return &v }
func int32ptr(v int32) *int32 { return &v } func int32ptr(v int32) *int32 { return &v }

View File

@ -28,10 +28,81 @@ func TestCoverInt(t *testing.T) {
A *int `json:"a,string"` A *int `json:"a,string"`
} }
type structIntTriplePtr struct {
A ***int `json:"a"`
}
type structIntTriplePtrOmitEmpty struct {
A ***int `json:"a,omitempty"`
}
type structIntTriplePtrString struct {
A ***int `json:"a,string"`
}
tests := []struct { tests := []struct {
name string name string
data interface{} data interface{}
}{ }{
{
name: "Int",
data: 10,
},
{
name: "IntPtr",
data: intptr(10),
},
{
name: "IntTriplePtr",
data: intptr3(10),
},
{
name: "IntSlice",
data: []int{1, 2, 3, 4, 5},
},
{
name: "IntPtrSlice",
data: []*int{nil, nil, intptr(1), nil, nil},
},
{
name: "StructIntSliceNil",
data: ([]structInt)(nil),
},
{
name: "PtrStructIntSliceNil",
data: ([]*structInt)(nil),
},
{
name: "StructIntSliceZero",
data: []structInt{},
},
{
name: "PtrStructIntSliceZero",
data: []*structInt{},
},
{
name: "PtrStructIntNilSlice",
data: []*structInt{nil, nil},
},
{
name: "StructIntOmitEmptySliceNil",
data: ([]structIntOmitEmpty)(nil),
},
{
name: "PtrStructIntOmitEmptySliceNil",
data: ([]*structIntOmitEmpty)(nil),
},
{
name: "StructIntOmitEmptySliceZero",
data: []structIntOmitEmpty{},
},
{
name: "PtrStructIntOmitEmptySliceZero",
data: []*structIntOmitEmpty{},
},
{
name: "PtrStructIntOmitEmptyNilSlice",
data: []*structIntOmitEmpty{nil, nil},
},
// HeadIntZero // HeadIntZero
{ {
name: "HeadIntZero", name: "HeadIntZero",

View File

@ -357,9 +357,7 @@ func encodeCompilePtr(ctx *encodeCompileContext) (*opcode, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
ptrHeadOp := code.op.headToPtrHead() if encodeConvertPtrOp(code) {
if code.op != ptrHeadOp {
code.op = ptrHeadOp
code.decOpcodeIndex() code.decOpcodeIndex()
ctx.decIndex() ctx.decIndex()
return code, nil return code, nil
@ -370,6 +368,84 @@ func encodeCompilePtr(ctx *encodeCompileContext) (*opcode, error) {
return newOpCodeWithNext(c, opPtr, code), nil return newOpCodeWithNext(c, opPtr, code), nil
} }
func encodeConvertPtrOp(code *opcode) bool {
ptrHeadOp := code.op.headToPtrHead()
if code.op != ptrHeadOp {
code.op = ptrHeadOp
return true
}
switch code.op {
case opInt:
code.op = opIntPtr
code.ptrNum++
return true
case opIntPtr:
code.op = opIntNPtr
code.ptrNum++
return true
case opIntNPtr:
code.ptrNum++
return true
case opUint:
code.op = opUintPtr
code.ptrNum++
return true
case opUintPtr:
code.op = opUintNPtr
code.ptrNum++
return true
case opUintNPtr:
code.ptrNum++
return true
case opFloat32:
code.op = opFloat32Ptr
code.ptrNum++
return true
case opFloat32Ptr:
code.op = opFloat32NPtr
code.ptrNum++
return true
case opFloat32NPtr:
code.ptrNum++
return true
case opFloat64:
code.op = opFloat64Ptr
code.ptrNum++
return true
case opFloat64Ptr:
code.op = opFloat64NPtr
code.ptrNum++
return true
case opFloat64NPtr:
code.ptrNum++
return true
case opString:
code.op = opStringPtr
code.ptrNum++
return true
case opStringPtr:
code.op = opStringNPtr
code.ptrNum++
return true
case opStringNPtr:
code.ptrNum++
return true
case opBool:
code.op = opBoolPtr
code.ptrNum++
return true
case opBoolPtr:
code.op = opBoolNPtr
code.ptrNum++
return true
case opBoolNPtr:
code.ptrNum++
return true
default:
return false
}
}
func encodeCompileMarshalJSON(ctx *encodeCompileContext) (*opcode, error) { func encodeCompileMarshalJSON(ctx *encodeCompileContext) (*opcode, error) {
code := newOpCode(ctx, opMarshalJSON) code := newOpCode(ctx, opMarshalJSON)
ctx.incIndex() ctx.incIndex()
@ -747,69 +823,42 @@ func encodeCompileMap(ctx *encodeCompileContext, withLoad bool) (*opcode, error)
func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType { func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
switch code.op { switch code.op {
case opPtr:
ptrNum := 1
c := code
ctx.decIndex()
for {
if code.next.op == opPtr {
ptrNum++
code = code.next
ctx.decIndex()
continue
}
break
}
c.ptrNum = ptrNum
if ptrNum > 1 {
switch code.next.op {
case opInt:
c.mask = code.next.mask
c.rshiftNum = code.next.rshiftNum
return opStructFieldHeadIntNPtr
case opUint:
c.mask = code.next.mask
return opStructFieldHeadUintNPtr
case opFloat32:
return opStructFieldHeadFloat32NPtr
case opFloat64:
return opStructFieldHeadFloat64NPtr
case opString:
return opStructFieldHeadStringNPtr
case opBool:
return opStructFieldHeadBoolNPtr
}
} else {
switch code.next.op {
case opInt:
c.mask = code.next.mask
c.rshiftNum = code.next.rshiftNum
return opStructFieldHeadIntPtr
case opUint:
c.mask = code.next.mask
return opStructFieldHeadUintPtr
case opFloat32:
return opStructFieldHeadFloat32Ptr
case opFloat64:
return opStructFieldHeadFloat64Ptr
case opString:
return opStructFieldHeadStringPtr
case opBool:
return opStructFieldHeadBoolPtr
}
}
case opInt: case opInt:
return opStructFieldHeadInt return opStructFieldHeadInt
case opIntPtr:
return opStructFieldHeadIntPtr
case opIntNPtr:
return opStructFieldHeadIntNPtr
case opUint: case opUint:
return opStructFieldHeadUint return opStructFieldHeadUint
case opUintPtr:
return opStructFieldHeadUintPtr
case opUintNPtr:
return opStructFieldHeadUintNPtr
case opFloat32: case opFloat32:
return opStructFieldHeadFloat32 return opStructFieldHeadFloat32
case opFloat32Ptr:
return opStructFieldHeadFloat32Ptr
case opFloat32NPtr:
return opStructFieldHeadFloat32NPtr
case opFloat64: case opFloat64:
return opStructFieldHeadFloat64 return opStructFieldHeadFloat64
case opFloat64Ptr:
return opStructFieldHeadFloat64Ptr
case opFloat64NPtr:
return opStructFieldHeadFloat64NPtr
case opString: case opString:
return opStructFieldHeadString return opStructFieldHeadString
case opStringPtr:
return opStructFieldHeadStringPtr
case opStringNPtr:
return opStructFieldHeadStringNPtr
case opBool: case opBool:
return opStructFieldHeadBool return opStructFieldHeadBool
case opBoolPtr:
return opStructFieldHeadBoolPtr
case opBoolNPtr:
return opStructFieldHeadBoolNPtr
case opMapHead: case opMapHead:
return opStructFieldHeadMap return opStructFieldHeadMap
case opMapHeadLoad: case opMapHeadLoad:
@ -830,69 +879,42 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType { func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType {
switch code.op { switch code.op {
case opPtr:
ptrNum := 1
ctx.decIndex()
c := code
for {
if code.next.op == opPtr {
ptrNum++
code = code.next
ctx.decIndex()
continue
}
break
}
c.ptrNum = ptrNum
if ptrNum > 1 {
switch code.next.op {
case opInt:
c.mask = code.next.mask
c.rshiftNum = code.next.rshiftNum
return opStructFieldIntNPtr
case opUint:
c.mask = code.next.mask
return opStructFieldUintNPtr
case opFloat32:
return opStructFieldFloat32NPtr
case opFloat64:
return opStructFieldFloat64NPtr
case opString:
return opStructFieldStringNPtr
case opBool:
return opStructFieldBoolNPtr
}
} else {
switch code.next.op {
case opInt:
c.mask = code.next.mask
c.rshiftNum = code.next.rshiftNum
return opStructFieldIntPtr
case opUint:
c.mask = code.next.mask
return opStructFieldUintPtr
case opFloat32:
return opStructFieldFloat32Ptr
case opFloat64:
return opStructFieldFloat64Ptr
case opString:
return opStructFieldStringPtr
case opBool:
return opStructFieldBoolPtr
}
}
case opInt: case opInt:
return opStructFieldInt return opStructFieldInt
case opIntPtr:
return opStructFieldIntPtr
case opIntNPtr:
return opStructFieldIntNPtr
case opUint: case opUint:
return opStructFieldUint return opStructFieldUint
case opUintPtr:
return opStructFieldUintPtr
case opUintNPtr:
return opStructFieldUintNPtr
case opFloat32: case opFloat32:
return opStructFieldFloat32 return opStructFieldFloat32
case opFloat32Ptr:
return opStructFieldFloat32Ptr
case opFloat32NPtr:
return opStructFieldFloat32NPtr
case opFloat64: case opFloat64:
return opStructFieldFloat64 return opStructFieldFloat64
case opFloat64Ptr:
return opStructFieldFloat64Ptr
case opFloat64NPtr:
return opStructFieldFloat64NPtr
case opString: case opString:
return opStructFieldString return opStructFieldString
case opStringPtr:
return opStructFieldStringPtr
case opStringNPtr:
return opStructFieldStringNPtr
case opBool: case opBool:
return opStructFieldBool return opStructFieldBool
case opBoolPtr:
return opStructFieldBoolPtr
case opBoolNPtr:
return opStructFieldBoolNPtr
case opMapHead: case opMapHead:
return opStructFieldMap return opStructFieldMap
case opMapHeadLoad: case opMapHeadLoad:

View File

@ -87,10 +87,58 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code)
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opIntPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = encodeComma(b)
code = code.next
case opIntNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = encodeComma(b)
code = code.next
case opUint: case opUint:
b = appendUint(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendUint(b, ptrToUint64(load(ctxptr, code.idx)), code)
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opUintPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = appendUint(b, ptrToUint64(p), code)
}
b = encodeComma(b)
code = code.next
case opUintNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendUint(b, ptrToUint64(p), code)
}
b = encodeComma(b)
code = code.next
case opIntString: case opIntString:
b = append(b, '"') b = append(b, '"')
b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code)
@ -107,6 +155,30 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
b = encodeFloat32(b, ptrToFloat32(load(ctxptr, code.idx))) b = encodeFloat32(b, ptrToFloat32(load(ctxptr, code.idx)))
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opFloat32Ptr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeFloat32(b, ptrToFloat32(p))
}
b = encodeComma(b)
code = code.next
case opFloat32NPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeFloat32(b, ptrToFloat32(p))
}
b = encodeComma(b)
code = code.next
case opFloat64: case opFloat64:
v := ptrToFloat64(load(ctxptr, code.idx)) v := ptrToFloat64(load(ctxptr, code.idx))
if math.IsInf(v, 0) || math.IsNaN(v) { if math.IsInf(v, 0) || math.IsNaN(v) {
@ -115,18 +187,98 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
b = encodeFloat64(b, v) b = encodeFloat64(b, v)
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opFloat64Ptr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
v := ptrToFloat64(p)
if math.IsInf(v, 0) || math.IsNaN(v) {
return nil, errUnsupportedFloat(v)
}
b = encodeFloat64(b, v)
}
b = encodeComma(b)
code = code.next
case opFloat64NPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
v := ptrToFloat64(p)
if math.IsInf(v, 0) || math.IsNaN(v) {
return nil, errUnsupportedFloat(v)
}
b = encodeFloat64(b, v)
}
b = encodeComma(b)
code = code.next
case opString: case opString:
b = encodeNoEscapedString(b, ptrToString(load(ctxptr, code.idx))) b = encodeNoEscapedString(b, ptrToString(load(ctxptr, code.idx)))
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opStringPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeEscapedString(b, ptrToString(p))
}
b = encodeComma(b)
code = code.next
case opStringNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeEscapedString(b, ptrToString(p))
}
b = encodeComma(b)
code = code.next
case opBool: case opBool:
b = encodeBool(b, ptrToBool(load(ctxptr, code.idx))) b = encodeBool(b, ptrToBool(load(ctxptr, code.idx)))
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opBoolPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeBool(b, ptrToBool(p))
}
b = encodeComma(b)
code = code.next
case opBoolNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeBool(b, ptrToBool(p))
}
b = encodeComma(b)
code = code.next
case opBytes: case opBytes:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
slice := ptrToSlice(ptr) slice := ptrToSlice(ptr)
if ptr == 0 || uintptr(slice.data) == 0 { if ptr == 0 || slice.data == nil {
b = encodeNull(b) b = encodeNull(b)
} else { } else {
b = encodeByteSlice(b, ptrToBytes(ptr)) b = encodeByteSlice(b, ptrToBytes(ptr))
@ -238,7 +390,7 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
case opSliceHead: case opSliceHead:
p := load(ctxptr, code.idx) p := load(ctxptr, code.idx)
slice := ptrToSlice(p) slice := ptrToSlice(p)
if p == 0 || uintptr(slice.data) == 0 { if p == 0 || slice.data == nil {
b = encodeNull(b) b = encodeNull(b)
b = encodeComma(b) b = encodeComma(b)
code = code.end.next code = code.end.next

View File

@ -30,10 +30,58 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o
b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code)
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opIntPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = encodeComma(b)
code = code.next
case opIntNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = encodeComma(b)
code = code.next
case opUint: case opUint:
b = appendUint(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendUint(b, ptrToUint64(load(ctxptr, code.idx)), code)
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opUintPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = appendUint(b, ptrToUint64(p), code)
}
b = encodeComma(b)
code = code.next
case opUintNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendUint(b, ptrToUint64(p), code)
}
b = encodeComma(b)
code = code.next
case opIntString: case opIntString:
b = append(b, '"') b = append(b, '"')
b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code)
@ -50,6 +98,30 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o
b = encodeFloat32(b, ptrToFloat32(load(ctxptr, code.idx))) b = encodeFloat32(b, ptrToFloat32(load(ctxptr, code.idx)))
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opFloat32Ptr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeFloat32(b, ptrToFloat32(p))
}
b = encodeComma(b)
code = code.next
case opFloat32NPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeFloat32(b, ptrToFloat32(p))
}
b = encodeComma(b)
code = code.next
case opFloat64: case opFloat64:
v := ptrToFloat64(load(ctxptr, code.idx)) v := ptrToFloat64(load(ctxptr, code.idx))
if math.IsInf(v, 0) || math.IsNaN(v) { if math.IsInf(v, 0) || math.IsNaN(v) {
@ -58,14 +130,94 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o
b = encodeFloat64(b, v) b = encodeFloat64(b, v)
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opFloat64Ptr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
v := ptrToFloat64(p)
if math.IsInf(v, 0) || math.IsNaN(v) {
return nil, errUnsupportedFloat(v)
}
b = encodeFloat64(b, v)
}
b = encodeComma(b)
code = code.next
case opFloat64NPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
v := ptrToFloat64(p)
if math.IsInf(v, 0) || math.IsNaN(v) {
return nil, errUnsupportedFloat(v)
}
b = encodeFloat64(b, v)
}
b = encodeComma(b)
code = code.next
case opString: case opString:
b = encodeEscapedString(b, ptrToString(load(ctxptr, code.idx))) b = encodeEscapedString(b, ptrToString(load(ctxptr, code.idx)))
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opStringPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeEscapedString(b, ptrToString(p))
}
b = encodeComma(b)
code = code.next
case opStringNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeEscapedString(b, ptrToString(p))
}
b = encodeComma(b)
code = code.next
case opBool: case opBool:
b = encodeBool(b, ptrToBool(load(ctxptr, code.idx))) b = encodeBool(b, ptrToBool(load(ctxptr, code.idx)))
b = encodeComma(b) b = encodeComma(b)
code = code.next code = code.next
case opBoolPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeBool(b, ptrToBool(p))
}
b = encodeComma(b)
code = code.next
case opBoolNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeBool(b, ptrToBool(p))
}
b = encodeComma(b)
code = code.next
case opBytes: case opBytes:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
slice := ptrToSlice(ptr) slice := ptrToSlice(ptr)
@ -180,7 +332,7 @@ func encodeRunEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, o
case opSliceHead: case opSliceHead:
p := load(ctxptr, code.idx) p := load(ctxptr, code.idx)
slice := ptrToSlice(p) slice := ptrToSlice(p)
if p == 0 || uintptr(slice.data) == 0 { if p == 0 || slice.data == nil {
b = encodeNull(b) b = encodeNull(b)
b = encodeComma(b) b = encodeComma(b)
code = code.end.next code = code.end.next

View File

@ -29,10 +29,58 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opIntPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = encodeIndentComma(b)
code = code.next
case opIntNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = encodeIndentComma(b)
code = code.next
case opUint: case opUint:
b = appendUint(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendUint(b, ptrToUint64(load(ctxptr, code.idx)), code)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opUintPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = appendUint(b, ptrToUint64(p), code)
}
b = encodeIndentComma(b)
code = code.next
case opUintNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendUint(b, ptrToUint64(p), code)
}
b = encodeIndentComma(b)
code = code.next
case opIntString: case opIntString:
b = append(b, '"') b = append(b, '"')
b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code)
@ -49,6 +97,30 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
b = encodeFloat32(b, ptrToFloat32(load(ctxptr, code.idx))) b = encodeFloat32(b, ptrToFloat32(load(ctxptr, code.idx)))
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opFloat32Ptr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeFloat32(b, ptrToFloat32(p))
}
b = encodeIndentComma(b)
code = code.next
case opFloat32NPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeFloat32(b, ptrToFloat32(p))
}
b = encodeIndentComma(b)
code = code.next
case opFloat64: case opFloat64:
v := ptrToFloat64(load(ctxptr, code.idx)) v := ptrToFloat64(load(ctxptr, code.idx))
if math.IsInf(v, 0) || math.IsNaN(v) { if math.IsInf(v, 0) || math.IsNaN(v) {
@ -57,14 +129,94 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
b = encodeFloat64(b, v) b = encodeFloat64(b, v)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opFloat64Ptr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
v := ptrToFloat64(p)
if math.IsInf(v, 0) || math.IsNaN(v) {
return nil, errUnsupportedFloat(v)
}
b = encodeFloat64(b, v)
}
b = encodeIndentComma(b)
code = code.next
case opFloat64NPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
v := ptrToFloat64(p)
if math.IsInf(v, 0) || math.IsNaN(v) {
return nil, errUnsupportedFloat(v)
}
b = encodeFloat64(b, v)
}
b = encodeIndentComma(b)
code = code.next
case opString: case opString:
b = encodeEscapedString(b, ptrToString(load(ctxptr, code.idx))) b = encodeEscapedString(b, ptrToString(load(ctxptr, code.idx)))
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opStringPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeEscapedString(b, ptrToString(p))
}
b = encodeIndentComma(b)
code = code.next
case opStringNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeEscapedString(b, ptrToString(p))
}
b = encodeIndentComma(b)
code = code.next
case opBool: case opBool:
b = encodeBool(b, ptrToBool(load(ctxptr, code.idx))) b = encodeBool(b, ptrToBool(load(ctxptr, code.idx)))
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opBoolPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeBool(b, ptrToBool(p))
}
b = encodeIndentComma(b)
code = code.next
case opBoolNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeBool(b, ptrToBool(p))
}
b = encodeIndentComma(b)
code = code.next
case opBytes: case opBytes:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
slice := ptrToSlice(ptr) slice := ptrToSlice(ptr)
@ -196,13 +348,13 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
code = code.next code = code.next
case opSliceHead: case opSliceHead:
p := load(ctxptr, code.idx) p := load(ctxptr, code.idx)
if p == 0 { slice := ptrToSlice(p)
if p == 0 || slice.data == nil {
b = appendIndent(ctx, b, code.indent) b = appendIndent(ctx, b, code.indent)
b = encodeNull(b) b = encodeNull(b)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.end.next code = code.end.next
} else { } else {
slice := ptrToSlice(p)
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(slice.len)) store(ctxptr, code.length, uintptr(slice.len))
store(ctxptr, code.idx, uintptr(slice.data)) store(ctxptr, code.idx, uintptr(slice.data))
@ -213,7 +365,7 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
store(ctxptr, code.idx, uintptr(slice.data)) store(ctxptr, code.idx, uintptr(slice.data))
} else { } else {
b = appendIndent(ctx, b, code.indent) b = appendIndent(ctx, b, code.indent)
b = append(b, '[', ']', '\n') b = append(b, '[', ']', ',', '\n')
code = code.end.next code = code.end.next
} }
} }
@ -3692,6 +3844,24 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
} }
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opStructFieldIntNPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ' ')
p := load(ctxptr, code.headIdx) + code.offset
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = encodeIndentComma(b)
code = code.next
case opStructFieldOmitEmptyIntPtr: case opStructFieldOmitEmptyIntPtr:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset) p := ptrToPtr(ptr + code.offset)
@ -4445,6 +4615,24 @@ func encodeRunEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
} }
b = appendStructEndIndent(ctx, b, code.indent-1) b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next code = code.next
case opStructEndIntNPtr:
b = appendIndent(ctx, b, code.indent)
b = append(b, code.escapedKey...)
b = append(b, ' ')
p := load(ctxptr, code.headIdx) + code.offset
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = appendStructEndIndent(ctx, b, code.indent-1)
code = code.next
case opStructEndOmitEmptyIntPtr: case opStructEndOmitEmptyIntPtr:
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
p := ptrToPtr(ptr + code.offset) p := ptrToPtr(ptr + code.offset)

View File

@ -29,10 +29,58 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op
b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opIntPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = encodeIndentComma(b)
code = code.next
case opIntNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendInt(b, ptrToUint64(p), code)
}
b = encodeIndentComma(b)
code = code.next
case opUint: case opUint:
b = appendUint(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendUint(b, ptrToUint64(load(ctxptr, code.idx)), code)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opUintPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = appendUint(b, ptrToUint64(p), code)
}
b = encodeIndentComma(b)
code = code.next
case opUintNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = appendUint(b, ptrToUint64(p), code)
}
b = encodeIndentComma(b)
code = code.next
case opIntString: case opIntString:
b = append(b, '"') b = append(b, '"')
b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code) b = appendInt(b, ptrToUint64(load(ctxptr, code.idx)), code)
@ -49,6 +97,30 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op
b = encodeFloat32(b, ptrToFloat32(load(ctxptr, code.idx))) b = encodeFloat32(b, ptrToFloat32(load(ctxptr, code.idx)))
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opFloat32Ptr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeFloat32(b, ptrToFloat32(p))
}
b = encodeIndentComma(b)
code = code.next
case opFloat32NPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeFloat32(b, ptrToFloat32(p))
}
b = encodeIndentComma(b)
code = code.next
case opFloat64: case opFloat64:
v := ptrToFloat64(load(ctxptr, code.idx)) v := ptrToFloat64(load(ctxptr, code.idx))
if math.IsInf(v, 0) || math.IsNaN(v) { if math.IsInf(v, 0) || math.IsNaN(v) {
@ -57,14 +129,94 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op
b = encodeFloat64(b, v) b = encodeFloat64(b, v)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opFloat64Ptr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
v := ptrToFloat64(p)
if math.IsInf(v, 0) || math.IsNaN(v) {
return nil, errUnsupportedFloat(v)
}
b = encodeFloat64(b, v)
}
b = encodeIndentComma(b)
code = code.next
case opFloat64NPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
v := ptrToFloat64(p)
if math.IsInf(v, 0) || math.IsNaN(v) {
return nil, errUnsupportedFloat(v)
}
b = encodeFloat64(b, v)
}
b = encodeIndentComma(b)
code = code.next
case opString: case opString:
b = encodeNoEscapedString(b, ptrToString(load(ctxptr, code.idx))) b = encodeNoEscapedString(b, ptrToString(load(ctxptr, code.idx)))
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opStringPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeEscapedString(b, ptrToString(p))
}
b = encodeIndentComma(b)
code = code.next
case opStringNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeEscapedString(b, ptrToString(p))
}
b = encodeIndentComma(b)
code = code.next
case opBool: case opBool:
b = encodeBool(b, ptrToBool(load(ctxptr, code.idx))) b = encodeBool(b, ptrToBool(load(ctxptr, code.idx)))
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.next code = code.next
case opBoolPtr:
p := ptrToPtr(load(ctxptr, code.idx))
if p == 0 {
b = encodeNull(b)
} else {
b = encodeBool(b, ptrToBool(p))
}
b = encodeIndentComma(b)
code = code.next
case opBoolNPtr:
p := load(ctxptr, code.idx)
for i := 0; i < code.ptrNum; i++ {
if p == 0 {
break
}
p = ptrToPtr(p)
}
if p == 0 {
b = encodeNull(b)
} else {
b = encodeBool(b, ptrToBool(p))
}
b = encodeIndentComma(b)
code = code.next
case opBytes: case opBytes:
ptr := load(ctxptr, code.idx) ptr := load(ctxptr, code.idx)
slice := ptrToSlice(ptr) slice := ptrToSlice(ptr)
@ -196,13 +348,13 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op
code = code.next code = code.next
case opSliceHead: case opSliceHead:
p := load(ctxptr, code.idx) p := load(ctxptr, code.idx)
if p == 0 { slice := ptrToSlice(p)
if p == 0 || slice.data == nil {
b = appendIndent(ctx, b, code.indent) b = appendIndent(ctx, b, code.indent)
b = encodeNull(b) b = encodeNull(b)
b = encodeIndentComma(b) b = encodeIndentComma(b)
code = code.end.next code = code.end.next
} else { } else {
slice := ptrToSlice(p)
store(ctxptr, code.elemIdx, 0) store(ctxptr, code.elemIdx, 0)
store(ctxptr, code.length, uintptr(slice.len)) store(ctxptr, code.length, uintptr(slice.len))
store(ctxptr, code.idx, uintptr(slice.data)) store(ctxptr, code.idx, uintptr(slice.data))
@ -213,7 +365,7 @@ func encodeRunIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, op
store(ctxptr, code.idx, uintptr(slice.data)) store(ctxptr, code.idx, uintptr(slice.data))
} else { } else {
b = appendIndent(ctx, b, code.indent) b = appendIndent(ctx, b, code.indent)
b = append(b, '[', ']', '\n') b = append(b, '[', ']', ',', '\n')
code = code.end.next code = code.end.next
} }
} }