1111import sys
1212
1313import parser
14- from parser import InstDef
14+ from parser import InstDef # TODO: Use parser.InstDef
1515
1616arg_parser = argparse .ArgumentParser ()
1717arg_parser .add_argument ("-i" , "--input" , type = str , default = "Python/bytecodes.c" )
@@ -29,19 +29,24 @@ def eopen(filename: str, mode: str = "r"):
2929 return open (filename , mode )
3030
3131
32- def parse_cases (src : str , filename : str | None = None ) -> tuple [list [InstDef ], list [parser .Family ]]:
32+ def parse_cases (
33+ src : str , filename : str | None = None
34+ ) -> tuple [list [InstDef ], list [parser .Super ], list [parser .Family ]]:
3335 psr = parser .Parser (src , filename = filename )
3436 instrs : list [InstDef ] = []
37+ supers : list [parser .Super ] = []
3538 families : list [parser .Family ] = []
3639 while not psr .eof ():
3740 if inst := psr .inst_def ():
3841 assert inst .block
39- instrs .append (InstDef (inst .name , inst .inputs , inst .outputs , inst .block ))
42+ instrs .append (inst )
43+ elif sup := psr .super_def ():
44+ supers .append (sup )
4045 elif fam := psr .family_def ():
4146 families .append (fam )
4247 else :
4348 raise psr .make_syntax_error (f"Unexpected token" )
44- return instrs , families
49+ return instrs , supers , families
4550
4651
4752def always_exits (block : parser .Block ) -> bool :
@@ -62,16 +67,18 @@ def always_exits(block: parser.Block) -> bool:
6267 return line .startswith (("goto " , "return " , "DISPATCH" , "GO_TO_" , "Py_UNREACHABLE()" ))
6368
6469
65- def write_cases (f : io .TextIOBase , instrs : list [InstDef ]):
70+ def write_cases (f : io .TextIOBase , instrs : list [InstDef ], supers : list [ parser . Super ] ):
6671 predictions = set ()
6772 for inst in instrs :
6873 for target in re .findall (r"(?:PREDICT|GO_TO_INSTRUCTION)\((\w+)\)" , inst .block .text ):
6974 predictions .add (target )
7075 indent = " "
7176 f .write (f"// This file is generated by { os .path .relpath (__file__ )} \n " )
7277 f .write ("// Do not edit!\n " )
78+ instr_index : dict [str , InstDef ] = {}
7379 for instr in instrs :
7480 assert isinstance (instr , InstDef )
81+ instr_index [instr .name ] = instr
7582 f .write (f"\n { indent } TARGET({ instr .name } ) {{\n " )
7683 if instr .name in predictions :
7784 f .write (f"{ indent } PREDICTED({ instr .name } );\n " )
@@ -102,6 +109,22 @@ def write_cases(f: io.TextIOBase, instrs: list[InstDef]):
102109 # Write trailing '}'
103110 f .write (f"{ indent } }}\n " )
104111
112+ for sup in supers :
113+ assert isinstance (sup , parser .Super )
114+ components = [instr_index [name ] for name in sup .ops ]
115+ f .write (f"\n { indent } TARGET({ sup .name } ) {{\n " )
116+ for i , instr in enumerate (components ):
117+ if i > 0 :
118+ f .write (f"{ indent } NEXTOPARG();\n " )
119+ f .write (f"{ indent } next_instr++;\n " )
120+ text = instr .block .to_text (- 4 )
121+ textlines = text .splitlines (True )
122+ textlines = [line for line in textlines if not line .strip ().startswith ("PREDICTED(" )]
123+ text = "" .join (textlines )
124+ f .write (f"{ indent } { text .strip ()} \n " )
125+ f .write (f"{ indent } DISPATCH();\n " )
126+ f .write (f"{ indent } }}\n " )
127+
105128
106129def main ():
107130 args = arg_parser .parse_args ()
@@ -110,21 +133,22 @@ def main():
110133 begin = srclines .index ("// BEGIN BYTECODES //" )
111134 end = srclines .index ("// END BYTECODES //" )
112135 src = "\n " .join (srclines [begin + 1 : end ])
113- instrs , families = parse_cases (src , filename = args .input )
114- ninstrs = nfamilies = 0
136+ instrs , supers , families = parse_cases (src , filename = args .input )
137+ ninstrs = nsupers = nfamilies = 0
115138 if not args .quiet :
116139 ninstrs = len (instrs )
140+ nsupers = len (supers )
117141 nfamilies = len (families )
118142 print (
119- f"Read { ninstrs } instructions "
143+ f"Read { ninstrs } instructions, { nsupers } supers, "
120144 f"and { nfamilies } families from { args .input } " ,
121145 file = sys .stderr ,
122146 )
123147 with eopen (args .output , "w" ) as f :
124- write_cases (f , instrs )
148+ write_cases (f , instrs , supers )
125149 if not args .quiet :
126150 print (
127- f"Wrote { ninstrs } instructions to { args .output } " ,
151+ f"Wrote { ninstrs + nsupers } instructions to { args .output } " ,
128152 file = sys .stderr ,
129153 )
130154
0 commit comments