@@ -597,7 +597,7 @@ def map_families(self) -> None:
597
597
self .error (
598
598
f"Instruction { member } is a member of multiple families "
599
599
f"({ member_instr .family .name } , { family .name } )." ,
600
- family
600
+ family ,
601
601
)
602
602
else :
603
603
member_instr .family = family
@@ -609,7 +609,7 @@ def map_families(self) -> None:
609
609
f"Component { part .instr .name } of macro { member } "
610
610
f"is a member of multiple families "
611
611
f"({ part .instr .family .name } , { family .name } )." ,
612
- family
612
+ family ,
613
613
)
614
614
else :
615
615
part .instr .family = family
@@ -629,7 +629,11 @@ def check_families(self) -> None:
629
629
for family in self .families .values ():
630
630
if len (family .members ) < 2 :
631
631
self .error (f"Family { family .name !r} has insufficient members" , family )
632
- members = [member for member in family .members if member in self .instrs or member in self .macro_instrs ]
632
+ members = [
633
+ member
634
+ for member in family .members
635
+ if member in self .instrs or member in self .macro_instrs
636
+ ]
633
637
if members != family .members :
634
638
unknown = set (family .members ) - set (members )
635
639
self .error (
@@ -859,7 +863,9 @@ def write_stack_effect_functions(self) -> None:
859
863
popped_data .append ((instr , popped ))
860
864
pushed_data .append ((instr , pushed ))
861
865
862
- def write_function (direction : str , data : list [tuple [AnyInstruction , str ]]) -> None :
866
+ def write_function (
867
+ direction : str , data : list [tuple [AnyInstruction , str ]]
868
+ ) -> None :
863
869
self .out .emit ("\n #ifndef NDEBUG" )
864
870
self .out .emit ("static int" )
865
871
self .out .emit (f"_PyOpcode_num_{ direction } (int opcode, int oparg) {{" )
@@ -1031,19 +1037,32 @@ def write_super(self, sup: SuperInstruction) -> None:
1031
1037
1032
1038
def write_macro (self , mac : MacroInstruction ) -> None :
1033
1039
"""Write code for a macro instruction."""
1040
+ last_instr : Instruction | None = None
1034
1041
with self .wrap_super_or_macro (mac ):
1035
1042
cache_adjust = 0
1036
1043
for part in mac .parts :
1037
1044
match part :
1038
1045
case parser .CacheEffect (size = size ):
1039
1046
cache_adjust += size
1040
1047
case Component () as comp :
1048
+ last_instr = comp .instr
1041
1049
comp .write_body (self .out , cache_adjust )
1042
1050
cache_adjust += comp .instr .cache_offset
1043
1051
1044
1052
if cache_adjust :
1045
1053
self .out .emit (f"JUMPBY({ cache_adjust } );" )
1046
1054
1055
+ if (
1056
+ last_instr
1057
+ and (family := last_instr .family )
1058
+ and mac .name == family .members [0 ]
1059
+ and (cache_size := family .size )
1060
+ ):
1061
+ self .out .emit (
1062
+ f"static_assert({ cache_size } == "
1063
+ f'{ cache_adjust } , "incorrect cache size");'
1064
+ )
1065
+
1047
1066
@contextlib .contextmanager
1048
1067
def wrap_super_or_macro (self , up : SuperOrMacroInstruction ):
1049
1068
"""Shared boilerplate for super- and macro instructions."""
0 commit comments