44"""
55
66import argparse
7+ import contextlib
78import os
89import posixpath
910import sys
@@ -141,6 +142,15 @@ def effect_str(effects: list[StackEffect]) -> str:
141142 typing .assert_never (thing )
142143 return instr , popped , pushed
143144
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+
144154 def write_stack_effect_functions (self ) -> None :
145155 popped_data : list [tuple [AnyInstruction , str ]] = []
146156 pushed_data : list [tuple [AnyInstruction , str ]] = []
@@ -156,25 +166,16 @@ def write_stack_effect_functions(self) -> None:
156166 def write_function (
157167 direction : str , data : list [tuple [AnyInstruction , str ]]
158168 ) -> 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;" )
178179
179180 write_function ("popped" , popped_data )
180181 write_function ("pushed" , pushed_data )
@@ -290,48 +291,33 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
290291 self .out .emit ("#define OPCODE_METADATA_SIZE 512" )
291292 self .out .emit ("#define OPCODE_UOP_NAME_SIZE 512" )
292293 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" )
307294
308- self .out . emit (
295+ with self .metadata_item (
309296 "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- 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 )
330315
331- with self .out . block (
316+ with self .metadata_item (
332317 "const struct opcode_macro_expansion "
333- "_PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE] =" ,
334- ";" ,
318+ "_PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE]" ,
319+ "=" ,
320+ ";"
335321 ):
336322 # Write macro expansion for each non-pseudo instruction
337323 for thing in self .everything :
@@ -360,13 +346,11 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
360346 case _:
361347 typing .assert_never (thing )
362348
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]" , " =" , ";"
365351 ):
366352 self .write_uop_items (lambda name , counter : f'[{ name } ] = "{ name } ",' )
367353
368- self .out .emit ("#endif // NEED_OPCODE_METADATA" )
369-
370354 with open (pymetadata_filename , "w" ) as f :
371355 # Create formatter
372356 self .out = Formatter (f , 0 , comment = "#" )
@@ -511,7 +495,7 @@ def emit_metadata_entry(self, name: str, fmt: str, flags: InstructionFlags) -> N
511495 if not flag_names :
512496 flag_names .append ("0" )
513497 self .out .emit (
514- f" [{ name } ] = {{ true, { INSTR_FMT_PREFIX } { fmt } ,"
498+ f"[{ name } ] = {{ true, { INSTR_FMT_PREFIX } { fmt } ,"
515499 f" { ' | ' .join (flag_names )} }},"
516500 )
517501
0 commit comments