summaryrefslogtreecommitdiff
path: root/vendor/github.com/goccy/go-json/internal/encoder/opcode.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goccy/go-json/internal/encoder/opcode.go')
-rw-r--r--vendor/github.com/goccy/go-json/internal/encoder/opcode.go772
1 files changed, 0 insertions, 772 deletions
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/opcode.go b/vendor/github.com/goccy/go-json/internal/encoder/opcode.go
deleted file mode 100644
index 7c50eefae..000000000
--- a/vendor/github.com/goccy/go-json/internal/encoder/opcode.go
+++ /dev/null
@@ -1,772 +0,0 @@
-package encoder
-
-import (
- "fmt"
- "strings"
- "unsafe"
-
- "github.com/goccy/go-json/internal/runtime"
-)
-
-const uintptrSize = 4 << (^uintptr(0) >> 63)
-
-type OpFlags uint16
-
-const (
- AnonymousHeadFlags OpFlags = 1 << 0
- AnonymousKeyFlags OpFlags = 1 << 1
- IndirectFlags OpFlags = 1 << 2
- IsTaggedKeyFlags OpFlags = 1 << 3
- NilCheckFlags OpFlags = 1 << 4
- AddrForMarshalerFlags OpFlags = 1 << 5
- IsNextOpPtrTypeFlags OpFlags = 1 << 6
- IsNilableTypeFlags OpFlags = 1 << 7
- MarshalerContextFlags OpFlags = 1 << 8
- NonEmptyInterfaceFlags OpFlags = 1 << 9
-)
-
-type Opcode struct {
- Op OpType // operation type
- Idx uint32 // offset to access ptr
- Next *Opcode // next opcode
- End *Opcode // array/slice/struct/map end
- NextField *Opcode // next struct field
- Key string // struct field key
- Offset uint32 // offset size from struct header
- PtrNum uint8 // pointer number: e.g. double pointer is 2.
- NumBitSize uint8
- Flags OpFlags
-
- Type *runtime.Type // go type
- PrevField *Opcode // prev struct field
- Jmp *CompiledCode // for recursive call
- ElemIdx uint32 // offset to access array/slice/map elem
- Length uint32 // offset to access slice/map length or array length
- MapIter uint32 // offset to access map iterator
- MapPos uint32 // offset to access position list for sorted map
- Indent uint32 // indent number
- Size uint32 // array/slice elem size
- DisplayIdx uint32 // opcode index
- DisplayKey string // key text to display
-}
-
-func (c *Opcode) MaxIdx() uint32 {
- max := uint32(0)
- for _, value := range []uint32{
- c.Idx,
- c.ElemIdx,
- c.Length,
- c.MapIter,
- c.MapPos,
- c.Size,
- } {
- if max < value {
- max = value
- }
- }
- return max
-}
-
-func (c *Opcode) ToHeaderType(isString bool) OpType {
- switch c.Op {
- case OpInt:
- if isString {
- return OpStructHeadIntString
- }
- return OpStructHeadInt
- case OpIntPtr:
- if isString {
- return OpStructHeadIntPtrString
- }
- return OpStructHeadIntPtr
- case OpUint:
- if isString {
- return OpStructHeadUintString
- }
- return OpStructHeadUint
- case OpUintPtr:
- if isString {
- return OpStructHeadUintPtrString
- }
- return OpStructHeadUintPtr
- case OpFloat32:
- if isString {
- return OpStructHeadFloat32String
- }
- return OpStructHeadFloat32
- case OpFloat32Ptr:
- if isString {
- return OpStructHeadFloat32PtrString
- }
- return OpStructHeadFloat32Ptr
- case OpFloat64:
- if isString {
- return OpStructHeadFloat64String
- }
- return OpStructHeadFloat64
- case OpFloat64Ptr:
- if isString {
- return OpStructHeadFloat64PtrString
- }
- return OpStructHeadFloat64Ptr
- case OpString:
- if isString {
- return OpStructHeadStringString
- }
- return OpStructHeadString
- case OpStringPtr:
- if isString {
- return OpStructHeadStringPtrString
- }
- return OpStructHeadStringPtr
- case OpNumber:
- if isString {
- return OpStructHeadNumberString
- }
- return OpStructHeadNumber
- case OpNumberPtr:
- if isString {
- return OpStructHeadNumberPtrString
- }
- return OpStructHeadNumberPtr
- case OpBool:
- if isString {
- return OpStructHeadBoolString
- }
- return OpStructHeadBool
- case OpBoolPtr:
- if isString {
- return OpStructHeadBoolPtrString
- }
- return OpStructHeadBoolPtr
- case OpBytes:
- return OpStructHeadBytes
- case OpBytesPtr:
- return OpStructHeadBytesPtr
- case OpMap:
- return OpStructHeadMap
- case OpMapPtr:
- c.Op = OpMap
- return OpStructHeadMapPtr
- case OpArray:
- return OpStructHeadArray
- case OpArrayPtr:
- c.Op = OpArray
- return OpStructHeadArrayPtr
- case OpSlice:
- return OpStructHeadSlice
- case OpSlicePtr:
- c.Op = OpSlice
- return OpStructHeadSlicePtr
- case OpMarshalJSON:
- return OpStructHeadMarshalJSON
- case OpMarshalJSONPtr:
- return OpStructHeadMarshalJSONPtr
- case OpMarshalText:
- return OpStructHeadMarshalText
- case OpMarshalTextPtr:
- return OpStructHeadMarshalTextPtr
- }
- return OpStructHead
-}
-
-func (c *Opcode) ToFieldType(isString bool) OpType {
- switch c.Op {
- case OpInt:
- if isString {
- return OpStructFieldIntString
- }
- return OpStructFieldInt
- case OpIntPtr:
- if isString {
- return OpStructFieldIntPtrString
- }
- return OpStructFieldIntPtr
- case OpUint:
- if isString {
- return OpStructFieldUintString
- }
- return OpStructFieldUint
- case OpUintPtr:
- if isString {
- return OpStructFieldUintPtrString
- }
- return OpStructFieldUintPtr
- case OpFloat32:
- if isString {
- return OpStructFieldFloat32String
- }
- return OpStructFieldFloat32
- case OpFloat32Ptr:
- if isString {
- return OpStructFieldFloat32PtrString
- }
- return OpStructFieldFloat32Ptr
- case OpFloat64:
- if isString {
- return OpStructFieldFloat64String
- }
- return OpStructFieldFloat64
- case OpFloat64Ptr:
- if isString {
- return OpStructFieldFloat64PtrString
- }
- return OpStructFieldFloat64Ptr
- case OpString:
- if isString {
- return OpStructFieldStringString
- }
- return OpStructFieldString
- case OpStringPtr:
- if isString {
- return OpStructFieldStringPtrString
- }
- return OpStructFieldStringPtr
- case OpNumber:
- if isString {
- return OpStructFieldNumberString
- }
- return OpStructFieldNumber
- case OpNumberPtr:
- if isString {
- return OpStructFieldNumberPtrString
- }
- return OpStructFieldNumberPtr
- case OpBool:
- if isString {
- return OpStructFieldBoolString
- }
- return OpStructFieldBool
- case OpBoolPtr:
- if isString {
- return OpStructFieldBoolPtrString
- }
- return OpStructFieldBoolPtr
- case OpBytes:
- return OpStructFieldBytes
- case OpBytesPtr:
- return OpStructFieldBytesPtr
- case OpMap:
- return OpStructFieldMap
- case OpMapPtr:
- c.Op = OpMap
- return OpStructFieldMapPtr
- case OpArray:
- return OpStructFieldArray
- case OpArrayPtr:
- c.Op = OpArray
- return OpStructFieldArrayPtr
- case OpSlice:
- return OpStructFieldSlice
- case OpSlicePtr:
- c.Op = OpSlice
- return OpStructFieldSlicePtr
- case OpMarshalJSON:
- return OpStructFieldMarshalJSON
- case OpMarshalJSONPtr:
- return OpStructFieldMarshalJSONPtr
- case OpMarshalText:
- return OpStructFieldMarshalText
- case OpMarshalTextPtr:
- return OpStructFieldMarshalTextPtr
- }
- return OpStructField
-}
-
-func newOpCode(ctx *compileContext, op OpType) *Opcode {
- return newOpCodeWithNext(ctx, op, newEndOp(ctx))
-}
-
-func opcodeOffset(idx int) uint32 {
- return uint32(idx) * uintptrSize
-}
-
-func copyOpcode(code *Opcode) *Opcode {
- codeMap := map[uintptr]*Opcode{}
- return code.copy(codeMap)
-}
-
-func setTotalLengthToInterfaceOp(code *Opcode) {
- c := code
- for c.Op != OpEnd && c.Op != OpInterfaceEnd {
- if c.Op == OpInterface {
- c.Length = uint32(code.TotalLength())
- }
- switch c.Op.CodeType() {
- case CodeArrayElem, CodeSliceElem, CodeMapKey:
- c = c.End
- default:
- c = c.Next
- }
- }
-}
-
-func ToEndCode(code *Opcode) *Opcode {
- c := code
- for c.Op != OpEnd && c.Op != OpInterfaceEnd {
- switch c.Op.CodeType() {
- case CodeArrayElem, CodeSliceElem, CodeMapKey:
- c = c.End
- default:
- c = c.Next
- }
- }
- return c
-}
-
-func copyToInterfaceOpcode(code *Opcode) *Opcode {
- copied := copyOpcode(code)
- c := copied
- c = ToEndCode(c)
- c.Idx += uintptrSize
- c.ElemIdx = c.Idx + uintptrSize
- c.Length = c.Idx + 2*uintptrSize
- c.Op = OpInterfaceEnd
- return copied
-}
-
-func newOpCodeWithNext(ctx *compileContext, op OpType, next *Opcode) *Opcode {
- return &Opcode{
- Op: op,
- Idx: opcodeOffset(ctx.ptrIndex),
- Next: next,
- Type: ctx.typ,
- DisplayIdx: ctx.opcodeIndex,
- Indent: ctx.indent,
- }
-}
-
-func newEndOp(ctx *compileContext) *Opcode {
- return newOpCodeWithNext(ctx, OpEnd, nil)
-}
-
-func (c *Opcode) copy(codeMap map[uintptr]*Opcode) *Opcode {
- if c == nil {
- return nil
- }
- addr := uintptr(unsafe.Pointer(c))
- if code, exists := codeMap[addr]; exists {
- return code
- }
- copied := &Opcode{
- Op: c.Op,
- Key: c.Key,
- PtrNum: c.PtrNum,
- NumBitSize: c.NumBitSize,
- Flags: c.Flags,
- Idx: c.Idx,
- Offset: c.Offset,
- Type: c.Type,
- DisplayIdx: c.DisplayIdx,
- DisplayKey: c.DisplayKey,
- ElemIdx: c.ElemIdx,
- Length: c.Length,
- MapIter: c.MapIter,
- MapPos: c.MapPos,
- Size: c.Size,
- Indent: c.Indent,
- }
- codeMap[addr] = copied
- copied.End = c.End.copy(codeMap)
- copied.PrevField = c.PrevField.copy(codeMap)
- copied.NextField = c.NextField.copy(codeMap)
- copied.Next = c.Next.copy(codeMap)
- copied.Jmp = c.Jmp
- return copied
-}
-
-func (c *Opcode) BeforeLastCode() *Opcode {
- code := c
- for {
- var nextCode *Opcode
- switch code.Op.CodeType() {
- case CodeArrayElem, CodeSliceElem, CodeMapKey:
- nextCode = code.End
- default:
- nextCode = code.Next
- }
- if nextCode.Op == OpEnd {
- return code
- }
- code = nextCode
- }
-}
-
-func (c *Opcode) TotalLength() int {
- var idx int
- code := c
- for code.Op != OpEnd && code.Op != OpInterfaceEnd {
- maxIdx := int(code.MaxIdx() / uintptrSize)
- if idx < maxIdx {
- idx = maxIdx
- }
- if code.Op == OpRecursiveEnd {
- break
- }
- switch code.Op.CodeType() {
- case CodeArrayElem, CodeSliceElem, CodeMapKey:
- code = code.End
- default:
- code = code.Next
- }
- }
- maxIdx := int(code.MaxIdx() / uintptrSize)
- if idx < maxIdx {
- idx = maxIdx
- }
- return idx + 1
-}
-
-func (c *Opcode) decOpcodeIndex() {
- for code := c; code.Op != OpEnd; {
- code.DisplayIdx--
- if code.Idx > 0 {
- code.Idx -= uintptrSize
- }
- if code.ElemIdx > 0 {
- code.ElemIdx -= uintptrSize
- }
- if code.MapIter > 0 {
- code.MapIter -= uintptrSize
- }
- if code.Length > 0 && code.Op.CodeType() != CodeArrayHead && code.Op.CodeType() != CodeArrayElem {
- code.Length -= uintptrSize
- }
- switch code.Op.CodeType() {
- case CodeArrayElem, CodeSliceElem, CodeMapKey:
- code = code.End
- default:
- code = code.Next
- }
- }
-}
-
-func (c *Opcode) decIndent() {
- for code := c; code.Op != OpEnd; {
- code.Indent--
- switch code.Op.CodeType() {
- case CodeArrayElem, CodeSliceElem, CodeMapKey:
- code = code.End
- default:
- code = code.Next
- }
- }
-}
-
-func (c *Opcode) dumpHead(code *Opcode) string {
- var length uint32
- if code.Op.CodeType() == CodeArrayHead {
- length = code.Length
- } else {
- length = code.Length / uintptrSize
- }
- return fmt.Sprintf(
- `[%d]%s%s ([idx:%d][elemIdx:%d][length:%d])`,
- code.DisplayIdx,
- strings.Repeat("-", int(code.Indent)),
- code.Op,
- code.Idx/uintptrSize,
- code.ElemIdx/uintptrSize,
- length,
- )
-}
-
-func (c *Opcode) dumpMapHead(code *Opcode) string {
- return fmt.Sprintf(
- `[%d]%s%s ([idx:%d][elemIdx:%d][length:%d][mapIter:%d])`,
- code.DisplayIdx,
- strings.Repeat("-", int(code.Indent)),
- code.Op,
- code.Idx/uintptrSize,
- code.ElemIdx/uintptrSize,
- code.Length/uintptrSize,
- code.MapIter/uintptrSize,
- )
-}
-
-func (c *Opcode) dumpMapEnd(code *Opcode) string {
- return fmt.Sprintf(
- `[%d]%s%s ([idx:%d][mapPos:%d][length:%d])`,
- code.DisplayIdx,
- strings.Repeat("-", int(code.Indent)),
- code.Op,
- code.Idx/uintptrSize,
- code.MapPos/uintptrSize,
- code.Length/uintptrSize,
- )
-}
-
-func (c *Opcode) dumpElem(code *Opcode) string {
- var length uint32
- if code.Op.CodeType() == CodeArrayElem {
- length = code.Length
- } else {
- length = code.Length / uintptrSize
- }
- return fmt.Sprintf(
- `[%d]%s%s ([idx:%d][elemIdx:%d][length:%d][size:%d])`,
- code.DisplayIdx,
- strings.Repeat("-", int(code.Indent)),
- code.Op,
- code.Idx/uintptrSize,
- code.ElemIdx/uintptrSize,
- length,
- code.Size,
- )
-}
-
-func (c *Opcode) dumpField(code *Opcode) string {
- return fmt.Sprintf(
- `[%d]%s%s ([idx:%d][key:%s][offset:%d])`,
- code.DisplayIdx,
- strings.Repeat("-", int(code.Indent)),
- code.Op,
- code.Idx/uintptrSize,
- code.DisplayKey,
- code.Offset,
- )
-}
-
-func (c *Opcode) dumpKey(code *Opcode) string {
- return fmt.Sprintf(
- `[%d]%s%s ([idx:%d][elemIdx:%d][length:%d][mapIter:%d])`,
- code.DisplayIdx,
- strings.Repeat("-", int(code.Indent)),
- code.Op,
- code.Idx/uintptrSize,
- code.ElemIdx/uintptrSize,
- code.Length/uintptrSize,
- code.MapIter/uintptrSize,
- )
-}
-
-func (c *Opcode) dumpValue(code *Opcode) string {
- return fmt.Sprintf(
- `[%d]%s%s ([idx:%d][mapIter:%d])`,
- code.DisplayIdx,
- strings.Repeat("-", int(code.Indent)),
- code.Op,
- code.Idx/uintptrSize,
- code.MapIter/uintptrSize,
- )
-}
-
-func (c *Opcode) Dump() string {
- codes := []string{}
- for code := c; code.Op != OpEnd && code.Op != OpInterfaceEnd; {
- switch code.Op.CodeType() {
- case CodeSliceHead:
- codes = append(codes, c.dumpHead(code))
- code = code.Next
- case CodeMapHead:
- codes = append(codes, c.dumpMapHead(code))
- code = code.Next
- case CodeArrayElem, CodeSliceElem:
- codes = append(codes, c.dumpElem(code))
- code = code.End
- case CodeMapKey:
- codes = append(codes, c.dumpKey(code))
- code = code.End
- case CodeMapValue:
- codes = append(codes, c.dumpValue(code))
- code = code.Next
- case CodeMapEnd:
- codes = append(codes, c.dumpMapEnd(code))
- code = code.Next
- case CodeStructField:
- codes = append(codes, c.dumpField(code))
- code = code.Next
- case CodeStructEnd:
- codes = append(codes, c.dumpField(code))
- code = code.Next
- default:
- codes = append(codes, fmt.Sprintf(
- "[%d]%s%s ([idx:%d])",
- code.DisplayIdx,
- strings.Repeat("-", int(code.Indent)),
- code.Op,
- code.Idx/uintptrSize,
- ))
- code = code.Next
- }
- }
- return strings.Join(codes, "\n")
-}
-
-func prevField(code *Opcode, removedFields map[*Opcode]struct{}) *Opcode {
- if _, exists := removedFields[code]; exists {
- return prevField(code.PrevField, removedFields)
- }
- return code
-}
-
-func nextField(code *Opcode, removedFields map[*Opcode]struct{}) *Opcode {
- if _, exists := removedFields[code]; exists {
- return nextField(code.NextField, removedFields)
- }
- return code
-}
-
-func linkPrevToNextField(cur *Opcode, removedFields map[*Opcode]struct{}) {
- prev := prevField(cur.PrevField, removedFields)
- prev.NextField = nextField(cur.NextField, removedFields)
- code := prev
- fcode := cur
- for {
- var nextCode *Opcode
- switch code.Op.CodeType() {
- case CodeArrayElem, CodeSliceElem, CodeMapKey:
- nextCode = code.End
- default:
- nextCode = code.Next
- }
- if nextCode == fcode {
- code.Next = fcode.Next
- break
- } else if nextCode.Op == OpEnd {
- break
- }
- code = nextCode
- }
-}
-
-func newSliceHeaderCode(ctx *compileContext) *Opcode {
- idx := opcodeOffset(ctx.ptrIndex)
- ctx.incPtrIndex()
- elemIdx := opcodeOffset(ctx.ptrIndex)
- ctx.incPtrIndex()
- length := opcodeOffset(ctx.ptrIndex)
- return &Opcode{
- Op: OpSlice,
- Idx: idx,
- DisplayIdx: ctx.opcodeIndex,
- ElemIdx: elemIdx,
- Length: length,
- Indent: ctx.indent,
- }
-}
-
-func newSliceElemCode(ctx *compileContext, head *Opcode, size uintptr) *Opcode {
- return &Opcode{
- Op: OpSliceElem,
- Idx: head.Idx,
- DisplayIdx: ctx.opcodeIndex,
- ElemIdx: head.ElemIdx,
- Length: head.Length,
- Indent: ctx.indent,
- Size: uint32(size),
- }
-}
-
-func newArrayHeaderCode(ctx *compileContext, alen int) *Opcode {
- idx := opcodeOffset(ctx.ptrIndex)
- ctx.incPtrIndex()
- elemIdx := opcodeOffset(ctx.ptrIndex)
- return &Opcode{
- Op: OpArray,
- Idx: idx,
- DisplayIdx: ctx.opcodeIndex,
- ElemIdx: elemIdx,
- Indent: ctx.indent,
- Length: uint32(alen),
- }
-}
-
-func newArrayElemCode(ctx *compileContext, head *Opcode, length int, size uintptr) *Opcode {
- return &Opcode{
- Op: OpArrayElem,
- Idx: head.Idx,
- DisplayIdx: ctx.opcodeIndex,
- ElemIdx: head.ElemIdx,
- Length: uint32(length),
- Indent: ctx.indent,
- Size: uint32(size),
- }
-}
-
-func newMapHeaderCode(ctx *compileContext) *Opcode {
- idx := opcodeOffset(ctx.ptrIndex)
- ctx.incPtrIndex()
- elemIdx := opcodeOffset(ctx.ptrIndex)
- ctx.incPtrIndex()
- length := opcodeOffset(ctx.ptrIndex)
- ctx.incPtrIndex()
- mapIter := opcodeOffset(ctx.ptrIndex)
- return &Opcode{
- Op: OpMap,
- Idx: idx,
- Type: ctx.typ,
- DisplayIdx: ctx.opcodeIndex,
- ElemIdx: elemIdx,
- Length: length,
- MapIter: mapIter,
- Indent: ctx.indent,
- }
-}
-
-func newMapKeyCode(ctx *compileContext, head *Opcode) *Opcode {
- return &Opcode{
- Op: OpMapKey,
- Idx: opcodeOffset(ctx.ptrIndex),
- DisplayIdx: ctx.opcodeIndex,
- ElemIdx: head.ElemIdx,
- Length: head.Length,
- MapIter: head.MapIter,
- Indent: ctx.indent,
- }
-}
-
-func newMapValueCode(ctx *compileContext, head *Opcode) *Opcode {
- return &Opcode{
- Op: OpMapValue,
- Idx: opcodeOffset(ctx.ptrIndex),
- DisplayIdx: ctx.opcodeIndex,
- ElemIdx: head.ElemIdx,
- Length: head.Length,
- MapIter: head.MapIter,
- Indent: ctx.indent,
- }
-}
-
-func newMapEndCode(ctx *compileContext, head *Opcode) *Opcode {
- mapPos := opcodeOffset(ctx.ptrIndex)
- ctx.incPtrIndex()
- idx := opcodeOffset(ctx.ptrIndex)
- return &Opcode{
- Op: OpMapEnd,
- Idx: idx,
- Next: newEndOp(ctx),
- DisplayIdx: ctx.opcodeIndex,
- Length: head.Length,
- MapPos: mapPos,
- Indent: ctx.indent,
- }
-}
-
-func newInterfaceCode(ctx *compileContext) *Opcode {
- var flag OpFlags
- if ctx.typ.NumMethod() > 0 {
- flag |= NonEmptyInterfaceFlags
- }
- return &Opcode{
- Op: OpInterface,
- Idx: opcodeOffset(ctx.ptrIndex),
- Next: newEndOp(ctx),
- Type: ctx.typ,
- DisplayIdx: ctx.opcodeIndex,
- Indent: ctx.indent,
- Flags: flag,
- }
-}
-
-func newRecursiveCode(ctx *compileContext, jmp *CompiledCode) *Opcode {
- return &Opcode{
- Op: OpRecursive,
- Idx: opcodeOffset(ctx.ptrIndex),
- Next: newEndOp(ctx),
- Type: ctx.typ,
- DisplayIdx: ctx.opcodeIndex,
- Indent: ctx.indent,
- Jmp: jmp,
- }
-}