4
4
"""
5
5
6
6
import argparse
7
+ import contextlib
7
8
import os
8
9
import posixpath
9
10
import sys
@@ -141,6 +142,15 @@ def effect_str(effects: list[StackEffect]) -> str:
141
142
typing .assert_never (thing )
142
143
return instr , popped , pushed
143
144
145
+ @contextlib .contextmanager
146
+ def metadata_item (self , signature , open , close ):
147
+ self .out .emit ("" )
148
+ self .out .emit (f"extern { signature } ;" )
149
+ self .out .emit ("#ifdef NEED_OPCODE_METADATA" )
150
+ with self .out .block (f"{ signature } { open } " , close ):
151
+ yield
152
+ self .out .emit ("#endif // NEED_OPCODE_METADATA" )
153
+
144
154
def write_stack_effect_functions (self ) -> None :
145
155
popped_data : list [tuple [AnyInstruction , str ]] = []
146
156
pushed_data : list [tuple [AnyInstruction , str ]] = []
@@ -156,25 +166,16 @@ def write_stack_effect_functions(self) -> None:
156
166
def write_function (
157
167
direction : str , data : list [tuple [AnyInstruction , str ]]
158
168
) -> None :
159
- self .out .emit ("" )
160
- self .out .emit ("#ifndef NEED_OPCODE_METADATA" )
161
- self .out .emit (
162
- f"extern int _PyOpcode_num_{ direction } (int opcode, int oparg, bool jump);"
163
- )
164
- self .out .emit ("#else" )
165
- self .out .emit ("int" )
166
- self .out .emit (
167
- f"_PyOpcode_num_{ direction } (int opcode, int oparg, bool jump) {{"
168
- )
169
- self .out .emit (" switch(opcode) {" )
170
- for instr , effect in data :
171
- self .out .emit (f" case { instr .name } :" )
172
- self .out .emit (f" return { effect } ;" )
173
- self .out .emit (" default:" )
174
- self .out .emit (" return -1;" )
175
- self .out .emit (" }" )
176
- self .out .emit ("}" )
177
- self .out .emit ("#endif" )
169
+
170
+ with self .metadata_item (
171
+ f"int _PyOpcode_num_{ direction } (int opcode, int oparg, bool jump)" , "" , ""
172
+ ):
173
+ with self .out .block ("switch(opcode)" ):
174
+ for instr , effect in data :
175
+ self .out .emit (f"case { instr .name } :" )
176
+ self .out .emit (f" return { effect } ;" )
177
+ self .out .emit ("default:" )
178
+ self .out .emit (" return -1;" )<
D7AE
/div>
178
179
179
180
write_function ("popped" , popped_data )
180
181
write_function ("pushed" , pushed_data )
@@ -290,48 +291,33 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
290
291
self .out .emit ("#define OPCODE_METADATA_SIZE 512" )
291
292
self .out .emit ("#define OPCODE_UOP_NAME_SIZE 512" )
292
293
self .out .emit ("#define OPCODE_MACRO_EXPANSION_SIZE 256" )
293
- self .out .emit ("" )
294
- self .out .emit ("#ifndef NEED_OPCODE_METADATA" )
295
- self .out .emit (
296
- "extern const struct opcode_metadata "
297
- "_PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE];"
298
- )
299
- self .out .emit (
300
- "extern const struct opcode_macro_expansion "
301
- "_PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE];"
302
- )
303
- self .out .emit (
304
- "extern const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE];"
305
- )
306
- self .out .emit ("#else // if NEED_OPCODE_METADATA" )
307
294
308
- self .out . emit (
295
+ with self .metadata_item (
309
296
"const struct opcode_metadata "
310
- "_PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {"
311
- )
312
-
313
- # Write metadata for each instruction
314
- for thing in self .everything :
315
- match thing :
316
- case OverriddenInstructionPlaceHolder ():
317
- continue
318
- case parsing .InstDef ():
319
- if thing .kind != "op" :
320
- self .write_metadata_for_inst (self .instrs [thing .name ])
321
- case parsing .Macro ():
322
F438
- self .write_metadata_for_macro (self .macro_instrs [thing .name ])
323
- case parsing .Pseudo ():
324
- self .write_metadata_for_pseudo (self .pseudo_instrs [thing .name ])
325
- case _:
326
- typing .assert_never (thing )
327
-
328
- # Write end of array
329
- self .out .emit ("};" )
297
+ "_PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE]" ,
298
+ "=" ,
299
+ ";"
300
+ ):
301
+ # Write metadata for each instruction
302
+ for thing in self .everything :
303
+ match thing :
304
+ case OverriddenInstructionPlaceHolder ():
305
+ continue
306
+ case parsing .InstDef ():
307
+ if thing .kind != "op" :
308
+ self .write_metadata_for_inst (self .instrs [thing .name ])
309
+ case parsing .Macro ():
310
+ self .write_metadata_for_macro (self .macro_instrs [thing .name ])
311
+ case parsing .Pseudo ():
312
+ self .write_metadata_for_pseudo (self .pseudo_instrs [thing .name ])
313
+ case _:
314
+ typing .assert_never (thing )
330
315
331
- with self .out . block (
316
+ with self .metadata_item (
332
317
"const struct opcode_macro_expansion "
333
- "_PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE] =" ,
334
- ";" ,
318
+ "_PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE]" ,
319
+ "=" ,
320
+ ";"
335
321
):
336
322
# Write macro expansion for each non-pseudo instruction
337
323
for thing in self .everything :
@@ -360,13 +346,11 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
360
346
case _:
361
347
typing .assert_never (thing )
362
348
363
- with self .out . block (
364
- "const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] =" , ";"
349
+ with self .metadata_item (
350
+ "const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE]" , " =" , ";"
365
351
):
366
352
self .write_uop_items (lambda name , counter : f'[{ name } ] = "{ name } ",' )
367
353
368
- self .out .emit ("#endif // NEED_OPCODE_METADATA" )
369
-
370
354
with open (pymetadata_filename , "w" ) as f :
371
355
# Create formatter
372
356
self .out = Formatter (f , 0 , comment = "#" )
@@ -511,7 +495,7 @@ def emit_metadata_entry(self, name: str, fmt: str, flags: InstructionFlags) -> N
511
495
if not flag_names :
512
496
flag_names .append ("0" )
513
497
self .out .emit (
514
- f" [{ name } ] = {{ true, { INSTR_FMT_PREFIX } { fmt } ,"
498
+ f"[{ name } ] = {{ true, { INSTR_FMT_PREFIX } { fmt } ,"
515
499
f" { ' | ' .join (flag_names )} }},"
516
500
)
517
501
0 commit comments