@@ -244,6 +244,7 @@ def write_body(self, out: Formatter, cache_adjust: int) -> None:
244244
245245# TODO: Use a common base class for {Super,Macro}Instruction
246246
247+
247248@dataclasses .dataclass
248249class SuperOrMacroInstruction :
249250 """Common fields for super- and macro instructions."""
@@ -583,11 +584,7 @@ def write_instructions(self) -> None:
583584
584585 def write_super (self , sup : SuperInstruction ) -> None :
585586 """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 ):
591588 first = True
592589 for comp in sup .parts :
593590 if not first :
@@ -598,16 +595,9 @@ def write_super(self, sup: SuperInstruction) -> None:
598595 if comp .instr .cache_offset :
599596 self .out .emit (f"next_instr += { comp .instr .cache_offset } ;" )
600597
601- self .write_stack_pokes (sup .stack , sup .initial_sp , sup .final_sp )
602- self .out .emit ("DISPATCH();" )
603-
604598 def write_macro (self , mac : MacroInstruction ) -> None :
605599 """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 ):
611601 cache_adjust = 0
612602 for part in mac .parts :
613603 match part :
@@ -617,27 +607,30 @@ def write_macro(self, mac: MacroInstruction) -> None:
617607 comp .write_body (self .out , cache_adjust )
618608 cache_adjust += comp .instr .cache_offset
619609
620- self .write_stack_pokes (mac .stack , mac .initial_sp , mac .final_sp )
621610 if cache_adjust :
622611 self .out .emit (f"next_instr += { cache_adjust } ;" )
623- self .out .emit (f"DISPATCH();" )
624612
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();" )
641634
642635
643636def always_exits (block : parser .Block ) -> bool :
0 commit comments