1#! /usr/bin/env python 2"""Generate C code for the jump table of the threaded code interpreter 3(for compilers supporting computed gotos or "labels-as-values", such as gcc). 4""" 5 6import os 7import sys 8 9 10try: 11 from importlib.machinery import SourceFileLoader 12except ImportError: 13 import imp 14 15 def find_module(modname): 16 """Finds and returns a module in the local dist/checkout. 17 """ 18 modpath = os.path.join( 19 os.path.dirname(os.path.dirname(__file__)), "Lib") 20 return imp.load_module(modname, *imp.find_module(modname, [modpath])) 21else: 22 def find_module(modname): 23 """Finds and returns a module in the local dist/checkout. 24 """ 25 modpath = os.path.join( 26 os.path.dirname(os.path.dirname(__file__)), "Lib", modname + ".py") 27 return SourceFileLoader(modname, modpath).load_module() 28 29 30def write_contents(f): 31 """Write C code contents to the target file object. 32 """ 33 opcode = find_module('opcode') 34 targets = ['_unknown_opcode'] * 256 35 targets[255] = "TARGET_DO_TRACING" 36 for opname, op in opcode.opmap.items(): 37 targets[op] = "TARGET_%s" % opname 38 next_op = 1 39 for opname in opcode._specialized_instructions: 40 while targets[next_op] != '_unknown_opcode': 41 next_op += 1 42 targets[next_op] = "TARGET_%s" % opname 43 f.write("static void *opcode_targets[256] = {\n") 44 f.write(",\n".join([" &&%s" % s for s in targets])) 45 f.write("\n};\n") 46 47 48def main(): 49 if len(sys.argv) >= 3: 50 sys.exit("Too many arguments") 51 if len(sys.argv) == 2: 52 target = sys.argv[1] 53 else: 54 target = "Python/opcode_targets.h" 55 with open(target, "w") as f: 56 write_contents(f) 57 print("Jump table written into %s" % target) 58 59 60if __name__ == "__main__": 61 main() 62