@@ -162,6 +162,7 @@ class Optimizer:
162162 label_prefix : str
163163 symbol_prefix : str
164164 re_global : re .Pattern [str ]
165+ frame_pointers : bool
165166 # The first block in the linked list:
166167 _root : _Block = dataclasses .field (init = False , default_factory = _Block )
167168 _labels : dict [str , _Block ] = dataclasses .field (init = False , default_factory = dict )
@@ -193,6 +194,7 @@ class Optimizer:
193194 _re_small_const_1 = _RE_NEVER_MATCH
194195 _re_small_const_2 = _RE_NEVER_MATCH
195196 const_reloc = "<Not supported>"
197+ _frame_pointer_prologue : typing .ClassVar [re .Pattern [str ]] = _RE_NEVER_MATCH
196198
197199 def __post_init__ (self ) -> None :
198200 # Split the code into a linked list of basic blocks. A basic block is an
@@ -553,6 +555,14 @@ def _small_const_2(self, inst: Instruction) -> tuple[str, Instruction | None]:
553555 def _small_consts_match (self , inst1 : Instruction , inst2 : Instruction ) -> bool :
554556 raise NotImplementedError ()
555557
558+ def _validate (self ):
559+ for block in self ._blocks ():
560+ if not block .instructions :
561+ continue
562+ for inst in block .instructions :
563+ if self .frame_pointers :
564+ assert self ._frame_pointer_prologue .match (inst .text ) is None , "Frame pointer should not be modified"
565+
556566 def run (self ) -> None :
557567 """Run this optimizer."""
558568 self ._insert_continue_label ()
@@ -565,6 +575,7 @@ def run(self) -> None:
565575 self ._remove_unreachable ()
566576 self ._fixup_external_labels ()
567577 self ._fixup_constants ()
578+ self ._validate ()
568579 self .path .write_text (self ._body ())
569580
570581
@@ -595,6 +606,7 @@ class OptimizerAArch64(Optimizer): # pylint: disable = too-few-public-methods
595606 r"\s*(?P<instruction>ldr)\s+.*(?P<value>_JIT_OP(ARG|ERAND(0|1))_(16|32)).*"
596607 )
597608 const_reloc = "CUSTOM_AARCH64_CONST"
609+ _frame_pointer_prologue = re .compile (r"\s*stp\s+x29.*" )
598610
599611 def _get_reg (self , inst : Instruction ) -> str :
600612 _ , rest = inst .text .split (inst .name )
@@ -649,4 +661,5 @@ class OptimizerX86(Optimizer): # pylint: disable = too-few-public-methods
649661 # https://www.felixcloutier.com/x86/jmp
650662 _re_jump = re .compile (r"\s*jmp\s+(?P<target>[\w.]+)" )
651663 # https://www.felixcloutier.com/x86/ret
652- _re_return = re .compile (r"\s*ret\b" )
664+ _re_return = re .compile (r"\s*retq?\b" )
665+ _frame_pointer_prologue = re .compile (r"\s*pushq\s+%rbp.*" )
0 commit comments