Add map test

This commit is contained in:
Masaaki Goshima 2021-03-04 18:50:39 +09:00
parent bac05564e0
commit cc84d92b1e
4 changed files with 2160 additions and 35 deletions

View File

@ -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

1859
cover_map_test.go Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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()
} }

View File

@ -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...)