|
| 1 | +"""Generate targets for computed goto dispatch |
| 2 | +Reads the instruction definitions from bytecodes.c. |
| 3 | +Writes the table to opcode_targets.h by default. |
| 4 | +""" |
| 5 | + |
| 6 | +import argparse |
| 7 | + |
| 8 | +from analyzer import ( |
| 9 | + Analysis, |
| 10 | + analyze_files, |
| 11 | +) |
| 12 | +from generators_common import ( |
| 13 | + DEFAULT_INPUT, |
| 14 | + ROOT, |
| 15 | +) |
| 16 | +from cwriter import CWriter |
| 17 | +from typing import TextIO |
| 18 | + |
| 19 | + |
| 20 | +DEFAULT_OUTPUT = ROOT / "Python/opcode_targets.h" |
| 21 | + |
| 22 | + |
| 23 | +def write_opcode_targets(analysis: Analysis, out: CWriter) -> None: |
| 24 | + """Write header file that defines the jump target table""" |
| 25 | + targets = ["&&_unknown_opcode,\n"] * 256 |
| 26 | + for name, op in analysis.opmap.items(): |
| 27 | + if op < 256: |
| 28 | + targets[op] = f"&&TARGET_{name},\n" |
| 29 | + out.emit("static void *opcode_targets[256] = {\n") |
| 30 | + for target in targets: |
| 31 | + out.emit(target) |
| 32 | + out.emit("};\n") |
| 33 | + |
| 34 | +arg_parser = argparse.ArgumentParser( |
| 35 | + description="Generate the file with dispatch targets.", |
| 36 | + formatter_class=argparse.ArgumentDefaultsHelpFormatter, |
| 37 | +) |
| 38 | + |
| 39 | +arg_parser.add_argument( |
| 40 | + "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT |
| 41 | +) |
| 42 | + |
| 43 | +arg_parser.add_argument( |
| 44 | + "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" |
| 45 | +) |
| 46 | + |
| 47 | +if __name__ == "__main__": |
| 48 | + args = arg_parser.parse_args() |
| 49 | + if len(args.input) == 0: |
| 50 | + args.input.append(DEFAULT_INPUT) |
| 51 | + data = analyze_files(args.input) |
| 52 | + with open(args.output, "w") as outfile: |
| 53 | + out = CWriter(outfile, 0, False) |
| 54 | + write_opcode_targets(data, out) |
0 commit comments