summaryrefslogtreecommitdiffstats
path: root/Tools/build
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2023-08-16 22:25:18 (GMT)
committerGitHub <noreply@github.com>2023-08-16 22:25:18 (GMT)
commit665a4391e10167dad1c854fb604c86f336fcd331 (patch)
treee1d55069486dd67e6857a13fafc12b6e865cacf7 /Tools/build
parente88eb3775ecdcb3af6c6d694a935b7fa5f41e5ce (diff)
downloadcpython-665a4391e10167dad1c854fb604c86f336fcd331.zip
cpython-665a4391e10167dad1c854fb604c86f336fcd331.tar.gz
cpython-665a4391e10167dad1c854fb604c86f336fcd331.tar.bz2
gh-105481: generate op IDs from bytecode.c instead of hard coding them in opcode.py (#107971)
Diffstat (limited to 'Tools/build')
-rw-r--r--Tools/build/deepfreeze.py8
-rw-r--r--Tools/build/generate_opcode_h.py106
2 files changed, 6 insertions, 108 deletions
diff --git a/Tools/build/deepfreeze.py b/Tools/build/deepfreeze.py
index ce609bd..8dbb7bf 100644
--- a/Tools/build/deepfreeze.py
+++ b/Tools/build/deepfreeze.py
@@ -22,7 +22,7 @@ ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
verbose = False
# This must be kept in sync with opcode.py
-RESUME = 151
+RESUME = 166
def isprintable(b: bytes) -> bool:
return all(0x20 <= c < 0x7f for c in b)
@@ -297,10 +297,12 @@ class Printer:
self.write(f".co_linetable = {co_linetable},")
self.write(f"._co_cached = NULL,")
self.write(f".co_code_adaptive = {co_code_adaptive},")
- for i, op in enumerate(code.co_code[::2]):
+ first_traceable = 0
+ for op in code.co_code[::2]:
if op == RESUME:
- self.write(f"._co_firsttraceable = {i},")
break
+ first_traceable += 1
+ self.write(f"._co_firsttraceable = {first_traceable},")
name_as_code = f"(PyCodeObject *)&{name}"
self.finis.append(f"_PyStaticCode_Fini({name_as_code});")
self.inits.append(f"_PyStaticCode_Init({name_as_code})")
diff --git a/Tools/build/generate_opcode_h.py b/Tools/build/generate_opcode_h.py
index 67f4a2c..344709a 100644
--- a/Tools/build/generate_opcode_h.py
+++ b/Tools/build/generate_opcode_h.py
@@ -27,27 +27,6 @@ opcode_h_footer = """
#endif /* !Py_OPCODE_H */
"""
-opcode_ids_h_header = f"""
-// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE}
-
-#ifndef Py_OPCODE_IDS_H
-#define Py_OPCODE_IDS_H
-#ifdef __cplusplus
-extern "C" {{
-#endif
-
-
-/* Instruction opcodes for compiled code */
-""".lstrip()
-
-opcode_ids_h_footer = """
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* !Py_OPCODE_IDS_H */
-"""
-
internal_header = f"""
// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE}
@@ -83,52 +62,10 @@ def get_python_module_dict(filename):
return mod
def main(opcode_py,
- _opcode_metadata_py='Lib/_opcode_metadata.py',
- opcode_ids_h='Include/opcode_ids.h',
opcode_h='Include/opcode.h',
- opcode_targets_h='Python/opcode_targets.h',
internal_opcode_h='Include/internal/pycore_opcode.h'):
- _opcode_metadata = get_python_module_dict(_opcode_metadata_py)
-
opcode = get_python_module_dict(opcode_py)
- opmap = opcode['opmap']
- opname = opcode['opname']
-
- MIN_INSTRUMENTED_OPCODE = opcode["MIN_INSTRUMENTED_OPCODE"]
-
- NUM_OPCODES = len(opname)
- used = [ False ] * len(opname)
- next_op = 1
-
- for name, op in opmap.items():
- used[op] = True
-
- specialized_opmap = {}
- opname_including_specialized = opname.copy()
- for name in _opcode_metadata['_specialized_instructions']:
- while used[next_op]:
- next_op += 1
- specialized_opmap[name] = next_op
- opname_including_specialized[next_op] = name
- used[next_op] = True
-
- with open(opcode_ids_h, 'w') as fobj:
- fobj.write(opcode_ids_h_header)
-
- for name in opname:
- if name in opmap:
- op = opmap[name]
- if op == MIN_INSTRUMENTED_OPCODE:
- fobj.write(DEFINE.format("MIN_INSTRUMENTED_OPCODE", MIN_INSTRUMENTED_OPCODE))
-
- fobj.write(DEFINE.format(name, op))
-
-
- for name, op in specialized_opmap.items():
- fobj.write(DEFINE.format(name, op))
-
- fobj.write(opcode_ids_h_footer)
with open(opcode_h, 'w') as fobj:
fobj.write(opcode_h_header)
@@ -143,7 +80,6 @@ def main(opcode_py,
iobj.write(internal_header)
iobj.write("\nextern const uint8_t _PyOpcode_Caches[256];\n")
- iobj.write("\nextern const uint8_t _PyOpcode_Deopt[256];\n")
iobj.write("\n#ifdef NEED_OPCODE_TABLES\n")
iobj.write("\nconst uint8_t _PyOpcode_Caches[256] = {\n")
@@ -151,52 +87,12 @@ def main(opcode_py,
iobj.write(f" [{name}] = {entries},\n")
iobj.write("};\n")
- deoptcodes = {}
- for basic, op in opmap.items():
- if op < 256:
- deoptcodes[basic] = basic
- for basic, family in _opcode_metadata["_specializations"].items():
- for specialized in family:
- deoptcodes[specialized] = basic
- iobj.write("\nconst uint8_t _PyOpcode_Deopt[256] = {\n")
- for opt, deopt in sorted(deoptcodes.items()):
- iobj.write(f" [{opt}] = {deopt},\n")
- iobj.write("};\n")
- iobj.write("#endif // NEED_OPCODE_TABLES\n")
-
- iobj.write("\n")
- iobj.write(f"\nextern const char *const _PyOpcode_OpName[{NUM_OPCODES}];\n")
- iobj.write("\n#ifdef NEED_OPCODE_TABLES\n")
- iobj.write(f"const char *const _PyOpcode_OpName[{NUM_OPCODES}] = {{\n")
- for op, name in enumerate(opname_including_specialized):
- if name[0] != "<":
- op = name
- iobj.write(f''' [{op}] = "{name}",\n''')
- iobj.write("};\n")
iobj.write("#endif // NEED_OPCODE_TABLES\n")
- iobj.write("\n")
- iobj.write("#define EXTRA_CASES \\\n")
- for i, flag in enumerate(used):
- if not flag:
- iobj.write(f" case {i}: \\\n")
- iobj.write(" ;\n")
-
iobj.write(internal_footer)
- with open(opcode_targets_h, "w") as f:
- targets = ["_unknown_opcode"] * 256
- for op, name in enumerate(opname_including_specialized):
- if op < 256 and not name.startswith("<"):
- targets[op] = f"TARGET_{name}"
-
- f.write("static void *opcode_targets[256] = {\n")
- f.write(",\n".join([f" &&{s}" for s in targets]))
- f.write("\n};\n")
-
print(f"{opcode_h} regenerated from {opcode_py}")
if __name__ == '__main__':
- main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4],
- sys.argv[5], sys.argv[6])
+ main(sys.argv[1], sys.argv[2], sys.argv[3])