context.go (1866B)
1 package encoder 2 3 import ( 4 "context" 5 "sync" 6 "unsafe" 7 8 "github.com/goccy/go-json/internal/runtime" 9 ) 10 11 type compileContext struct { 12 opcodeIndex uint32 13 ptrIndex int 14 indent uint32 15 escapeKey bool 16 structTypeToCodes map[uintptr]Opcodes 17 recursiveCodes *Opcodes 18 } 19 20 func (c *compileContext) incIndent() { 21 c.indent++ 22 } 23 24 func (c *compileContext) decIndent() { 25 c.indent-- 26 } 27 28 func (c *compileContext) incIndex() { 29 c.incOpcodeIndex() 30 c.incPtrIndex() 31 } 32 33 func (c *compileContext) decIndex() { 34 c.decOpcodeIndex() 35 c.decPtrIndex() 36 } 37 38 func (c *compileContext) incOpcodeIndex() { 39 c.opcodeIndex++ 40 } 41 42 func (c *compileContext) decOpcodeIndex() { 43 c.opcodeIndex-- 44 } 45 46 func (c *compileContext) incPtrIndex() { 47 c.ptrIndex++ 48 } 49 50 func (c *compileContext) decPtrIndex() { 51 c.ptrIndex-- 52 } 53 54 const ( 55 bufSize = 1024 56 ) 57 58 var ( 59 runtimeContextPool = sync.Pool{ 60 New: func() interface{} { 61 return &RuntimeContext{ 62 Buf: make([]byte, 0, bufSize), 63 Ptrs: make([]uintptr, 128), 64 KeepRefs: make([]unsafe.Pointer, 0, 8), 65 Option: &Option{}, 66 } 67 }, 68 } 69 ) 70 71 type RuntimeContext struct { 72 Context context.Context 73 Buf []byte 74 MarshalBuf []byte 75 Ptrs []uintptr 76 KeepRefs []unsafe.Pointer 77 SeenPtr []uintptr 78 BaseIndent uint32 79 Prefix []byte 80 IndentStr []byte 81 Option *Option 82 } 83 84 func (c *RuntimeContext) Init(p uintptr, codelen int) { 85 if len(c.Ptrs) < codelen { 86 c.Ptrs = make([]uintptr, codelen) 87 } 88 c.Ptrs[0] = p 89 c.KeepRefs = c.KeepRefs[:0] 90 c.SeenPtr = c.SeenPtr[:0] 91 c.BaseIndent = 0 92 } 93 94 func (c *RuntimeContext) Ptr() uintptr { 95 header := (*runtime.SliceHeader)(unsafe.Pointer(&c.Ptrs)) 96 return uintptr(header.Data) 97 } 98 99 func TakeRuntimeContext() *RuntimeContext { 100 return runtimeContextPool.Get().(*RuntimeContext) 101 } 102 103 func ReleaseRuntimeContext(ctx *RuntimeContext) { 104 runtimeContextPool.Put(ctx) 105 }