13
13
from collections .abc import Iterator
14
14
15
15
import stacking # Early import to avoid circular import
16
+ from _typing_backports import assert_never
16
17
from analysis import Analyzer
17
18
from formatting import Formatter , list_effect_size
18
19
from flags import InstructionFlags , variable_used
146
147
class Generator (Analyzer ):
147
148
def get_stack_effect_info (
148
149
self , thing : parsing .InstDef | parsing .Macro | parsing .Pseudo
149
- ) -> tuple [AnyInstruction | None , str | None , str | None ]:
150
+ ) -> tuple [AnyInstruction | None , str , str ]:
150
151
def effect_str (effects : list [StackEffect ]) -> str :
151
152
n_effect , sym_effect = list_effect_size (effects )
152
153
if sym_effect :
153
154
return f"{ sym_effect } + { n_effect } " if n_effect else sym_effect
154
155
return str (n_effect )
155
156
156
157
instr : AnyInstruction | None
157
- popped : str | None
158
- pushed : str | None
159
158
match thing :
160
159
case parsing .InstDef ():
161
160
if thing .kind != "op" or self .instrs [thing .name ].is_viable_uop ():
@@ -171,25 +170,23 @@ def effect_str(effects: list[StackEffect]) -> str:
171
170
popped , pushed = stacking .get_stack_effect_info_for_macro (instr )
172
171
case parsing .Pseudo ():
173
172
instr = self .pseudo_instrs [thing .name ]
174
- popped = pushed = None
175
173
# Calculate stack effect, and check that it's the the same
176
174
# for all targets.
177
- for target in self .pseudos [thing .name ].targets :
175
+ for idx , target in enumerate ( self .pseudos [thing .name ].targets ) :
178
176
target_instr = self .instrs .get (target )
179
177
# Currently target is always an instr. This could change
180
178
# in the future, e.g., if we have a pseudo targetting a
181
179
# macro instruction.
182
180
assert target_instr
183
181
target_popped = effect_str (target_instr .input_effects )
184
182
target_pushed = effect_str (target_instr .output_effects )
185
- if pushed is None :
186
- assert popped is None
183
+ if idx == 0 :
187
184
popped , pushed = target_popped , target_pushed
188
185
else :
189
186
assert popped == target_popped
190
187
assert pushed == target_pushed
191
188
case _:
192
- typing . assert_never (thing )
189
+ assert_never (thing )
193
190
return instr , popped , pushed
194
191
195
192
@contextlib .contextmanager
@@ -209,7 +206,6 @@ def write_stack_effect_functions(self) -> None:
209
206
continue
210
207
instr , popped , pushed = self .get_stack_effect_info (thing )
211
208
if instr is not None :
212
- assert popped is not None and pushed is not None
213
209
popped_data .append ((instr , popped ))
214
210
pushed_data .append ((instr , pushed ))
215
211
@@ -379,7 +375,6 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
379
375
# Compute the set of all instruction formats.
380
376
all_formats : set [str ] = set ()
381
377
for thing in self .everything :
382
- format : str | None
383
378
match thing :
384
379
case OverriddenInstructionPlaceHolder ():
385
380
continue
@@ -388,17 +383,15 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
388
383
case parsing .Macro ():
389
384
format = self .macro_instrs [thing .name ].instr_fmt
390
385
case parsing .Pseudo ():
391
- format = None
392
- for target in self .pseudos [thing .name ].targets :
386
+ for idx , target in enumerate (self .pseudos [thing .name ].targets ):
393
387
target_instr = self .instrs .get (target )
394
388
assert target_instr
395
- if format is None :
389
+ if idx == 0 :
396
390
format = target_instr .instr_fmt
397
391
else :
398
392
assert format == target_instr .instr_fmt
399
- assert format is not None
400
393
case _:
401
- typing . assert_never (thing )
394
+ assert_never (thing )
402
395
all_formats .add (format )
403
396
404
397
# Turn it into a sorted list of enum values.
@@ -488,7 +481,7 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
488
481
self .pseudo_instrs [thing .name ]
489
482
)
490
483
case _:
491
- typing . assert_never (thing )
484
+ assert_never (thing )
492
485
493
486
with self .metadata_item (
494
487
"const struct opcode_macro_expansion "
@@ -525,7 +518,7 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
525
518
case parsing .Pseudo ():
526
519
pass
527
520
case _:
528
- typing . assert_never (thing )
521
+ assert_never (thing )
529
522
530
523
with self .metadata_item (
531
524
"const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE]" , "=" , ";"
@@ -774,7 +767,7 @@ def write_instructions(
774
767
case parsing .Pseudo ():
775
768
pass
776
769
case _:
777
- typing . assert_never (thing )
770
+ assert_never (thing )
778
771
779
772
print (
780
773
f"Wrote { n_instrs } instructions and { n_macros } macros "
@@ -818,7 +811,7 @@ def write_executor_instructions(
818
811
case parsing .Pseudo ():
819
812
pass
820
813
case _:
821
- typing . assert_never (thing )
814
+ assert_never (thing )
822
815
print (
823
816
f"Wrote { n_instrs } instructions and { n_uops } ops to { executor_filename } " ,
824
817
file = sys .stderr ,
@@ -850,7 +843,7 @@ def write_abstract_interpreter_instructions(
850
843
case parsing .Pseudo ():
851
844
pass
852
845
case _:
853
- typing . assert_never (thing )
846
+ assert_never (thing )
854
847
print (
855
848
f"Wrote some stuff to { abstract_interpreter_filename } " ,
856
849
file = sys .stderr ,
0 commit comments