mirror of https://github.com/goccy/go-json.git
work cover map and slice
This commit is contained in:
parent
6a00602e6a
commit
f6d91525b2
|
@ -228,8 +228,8 @@ func (c *SliceCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
size := c.typ.Elem().Size()
|
size := c.typ.Elem().Size()
|
||||||
header := newSliceHeaderCode(ctx)
|
header := newSliceHeaderCode(ctx)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
codes := c.value.ToOpcode(ctx)
|
codes := c.value.ToOpcode(ctx.incIndent())
|
||||||
elemCode := newSliceElemCode(ctx.withType(c.typ.Elem()).incIndent(), header, size)
|
elemCode := newSliceElemCode(ctx.withType(c.typ.Elem()), header, size)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
end := newOpCode(ctx, OpSliceEnd)
|
end := newOpCode(ctx, OpSliceEnd)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
|
@ -292,7 +292,6 @@ func (c *MapCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
// header => code => value => code => key => code => value => code => end
|
// header => code => value => code => key => code => value => code => end
|
||||||
// ^ |
|
// ^ |
|
||||||
// |_______________________|
|
// |_______________________|
|
||||||
ctx = ctx.incIndent()
|
|
||||||
header := newMapHeaderCode(ctx)
|
header := newMapHeaderCode(ctx)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
|
|
||||||
|
@ -300,13 +299,11 @@ func (c *MapCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
|
|
||||||
value := newMapValueCode(ctx, header)
|
value := newMapValueCode(ctx, header)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
valueCodes := c.value.ToOpcode(ctx)
|
valueCodes := c.value.ToOpcode(ctx.incIndent())
|
||||||
|
|
||||||
key := newMapKeyCode(ctx, header)
|
key := newMapKeyCode(ctx, header)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
|
|
||||||
ctx = ctx.decIndent()
|
|
||||||
|
|
||||||
end := newMapEndCode(ctx, header)
|
end := newMapEndCode(ctx, header)
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
|
|
||||||
|
@ -340,14 +337,11 @@ func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
// header => code => structField => code => end
|
// header => code => structField => code => end
|
||||||
// ^ |
|
// ^ |
|
||||||
// |__________|
|
// |__________|
|
||||||
var recursive *Opcode
|
|
||||||
compiled := &CompiledCode{}
|
|
||||||
if c.isRecursive {
|
if c.isRecursive {
|
||||||
recursive = newRecursiveCode(ctx, compiled)
|
recursive := newRecursiveCode(ctx, &CompiledCode{})
|
||||||
|
recursive.Type = c.typ
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
}
|
*ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
|
||||||
if len(c.recursiveCodes) > 0 {
|
|
||||||
c.linkRecursiveCode(compiled, c.recursiveCodes)
|
|
||||||
return Opcodes{recursive}
|
return Opcodes{recursive}
|
||||||
}
|
}
|
||||||
codes := Opcodes{}
|
codes := Opcodes{}
|
||||||
|
@ -389,12 +383,27 @@ func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
}
|
}
|
||||||
codes = append(codes, fieldCodes...)
|
codes = append(codes, fieldCodes...)
|
||||||
}
|
}
|
||||||
ctx = ctx.decIndent()
|
if len(codes) == 0 {
|
||||||
if c.isRecursive {
|
end := &Opcode{
|
||||||
c.recursiveCodes = codes
|
Op: OpStructEnd,
|
||||||
c.linkRecursiveCode(compiled, c.recursiveCodes)
|
Idx: opcodeOffset(ctx.ptrIndex),
|
||||||
return Opcodes{recursive}
|
DisplayIdx: ctx.opcodeIndex,
|
||||||
|
Indent: ctx.indent,
|
||||||
|
}
|
||||||
|
head := &Opcode{
|
||||||
|
Op: OpStructHead,
|
||||||
|
Idx: opcodeOffset(ctx.ptrIndex),
|
||||||
|
NextField: end,
|
||||||
|
Type: c.typ,
|
||||||
|
DisplayIdx: ctx.opcodeIndex,
|
||||||
|
Indent: ctx.indent,
|
||||||
|
}
|
||||||
|
codes = append(codes, head, end)
|
||||||
|
end.PrevField = head
|
||||||
|
ctx.incIndex()
|
||||||
}
|
}
|
||||||
|
ctx = ctx.decIndent()
|
||||||
|
ctx.structTypeToCodes[uintptr(unsafe.Pointer(c.typ))] = codes
|
||||||
return codes
|
return codes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,14 +411,11 @@ func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
|
||||||
// header => code => structField => code => end
|
// header => code => structField => code => end
|
||||||
// ^ |
|
// ^ |
|
||||||
// |__________|
|
// |__________|
|
||||||
var recursive *Opcode
|
|
||||||
compiled := &CompiledCode{}
|
|
||||||
if c.isRecursive {
|
if c.isRecursive {
|
||||||
recursive = newRecursiveCode(ctx, compiled)
|
recursive := newRecursiveCode(ctx, &CompiledCode{})
|
||||||
|
recursive.Type = c.typ
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
}
|
*ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
|
||||||
if len(c.recursiveCodes) > 0 {
|
|
||||||
c.linkRecursiveCode(compiled, c.recursiveCodes)
|
|
||||||
return Opcodes{recursive}
|
return Opcodes{recursive}
|
||||||
}
|
}
|
||||||
codes := Opcodes{}
|
codes := Opcodes{}
|
||||||
|
@ -440,36 +446,35 @@ func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
|
||||||
prevField = fieldCodes.First()
|
prevField = fieldCodes.First()
|
||||||
codes = append(codes, fieldCodes...)
|
codes = append(codes, fieldCodes...)
|
||||||
}
|
}
|
||||||
if c.isRecursive {
|
|
||||||
c.recursiveCodes = codes
|
|
||||||
c.linkRecursiveCode(compiled, c.recursiveCodes)
|
|
||||||
return Opcodes{recursive}
|
|
||||||
}
|
|
||||||
return codes
|
return codes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StructCode) linkRecursiveCode(compiled *CompiledCode, codes Opcodes) {
|
func linkRecursiveCode2(ctx *compileContext) {
|
||||||
compiled.Code = copyOpcode(codes.First())
|
for _, recursive := range *ctx.recursiveCodes {
|
||||||
code := compiled.Code
|
typeptr := uintptr(unsafe.Pointer(recursive.Type))
|
||||||
code.End.Next = newEndOp(&compileContext{})
|
codes := ctx.structTypeToCodes[typeptr]
|
||||||
code.Op = code.Op.PtrHeadToHead()
|
compiled := recursive.Jmp
|
||||||
|
compiled.Code = copyOpcode(codes.First())
|
||||||
|
code := compiled.Code
|
||||||
|
code.End.Next = newEndOp(&compileContext{})
|
||||||
|
code.Op = code.Op.PtrHeadToHead()
|
||||||
|
|
||||||
beforeLastCode := code.End
|
beforeLastCode := code.End
|
||||||
lastCode := beforeLastCode.Next
|
lastCode := beforeLastCode.Next
|
||||||
|
|
||||||
lastCode.Idx = beforeLastCode.Idx + uintptrSize
|
lastCode.Idx = beforeLastCode.Idx + uintptrSize
|
||||||
lastCode.ElemIdx = lastCode.Idx + uintptrSize
|
lastCode.ElemIdx = lastCode.Idx + uintptrSize
|
||||||
lastCode.Length = lastCode.Idx + 2*uintptrSize
|
lastCode.Length = lastCode.Idx + 2*uintptrSize
|
||||||
|
code.End.Next.Op = OpRecursiveEnd
|
||||||
|
|
||||||
// extend length to alloc slot for elemIdx + length
|
// extend length to alloc slot for elemIdx + length
|
||||||
totalLength := uintptr((codes.Last().MaxIdx() / uintptrSize) + 3)
|
totalLength := uintptr(recursive.TotalLength()) + 3
|
||||||
nextTotalLength := uintptr(code.TotalLength() + 3)
|
nextTotalLength := uintptr(codes.First().TotalLength()) + 3
|
||||||
|
|
||||||
code.End.Next.Op = OpRecursiveEnd
|
compiled.CurLen = totalLength
|
||||||
|
compiled.NextLen = nextTotalLength
|
||||||
compiled.CurLen = totalLength
|
compiled.Linked = true
|
||||||
compiled.NextLen = nextTotalLength
|
}
|
||||||
compiled.Linked = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StructCode) removeFieldsByTags(tags runtime.StructTags) {
|
func (c *StructCode) removeFieldsByTags(tags runtime.StructTags) {
|
||||||
|
@ -567,9 +572,9 @@ func (c *StructFieldCode) ToOpcode(ctx *compileContext, isFirstField, isEndField
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
var codes Opcodes
|
var codes Opcodes
|
||||||
if c.isAnonymous {
|
if c.isAnonymous {
|
||||||
codes = c.value.(AnonymousCode).ToAnonymousOpcode(ctx)
|
codes = c.value.(AnonymousCode).ToAnonymousOpcode(ctx.withType(c.typ))
|
||||||
} else {
|
} else {
|
||||||
codes = c.value.ToOpcode(ctx)
|
codes = c.value.ToOpcode(ctx.withType(c.typ))
|
||||||
}
|
}
|
||||||
if isFirstField {
|
if isFirstField {
|
||||||
op := optimizeStructHeader(codes.First(), c.tag)
|
op := optimizeStructHeader(codes.First(), c.tag)
|
||||||
|
@ -673,9 +678,9 @@ func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField, i
|
||||||
ctx.incIndex()
|
ctx.incIndex()
|
||||||
var codes Opcodes
|
var codes Opcodes
|
||||||
if c.isAnonymous {
|
if c.isAnonymous {
|
||||||
codes = c.value.(AnonymousCode).ToAnonymousOpcode(ctx)
|
codes = c.value.(AnonymousCode).ToAnonymousOpcode(ctx.withType(c.typ))
|
||||||
} else {
|
} else {
|
||||||
codes = c.value.ToOpcode(ctx)
|
codes = c.value.ToOpcode(ctx.withType(c.typ))
|
||||||
}
|
}
|
||||||
if isFirstField {
|
if isFirstField {
|
||||||
op := optimizeStructHeader(codes.First(), c.tag)
|
op := optimizeStructHeader(codes.First(), c.tag)
|
||||||
|
@ -746,7 +751,7 @@ func (c *MarshalJSONCode) Type() CodeType2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MarshalJSONCode) ToOpcode(ctx *compileContext) Opcodes {
|
func (c *MarshalJSONCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
code := newOpCode(ctx, OpMarshalJSON)
|
code := newOpCode(ctx.withType(c.typ), OpMarshalJSON)
|
||||||
typ := c.typ
|
typ := c.typ
|
||||||
if isPtrMarshalJSONType(typ) {
|
if isPtrMarshalJSONType(typ) {
|
||||||
code.Flags |= AddrForMarshalerFlags
|
code.Flags |= AddrForMarshalerFlags
|
||||||
|
@ -772,7 +777,7 @@ func (c *MarshalTextCode) Type() CodeType2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MarshalTextCode) ToOpcode(ctx *compileContext) Opcodes {
|
func (c *MarshalTextCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
code := newOpCode(ctx, OpMarshalText)
|
code := newOpCode(ctx.withType(c.typ), OpMarshalText)
|
||||||
typ := c.typ
|
typ := c.typ
|
||||||
if !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType) {
|
if !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType) {
|
||||||
code.Flags |= AddrForMarshalerFlags
|
code.Flags |= AddrForMarshalerFlags
|
||||||
|
@ -797,14 +802,14 @@ func (c *PtrCode) Type() CodeType2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PtrCode) ToOpcode(ctx *compileContext) Opcodes {
|
func (c *PtrCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
codes := c.value.ToOpcode(ctx)
|
codes := c.value.ToOpcode(ctx.withType(c.typ.Elem()))
|
||||||
codes.First().Op = convertPtrOp(codes.First())
|
codes.First().Op = convertPtrOp(codes.First())
|
||||||
codes.First().PtrNum = c.ptrNum
|
codes.First().PtrNum = c.ptrNum
|
||||||
return codes
|
return codes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PtrCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
|
func (c *PtrCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
|
||||||
codes := c.value.(AnonymousCode).ToAnonymousOpcode(ctx)
|
codes := c.value.(AnonymousCode).ToAnonymousOpcode(ctx.withType(c.typ.Elem()))
|
||||||
codes.First().Op = convertPtrOp(codes.First())
|
codes.First().Op = convertPtrOp(codes.First())
|
||||||
codes.First().PtrNum = c.ptrNum
|
codes.First().PtrNum = c.ptrNum
|
||||||
return codes
|
return codes
|
||||||
|
@ -954,17 +959,17 @@ func compileInt2(ctx *compileContext, isPtr bool) (*IntCode, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileInt82(ctx *compileContext, isPtr bool) (*IntCode, error) {
|
func compileInt82(ctx *compileContext, isPtr bool) (*IntCode, error) {
|
||||||
return &IntCode{typ: ctx.typ, bitSize: intSize, isPtr: isPtr}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func compileInt162(ctx *compileContext, isPtr bool) (*IntCode, error) {
|
|
||||||
return &IntCode{typ: ctx.typ, bitSize: 8, isPtr: isPtr}, nil
|
return &IntCode{typ: ctx.typ, bitSize: 8, isPtr: isPtr}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileInt322(ctx *compileContext, isPtr bool) (*IntCode, error) {
|
func compileInt162(ctx *compileContext, isPtr bool) (*IntCode, error) {
|
||||||
return &IntCode{typ: ctx.typ, bitSize: 16, isPtr: isPtr}, nil
|
return &IntCode{typ: ctx.typ, bitSize: 16, isPtr: isPtr}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compileInt322(ctx *compileContext, isPtr bool) (*IntCode, error) {
|
||||||
|
return &IntCode{typ: ctx.typ, bitSize: 32, isPtr: isPtr}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func compileInt642(ctx *compileContext, isPtr bool) (*IntCode, error) {
|
func compileInt642(ctx *compileContext, isPtr bool) (*IntCode, error) {
|
||||||
return &IntCode{typ: ctx.typ, bitSize: 64, isPtr: isPtr}, nil
|
return &IntCode{typ: ctx.typ, bitSize: 64, isPtr: isPtr}, nil
|
||||||
}
|
}
|
||||||
|
@ -974,17 +979,17 @@ func compileUint2(ctx *compileContext, isPtr bool) (*UintCode, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileUint82(ctx *compileContext, isPtr bool) (*UintCode, error) {
|
func compileUint82(ctx *compileContext, isPtr bool) (*UintCode, error) {
|
||||||
return &UintCode{typ: ctx.typ, bitSize: intSize, isPtr: isPtr}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func compileUint162(ctx *compileContext, isPtr bool) (*UintCode, error) {
|
|
||||||
return &UintCode{typ: ctx.typ, bitSize: 8, isPtr: isPtr}, nil
|
return &UintCode{typ: ctx.typ, bitSize: 8, isPtr: isPtr}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileUint322(ctx *compileContext, isPtr bool) (*UintCode, error) {
|
func compileUint162(ctx *compileContext, isPtr bool) (*UintCode, error) {
|
||||||
return &UintCode{typ: ctx.typ, bitSize: 16, isPtr: isPtr}, nil
|
return &UintCode{typ: ctx.typ, bitSize: 16, isPtr: isPtr}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compileUint322(ctx *compileContext, isPtr bool) (*UintCode, error) {
|
||||||
|
return &UintCode{typ: ctx.typ, bitSize: 32, isPtr: isPtr}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func compileUint642(ctx *compileContext, isPtr bool) (*UintCode, error) {
|
func compileUint642(ctx *compileContext, isPtr bool) (*UintCode, error) {
|
||||||
return &UintCode{typ: ctx.typ, bitSize: 64, isPtr: isPtr}, nil
|
return &UintCode{typ: ctx.typ, bitSize: 64, isPtr: isPtr}, nil
|
||||||
}
|
}
|
||||||
|
@ -1002,17 +1007,17 @@ func compileIntString2(ctx *compileContext) (*IntCode, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileInt8String2(ctx *compileContext) (*IntCode, error) {
|
func compileInt8String2(ctx *compileContext) (*IntCode, error) {
|
||||||
return &IntCode{typ: ctx.typ, bitSize: intSize, isString: true}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func compileInt16String2(ctx *compileContext) (*IntCode, error) {
|
|
||||||
return &IntCode{typ: ctx.typ, bitSize: 8, isString: true}, nil
|
return &IntCode{typ: ctx.typ, bitSize: 8, isString: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileInt32String2(ctx *compileContext) (*IntCode, error) {
|
func compileInt16String2(ctx *compileContext) (*IntCode, error) {
|
||||||
return &IntCode{typ: ctx.typ, bitSize: 16, isString: true}, nil
|
return &IntCode{typ: ctx.typ, bitSize: 16, isString: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compileInt32String2(ctx *compileContext) (*IntCode, error) {
|
||||||
|
return &IntCode{typ: ctx.typ, bitSize: 32, isString: true}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func compileInt64String2(ctx *compileContext) (*IntCode, error) {
|
func compileInt64String2(ctx *compileContext) (*IntCode, error) {
|
||||||
return &IntCode{typ: ctx.typ, bitSize: 64, isString: true}, nil
|
return &IntCode{typ: ctx.typ, bitSize: 64, isString: true}, nil
|
||||||
}
|
}
|
||||||
|
@ -1022,17 +1027,17 @@ func compileUintString2(ctx *compileContext) (*UintCode, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileUint8String2(ctx *compileContext) (*UintCode, error) {
|
func compileUint8String2(ctx *compileContext) (*UintCode, error) {
|
||||||
return &UintCode{typ: ctx.typ, bitSize: intSize, isString: true}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func compileUint16String2(ctx *compileContext) (*UintCode, error) {
|
|
||||||
return &UintCode{typ: ctx.typ, bitSize: 8, isString: true}, nil
|
return &UintCode{typ: ctx.typ, bitSize: 8, isString: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileUint32String2(ctx *compileContext) (*UintCode, error) {
|
func compileUint16String2(ctx *compileContext) (*UintCode, error) {
|
||||||
return &UintCode{typ: ctx.typ, bitSize: 16, isString: true}, nil
|
return &UintCode{typ: ctx.typ, bitSize: 16, isString: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compileUint32String2(ctx *compileContext) (*UintCode, error) {
|
||||||
|
return &UintCode{typ: ctx.typ, bitSize: 32, isString: true}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func compileUint64String2(ctx *compileContext) (*UintCode, error) {
|
func compileUint64String2(ctx *compileContext) (*UintCode, error) {
|
||||||
return &UintCode{typ: ctx.typ, bitSize: 64, isString: true}, nil
|
return &UintCode{typ: ctx.typ, bitSize: 64, isString: true}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,11 +102,14 @@ func compileHead(ctx *compileContext) (*Opcode, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
//pp.Println(code)
|
//pp.Println(code)
|
||||||
newCtx := *ctx
|
derefctx := *ctx
|
||||||
codes := code.ToOpcode(&newCtx)
|
newCtx := &derefctx
|
||||||
codes.Last().Next = newEndOp(ctx)
|
codes := code.ToOpcode(newCtx)
|
||||||
//pp.Println(codes)
|
codes.Last().Next = newEndOp(newCtx)
|
||||||
|
//pp.Println(codes.First())
|
||||||
fmt.Println(codes.First().Dump())
|
fmt.Println(codes.First().Dump())
|
||||||
|
linkRecursiveCode2(newCtx)
|
||||||
|
return codes.First(), nil
|
||||||
|
|
||||||
typ := ctx.typ
|
typ := ctx.typ
|
||||||
switch {
|
switch {
|
||||||
|
|
|
@ -25,6 +25,8 @@ func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) {
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
||||||
structTypeToCode: map[uintptr]*StructCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
|
recursiveCodes: &Opcodes{},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -33,6 +35,8 @@ func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) {
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
||||||
structTypeToCode: map[uintptr]*StructCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
|
recursiveCodes: &Opcodes{},
|
||||||
escapeKey: true,
|
escapeKey: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -31,6 +31,8 @@ func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) {
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
||||||
structTypeToCode: map[uintptr]*StructCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
|
recursiveCodes: &Opcodes{},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -39,6 +41,8 @@ func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) {
|
||||||
typ: copiedType,
|
typ: copiedType,
|
||||||
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
structTypeToCompiledCode: map[uintptr]*CompiledCode{},
|
||||||
structTypeToCode: map[uintptr]*StructCode{},
|
structTypeToCode: map[uintptr]*StructCode{},
|
||||||
|
structTypeToCodes: map[uintptr]Opcodes{},
|
||||||
|
recursiveCodes: &Opcodes{},
|
||||||
escapeKey: true,
|
escapeKey: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -16,6 +16,8 @@ type compileContext struct {
|
||||||
escapeKey bool
|
escapeKey bool
|
||||||
structTypeToCompiledCode map[uintptr]*CompiledCode
|
structTypeToCompiledCode map[uintptr]*CompiledCode
|
||||||
structTypeToCode map[uintptr]*StructCode
|
structTypeToCode map[uintptr]*StructCode
|
||||||
|
structTypeToCodes map[uintptr]Opcodes
|
||||||
|
recursiveCodes *Opcodes
|
||||||
|
|
||||||
parent *compileContext
|
parent *compileContext
|
||||||
}
|
}
|
||||||
|
@ -29,6 +31,8 @@ func (c *compileContext) context() *compileContext {
|
||||||
escapeKey: c.escapeKey,
|
escapeKey: c.escapeKey,
|
||||||
structTypeToCompiledCode: c.structTypeToCompiledCode,
|
structTypeToCompiledCode: c.structTypeToCompiledCode,
|
||||||
structTypeToCode: c.structTypeToCode,
|
structTypeToCode: c.structTypeToCode,
|
||||||
|
structTypeToCodes: c.structTypeToCodes,
|
||||||
|
recursiveCodes: c.recursiveCodes,
|
||||||
parent: c,
|
parent: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package json_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
|
@ -1881,19 +1882,21 @@ func TestCoverMap(t *testing.T) {
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
for _, indent := range []bool{true, false} {
|
for _, indent := range []bool{true, false} {
|
||||||
for _, htmlEscape := range []bool{true, false} {
|
for _, htmlEscape := range []bool{true, false} {
|
||||||
var buf bytes.Buffer
|
t.Run(fmt.Sprintf("%s_indent_%t_escape_%t", test.name, indent, htmlEscape), func(t *testing.T) {
|
||||||
enc := json.NewEncoder(&buf)
|
var buf bytes.Buffer
|
||||||
enc.SetEscapeHTML(htmlEscape)
|
enc := json.NewEncoder(&buf)
|
||||||
if indent {
|
enc.SetEscapeHTML(htmlEscape)
|
||||||
enc.SetIndent("", " ")
|
if indent {
|
||||||
}
|
enc.SetIndent("", " ")
|
||||||
if err := enc.Encode(test.data); err != nil {
|
}
|
||||||
t.Fatalf("%s(htmlEscape:%v,indent:%v): %+v: %s", test.name, htmlEscape, indent, test.data, err)
|
if err := enc.Encode(test.data); err != nil {
|
||||||
}
|
t.Fatalf("%s(htmlEscape:%v,indent:%v): %+v: %s", test.name, htmlEscape, indent, test.data, err)
|
||||||
stdresult := encodeByEncodingJSON(test.data, indent, htmlEscape)
|
}
|
||||||
if buf.String() != stdresult {
|
stdresult := encodeByEncodingJSON(test.data, indent, htmlEscape)
|
||||||
t.Errorf("%s(htmlEscape:%v,indent:%v): doesn't compatible with encoding/json. expected %q but got %q", test.name, htmlEscape, indent, stdresult, buf.String())
|
if buf.String() != stdresult {
|
||||||
}
|
t.Errorf("%s(htmlEscape:%v,indent:%v): doesn't compatible with encoding/json. expected %q but got %q", test.name, htmlEscape, indent, stdresult, buf.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package json_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
|
@ -2047,9 +2048,9 @@ func TestCoverSlice(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
for _, indent := range []bool{true, false} {
|
||||||
for _, indent := range []bool{true, false} {
|
for _, htmlEscape := range []bool{true, false} {
|
||||||
for _, htmlEscape := range []bool{true, false} {
|
t.Run(fmt.Sprintf("%s_indent_%t_escape_%t", test.name, indent, htmlEscape), func(t *testing.T) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
enc := json.NewEncoder(&buf)
|
enc := json.NewEncoder(&buf)
|
||||||
enc.SetEscapeHTML(htmlEscape)
|
enc.SetEscapeHTML(htmlEscape)
|
||||||
|
@ -2063,8 +2064,8 @@ func TestCoverSlice(t *testing.T) {
|
||||||
if buf.String() != stdresult {
|
if buf.String() != stdresult {
|
||||||
t.Errorf("%s(htmlEscape:%v,indent:%v): doesn't compatible with encoding/json. expected %q but got %q", test.name, htmlEscape, indent, stdresult, buf.String())
|
t.Errorf("%s(htmlEscape:%v,indent:%v): doesn't compatible with encoding/json. expected %q but got %q", test.name, htmlEscape, indent, stdresult, buf.String())
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue