@@ -244,6 +244,7 @@ def write_body(self, out: Formatter, cache_adjust: int) -> None:
244
244
245
245
# TODO: Use a common base class for {Super,Macro}Instruction
246
246
247
+
247
248
@dataclasses .dataclass
248
249
class SuperOrMacroInstruction :
249
250
"""Common fields for super- and macro instructions."""
@@ -583,11 +584,7 @@ def write_instructions(self) -> None:
583
584
584
585
def write_super (self , sup : SuperInstruction ) -> None :
585
586
"""Write code for a super-instruction."""
586
- self .out .emit ("" )
587
-
588
- with self .out .block (f"TARGET({ sup .name } )" ):
589
- self .write_stack_vars (sup .stack , sup .initial_sp )
590
-
587
+ with self .wrap_super_or_macro (sup ):
591
588
first = True
592
589
for comp in sup .parts :
593
590
if not first :
@@ -598,16 +595,9 @@ def write_super(self, sup: SuperInstruction) -> None:
598
595
if comp .instr .cache_offset :
599
596
self .out .emit (f"next_instr += { comp .instr .cache_offset } ;" )
600
597
601
- self .write_stack_pokes (sup .stack , sup .initial_sp , sup .final_sp )
602
- self .out .emit ("DISPATCH();" )
603
-
604
598
def write_macro (self , mac : MacroInstruction ) -> None :
605
599
"""Write code for a macro instruction."""
606
- self .out .emit ("" )
607
-
608
- with self .out .block (f"TARGET({ mac .name } )" ):
609
- self .write_stack_vars (mac .stack , mac .initial_sp )
610
-
600
+ with self .wrap_super_or_macro (mac ):
611
601
cache_adjust = 0
612
602
for part in mac .parts :
613
603
match part :
@@ -617,27 +607,30 @@ def write_macro(self, mac: MacroInstruction) -> None:
617
607
comp .write_body (self .out , cache_adjust )
618
608
cache_adjust += comp .instr .cache_offset
619
609
620
- self .write_stack_pokes (mac .stack , mac .initial_sp , mac .final_sp )
621
610
if cache_adjust :
622
611
self .out .emit (f"next_instr += { cache_adjust } ;" )
623
- self .out .emit (f"DISPATCH();" )
624
612
625
- def write_stack_vars (self , stack : list [str ], initial_sp : int ) -> None :
626
- for i , var in enumerate (stack ):
627
- if i < initial_sp :
628
- self .out .emit (f"PyObject *{ var } = PEEK({ initial_sp - i } );" )
629
- else :
630
- self .out .emit (f"PyObject *{ var } ;" )
631
-
632
- def write_stack_pokes (
633
- self , stack : list [str ], initial_sp : int , final_sp : int
634
- ) -> None :
635
- if final_sp > initial_sp :
636
- self .out .emit (f"STACK_GROW({ final_sp - initial_sp } );" )
637
- elif final_sp < initial_sp :
638
- self .out .emit (f"STACK_SHRINK({ initial_sp - final_sp } );" )
639
- for i , var in enumerate (reversed (stack [:final_sp ]), 1 ):
640
- self .out .emit (f"POKE({ i } , { var } );" )
613
+ @contextlib .contextmanager
614
+ def wrap_super_or_macro (self , up : SuperOrMacroInstruction ):
615
+ """Shared boilerplate for super- and macro instructions."""
616
+ self .out .emit ("" )
617
+ with self .out .block (f"TARGET({ up .name } )" ):
618
+ for i , var in enumerate (up .stack ):
619
+ if i < up .initial_sp :
620
+ self .out .emit (f"PyObject *{ var } = PEEK({ up .initial_sp - i } );" )
621
+ else :
622
+ self .out .emit (f"PyObject *{ var } ;" )
623
+
624
+ yield
625
+
626
+ if up .final_sp > up .initial_sp :
627
+ self .out .emit (f"STACK_GROW({ up .final_sp - up .initial_sp } );" )
628
+ elif up .final_sp < up .initial_sp :
629
+ self .out .emit (f"STACK_SHRINK({ up .initial_sp - up .final_sp } );" )
630
+ for i , var in enumerate (reversed (up .stack [: up .final_sp ]), 1 ):
631
+ self .out .emit (f"POKE({ i } , { var } );" )
632
+
633
+ self .out .emit (f"DISPATCH();" )
641
634
642
635
643
636
def always_exits (block : parser .Block ) -> bool :
0 commit comments