1"""Generate the list of opcode IDs. 2Reads the instruction definitions from bytecodes.c. 3Writes the IDs to opcode_ids.h by default. 4""" 5 6import argparse 7import os.path 8import sys 9 10from analyzer import ( 11 Analysis, 12 Instruction, 13 analyze_files, 14) 15from generators_common import ( 16 DEFAULT_INPUT, 17 ROOT, 18 write_header, 19) 20from cwriter import CWriter 21from typing import TextIO 22 23 24DEFAULT_OUTPUT = ROOT / "Include/opcode_ids.h" 25 26 27def generate_opcode_header( 28 filenames: list[str], analysis: Analysis, outfile: TextIO 29) -> None: 30 write_header(__file__, filenames, outfile) 31 out = CWriter(outfile, 0, False) 32 with out.header_guard("Py_OPCODE_IDS_H"): 33 out.emit("/* Instruction opcodes for compiled code */\n") 34 35 def write_define(name: str, op: int) -> None: 36 out.emit(f"#define {name:<38} {op:>3}\n") 37 38 for op, name in sorted([(op, name) for (name, op) in analysis.opmap.items()]): 39 write_define(name, op) 40 41 out.emit("\n") 42 write_define("HAVE_ARGUMENT", analysis.have_arg) 43 write_define("MIN_INSTRUMENTED_OPCODE", analysis.min_instrumented) 44 45 46arg_parser = argparse.ArgumentParser( 47 description="Generate the header file with all opcode IDs.", 48 formatter_class=argparse.ArgumentDefaultsHelpFormatter, 49) 50 51arg_parser.add_argument( 52 "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT 53) 54 55arg_parser.add_argument( 56 "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" 57) 58 59if __name__ == "__main__": 60 args = arg_parser.parse_args() 61 if len(args.input) == 0: 62 args.input.append(DEFAULT_INPUT) 63 data = analyze_files(args.input) 64 with open(args.output, "w") as outfile: 65 generate_opcode_header(args.input, data, outfile) 66