forked from mirror/go-json
Add map test
This commit is contained in:
parent
bac05564e0
commit
cc84d92b1e
|
@ -21,6 +21,7 @@ func stringptr(v string) *string { return &v }
|
||||||
func boolptr(v bool) *bool { return &v }
|
func boolptr(v bool) *bool { return &v }
|
||||||
func sliceptr(v []int) *[]int { return &v }
|
func sliceptr(v []int) *[]int { return &v }
|
||||||
func arrayptr(v [2]int) *[2]int { return &v }
|
func arrayptr(v [2]int) *[2]int { return &v }
|
||||||
|
func mapptr(v map[string]int) *map[string]int { return &v }
|
||||||
|
|
||||||
func encodeByEncodingJSON(data interface{}, indent, escape bool) string {
|
func encodeByEncodingJSON(data interface{}, indent, escape bool) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -228,7 +228,7 @@ func encodeCompile(ctx *encodeCompileContext, isPtr bool) (*opcode, error) {
|
||||||
case reflect.Array:
|
case reflect.Array:
|
||||||
return encodeCompileArray(ctx)
|
return encodeCompileArray(ctx)
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
return encodeCompileMap(ctx, true)
|
return encodeCompileMap(ctx, isPtr)
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
return encodeCompileStruct(ctx, isPtr)
|
return encodeCompileStruct(ctx, isPtr)
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
|
@ -661,7 +661,7 @@ func encodeCompileMap(ctx *encodeCompileContext, withLoad bool) (*opcode, error)
|
||||||
// ^ |
|
// ^ |
|
||||||
// |_______________________|
|
// |_______________________|
|
||||||
ctx = ctx.incIndent()
|
ctx = ctx.incIndent()
|
||||||
header := newMapHeaderCode(ctx, withLoad)
|
header := newMapHeaderCode(ctx, false) //withLoad)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
|
|
||||||
typ := ctx.typ
|
typ := ctx.typ
|
||||||
|
@ -759,6 +759,8 @@ func encodeTypeToHeaderType(ctx *encodeCompileContext, code *opcode) opType {
|
||||||
return opStructFieldHeadSlicePtr
|
return opStructFieldHeadSlicePtr
|
||||||
case opArrayHead:
|
case opArrayHead:
|
||||||
return opStructFieldHeadArrayPtr
|
return opStructFieldHeadArrayPtr
|
||||||
|
case opMapHead:
|
||||||
|
return opStructFieldHeadMapPtr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case opInt:
|
case opInt:
|
||||||
|
@ -844,6 +846,10 @@ func encodeTypeToFieldType(ctx *encodeCompileContext, code *opcode) opType {
|
||||||
return opStructFieldBoolPtr
|
return opStructFieldBoolPtr
|
||||||
case opSliceHead:
|
case opSliceHead:
|
||||||
return opStructFieldSlicePtr
|
return opStructFieldSlicePtr
|
||||||
|
case opArrayHead:
|
||||||
|
return opStructFieldArrayPtr
|
||||||
|
case opMapHead:
|
||||||
|
return opStructFieldMapPtr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case opInt:
|
case opInt:
|
||||||
|
@ -934,6 +940,8 @@ func encodeStructHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode
|
||||||
opStructFieldHeadStringTagArray,
|
opStructFieldHeadStringTagArray,
|
||||||
opStructFieldHeadOmitEmptyMap,
|
opStructFieldHeadOmitEmptyMap,
|
||||||
opStructFieldHeadOmitEmptyMapLoad,
|
opStructFieldHeadOmitEmptyMapLoad,
|
||||||
|
opStructFieldHeadStringTagMap,
|
||||||
|
opStructFieldHeadStringTagMapLoad,
|
||||||
opStructFieldHeadOmitEmptyStruct,
|
opStructFieldHeadOmitEmptyStruct,
|
||||||
opStructFieldHeadStringTag:
|
opStructFieldHeadStringTag:
|
||||||
return valueCode.beforeLastCode()
|
return valueCode.beforeLastCode()
|
||||||
|
@ -942,7 +950,10 @@ func encodeStructHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode
|
||||||
opStructFieldHeadStringTagSlicePtr,
|
opStructFieldHeadStringTagSlicePtr,
|
||||||
opStructFieldHeadArrayPtr,
|
opStructFieldHeadArrayPtr,
|
||||||
opStructFieldHeadOmitEmptyArrayPtr,
|
opStructFieldHeadOmitEmptyArrayPtr,
|
||||||
opStructFieldHeadStringTagArrayPtr:
|
opStructFieldHeadStringTagArrayPtr,
|
||||||
|
opStructFieldHeadMapPtr,
|
||||||
|
opStructFieldHeadOmitEmptyMapPtr,
|
||||||
|
opStructFieldHeadStringTagMapPtr:
|
||||||
*valueCode = *valueCode.next
|
*valueCode = *valueCode.next
|
||||||
return valueCode.beforeLastCode()
|
return valueCode.beforeLastCode()
|
||||||
}
|
}
|
||||||
|
@ -971,6 +982,8 @@ func encodeStructField(ctx *encodeCompileContext, fieldCode *opcode, valueCode *
|
||||||
opStructFieldStringTagArray,
|
opStructFieldStringTagArray,
|
||||||
opStructFieldOmitEmptyMap,
|
opStructFieldOmitEmptyMap,
|
||||||
opStructFieldOmitEmptyMapLoad,
|
opStructFieldOmitEmptyMapLoad,
|
||||||
|
opStructFieldStringTagMap,
|
||||||
|
opStructFieldStringTagMapLoad,
|
||||||
opStructFieldOmitEmptyStruct,
|
opStructFieldOmitEmptyStruct,
|
||||||
opStructFieldStringTag:
|
opStructFieldStringTag:
|
||||||
return valueCode.beforeLastCode()
|
return valueCode.beforeLastCode()
|
||||||
|
@ -979,7 +992,10 @@ func encodeStructField(ctx *encodeCompileContext, fieldCode *opcode, valueCode *
|
||||||
opStructFieldStringTagSlicePtr,
|
opStructFieldStringTagSlicePtr,
|
||||||
opStructFieldArrayPtr,
|
opStructFieldArrayPtr,
|
||||||
opStructFieldOmitEmptyArrayPtr,
|
opStructFieldOmitEmptyArrayPtr,
|
||||||
opStructFieldStringTagArrayPtr:
|
opStructFieldStringTagArrayPtr,
|
||||||
|
opStructFieldMapPtr,
|
||||||
|
opStructFieldOmitEmptyMapPtr,
|
||||||
|
opStructFieldStringTagMapPtr:
|
||||||
*valueCode = *valueCode.next
|
*valueCode = *valueCode.next
|
||||||
return valueCode.beforeLastCode()
|
return valueCode.beforeLastCode()
|
||||||
}
|
}
|
||||||
|
|
269
encode_vm.go
269
encode_vm.go
|
@ -2965,7 +2965,8 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
|
||||||
code = code.next
|
code = code.next
|
||||||
store(ctxptr, code.idx, p)
|
store(ctxptr, code.idx, p)
|
||||||
}
|
}
|
||||||
case opStructFieldPtrAnonymousHeadOmitEmptyArrayPtr, opStructFieldPtrAnonymousHeadOmitEmptySlicePtr:
|
case opStructFieldPtrAnonymousHeadOmitEmptyArrayPtr,
|
||||||
|
opStructFieldPtrAnonymousHeadOmitEmptySlicePtr:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
code = code.end.next
|
code = code.end.next
|
||||||
|
@ -2973,7 +2974,8 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
|
||||||
}
|
}
|
||||||
store(ctxptr, code.idx, ptrToPtr(p))
|
store(ctxptr, code.idx, ptrToPtr(p))
|
||||||
fallthrough
|
fallthrough
|
||||||
case opStructFieldAnonymousHeadOmitEmptyArrayPtr, opStructFieldAnonymousHeadOmitEmptySlicePtr:
|
case opStructFieldAnonymousHeadOmitEmptyArrayPtr,
|
||||||
|
opStructFieldAnonymousHeadOmitEmptySlicePtr:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 && code.indirect {
|
if p == 0 && code.indirect {
|
||||||
code = code.end.next
|
code = code.end.next
|
||||||
|
@ -2989,6 +2991,228 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
|
||||||
code = code.next
|
code = code.next
|
||||||
store(ctxptr, code.idx, p)
|
store(ctxptr, code.idx, p)
|
||||||
}
|
}
|
||||||
|
case opStructFieldPtrHeadMap, opStructFieldPtrHeadStringTagMap:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 && code.indirect {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldHeadMap, opStructFieldHeadStringTagMap:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 && code.indirect {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.key...)
|
||||||
|
if p != 0 && code.indirect {
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
}
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
case opStructFieldPtrHeadOmitEmptyMap:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 && code.indirect {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldHeadOmitEmptyMap:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 && code.indirect {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
b = append(b, '{')
|
||||||
|
if p != 0 && code.indirect {
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
}
|
||||||
|
if maplen(ptrToUnsafePtr(p)) == 0 {
|
||||||
|
code = code.nextField
|
||||||
|
} else {
|
||||||
|
b = append(b, code.key...)
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
}
|
||||||
|
case opStructFieldPtrHeadMapPtr, opStructFieldPtrHeadStringTagMapPtr:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldHeadMapPtr, opStructFieldHeadStringTagMapPtr:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 && code.indirect {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
b = append(b, '{')
|
||||||
|
b = append(b, code.key...)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.nextField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.nextField
|
||||||
|
} else {
|
||||||
|
if code.indirect {
|
||||||
|
p = ptrToPtr(p)
|
||||||
|
}
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
}
|
||||||
|
case opStructFieldPtrHeadOmitEmptyMapPtr:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldHeadOmitEmptyMapPtr:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 && code.indirect {
|
||||||
|
b = encodeNull(b)
|
||||||
|
b = encodeComma(b)
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
b = append(b, '{')
|
||||||
|
if p == 0 {
|
||||||
|
code = code.nextField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
if p == 0 {
|
||||||
|
code = code.nextField
|
||||||
|
} else {
|
||||||
|
if code.indirect {
|
||||||
|
p = ptrToPtr(p)
|
||||||
|
}
|
||||||
|
b = append(b, code.key...)
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
}
|
||||||
|
case opStructFieldPtrAnonymousHeadMap, opStructFieldPtrAnonymousHeadStringTagMap:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldAnonymousHeadMap, opStructFieldAnonymousHeadStringTagMap:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
b = append(b, code.key...)
|
||||||
|
if p != 0 && code.indirect {
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
}
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
case opStructFieldPtrAnonymousHeadOmitEmptyMap:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldAnonymousHeadOmitEmptyMap:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if p != 0 && code.indirect {
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
}
|
||||||
|
if maplen(ptrToUnsafePtr(p)) == 0 {
|
||||||
|
code = code.nextField
|
||||||
|
} else {
|
||||||
|
b = append(b, code.key...)
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
}
|
||||||
|
case opStructFieldPtrAnonymousHeadMapPtr, opStructFieldPtrAnonymousHeadStringTagMapPtr:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldAnonymousHeadMapPtr, opStructFieldAnonymousHeadStringTagMapPtr:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 && code.indirect {
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
b = append(b, code.key...)
|
||||||
|
if p != 0 {
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
}
|
||||||
|
if p != 0 && code.indirect {
|
||||||
|
p = ptrToPtr(p)
|
||||||
|
}
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
case opStructFieldPtrAnonymousHeadOmitEmptyMapPtr:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 {
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
store(ctxptr, code.idx, ptrToPtr(p))
|
||||||
|
fallthrough
|
||||||
|
case opStructFieldAnonymousHeadOmitEmptyMapPtr:
|
||||||
|
p := load(ctxptr, code.idx)
|
||||||
|
if p == 0 && code.indirect {
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if p == 0 {
|
||||||
|
code = code.end.next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
if p == 0 {
|
||||||
|
code = code.nextField
|
||||||
|
} else {
|
||||||
|
if code.indirect {
|
||||||
|
p = ptrToPtr(p)
|
||||||
|
}
|
||||||
|
b = append(b, code.key...)
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
}
|
||||||
case opStructFieldPtrHeadMarshalJSON:
|
case opStructFieldPtrHeadMarshalJSON:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
|
@ -4004,26 +4228,51 @@ func encodeRun(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet, opt Enco
|
||||||
} else {
|
} else {
|
||||||
code = code.nextField
|
code = code.nextField
|
||||||
}
|
}
|
||||||
case opStructFieldMap:
|
case opStructFieldMap, opStructFieldStringTagMap:
|
||||||
b = append(b, code.key...)
|
b = append(b, code.key...)
|
||||||
ptr := load(ctxptr, code.headIdx)
|
p := load(ctxptr, code.headIdx)
|
||||||
p := ptr + code.offset
|
if p != 0 {
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
}
|
||||||
code = code.next
|
code = code.next
|
||||||
store(ctxptr, code.idx, p)
|
store(ctxptr, code.idx, p)
|
||||||
case opStructFieldOmitEmptyMap:
|
case opStructFieldOmitEmptyMap:
|
||||||
ptr := load(ctxptr, code.headIdx)
|
p := load(ctxptr, code.headIdx)
|
||||||
p := ptr + code.offset
|
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
code = code.nextField
|
code = code.nextField
|
||||||
} else {
|
break
|
||||||
mlen := maplen(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
|
}
|
||||||
if mlen == 0 {
|
p = ptrToPtr(p + code.offset)
|
||||||
|
if p == 0 {
|
||||||
code = code.nextField
|
code = code.nextField
|
||||||
} else {
|
} else {
|
||||||
b = append(b, code.key...)
|
b = append(b, code.key...)
|
||||||
code = code.next
|
code = code.next
|
||||||
store(ctxptr, code.idx, p)
|
store(ctxptr, code.idx, p)
|
||||||
}
|
}
|
||||||
|
case opStructFieldMapPtr, opStructFieldStringTagMapPtr:
|
||||||
|
b = append(b, code.key...)
|
||||||
|
p := load(ctxptr, code.headIdx)
|
||||||
|
if p != 0 {
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
}
|
||||||
|
if p != 0 {
|
||||||
|
p = ptrToPtr(p)
|
||||||
|
}
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
case opStructFieldOmitEmptyMapPtr:
|
||||||
|
p := load(ctxptr, code.headIdx)
|
||||||
|
p = ptrToPtr(p + code.offset)
|
||||||
|
if p != 0 {
|
||||||
|
p = ptrToPtr(p)
|
||||||
|
}
|
||||||
|
if p != 0 {
|
||||||
|
b = append(b, code.key...)
|
||||||
|
code = code.next
|
||||||
|
store(ctxptr, code.idx, p)
|
||||||
|
} else {
|
||||||
|
code = code.nextField
|
||||||
}
|
}
|
||||||
case opStructFieldMapLoad:
|
case opStructFieldMapLoad:
|
||||||
b = append(b, code.key...)
|
b = append(b, code.key...)
|
||||||
|
|
Loading…
Reference in New Issue