diff --git a/Include/opcode.h b/Include/opcode.h
index e5c42d5a718..2619b690019 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -1,5 +1,3 @@
-// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py
-
#ifndef Py_OPCODE_H
#define Py_OPCODE_H
#ifdef __cplusplus
@@ -36,6 +34,7 @@ extern "C" {
#define NB_INPLACE_TRUE_DIVIDE 24
#define NB_INPLACE_XOR 25
+#define NB_OPARG_LAST 25
#ifdef __cplusplus
}
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 6b9d9ce811a..f8487522bfd 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -44,39 +44,10 @@ if sys.version_info[:2] >= (3, 13):
_intrinsic_1_descs = _opcode.get_intrinsic1_descs()
_intrinsic_2_descs = _opcode.get_intrinsic2_descs()
+ _nb_ops = _opcode.get_nb_ops()
hascompare = [opmap["COMPARE_OP"]]
-_nb_ops = [
- ("NB_ADD", "+"),
- ("NB_AND", "&"),
- ("NB_FLOOR_DIVIDE", "//"),
- ("NB_LSHIFT", "<<"),
- ("NB_MATRIX_MULTIPLY", "@"),
- ("NB_MULTIPLY", "*"),
- ("NB_REMAINDER", "%"),
- ("NB_OR", "|"),
- ("NB_POWER", "**"),
- ("NB_RSHIFT", ">>"),
- ("NB_SUBTRACT", "-"),
- ("NB_TRUE_DIVIDE", "/"),
- ("NB_XOR", "^"),
- ("NB_INPLACE_ADD", "+="),
- ("NB_INPLACE_AND", "&="),
- ("NB_INPLACE_FLOOR_DIVIDE", "//="),
- ("NB_INPLACE_LSHIFT", "<<="),
- ("NB_INPLACE_MATRIX_MULTIPLY", "@="),
- ("NB_INPLACE_MULTIPLY", "*="),
- ("NB_INPLACE_REMAINDER", "%="),
- ("NB_INPLACE_OR", "|="),
- ("NB_INPLACE_POWER", "**="),
- ("NB_INPLACE_RSHIFT", ">>="),
- ("NB_INPLACE_SUBTRACT", "-="),
- ("NB_INPLACE_TRUE_DIVIDE", "/="),
- ("NB_INPLACE_XOR", "^="),
-]
-
-
_cache_format = {
"LOAD_GLOBAL": {
"counter": 1,
diff --git a/Makefile.pre.in b/Makefile.pre.in
index bcec0782f6e..9be5c3b50eb 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -1427,13 +1427,11 @@ regen-ast:
.PHONY: regen-opcode
regen-opcode:
- # Regenerate Include/opcode.h from Lib/opcode.py
+ # Regenerate Include/internal/pycore_opcode.h from Lib/opcode.py
# using Tools/build/generate_opcode_h.py
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_opcode_h.py \
$(srcdir)/Lib/opcode.py \
- $(srcdir)/Include/opcode.h.new \
$(srcdir)/Include/internal/pycore_opcode.h.new
- $(UPDATE_FILE) $(srcdir)/Include/opcode.h $(srcdir)/Include/opcode.h.new
$(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode.h $(srcdir)/Include/internal/pycore_opcode.h.new
.PHONY: regen-token
diff --git a/Modules/_opcode.c b/Modules/_opcode.c
index ad0fa736f82..4f85e7ee26d 100644
--- a/Modules/_opcode.c
+++ b/Modules/_opcode.c
@@ -223,6 +223,75 @@ _opcode_get_specialization_stats_impl(PyObject *module)
/*[clinic input]
+_opcode.get_nb_ops
+
+Return array of symbols of binary ops.
+
+Indexed by the BINARY_OP oparg value.
+[clinic start generated code]*/
+
+static PyObject *
+_opcode_get_nb_ops_impl(PyObject *module)
+/*[clinic end generated code: output=d997d306cc15426f input=9462fc544c823176]*/
+{
+ PyObject *list = PyList_New(NB_OPARG_LAST + 1);
+ if (list == NULL) {
+ return NULL;
+ }
+#define ADD_NB_OP(NUM, STR) \
+ do { \
+ PyObject *pair = Py_BuildValue( \
+ "NN", PyUnicode_FromString(#NUM), PyUnicode_FromString(STR)); \
+ if (pair == NULL) { \
+ Py_DECREF(list); \
+ return NULL; \
+ } \
+ PyList_SET_ITEM(list, (NUM), pair); \
+ } while(0);
+
+ ADD_NB_OP(NB_ADD, "+");
+ ADD_NB_OP(NB_AND, "&");
+ ADD_NB_OP(NB_FLOOR_DIVIDE, "//");
+ ADD_NB_OP(NB_LSHIFT, "<<");
+ ADD_NB_OP(NB_MATRIX_MULTIPLY, "@");
+ ADD_NB_OP(NB_MULTIPLY, "*");
+ ADD_NB_OP(NB_REMAINDER, "%");
+ ADD_NB_OP(NB_OR, "|");
+ ADD_NB_OP(NB_POWER, "**");
+ ADD_NB_OP(NB_RSHIFT, ">>");
+ ADD_NB_OP(NB_SUBTRACT, "-");
+ ADD_NB_OP(NB_TRUE_DIVIDE, "/");
+ ADD_NB_OP(NB_XOR, "^");
+ ADD_NB_OP(NB_INPLACE_ADD, "+=");
+ ADD_NB_OP(NB_INPLACE_AND, "&=");
+ ADD_NB_OP(NB_INPLACE_FLOOR_DIVIDE, "//=");
+ ADD_NB_OP(NB_INPLACE_LSHIFT, "<<=");
+ ADD_NB_OP(NB_INPLACE_MATRIX_MULTIPLY, "@=");
+ ADD_NB_OP(NB_INPLACE_MULTIPLY, "*=");
+ ADD_NB_OP(NB_INPLACE_REMAINDER, "%=");
+ ADD_NB_OP(NB_INPLACE_OR, "|=");
+ ADD_NB_OP(NB_INPLACE_POWER, "**=");
+ ADD_NB_OP(NB_INPLACE_RSHIFT, ">>=");
+ ADD_NB_OP(NB_INPLACE_SUBTRACT, "-=");
+ ADD_NB_OP(NB_INPLACE_TRUE_DIVIDE, "/=");
+ ADD_NB_OP(NB_INPLACE_XOR, "^=");
+
+#undef ADD_NB_OP
+
+ for(int i = 0; i <= NB_OPARG_LAST; i++) {
+ if (PyList_GET_ITEM(list, i) == NULL) {
+ Py_DECREF(list);
+ PyErr_Format(PyExc_ValueError,
+ "Missing initialization for NB_OP %d",
+ i);
+ return NULL;
+ }
+ }
+ return list;
+}
+
+/*[clinic input]
+
_opcode.get_intrinsic1_descs
Return a list of names of the unary intrinsics.
@@ -287,6 +356,7 @@ opcode_functions[] = {
_OPCODE_HAS_LOCAL_METHODDEF
_OPCODE_HAS_EXC_METHODDEF
_OPCODE_GET_SPECIALIZATION_STATS_METHODDEF
+ _OPCODE_GET_NB_OPS_METHODDEF
_OPCODE_GET_INTRINSIC1_DESCS_METHODDEF
_OPCODE_GET_INTRINSIC2_DESCS_METHODDEF
{NULL, NULL, 0, NULL}
diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h
index e1fc5ba17f7..52fbdcbd2a6 100644
--- a/Modules/clinic/_opcode.c.h
+++ b/Modules/clinic/_opcode.c.h
@@ -613,6 +613,26 @@ _opcode_get_specialization_stats(PyObject *module, PyObject *Py_UNUSED(ignored))
return _opcode_get_specialization_stats_impl(module);
}
+PyDoc_STRVAR(_opcode_get_nb_ops__doc__,
+"get_nb_ops($module, /)\n"
+"--\n"
+"\n"
+"Return array of symbols of binary ops.\n"
+"\n"
+"Indexed by the BINARY_OP oparg value.");
+
+#define _OPCODE_GET_NB_OPS_METHODDEF \
+ {"get_nb_ops", (PyCFunction)_opcode_get_nb_ops, METH_NOARGS, _opcode_get_nb_ops__doc__},
+
+static PyObject *
+_opcode_get_nb_ops_impl(PyObject *module);
+
+static PyObject *
+_opcode_get_nb_ops(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return _opcode_get_nb_ops_impl(module);
+}
+
PyDoc_STRVAR(_opcode_get_intrinsic1_descs__doc__,
"get_intrinsic1_descs($module, /)\n"
"--\n"
@@ -648,4 +668,4 @@ _opcode_get_intrinsic2_descs(PyObject *module, PyObject *Py_UNUSED(ignored))
{
return _opcode_get_intrinsic2_descs_impl(module);
}
-/*[clinic end generated code: output=d85de5f2887b3661 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=31a1a11c2f81dca4 input=a9049054013a1b77]*/
diff --git a/PCbuild/regen.targets b/PCbuild/regen.targets
index ed02f916354..2ff18a8966f 100644
--- a/PCbuild/regen.targets
+++ b/PCbuild/regen.targets
@@ -14,7 +14,7 @@
-C
<_OpcodeSources Include="$(PySourcePath)Tools\build\generate_opcode_h.py;$(PySourcePath)Lib\opcode.py" />
- <_OpcodeOutputs Include="$(PySourcePath)Include\opcode.h;$(PySourcePath)Include\internal\pycore_opcode.h" />
+ <_OpcodeOutputs Include="$(PySourcePath)Include\internal\pycore_opcode.h" />
<_TokenSources Include="$(PySourcePath)Grammar\Tokens" />
<_TokenOutputs Include="$(PySourcePath)Doc\library\token-list.inc">
rst
@@ -59,7 +59,7 @@
Inputs="@(_OpcodeSources)" Outputs="@(_OpcodeOutputs)"
DependsOnTargets="FindPythonForBuild">
-
diff --git a/Tools/build/generate_opcode_h.py b/Tools/build/generate_opcode_h.py
index 344709a0518..643918c1bc2 100644
--- a/Tools/build/generate_opcode_h.py
+++ b/Tools/build/generate_opcode_h.py
@@ -1,4 +1,4 @@
-# This script generates the opcode.h header file.
+# This script generates the pycore_opcode.h header file.
import sys
import tokenize
@@ -6,27 +6,6 @@ import tokenize
SCRIPT_NAME = "Tools/build/generate_opcode_h.py"
PYTHON_OPCODE = "Lib/opcode.py"
-opcode_h_header = f"""
-// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE}
-
-#ifndef Py_OPCODE_H
-#define Py_OPCODE_H
-#ifdef __cplusplus
-extern "C" {{
-#endif
-
-#include "opcode_ids.h"
-
-""".lstrip()
-
-opcode_h_footer = """
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* !Py_OPCODE_H */
-"""
-
internal_header = f"""
// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE}
@@ -62,20 +41,10 @@ def get_python_module_dict(filename):
return mod
def main(opcode_py,
- opcode_h='Include/opcode.h',
internal_opcode_h='Include/internal/pycore_opcode.h'):
opcode = get_python_module_dict(opcode_py)
- with open(opcode_h, 'w') as fobj:
- fobj.write(opcode_h_header)
-
- fobj.write("\n")
- for i, (op, _) in enumerate(opcode["_nb_ops"]):
- fobj.write(DEFINE.format(op, i))
-
- fobj.write(opcode_h_footer)
-
with open(internal_opcode_h, 'w') as iobj:
iobj.write(internal_header)
@@ -91,8 +60,8 @@ def main(opcode_py,
iobj.write(internal_footer)
- print(f"{opcode_h} regenerated from {opcode_py}")
+ print(f"{internal_opcode_h} regenerated from {opcode_py}")
if __name__ == '__main__':
- main(sys.argv[1], sys.argv[2], sys.argv[3])
+ main(sys.argv[1], sys.argv[2])