You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			106 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
			
		
		
	
	
			106 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
| package encoder
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"sync"
 | |
| 	"unsafe"
 | |
| 
 | |
| 	"github.com/goccy/go-json/internal/runtime"
 | |
| )
 | |
| 
 | |
| type compileContext struct {
 | |
| 	opcodeIndex       uint32
 | |
| 	ptrIndex          int
 | |
| 	indent            uint32
 | |
| 	escapeKey         bool
 | |
| 	structTypeToCodes map[uintptr]Opcodes
 | |
| 	recursiveCodes    *Opcodes
 | |
| }
 | |
| 
 | |
| func (c *compileContext) incIndent() {
 | |
| 	c.indent++
 | |
| }
 | |
| 
 | |
| func (c *compileContext) decIndent() {
 | |
| 	c.indent--
 | |
| }
 | |
| 
 | |
| func (c *compileContext) incIndex() {
 | |
| 	c.incOpcodeIndex()
 | |
| 	c.incPtrIndex()
 | |
| }
 | |
| 
 | |
| func (c *compileContext) decIndex() {
 | |
| 	c.decOpcodeIndex()
 | |
| 	c.decPtrIndex()
 | |
| }
 | |
| 
 | |
| func (c *compileContext) incOpcodeIndex() {
 | |
| 	c.opcodeIndex++
 | |
| }
 | |
| 
 | |
| func (c *compileContext) decOpcodeIndex() {
 | |
| 	c.opcodeIndex--
 | |
| }
 | |
| 
 | |
| func (c *compileContext) incPtrIndex() {
 | |
| 	c.ptrIndex++
 | |
| }
 | |
| 
 | |
| func (c *compileContext) decPtrIndex() {
 | |
| 	c.ptrIndex--
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	bufSize = 1024
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	runtimeContextPool = sync.Pool{
 | |
| 		New: func() interface{} {
 | |
| 			return &RuntimeContext{
 | |
| 				Buf:      make([]byte, 0, bufSize),
 | |
| 				Ptrs:     make([]uintptr, 128),
 | |
| 				KeepRefs: make([]unsafe.Pointer, 0, 8),
 | |
| 				Option:   &Option{},
 | |
| 			}
 | |
| 		},
 | |
| 	}
 | |
| )
 | |
| 
 | |
| type RuntimeContext struct {
 | |
| 	Context    context.Context
 | |
| 	Buf        []byte
 | |
| 	MarshalBuf []byte
 | |
| 	Ptrs       []uintptr
 | |
| 	KeepRefs   []unsafe.Pointer
 | |
| 	SeenPtr    []uintptr
 | |
| 	BaseIndent uint32
 | |
| 	Prefix     []byte
 | |
| 	IndentStr  []byte
 | |
| 	Option     *Option
 | |
| }
 | |
| 
 | |
| func (c *RuntimeContext) Init(p uintptr, codelen int) {
 | |
| 	if len(c.Ptrs) < codelen {
 | |
| 		c.Ptrs = make([]uintptr, codelen)
 | |
| 	}
 | |
| 	c.Ptrs[0] = p
 | |
| 	c.KeepRefs = c.KeepRefs[:0]
 | |
| 	c.SeenPtr = c.SeenPtr[:0]
 | |
| 	c.BaseIndent = 0
 | |
| }
 | |
| 
 | |
| func (c *RuntimeContext) Ptr() uintptr {
 | |
| 	header := (*runtime.SliceHeader)(unsafe.Pointer(&c.Ptrs))
 | |
| 	return uintptr(header.Data)
 | |
| }
 | |
| 
 | |
| func TakeRuntimeContext() *RuntimeContext {
 | |
| 	return runtimeContextPool.Get().(*RuntimeContext)
 | |
| }
 | |
| 
 | |
| func ReleaseRuntimeContext(ctx *RuntimeContext) {
 | |
| 	runtimeContextPool.Put(ctx)
 | |
| }
 |