@@ -21,6 +21,55 @@ pub struct Stack {
21
21
last_local : Option < OperandIdx > ,
22
22
/// The maximum size of the [`Stack`].
23
23
max_stack_height : usize ,
24
+ /// The current phase of the [`Stack`].
25
+ phase : StackPhase ,
26
+ }
27
+
28
+ /// The current phase of the [`Stack`].
29
+ #[ derive( Debug , Default , Copy , Clone ) ]
30
+ pub enum StackPhase {
31
+ /// Phase that allows to define local variables.
32
+ #[ default]
33
+ DefineLocals ,
34
+ /// Phase that allows to manipulate the stack and allocate function local constants.
35
+ Translation ,
36
+ /// Phase after finishing translation.
37
+ ///
38
+ /// In this phase state changes are no longer allowed.
39
+ /// Only resetting the [`Stack`] is allowed in order to restart the phase cycle.
40
+ Finish ,
41
+ }
42
+
43
+ impl StackPhase {
44
+ /// Resets the [`StackPhase`] to the [`StackPhase::DefineLocals`] phase.
45
+ pub fn reset ( & mut self ) {
46
+ * self = Self :: default ( ) ;
47
+ }
48
+
49
+ /// Ensures that the current phase is [`StackPhase::DefineLocals`].
50
+ pub fn assert_define_locals ( & self ) {
51
+ assert ! ( matches!( self , Self :: DefineLocals ) ) ;
52
+ }
53
+
54
+ /// Turns the current phase into [`StackPhase::Translation`].
55
+ ///
56
+ /// # Panics
57
+ ///
58
+ /// If the current phase is incompatible with this phase shift.
59
+ pub fn assert_translation ( & mut self ) {
60
+ assert ! ( matches!( self , Self :: DefineLocals | Self :: Translation ) ) ;
61
+ * self = Self :: Translation ;
62
+ }
63
+
64
+ /// Turns the current phase into [`StackPhase::Finish`].
65
+ ///
66
+ /// # Panics
67
+ ///
68
+ /// If the current phase is incompatible with this phase shift.
69
+ pub fn assert_finish ( & mut self ) {
70
+ assert ! ( matches!( self , Self :: Translation | Self :: Finish ) ) ;
71
+ * self = Self :: Finish ;
72
+ }
24
73
}
25
74
26
75
/// A [`StackOperand`] or [`Operand`] index on the [`Stack`].
0 commit comments