@@ -45,6 +45,17 @@ impl Opcode {
4545 pub const fn is_block_push ( & self ) -> bool {
4646 false
4747 }
48+
49+ /// Stack effect when the instruction takes its branch (jump=true).
50+ ///
51+ /// CPython equivalent: `stack_effect(opcode, oparg, jump=True)`.
52+ /// For most instructions this equals the fallthrough effect.
53+ /// Override for instructions where branch and fallthrough differ
54+ /// (e.g. [`Self::ForIter`]: fallthrough = +1, branch = −1).
55+ #[ must_use]
56+ pub fn stack_effect_jump ( & self , oparg : u32 ) -> i32 {
57+ self . stack_effect ( oparg)
58+ }
4859}
4960
5061impl PseudoOpcode {
@@ -60,6 +71,22 @@ impl PseudoOpcode {
6071 Self :: SetupCleanup | Self :: SetupFinally | Self :: SetupWith
6172 )
6273 }
74+
75+ /// Handler entry effect for SETUP_* pseudo ops.
76+ ///
77+ /// Fallthrough effect is 0 (NOPs), but when the branch is taken the
78+ /// handler block starts with extra values on the stack:
79+ /// SETUP_FINALLY: +1 (exc)
80+ /// SETUP_CLEANUP: +2 (lasti + exc)
81+ /// SETUP_WITH: +1 (pops __enter__ result, pushes lasti + exc)
82+ #[ must_use]
83+ pub fn stack_effect_jump ( & self , oparg : u32 ) -> i32 {
84+ match self {
85+ Self :: SetupFinally | Self :: SetupWith => 1 ,
86+ Self :: SetupCleanup => 2 ,
87+ _ => self . stack_effect ( oparg) ,
88+ }
89+ }
6390}
6491
6592impl Instruction {
@@ -91,15 +118,9 @@ impl Instruction {
91118 self . as_opcode ( ) . deoptimize ( ) . as_instruction ( )
92119 }
93120
94- /// Stack effect when the instruction takes its branch (jump=true).
95- ///
96- /// CPython equivalent: `stack_effect(opcode, oparg, jump=True)`.
97- /// For most instructions this equals the fallthrough effect.
98- /// Override for instructions where branch and fallthrough differ
99- /// (e.g. [`Self::ForIter`]: fallthrough = +1, branch = −1).
100121 #[ must_use]
101122 pub fn stack_effect_jump ( & self , oparg : u32 ) -> i32 {
102- self . stack_effect ( oparg)
123+ self . as_opcode ( ) . stack_effect ( oparg)
103124 }
104125}
105126
@@ -126,20 +147,9 @@ impl PseudoInstruction {
126147 false
127148 }
128149
129- /// Handler entry effect for SETUP_* pseudo ops.
130- ///
131- /// Fallthrough effect is 0 (NOPs), but when the branch is taken the
132- /// handler block starts with extra values on the stack:
133- /// SETUP_FINALLY: +1 (exc)
134- /// SETUP_CLEANUP: +2 (lasti + exc)
135- /// SETUP_WITH: +1 (pops __enter__ result, pushes lasti + exc)
136150 #[ must_use]
137151 pub fn stack_effect_jump ( & self , oparg : u32 ) -> i32 {
138- match self . as_opcode ( ) {
139- PseudoOpcode :: SetupFinally | PseudoOpcode :: SetupWith => 1 ,
140- PseudoOpcode :: SetupCleanup => 2 ,
141- _ => self . stack_effect ( oparg) ,
142- }
152+ self . as_opcode ( ) . stack_effect_jump ( oparg)
143153 }
144154}
145155
@@ -457,6 +467,16 @@ impl AnyOpcode {
457467 pub const fn is_block_push( & self ) -> bool
458468 ) ;
459469
470+ either_real_pseudo ! (
471+ #[ must_use]
472+ pub fn stack_effect_jump( & self , oparg: u32 ) -> i32
473+ ) ;
474+
475+ either_real_pseudo ! (
476+ #[ must_use]
477+ pub fn stack_effect( & self , oparg: u32 ) -> i32
478+ ) ;
479+
460480 #[ must_use]
461481 pub const fn deopt ( & self ) -> Option < Self > {
462482 match self {
0 commit comments