ui: panic if a StackOp does not Pop in the same macro as Push

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-09-17 11:55:45 +02:00
parent bae2e0ecf2
commit ee89d643cc
+13 -6
View File
@@ -20,6 +20,7 @@ type Ops struct {
refs []interface{} refs []interface{}
stackDepth int stackDepth int
macroDepth int
inAux bool inAux bool
auxOff int auxOff int
@@ -29,9 +30,10 @@ type Ops struct {
// StackOp can save and restore the operation state // StackOp can save and restore the operation state
// in a stack-like manner. // in a stack-like manner.
type StackOp struct { type StackOp struct {
depth int stackDepth int
active bool macroDepth int
ops *Ops active bool
ops *Ops
} }
// MacroOp can record a list of operations for later // MacroOp can record a list of operations for later
@@ -56,7 +58,8 @@ func (s *StackOp) Push(o *Ops) {
s.active = true s.active = true
s.ops = o s.ops = o
o.stackDepth++ o.stackDepth++
s.depth = o.stackDepth s.stackDepth = o.stackDepth
s.macroDepth = o.macroDepth
o.Write([]byte{byte(opconst.TypePush)}) o.Write([]byte{byte(opconst.TypePush)})
} }
@@ -65,10 +68,12 @@ func (s *StackOp) Pop() {
if !s.active { if !s.active {
panic("unbalanced pop") panic("unbalanced pop")
} }
d := s.ops.stackDepth if s.ops.stackDepth != s.stackDepth {
if d != s.depth {
panic("unbalanced pop") panic("unbalanced pop")
} }
if s.ops.macroDepth != s.macroDepth {
panic("pop in a different macro than push")
}
s.active = false s.active = false
s.ops.stackDepth-- s.ops.stackDepth--
s.ops.Write([]byte{byte(opconst.TypePop)}) s.ops.Write([]byte{byte(opconst.TypePop)})
@@ -156,6 +161,7 @@ func (m *MacroOp) Record(o *Ops) {
} }
m.recording = true m.recording = true
m.ops = o m.ops = o
m.ops.macroDepth++
m.pc = o.pc() m.pc = o.pc()
// Reserve room for a macro definition. Updated in Stop. // Reserve room for a macro definition. Updated in Stop.
m.ops.Write(make([]byte, opconst.TypeMacroDefLen)) m.ops.Write(make([]byte, opconst.TypeMacroDefLen))
@@ -167,6 +173,7 @@ func (m *MacroOp) Stop() {
if !m.recording { if !m.recording {
panic("not recording") panic("not recording")
} }
m.ops.macroDepth--
m.recording = false m.recording = false
m.fill() m.fill()
} }