mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 09:55:40 +00:00
op: move Ops internal methods and state to internal package ops
Merge package opconsts into ops as well; it only existed to break import cycles. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -1,172 +0,0 @@
|
||||
// SPDX-License-Identifier: Unlicense OR MIT
|
||||
|
||||
package opconst
|
||||
|
||||
type OpType byte
|
||||
|
||||
// Start at a high number for easier debugging.
|
||||
const firstOpIndex = 200
|
||||
|
||||
const (
|
||||
TypeMacro OpType = iota + firstOpIndex
|
||||
TypeCall
|
||||
TypeDefer
|
||||
TypeTransform
|
||||
TypePopTransform
|
||||
TypeInvalidate
|
||||
TypeImage
|
||||
TypePaint
|
||||
TypeColor
|
||||
TypeLinearGradient
|
||||
TypeArea
|
||||
TypePopArea
|
||||
TypePointerInput
|
||||
TypeClipboardRead
|
||||
TypeClipboardWrite
|
||||
TypeKeyInput
|
||||
TypeKeyFocus
|
||||
TypeKeySoftKeyboard
|
||||
TypeSave
|
||||
TypeLoad
|
||||
TypeAux
|
||||
TypeClip
|
||||
TypePopClip
|
||||
TypeProfile
|
||||
TypeCursor
|
||||
TypePath
|
||||
TypeStroke
|
||||
)
|
||||
|
||||
const (
|
||||
TypeMacroLen = 1 + 4 + 4
|
||||
TypeCallLen = 1 + 4 + 4
|
||||
TypeDeferLen = 1
|
||||
TypeTransformLen = 1 + 1 + 4*6
|
||||
TypePopTransformLen = 1
|
||||
TypeRedrawLen = 1 + 8
|
||||
TypeImageLen = 1
|
||||
TypePaintLen = 1
|
||||
TypeColorLen = 1 + 4
|
||||
TypeLinearGradientLen = 1 + 8*2 + 4*2
|
||||
TypeAreaLen = 1 + 1 + 1 + 4*4
|
||||
TypePopAreaLen = 1
|
||||
TypePointerInputLen = 1 + 1 + 1 + 2*4 + 2*4
|
||||
TypeClipboardReadLen = 1
|
||||
TypeClipboardWriteLen = 1
|
||||
TypeKeyInputLen = 1 + 1
|
||||
TypeKeyFocusLen = 1 + 1
|
||||
TypeKeySoftKeyboardLen = 1 + 1
|
||||
TypeSaveLen = 1 + 4
|
||||
TypeLoadLen = 1 + 4
|
||||
TypeAuxLen = 1
|
||||
TypeClipLen = 1 + 4*4 + 1 + 1
|
||||
TypePopClipLen = 1
|
||||
TypeProfileLen = 1
|
||||
TypeCursorLen = 1 + 1
|
||||
TypePathLen = 8 + 1
|
||||
TypeStrokeLen = 1 + 4
|
||||
)
|
||||
|
||||
func (t OpType) Size() int {
|
||||
return [...]int{
|
||||
TypeMacroLen,
|
||||
TypeCallLen,
|
||||
TypeDeferLen,
|
||||
TypeTransformLen,
|
||||
TypePopTransformLen,
|
||||
TypeRedrawLen,
|
||||
TypeImageLen,
|
||||
TypePaintLen,
|
||||
TypeColorLen,
|
||||
TypeLinearGradientLen,
|
||||
TypeAreaLen,
|
||||
TypePopAreaLen,
|
||||
TypePointerInputLen,
|
||||
TypeClipboardReadLen,
|
||||
TypeClipboardWriteLen,
|
||||
TypeKeyInputLen,
|
||||
TypeKeyFocusLen,
|
||||
TypeKeySoftKeyboardLen,
|
||||
TypeSaveLen,
|
||||
TypeLoadLen,
|
||||
TypeAuxLen,
|
||||
TypeClipLen,
|
||||
TypePopClipLen,
|
||||
TypeProfileLen,
|
||||
TypeCursorLen,
|
||||
TypePathLen,
|
||||
TypeStrokeLen,
|
||||
}[t-firstOpIndex]
|
||||
}
|
||||
|
||||
func (t OpType) NumRefs() int {
|
||||
switch t {
|
||||
case TypeKeyInput, TypeKeyFocus, TypePointerInput, TypeProfile, TypeCall, TypeClipboardRead, TypeClipboardWrite, TypeCursor:
|
||||
return 1
|
||||
case TypeImage:
|
||||
return 2
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (t OpType) String() string {
|
||||
switch t {
|
||||
case TypeMacro:
|
||||
return "Macro"
|
||||
case TypeCall:
|
||||
return "Call"
|
||||
case TypeDefer:
|
||||
return "Defer"
|
||||
case TypeTransform:
|
||||
return "Transform"
|
||||
case TypePopTransform:
|
||||
return "PopTransform"
|
||||
case TypeInvalidate:
|
||||
return "Invalidate"
|
||||
case TypeImage:
|
||||
return "Image"
|
||||
case TypePaint:
|
||||
return "Paint"
|
||||
case TypeColor:
|
||||
return "Color"
|
||||
case TypeLinearGradient:
|
||||
return "LinearGradient"
|
||||
case TypeArea:
|
||||
return "Area"
|
||||
case TypePopArea:
|
||||
return "PopArea"
|
||||
case TypePointerInput:
|
||||
return "PointerInput"
|
||||
case TypeClipboardRead:
|
||||
return "ClipboardRead"
|
||||
case TypeClipboardWrite:
|
||||
return "ClipboardWrite"
|
||||
case TypeKeyInput:
|
||||
return "KeyInput"
|
||||
case TypeKeyFocus:
|
||||
return "KeyFocus"
|
||||
case TypeKeySoftKeyboard:
|
||||
return "KeySoftKeyboard"
|
||||
case TypeSave:
|
||||
return "Save"
|
||||
case TypeLoad:
|
||||
return "Load"
|
||||
case TypeAux:
|
||||
return "Aux"
|
||||
case TypeClip:
|
||||
return "Clip"
|
||||
case TypePopClip:
|
||||
return "PopClip"
|
||||
case TypeProfile:
|
||||
return "Profile"
|
||||
case TypeCursor:
|
||||
return "Cursor"
|
||||
case TypePath:
|
||||
return "Path"
|
||||
case TypeStroke:
|
||||
return "Stroke"
|
||||
default:
|
||||
panic("unnkown OpType")
|
||||
}
|
||||
}
|
||||
+351
-4
@@ -8,10 +8,250 @@ import (
|
||||
|
||||
"gioui.org/f32"
|
||||
"gioui.org/internal/byteslice"
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/internal/scene"
|
||||
)
|
||||
|
||||
type Ops struct {
|
||||
// version is incremented at each Reset.
|
||||
version int
|
||||
// data contains the serialized operations.
|
||||
data []byte
|
||||
// refs hold external references for operations.
|
||||
refs []interface{}
|
||||
// nextStateID is the id allocated for the next
|
||||
// StateOp.
|
||||
nextStateID int
|
||||
|
||||
macroStack stack
|
||||
stacks [3]stack
|
||||
}
|
||||
|
||||
type OpType byte
|
||||
|
||||
// Start at a high number for easier debugging.
|
||||
const firstOpIndex = 200
|
||||
|
||||
const (
|
||||
TypeMacro OpType = iota + firstOpIndex
|
||||
TypeCall
|
||||
TypeDefer
|
||||
TypePushTransform
|
||||
TypeTransform
|
||||
TypePopTransform
|
||||
TypeInvalidate
|
||||
TypeImage
|
||||
TypePaint
|
||||
TypeColor
|
||||
TypeLinearGradient
|
||||
TypeArea
|
||||
TypePopArea
|
||||
TypePointerInput
|
||||
TypeClipboardRead
|
||||
TypeClipboardWrite
|
||||
TypeKeyInput
|
||||
TypeKeyFocus
|
||||
TypeKeySoftKeyboard
|
||||
TypeSave
|
||||
TypeLoad
|
||||
TypeAux
|
||||
TypeClip
|
||||
TypePopClip
|
||||
TypeProfile
|
||||
TypeCursor
|
||||
TypePath
|
||||
TypeStroke
|
||||
)
|
||||
|
||||
type StackID struct {
|
||||
id int
|
||||
prev int
|
||||
}
|
||||
|
||||
// StateOp represents a saved operation snapshop to be restored
|
||||
// later.
|
||||
type StateOP struct {
|
||||
id int
|
||||
macroID int
|
||||
ops *Ops
|
||||
}
|
||||
|
||||
// stack tracks the integer identities of stack operations to ensure correct
|
||||
// pairing of their push and pop methods.
|
||||
type stack struct {
|
||||
currentID int
|
||||
nextID int
|
||||
}
|
||||
|
||||
type StackKind uint8
|
||||
|
||||
const (
|
||||
ClipStack StackKind = iota
|
||||
AreaStack
|
||||
TransStack
|
||||
)
|
||||
|
||||
const (
|
||||
TypeMacroLen = 1 + 4 + 4
|
||||
TypeCallLen = 1 + 4 + 4
|
||||
TypeDeferLen = 1
|
||||
TypePushTransformLen = 1 + 4*6
|
||||
TypeTransformLen = 1 + 1 + 4*6
|
||||
TypePopTransformLen = 1
|
||||
TypeRedrawLen = 1 + 8
|
||||
TypeImageLen = 1
|
||||
TypePaintLen = 1
|
||||
TypeColorLen = 1 + 4
|
||||
TypeLinearGradientLen = 1 + 8*2 + 4*2
|
||||
TypeAreaLen = 1 + 1 + 1 + 4*4
|
||||
TypePopAreaLen = 1
|
||||
TypePointerInputLen = 1 + 1 + 1 + 2*4 + 2*4
|
||||
TypeClipboardReadLen = 1
|
||||
TypeClipboardWriteLen = 1
|
||||
TypeKeyInputLen = 1 + 1
|
||||
TypeKeyFocusLen = 1 + 1
|
||||
TypeKeySoftKeyboardLen = 1 + 1
|
||||
TypeSaveLen = 1 + 4
|
||||
TypeLoadLen = 1 + 4
|
||||
TypeAuxLen = 1
|
||||
TypeClipLen = 1 + 4*4 + 1 + 1
|
||||
TypePopClipLen = 1
|
||||
TypeProfileLen = 1
|
||||
TypeCursorLen = 1 + 1
|
||||
TypePathLen = 8 + 1
|
||||
TypeStrokeLen = 1 + 4
|
||||
)
|
||||
|
||||
func (o *Ops) Reset() {
|
||||
o.macroStack = stack{}
|
||||
for i := range o.stacks {
|
||||
o.stacks[i] = stack{}
|
||||
}
|
||||
// Leave references to the GC.
|
||||
for i := range o.refs {
|
||||
o.refs[i] = nil
|
||||
}
|
||||
o.data = o.data[:0]
|
||||
o.refs = o.refs[:0]
|
||||
o.nextStateID = 0
|
||||
o.version++
|
||||
}
|
||||
|
||||
func (o *Ops) Data() []byte {
|
||||
return o.data
|
||||
}
|
||||
|
||||
func (o *Ops) Refs() []interface{} {
|
||||
return o.refs
|
||||
}
|
||||
|
||||
func (o *Ops) Version() int {
|
||||
return o.version
|
||||
}
|
||||
|
||||
func (o *Ops) Write(n int) []byte {
|
||||
o.data = append(o.data, make([]byte, n)...)
|
||||
return o.data[len(o.data)-n:]
|
||||
}
|
||||
|
||||
func (o *Ops) PushMacro() StackID {
|
||||
return o.macroStack.push()
|
||||
}
|
||||
|
||||
func (o *Ops) PopMacro(id StackID) {
|
||||
o.macroStack.pop(id)
|
||||
}
|
||||
|
||||
func (o *Ops) FillMacro(startPC PC) {
|
||||
pc := o.PC()
|
||||
// Fill out the macro definition reserved in Record.
|
||||
data := o.data[startPC.data:]
|
||||
data = data[:TypeMacroLen]
|
||||
data[0] = byte(TypeMacro)
|
||||
bo := binary.LittleEndian
|
||||
bo.PutUint32(data[1:], uint32(pc.data))
|
||||
bo.PutUint32(data[5:], uint32(pc.refs))
|
||||
}
|
||||
|
||||
func (o *Ops) AddCall(callOps *Ops, pc PC) {
|
||||
data := o.Write1(TypeCallLen, callOps)
|
||||
data[0] = byte(TypeCall)
|
||||
bo := binary.LittleEndian
|
||||
bo.PutUint32(data[1:], uint32(pc.data))
|
||||
bo.PutUint32(data[5:], uint32(pc.refs))
|
||||
}
|
||||
|
||||
func (o *Ops) PushOp(kind StackKind) (StackID, int) {
|
||||
return o.stacks[kind].push(), o.macroStack.currentID
|
||||
}
|
||||
|
||||
func (o *Ops) PopOp(kind StackKind, sid StackID, macroID int) {
|
||||
if o.macroStack.currentID != macroID {
|
||||
panic("stack push and pop must not cross macro boundary")
|
||||
}
|
||||
o.stacks[kind].pop(sid)
|
||||
}
|
||||
|
||||
func (o *Ops) Write1(n int, ref1 interface{}) []byte {
|
||||
o.data = append(o.data, make([]byte, n)...)
|
||||
o.refs = append(o.refs, ref1)
|
||||
return o.data[len(o.data)-n:]
|
||||
}
|
||||
|
||||
func (o *Ops) Write2(n int, ref1, ref2 interface{}) []byte {
|
||||
o.data = append(o.data, make([]byte, n)...)
|
||||
o.refs = append(o.refs, ref1, ref2)
|
||||
return o.data[len(o.data)-n:]
|
||||
}
|
||||
|
||||
func (o *Ops) PC() PC {
|
||||
return PC{data: len(o.data), refs: len(o.refs)}
|
||||
}
|
||||
|
||||
func (s *stack) push() StackID {
|
||||
s.nextID++
|
||||
sid := StackID{
|
||||
id: s.nextID,
|
||||
prev: s.currentID,
|
||||
}
|
||||
s.currentID = s.nextID
|
||||
return sid
|
||||
}
|
||||
|
||||
func (s *stack) check(sid StackID) {
|
||||
if s.currentID != sid.id {
|
||||
panic("unbalanced operation")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *stack) pop(sid StackID) {
|
||||
s.check(sid)
|
||||
s.currentID = sid.prev
|
||||
}
|
||||
|
||||
// Save the effective transformation.
|
||||
func (o *Ops) Save() StateOP {
|
||||
o.nextStateID++
|
||||
s := StateOP{
|
||||
ops: o,
|
||||
id: o.nextStateID,
|
||||
macroID: o.macroStack.currentID,
|
||||
}
|
||||
bo := binary.LittleEndian
|
||||
data := o.Write(TypeSaveLen)
|
||||
data[0] = byte(TypeSave)
|
||||
bo.PutUint32(data[1:], uint32(s.id))
|
||||
return s
|
||||
}
|
||||
|
||||
// load a previously saved operations state given
|
||||
// its ID.
|
||||
func (s StateOP) Load() {
|
||||
bo := binary.LittleEndian
|
||||
data := s.ops.Write(TypeLoadLen)
|
||||
data[0] = byte(TypeLoad)
|
||||
bo.PutUint32(data[1:], uint32(s.id))
|
||||
}
|
||||
|
||||
func DecodeCommand(d []byte) scene.Command {
|
||||
var cmd scene.Command
|
||||
copy(byteslice.Uint32(cmd[:]), d)
|
||||
@@ -23,7 +263,7 @@ func EncodeCommand(out []byte, cmd scene.Command) {
|
||||
}
|
||||
|
||||
func DecodeTransform(data []byte) (t f32.Affine2D, push bool) {
|
||||
if opconst.OpType(data[0]) != opconst.TypeTransform {
|
||||
if OpType(data[0]) != TypeTransform {
|
||||
panic("invalid op")
|
||||
}
|
||||
push = data[1] != 0
|
||||
@@ -42,7 +282,7 @@ func DecodeTransform(data []byte) (t f32.Affine2D, push bool) {
|
||||
|
||||
// DecodeSave decodes the state id of a save op.
|
||||
func DecodeSave(data []byte) int {
|
||||
if opconst.OpType(data[0]) != opconst.TypeSave {
|
||||
if OpType(data[0]) != TypeSave {
|
||||
panic("invalid op")
|
||||
}
|
||||
bo := binary.LittleEndian
|
||||
@@ -51,9 +291,116 @@ func DecodeSave(data []byte) int {
|
||||
|
||||
// DecodeLoad decodes the state id of a load op.
|
||||
func DecodeLoad(data []byte) int {
|
||||
if opconst.OpType(data[0]) != opconst.TypeLoad {
|
||||
if OpType(data[0]) != TypeLoad {
|
||||
panic("invalid op")
|
||||
}
|
||||
bo := binary.LittleEndian
|
||||
return int(bo.Uint32(data[1:]))
|
||||
}
|
||||
|
||||
func (t OpType) Size() int {
|
||||
return [...]int{
|
||||
TypeMacroLen,
|
||||
TypeCallLen,
|
||||
TypeDeferLen,
|
||||
TypePushTransformLen,
|
||||
TypeTransformLen,
|
||||
TypePopTransformLen,
|
||||
TypeRedrawLen,
|
||||
TypeImageLen,
|
||||
TypePaintLen,
|
||||
TypeColorLen,
|
||||
TypeLinearGradientLen,
|
||||
TypeAreaLen,
|
||||
TypePopAreaLen,
|
||||
TypePointerInputLen,
|
||||
TypeClipboardReadLen,
|
||||
TypeClipboardWriteLen,
|
||||
TypeKeyInputLen,
|
||||
TypeKeyFocusLen,
|
||||
TypeKeySoftKeyboardLen,
|
||||
TypeSaveLen,
|
||||
TypeLoadLen,
|
||||
TypeAuxLen,
|
||||
TypeClipLen,
|
||||
TypePopClipLen,
|
||||
TypeProfileLen,
|
||||
TypeCursorLen,
|
||||
TypePathLen,
|
||||
TypeStrokeLen,
|
||||
}[t-firstOpIndex]
|
||||
}
|
||||
|
||||
func (t OpType) NumRefs() int {
|
||||
switch t {
|
||||
case TypeKeyInput, TypeKeyFocus, TypePointerInput, TypeProfile, TypeCall, TypeClipboardRead, TypeClipboardWrite, TypeCursor:
|
||||
return 1
|
||||
case TypeImage:
|
||||
return 2
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (t OpType) String() string {
|
||||
switch t {
|
||||
case TypeMacro:
|
||||
return "Macro"
|
||||
case TypeCall:
|
||||
return "Call"
|
||||
case TypeDefer:
|
||||
return "Defer"
|
||||
case TypePushTransform:
|
||||
return "PushTransform"
|
||||
case TypeTransform:
|
||||
return "Transform"
|
||||
case TypePopTransform:
|
||||
return "PopTransform"
|
||||
case TypeInvalidate:
|
||||
return "Invalidate"
|
||||
case TypeImage:
|
||||
return "Image"
|
||||
case TypePaint:
|
||||
return "Paint"
|
||||
case TypeColor:
|
||||
return "Color"
|
||||
case TypeLinearGradient:
|
||||
return "LinearGradient"
|
||||
case TypeArea:
|
||||
return "Area"
|
||||
case TypePopArea:
|
||||
return "PopArea"
|
||||
case TypePointerInput:
|
||||
return "PointerInput"
|
||||
case TypeClipboardRead:
|
||||
return "ClipboardRead"
|
||||
case TypeClipboardWrite:
|
||||
return "ClipboardWrite"
|
||||
case TypeKeyInput:
|
||||
return "KeyInput"
|
||||
case TypeKeyFocus:
|
||||
return "KeyFocus"
|
||||
case TypeKeySoftKeyboard:
|
||||
return "KeySoftKeyboard"
|
||||
case TypeSave:
|
||||
return "Save"
|
||||
case TypeLoad:
|
||||
return "Load"
|
||||
case TypeAux:
|
||||
return "Aux"
|
||||
case TypeClip:
|
||||
return "Clip"
|
||||
case TypePopClip:
|
||||
return "PopClip"
|
||||
case TypeProfile:
|
||||
return "Profile"
|
||||
case TypeCursor:
|
||||
return "Cursor"
|
||||
case TypePath:
|
||||
return "Path"
|
||||
case TypeStroke:
|
||||
return "Stroke"
|
||||
default:
|
||||
panic("unnkown OpType")
|
||||
}
|
||||
}
|
||||
|
||||
+20
-32
@@ -4,17 +4,14 @@ package ops
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"gioui.org/internal/opconst"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// Reader parses an ops list.
|
||||
type Reader struct {
|
||||
pc PC
|
||||
stack []macro
|
||||
ops *op.Ops
|
||||
deferOps op.Ops
|
||||
ops *Ops
|
||||
deferOps Ops
|
||||
deferDone bool
|
||||
}
|
||||
|
||||
@@ -28,14 +25,14 @@ type EncodedOp struct {
|
||||
|
||||
// Key is a unique key for a given op.
|
||||
type Key struct {
|
||||
ops *op.Ops
|
||||
ops *Ops
|
||||
pc int
|
||||
version int
|
||||
}
|
||||
|
||||
// Shadow of op.MacroOp.
|
||||
type macroOp struct {
|
||||
ops *op.Ops
|
||||
ops *Ops
|
||||
pc PC
|
||||
}
|
||||
|
||||
@@ -46,7 +43,7 @@ type PC struct {
|
||||
}
|
||||
|
||||
type macro struct {
|
||||
ops *op.Ops
|
||||
ops *Ops
|
||||
retPC PC
|
||||
endPC PC
|
||||
}
|
||||
@@ -56,12 +53,12 @@ type opMacroDef struct {
|
||||
}
|
||||
|
||||
// Reset start reading from the beginning of ops.
|
||||
func (r *Reader) Reset(ops *op.Ops) {
|
||||
func (r *Reader) Reset(ops *Ops) {
|
||||
r.ResetAt(ops, PC{})
|
||||
}
|
||||
|
||||
// ResetAt is like Reset, except it starts reading from pc.
|
||||
func (r *Reader) ResetAt(ops *op.Ops, pc PC) {
|
||||
func (r *Reader) ResetAt(ops *Ops, pc PC) {
|
||||
r.stack = r.stack[:0]
|
||||
r.deferOps.Reset()
|
||||
r.deferDone = false
|
||||
@@ -69,15 +66,6 @@ func (r *Reader) ResetAt(ops *op.Ops, pc PC) {
|
||||
r.ops = ops
|
||||
}
|
||||
|
||||
// NewPC returns a PC representing the current instruction counter of
|
||||
// ops.
|
||||
func NewPC(ops *op.Ops) PC {
|
||||
return PC{
|
||||
data: len(ops.Data()),
|
||||
refs: len(ops.Refs()),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reader) Decode() (EncodedOp, bool) {
|
||||
if r.ops == nil {
|
||||
return EncodedOp{}, false
|
||||
@@ -107,25 +95,25 @@ func (r *Reader) Decode() (EncodedOp, bool) {
|
||||
continue
|
||||
}
|
||||
key := Key{ops: r.ops, pc: r.pc.data, version: r.ops.Version()}
|
||||
t := opconst.OpType(data[0])
|
||||
t := OpType(data[0])
|
||||
n := t.Size()
|
||||
nrefs := t.NumRefs()
|
||||
data = data[:n]
|
||||
refs = refs[r.pc.refs:]
|
||||
refs = refs[:nrefs]
|
||||
switch t {
|
||||
case opconst.TypeDefer:
|
||||
case TypeDefer:
|
||||
deferring = true
|
||||
r.pc.data += n
|
||||
r.pc.refs += nrefs
|
||||
continue
|
||||
case opconst.TypeAux:
|
||||
case TypeAux:
|
||||
// An Aux operations is always wrapped in a macro, and
|
||||
// its length is the remaining space.
|
||||
block := r.stack[len(r.stack)-1]
|
||||
n += block.endPC.data - r.pc.data - opconst.TypeAuxLen
|
||||
n += block.endPC.data - r.pc.data - TypeAuxLen
|
||||
data = data[:n]
|
||||
case opconst.TypeCall:
|
||||
case TypeCall:
|
||||
if deferring {
|
||||
deferring = false
|
||||
// Copy macro for deferred execution.
|
||||
@@ -141,11 +129,11 @@ func (r *Reader) Decode() (EncodedOp, bool) {
|
||||
var op macroOp
|
||||
op.decode(data, refs)
|
||||
macroData := op.ops.Data()[op.pc.data:]
|
||||
if opconst.OpType(macroData[0]) != opconst.TypeMacro {
|
||||
if OpType(macroData[0]) != TypeMacro {
|
||||
panic("invalid macro reference")
|
||||
}
|
||||
var opDef opMacroDef
|
||||
opDef.decode(macroData[:opconst.TypeMacro.Size()])
|
||||
opDef.decode(macroData[:TypeMacro.Size()])
|
||||
retPC := r.pc
|
||||
retPC.data += n
|
||||
retPC.refs += nrefs
|
||||
@@ -156,10 +144,10 @@ func (r *Reader) Decode() (EncodedOp, bool) {
|
||||
})
|
||||
r.ops = op.ops
|
||||
r.pc = op.pc
|
||||
r.pc.data += opconst.TypeMacro.Size()
|
||||
r.pc.refs += opconst.TypeMacro.NumRefs()
|
||||
r.pc.data += TypeMacro.Size()
|
||||
r.pc.refs += TypeMacro.NumRefs()
|
||||
continue
|
||||
case opconst.TypeMacro:
|
||||
case TypeMacro:
|
||||
var op opMacroDef
|
||||
op.decode(data)
|
||||
r.pc = op.endpc
|
||||
@@ -172,7 +160,7 @@ func (r *Reader) Decode() (EncodedOp, bool) {
|
||||
}
|
||||
|
||||
func (op *opMacroDef) decode(data []byte) {
|
||||
if opconst.OpType(data[0]) != opconst.TypeMacro {
|
||||
if OpType(data[0]) != TypeMacro {
|
||||
panic("invalid op")
|
||||
}
|
||||
bo := binary.LittleEndian
|
||||
@@ -188,7 +176,7 @@ func (op *opMacroDef) decode(data []byte) {
|
||||
}
|
||||
|
||||
func (m *macroOp) decode(data []byte, refs []interface{}) {
|
||||
if opconst.OpType(data[0]) != opconst.TypeCall {
|
||||
if OpType(data[0]) != TypeCall {
|
||||
panic("invalid op")
|
||||
}
|
||||
data = data[:9]
|
||||
@@ -196,7 +184,7 @@ func (m *macroOp) decode(data []byte, refs []interface{}) {
|
||||
dataIdx := int(int32(bo.Uint32(data[1:])))
|
||||
refsIdx := int(int32(bo.Uint32(data[5:])))
|
||||
*m = macroOp{
|
||||
ops: refs[0].(*op.Ops),
|
||||
ops: refs[0].(*Ops),
|
||||
pc: PC{
|
||||
data: dataIdx,
|
||||
refs: refsIdx,
|
||||
|
||||
Reference in New Issue
Block a user