mirror of https://github.com/goccy/go-json.git
Refactor opcode
This commit is contained in:
parent
2b98da0634
commit
078c1e9bf3
|
@ -50,6 +50,42 @@ type Opcode struct {
|
||||||
DisplayKey string // key text to display
|
DisplayKey string // key text to display
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Opcode) Validate() error {
|
||||||
|
var prevIdx uint32
|
||||||
|
for code := c; !code.IsEnd(); {
|
||||||
|
if prevIdx != 0 {
|
||||||
|
if code.DisplayIdx != prevIdx+1 {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"invalid index. previous display index is %d but next is %d. dump = %s",
|
||||||
|
prevIdx, code.DisplayIdx, c.Dump(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prevIdx = code.DisplayIdx
|
||||||
|
code = code.IterNext()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Opcode) IterNext() *Opcode {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
switch c.Op.CodeType() {
|
||||||
|
case CodeArrayElem, CodeSliceElem, CodeMapKey:
|
||||||
|
return c.End
|
||||||
|
default:
|
||||||
|
return c.Next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Opcode) IsEnd() bool {
|
||||||
|
if c == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return c.Op == OpEnd || c.Op == OpInterfaceEnd
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Opcode) IsStructHeadOp() bool {
|
func (c *Opcode) IsStructHeadOp() bool {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return false
|
return false
|
||||||
|
@ -392,14 +428,8 @@ func (c *Opcode) copy(codeMap map[uintptr]*Opcode) *Opcode {
|
||||||
func (c *Opcode) BeforeLastCode() *Opcode {
|
func (c *Opcode) BeforeLastCode() *Opcode {
|
||||||
code := c
|
code := c
|
||||||
for {
|
for {
|
||||||
var nextCode *Opcode
|
nextCode := code.IterNext()
|
||||||
switch code.Op.CodeType() {
|
if nextCode.IsEnd() {
|
||||||
case CodeArrayElem, CodeSliceElem, CodeMapKey:
|
|
||||||
nextCode = code.End
|
|
||||||
default:
|
|
||||||
nextCode = code.Next
|
|
||||||
}
|
|
||||||
if nextCode.Op == OpEnd {
|
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
code = nextCode
|
code = nextCode
|
||||||
|
@ -409,7 +439,7 @@ func (c *Opcode) BeforeLastCode() *Opcode {
|
||||||
func (c *Opcode) TotalLength() int {
|
func (c *Opcode) TotalLength() int {
|
||||||
var idx int
|
var idx int
|
||||||
code := c
|
code := c
|
||||||
for code.Op != OpEnd && code.Op != OpInterfaceEnd {
|
for !code.IsEnd() {
|
||||||
maxIdx := int(code.MaxIdx() / uintptrSize)
|
maxIdx := int(code.MaxIdx() / uintptrSize)
|
||||||
if idx < maxIdx {
|
if idx < maxIdx {
|
||||||
idx = maxIdx
|
idx = maxIdx
|
||||||
|
@ -417,12 +447,7 @@ func (c *Opcode) TotalLength() int {
|
||||||
if code.Op == OpRecursiveEnd {
|
if code.Op == OpRecursiveEnd {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch code.Op.CodeType() {
|
code = code.IterNext()
|
||||||
case CodeArrayElem, CodeSliceElem, CodeMapKey:
|
|
||||||
code = code.End
|
|
||||||
default:
|
|
||||||
code = code.Next
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
maxIdx := int(code.MaxIdx() / uintptrSize)
|
maxIdx := int(code.MaxIdx() / uintptrSize)
|
||||||
if idx < maxIdx {
|
if idx < maxIdx {
|
||||||
|
@ -432,7 +457,7 @@ func (c *Opcode) TotalLength() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Opcode) decOpcodeIndex() {
|
func (c *Opcode) decOpcodeIndex() {
|
||||||
for code := c; code.Op != OpEnd; {
|
for code := c; !code.IsEnd(); {
|
||||||
code.DisplayIdx--
|
code.DisplayIdx--
|
||||||
if code.Idx > 0 {
|
if code.Idx > 0 {
|
||||||
code.Idx -= uintptrSize
|
code.Idx -= uintptrSize
|
||||||
|
@ -446,24 +471,14 @@ func (c *Opcode) decOpcodeIndex() {
|
||||||
if code.Length > 0 && code.Op.CodeType() != CodeArrayHead && code.Op.CodeType() != CodeArrayElem {
|
if code.Length > 0 && code.Op.CodeType() != CodeArrayHead && code.Op.CodeType() != CodeArrayElem {
|
||||||
code.Length -= uintptrSize
|
code.Length -= uintptrSize
|
||||||
}
|
}
|
||||||
switch code.Op.CodeType() {
|
code = code.IterNext()
|
||||||
case CodeArrayElem, CodeSliceElem, CodeMapKey:
|
|
||||||
code = code.End
|
|
||||||
default:
|
|
||||||
code = code.Next
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Opcode) decIndent() {
|
func (c *Opcode) decIndent() {
|
||||||
for code := c; code.Op != OpEnd; {
|
for code := c; !code.IsEnd(); {
|
||||||
code.Indent--
|
code.Indent--
|
||||||
switch code.Op.CodeType() {
|
code = code.IterNext()
|
||||||
case CodeArrayElem, CodeSliceElem, CodeMapKey:
|
|
||||||
code = code.End
|
|
||||||
default:
|
|
||||||
code = code.Next
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,7 +582,7 @@ func (c *Opcode) dumpValue(code *Opcode) string {
|
||||||
|
|
||||||
func (c *Opcode) Dump() string {
|
func (c *Opcode) Dump() string {
|
||||||
codes := []string{}
|
codes := []string{}
|
||||||
for code := c; code.Op != OpEnd && code.Op != OpInterfaceEnd; {
|
for code := c; !code.IsEnd(); {
|
||||||
switch code.Op.CodeType() {
|
switch code.Op.CodeType() {
|
||||||
case CodeSliceHead:
|
case CodeSliceHead:
|
||||||
codes = append(codes, c.dumpHead(code))
|
codes = append(codes, c.dumpHead(code))
|
||||||
|
@ -625,17 +640,10 @@ func linkPrevToNextField(cur *Opcode, removedFields map[*Opcode]struct{}) {
|
||||||
prev := prevField(cur.PrevField, removedFields)
|
prev := prevField(cur.PrevField, removedFields)
|
||||||
prev.NextField = nextField(cur.NextField, removedFields)
|
prev.NextField = nextField(cur.NextField, removedFields)
|
||||||
code := prev
|
code := prev
|
||||||
fcode := cur
|
|
||||||
for {
|
for {
|
||||||
var nextCode *Opcode
|
nextCode := code.IterNext()
|
||||||
switch code.Op.CodeType() {
|
if nextCode == cur {
|
||||||
case CodeArrayElem, CodeSliceElem, CodeMapKey:
|
code.Next = cur.NextField
|
||||||
nextCode = code.End
|
|
||||||
default:
|
|
||||||
nextCode = code.Next
|
|
||||||
}
|
|
||||||
if nextCode == fcode {
|
|
||||||
code.Next = fcode.NextField
|
|
||||||
break
|
break
|
||||||
} else if nextCode.Op == OpEnd {
|
} else if nextCode.Op == OpEnd {
|
||||||
break
|
break
|
||||||
|
|
Loading…
Reference in New Issue