Skip to content

Commit 64a54e5

Browse files
authored
gh-91719: Add pycore_opcode.h internal header file (#91906)
Move the following API from Include/opcode.h (public C API) to a new Include/internal/pycore_opcode.h header file (internal C API): * EXTRA_CASES * _PyOpcode_Caches * _PyOpcode_Deopt * _PyOpcode_Jump * _PyOpcode_OpName * _PyOpcode_RelativeJump
1 parent 20cc695 commit 64a54e5

File tree

11 files changed

+661
-605
lines changed

11 files changed

+661
-605
lines changed

Include/internal/pycore_opcode.h

+581
Large diffs are not rendered by default.

Include/opcode.h

+2-564
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile.pre.in

+3-1
Original file line numberDiff line numberDiff line change
@@ -1311,8 +1311,10 @@ regen-opcode:
13111311
# using Tools/scripts/generate_opcode_h.py
13121312
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_opcode_h.py \
13131313
$(srcdir)/Lib/opcode.py \
1314-
$(srcdir)/Include/opcode.h.new
1314+
$(srcdir)/Include/opcode.h.new \
1315+
$(srcdir)/Include/internal/pycore_opcode.h.new
13151316
$(UPDATE_FILE) $(srcdir)/Include/opcode.h $(srcdir)/Include/opcode.h.new
1317+
$(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode.h $(srcdir)/Include/internal/pycore_opcode.h.new
13161318

13171319
.PHONY: regen-token
13181320
regen-token:

Objects/codeobject.c

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "structmember.h" // PyMemberDef
66
#include "pycore_code.h" // _PyCodeConstructor
77
#include "pycore_interp.h" // PyInterpreterState.co_extra_freefuncs
8+
#include "pycore_opcode.h" // _PyOpcode_Deopt
89
#include "pycore_pystate.h" // _PyInterpreterState_GET()
910
#include "pycore_tuple.h" // _PyTuple_ITEMS()
1011
#include "clinic/codeobject.c.h"

Objects/frameobject.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
#include "Python.h"
44
#include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals()
5-
#include "pycore_moduleobject.h" // _PyModule_GetDict()
6-
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
75
#include "pycore_code.h" // CO_FAST_LOCAL, etc.
86
#include "pycore_function.h" // _PyFunction_FromConstructor()
7+
#include "pycore_moduleobject.h" // _PyModule_GetDict()
8+
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
9+
#include "pycore_opcode.h" // _PyOpcode_Caches
910

1011
#include "frameobject.h" // PyFrameObject
1112
#include "pycore_frame.h"

Objects/genobject.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
#include "Python.h"
44
#include "pycore_call.h" // _PyObject_CallNoArgs()
55
#include "pycore_ceval.h" // _PyEval_EvalFrame()
6+
#include "pycore_frame.h" // _PyInterpreterFrame
67
#include "pycore_genobject.h" // struct _Py_async_gen_state
78
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
9+
#include "pycore_opcode.h" // _PyOpcode_Deopt
810
#include "pycore_pyerrors.h" // _PyErr_ClearExcState()
911
#include "pycore_pystate.h" // _PyThreadState_GET()
10-
#include "pycore_frame.h" // _PyInterpreterFrame
11-
#include "frameobject.h" // PyFrameObject
1212
#include "structmember.h" // PyMemberDef
1313
#include "opcode.h" // SEND
1414

PCbuild/regen.targets

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<Argument>-C</Argument>
1515
</_ASTOutputs>
1616
<_OpcodeSources Include="$(PySourcePath)Tools\scripts\generate_opcode_h.py;$(PySourcePath)Lib\opcode.py" />
17-
<_OpcodeOutputs Include="$(PySourcePath)Include\opcode.h;$(PySourcePath)Python\opcode_targets.h" />
17+
<_OpcodeOutputs Include="$(PySourcePath)Include\opcode.h;$(PySourcePath)Include\internal\pycore_opcode.h;$(PySourcePath)Python\opcode_targets.h" />
1818
<_TokenSources Include="$(PySourcePath)Grammar\Tokens" />
1919
<_TokenOutputs Include="$(PySourcePath)Doc\library\token-list.inc">
2020
<Format>rst</Format>
@@ -59,7 +59,7 @@
5959
Inputs="@(_OpcodeSources)" Outputs="@(_OpcodeOutputs)"
6060
DependsOnTargets="FindPythonForBuild">
6161
<Message Text="Regenerate @(_OpcodeOutputs->'%(Filename)%(Extension)',' ')" Importance="high" />
62-
<Exec Command="$(PythonForBuild) Tools\scripts\generate_opcode_h.py Lib\opcode.py Include\opcode.h"
62+
<Exec Command="$(PythonForBuild) Tools\scripts\generate_opcode_h.py Lib\opcode.py Include\opcode.h Include\internal\pycore_opcode.h"
6363
WorkingDirectory="$(PySourcePath)" />
6464
<Exec Command="$(PythonForBuild) Python\makeopcodetargets.py Python\opcode_targets.h"
6565
WorkingDirectory="$(PySourcePath)" />

Python/ceval.c

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "pycore_long.h" // _PyLong_GetZero()
1616
#include "pycore_object.h" // _PyObject_GC_TRACK()
1717
#include "pycore_moduleobject.h" // PyModuleObject
18+
#include "pycore_opcode.h" // EXTRA_CASES
1819
#include "pycore_pyerrors.h" // _PyErr_Fetch()
1920
#include "pycore_pylifecycle.h" // _PyErr_Print()
2021
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()

Python/compile.c

+6-5
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,18 @@
2323

2424
#include <stdbool.h>
2525

26+
// Need _PyOpcode_RelativeJump of pycore_opcode.h
27+
#define NEED_OPCODE_TABLES
28+
2629
#include "Python.h"
2730
#include "pycore_ast.h" // _PyAST_GetDocString()
28-
#include "pycore_compile.h" // _PyFuture_FromAST()
2931
#include "pycore_code.h" // _PyCode_New()
30-
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
32+
#include "pycore_compile.h" // _PyFuture_FromAST()
3133
#include "pycore_long.h" // _PyLong_GetZero()
34+
#include "pycore_opcode.h" // _PyOpcode_Caches
35+
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
3236
#include "pycore_symtable.h" // PySTEntryObject
3337

34-
#define NEED_OPCODE_TABLES
35-
#include "opcode.h" // EXTENDED_ARG
36-
3738

3839
#define DEFAULT_BLOCK_SIZE 16
3940
#define DEFAULT_CODE_SIZE 128

Python/specialize.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "pycore_long.h"
77
#include "pycore_moduleobject.h"
88
#include "pycore_object.h"
9-
#include "opcode.h"
9+
#include "pycore_opcode.h" // _PyOpcode_Caches
1010
#include "structmember.h" // struct PyMemberDef, T_OFFSET_EX
1111

1212
#include <stdlib.h> // rand()

Tools/scripts/generate_opcode_h.py

+59-28
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
import sys
44
import tokenize
55

6-
header = """
7-
/* Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py */
6+
SCRIPT_NAME = "Tools/scripts/generate_opcode_h.py"
7+
PYTHON_OPCODE = "Lib/opcode.py"
8+
9+
header = f"""
10+
// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE}
11+
812
#ifndef Py_OPCODE_H
913
#define Py_OPCODE_H
1014
#ifdef __cplusplus
11-
extern "C" {
15+
extern "C" {{
1216
#endif
1317
1418
@@ -28,6 +32,29 @@
2832
#endif /* !Py_OPCODE_H */
2933
"""
3034

35+
internal_header = f"""
36+
// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE}
37+
38+
#ifndef Py_INTERNAL_OPCODE_H
39+
#define Py_INTERNAL_OPCODE_H
40+
#ifdef __cplusplus
41+
extern "C" {{
42+
#endif
43+
44+
#ifndef Py_BUILD_CORE
45+
# error "this header requires Py_BUILD_CORE define"
46+
#endif
47+
48+
#include "opcode.h"
49+
""".lstrip()
50+
51+
internal_footer = """
52+
#ifdef __cplusplus
53+
}
54+
#endif
55+
#endif // !Py_INTERNAL_OPCODE_H
56+
"""
57+
3158
DEFINE = "#define {:<38} {:>3}\n"
3259

3360
UINT32_MASK = (1<<32)-1
@@ -43,7 +70,7 @@ def write_int_array_from_ops(name, ops, out):
4370
assert bits == 0
4471
out.write(f"}};\n")
4572

46-
def main(opcode_py, outfile='Include/opcode.h'):
73+
def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/internal/pycore_opcode.h'):
4774
opcode = {}
4875
if hasattr(tokenize, 'open'):
4976
fp = tokenize.open(opcode_py) # Python 3.2+
@@ -75,8 +102,10 @@ def main(opcode_py, outfile='Include/opcode.h'):
75102
opname_including_specialized[255] = 'DO_TRACING'
76103
used[255] = True
77104

78-
with open(outfile, 'w') as fobj:
105+
with (open(outfile, 'w') as fobj, open(internaloutfile, 'w') as iobj):
79106
fobj.write(header)
107+
iobj.write(internal_header)
108+
80109
for name in opname:
81110
if name in opmap:
82111
fobj.write(DEFINE.format(name, opmap[name]))
@@ -86,28 +115,29 @@ def main(opcode_py, outfile='Include/opcode.h'):
86115
for name, op in specialized_opmap.items():
87116
fobj.write(DEFINE.format(name, op))
88117

89-
fobj.write("\nextern const uint8_t _PyOpcode_Caches[256];\n")
90-
fobj.write("\nextern const uint8_t _PyOpcode_Deopt[256];\n")
91-
fobj.write("\n#ifdef NEED_OPCODE_TABLES\n")
92-
write_int_array_from_ops("_PyOpcode_RelativeJump", opcode['hasjrel'], fobj)
93-
write_int_array_from_ops("_PyOpcode_Jump", opcode['hasjrel'] + opcode['hasjabs'], fobj)
118+
iobj.write("\nextern const uint8_t _PyOpcode_Caches[256];\n")
119+
iobj.write("\nextern const uint8_t _PyOpcode_Deopt[256];\n")
120+
iobj.write("\n#ifdef NEED_OPCODE_TABLES\n")
121+
write_int_array_from_ops("_PyOpcode_RelativeJump", opcode['hasjrel'], iobj)
122+
write_int_array_from_ops("_PyOpcode_Jump", opcode['hasjrel'] + opcode['hasjabs'], iobj)
94123

95-
fobj.write("\nconst uint8_t _PyOpcode_Caches[256] = {\n")
124+
iobj.write("\nconst uint8_t _PyOpcode_Caches[256] = {\n")
96125
for i, entries in enumerate(opcode["_inline_cache_entries"]):
97126
if entries:
98-
fobj.write(f" [{opname[i]}] = {entries},\n")
99-
fobj.write("};\n")
127+
iobj.write(f" [{opname[i]}] = {entries},\n")
128+
iobj.write("};\n")
129+
100130
deoptcodes = {}
101131
for basic in opmap:
102132
deoptcodes[basic] = basic
103133
for basic, family in opcode["_specializations"].items():
104134
for specialized in family:
105135
deoptcodes[specialized] = basic
106-
fobj.write("\nconst uint8_t _PyOpcode_Deopt[256] = {\n")
136+
iobj.write("\nconst uint8_t _PyOpcode_Deopt[256] = {\n")
107137
for opt, deopt in sorted(deoptcodes.items()):
108-
fobj.write(f" [{opt}] = {deopt},\n")
109-
fobj.write("};\n")
110-
fobj.write("#endif /* OPCODE_TABLES */\n")
138+
iobj.write(f" [{opt}] = {deopt},\n")
139+
iobj.write("};\n")
140+
iobj.write("#endif // NEED_OPCODE_TABLES\n")
111141

112142
fobj.write("\n")
113143
fobj.write("#define HAS_CONST(op) (false\\")
@@ -119,28 +149,29 @@ def main(opcode_py, outfile='Include/opcode.h'):
119149
for i, (op, _) in enumerate(opcode["_nb_ops"]):
120150
fobj.write(DEFINE.format(op, i))
121151

122-
fobj.write("\n")
123-
fobj.write("#ifdef Py_DEBUG\n")
124-
fobj.write("static const char *const _PyOpcode_OpName[256] = {\n")
152+
iobj.write("\n")
153+
iobj.write("#ifdef Py_DEBUG\n")
154+
iobj.write("static const char *const _PyOpcode_OpName[256] = {\n")
125155
for op, name in enumerate(opname_including_specialized):
126156
if name[0] != "<":
127157
op = name
128-
fobj.write(f''' [{op}] = "{name}",\n''')
129-
fobj.write("};\n")
130-
fobj.write("#endif\n")
158+
iobj.write(f''' [{op}] = "{name}",\n''')
159+
iobj.write("};\n")
160+
iobj.write("#endif\n")
131161

132-
fobj.write("\n")
133-
fobj.write("#define EXTRA_CASES \\\n")
162+
iobj.write("\n")
163+
iobj.write("#define EXTRA_CASES \\\n")
134164
for i, flag in enumerate(used):
135165
if not flag:
136-
fobj.write(f" case {i}: \\\n")
137-
fobj.write(" ;\n")
166+
iobj.write(f" case {i}: \\\n")
167+
iobj.write(" ;\n")
138168

139169
fobj.write(footer)
170+
iobj.write(internal_footer)
140171

141172

142173
print(f"{outfile} regenerated from {opcode_py}")
143174

144175

145176
if __name__ == '__main__':
146-
main(sys.argv[1], sys.argv[2])
177+
main(sys.argv[1], sys.argv[2], sys.argv[3])

0 commit comments

Comments
 (0)