forked from mirror/go-json
Add keepRefs field
This commit is contained in:
parent
3e4e83bf34
commit
02e04238a2
|
@ -196,7 +196,8 @@ func (e *Encoder) encode(v interface{}) error {
|
||||||
ctx: sync.Pool{
|
ctx: sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
return &encodeRuntimeContext{
|
return &encodeRuntimeContext{
|
||||||
ptrs: make([]uintptr, codeLength),
|
ptrs: make([]uintptr, codeLength),
|
||||||
|
keepRefs: make([]unsafe.Pointer, 8),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -85,11 +85,13 @@ func (c *encodeCompileContext) decPtrIndex() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type encodeRuntimeContext struct {
|
type encodeRuntimeContext struct {
|
||||||
ptrs []uintptr
|
ptrs []uintptr
|
||||||
|
keepRefs []unsafe.Pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *encodeRuntimeContext) init(p uintptr) {
|
func (c *encodeRuntimeContext) init(p uintptr) {
|
||||||
c.ptrs[0] = p
|
c.ptrs[0] = p
|
||||||
|
c.keepRefs = c.keepRefs[:0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *encodeRuntimeContext) ptr() uintptr {
|
func (c *encodeRuntimeContext) ptr() uintptr {
|
||||||
|
|
10
encode_vm.go
10
encode_vm.go
|
@ -21,10 +21,6 @@ func store(base uintptr, idx uintptr, p uintptr) {
|
||||||
*(*uintptr)(unsafe.Pointer(base + idx)) = p
|
*(*uintptr)(unsafe.Pointer(base + idx)) = p
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
globalArray = []interface{}{}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
recursiveLevel := 0
|
recursiveLevel := 0
|
||||||
seenPtr := map[uintptr]struct{}{}
|
seenPtr := map[uintptr]struct{}{}
|
||||||
|
@ -434,7 +430,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
mlen := maplen(unsafe.Pointer(ptr))
|
mlen := maplen(unsafe.Pointer(ptr))
|
||||||
if mlen > 0 {
|
if mlen > 0 {
|
||||||
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
||||||
globalArray = append(globalArray, iter)
|
ctx.keepRefs = append(ctx.keepRefs, iter)
|
||||||
store(ctxptr, code.elemIdx, 0)
|
store(ctxptr, code.elemIdx, 0)
|
||||||
store(ctxptr, code.length, uintptr(mlen))
|
store(ctxptr, code.length, uintptr(mlen))
|
||||||
store(ctxptr, code.mapIter, uintptr(iter))
|
store(ctxptr, code.mapIter, uintptr(iter))
|
||||||
|
@ -458,6 +454,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
mlen := maplen(unsafe.Pointer(ptr))
|
mlen := maplen(unsafe.Pointer(ptr))
|
||||||
if mlen > 0 {
|
if mlen > 0 {
|
||||||
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
||||||
|
ctx.keepRefs = append(ctx.keepRefs, iter)
|
||||||
store(ctxptr, code.elemIdx, 0)
|
store(ctxptr, code.elemIdx, 0)
|
||||||
store(ctxptr, code.length, uintptr(mlen))
|
store(ctxptr, code.length, uintptr(mlen))
|
||||||
store(ctxptr, code.mapIter, uintptr(iter))
|
store(ctxptr, code.mapIter, uintptr(iter))
|
||||||
|
@ -502,6 +499,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
if mlen > 0 {
|
if mlen > 0 {
|
||||||
e.encodeBytes([]byte{'{', '\n'})
|
e.encodeBytes([]byte{'{', '\n'})
|
||||||
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
||||||
|
ctx.keepRefs = append(ctx.keepRefs, iter)
|
||||||
store(ctxptr, code.elemIdx, 0)
|
store(ctxptr, code.elemIdx, 0)
|
||||||
store(ctxptr, code.length, uintptr(mlen))
|
store(ctxptr, code.length, uintptr(mlen))
|
||||||
store(ctxptr, code.mapIter, uintptr(iter))
|
store(ctxptr, code.mapIter, uintptr(iter))
|
||||||
|
@ -528,6 +526,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
if mlen > 0 {
|
if mlen > 0 {
|
||||||
e.encodeBytes([]byte{'{', '\n'})
|
e.encodeBytes([]byte{'{', '\n'})
|
||||||
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
||||||
|
ctx.keepRefs = append(ctx.keepRefs, iter)
|
||||||
store(ctxptr, code.elemIdx, 0)
|
store(ctxptr, code.elemIdx, 0)
|
||||||
store(ctxptr, code.length, uintptr(mlen))
|
store(ctxptr, code.length, uintptr(mlen))
|
||||||
store(ctxptr, code.mapIter, uintptr(iter))
|
store(ctxptr, code.mapIter, uintptr(iter))
|
||||||
|
@ -552,6 +551,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
if mlen > 0 {
|
if mlen > 0 {
|
||||||
e.encodeBytes([]byte{'{', '\n'})
|
e.encodeBytes([]byte{'{', '\n'})
|
||||||
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
|
||||||
|
ctx.keepRefs = append(ctx.keepRefs, iter)
|
||||||
store(ctxptr, code.elemIdx, 0)
|
store(ctxptr, code.elemIdx, 0)
|
||||||
store(ctxptr, code.length, uintptr(mlen))
|
store(ctxptr, code.length, uintptr(mlen))
|
||||||
store(ctxptr, code.mapIter, uintptr(iter))
|
store(ctxptr, code.mapIter, uintptr(iter))
|
||||||
|
|
Loading…
Reference in New Issue