Skip to content

gh-105481: do not auto-generate pycore_intrinsics.h #106913

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Include/cpython/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,5 @@ PyAPI_FUNC(int) PyUnstable_OpcodeHasFree(int opcode);
PyAPI_FUNC(int) PyUnstable_OpcodeHasLocal(int opcode);
PyAPI_FUNC(int) PyUnstable_OpcodeHasExc(int opcode);

PyAPI_FUNC(PyObject*) _PyUnstable_GetUnaryIntrinsicName(int index);
PyAPI_FUNC(PyObject*) _PyUnstable_GetBinaryIntrinsicName(int index);
20 changes: 15 additions & 5 deletions Include/internal/pycore_intrinsics.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py

/* Unary Functions: */
#define INTRINSIC_1_INVALID 0
Expand Down Expand Up @@ -26,7 +25,18 @@

#define MAX_INTRINSIC_2 4

typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);
extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[];
typedef PyObject *(*intrinsic_func1)(PyThreadState* tstate, PyObject *value);
typedef PyObject *(*intrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);

typedef struct {
intrinsic_func1 func;
const char *name;
} intrinsic_func1_info;

typedef struct {
intrinsic_func2 func;
const char *name;
} intrinsic_func2_info;

extern const intrinsic_func1_info _PyIntrinsics_UnaryFunctions[];
extern const intrinsic_func2_info _PyIntrinsics_BinaryFunctions[];
26 changes: 3 additions & 23 deletions Lib/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ def pseudo_op(name, op, real_ops):
__all__.extend(["hasarg", "hasconst", "hasname", "hasjump", "hasjrel",
"hasjabs", "hasfree", "haslocal", "hasexc"])

_intrinsic_1_descs = _opcode.get_intrinsic1_descs()
_intrinsic_2_descs = _opcode.get_intrinsic2_descs()

hascompare = [opmap["COMPARE_OP"]]

_nb_ops = [
Expand Down Expand Up @@ -288,29 +291,6 @@ def pseudo_op(name, op, real_ops):
("NB_INPLACE_XOR", "^="),
]

_intrinsic_1_descs = [
"INTRINSIC_1_INVALID",
"INTRINSIC_PRINT",
"INTRINSIC_IMPORT_STAR",
"INTRINSIC_STOPITERATION_ERROR",
"INTRINSIC_ASYNC_GEN_WRAP",
"INTRINSIC_UNARY_POSITIVE",
"INTRINSIC_LIST_TO_TUPLE",
"INTRINSIC_TYPEVAR",
"INTRINSIC_PARAMSPEC",
"INTRINSIC_TYPEVARTUPLE",
"INTRINSIC_SUBSCRIPT_GENERIC",
"INTRINSIC_TYPEALIAS",
]

_intrinsic_2_descs = [
"INTRINSIC_2_INVALID",
"INTRINSIC_PREP_RERAISE_STAR",
"INTRINSIC_TYPEVAR_WITH_BOUND",
"INTRINSIC_TYPEVAR_WITH_CONSTRAINTS",
"INTRINSIC_SET_FUNCTION_TYPE_PARAMS",
]


_cache_format = {
"LOAD_GLOBAL": {
Expand Down
4 changes: 1 addition & 3 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -1427,11 +1427,9 @@ regen-opcode:
$(srcdir)/Lib/opcode.py \
$(srcdir)/Lib/_opcode_metadata.py \
$(srcdir)/Include/opcode.h.new \
$(srcdir)/Include/internal/pycore_opcode.h.new \
$(srcdir)/Include/internal/pycore_intrinsics.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
$(UPDATE_FILE) $(srcdir)/Include/internal/pycore_intrinsics.h $(srcdir)/Include/internal/pycore_intrinsics.h.new

.PHONY: regen-token
regen-token:
Expand Down
57 changes: 57 additions & 0 deletions Modules/_opcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "compile.h"
#include "opcode.h"
#include "internal/pycore_code.h"
#include "internal/pycore_intrinsics.h"

/*[clinic input]
module _opcode
Expand Down Expand Up @@ -220,6 +221,60 @@ _opcode_get_specialization_stats_impl(PyObject *module)
#endif
}

/*[clinic input]

_opcode.get_intrinsic1_descs

Return a list of names of the unary intrinsics.
[clinic start generated code]*/

static PyObject *
_opcode_get_intrinsic1_descs_impl(PyObject *module)
/*[clinic end generated code: output=bd1ddb6b4447d18b input=13b51c712618459b]*/
{
PyObject *list = PyList_New(MAX_INTRINSIC_1 + 1);
if (list == NULL) {
return NULL;
}
for (int i=0; i <= MAX_INTRINSIC_1; i++) {
PyObject *name = _PyUnstable_GetUnaryIntrinsicName(i);
if (name == NULL) {
Py_DECREF(list);
return NULL;
}
PyList_SET_ITEM(list, i, name);
}
return list;
}


/*[clinic input]

_opcode.get_intrinsic2_descs

Return a list of names of the binary intrinsics.
[clinic start generated code]*/

static PyObject *
_opcode_get_intrinsic2_descs_impl(PyObject *module)
/*[clinic end generated code: output=40e62bc27584c8a0 input=e83068f249f5471b]*/
{
PyObject *list = PyList_New(MAX_INTRINSIC_2 + 1);
if (list == NULL) {
return NULL;
}
for (int i=0; i <= MAX_INTRINSIC_2; i++) {
PyObject *name = _PyUnstable_GetBinaryIntrinsicName(i);
if (name == NULL) {
Py_DECREF(list);
return NULL;
}
PyList_SET_ITEM(list, i, name);
}
return list;
}


static PyMethodDef
opcode_functions[] = {
_OPCODE_STACK_EFFECT_METHODDEF
Expand All @@ -232,6 +287,8 @@ opcode_functions[] = {
_OPCODE_HAS_LOCAL_METHODDEF
_OPCODE_HAS_EXC_METHODDEF
_OPCODE_GET_SPECIALIZATION_STATS_METHODDEF
_OPCODE_GET_INTRINSIC1_DESCS_METHODDEF
_OPCODE_GET_INTRINSIC2_DESCS_METHODDEF
{NULL, NULL, 0, NULL}
};

Expand Down
38 changes: 37 additions & 1 deletion Modules/clinic/_opcode.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,14 +698,14 @@ dummy_func(

inst(CALL_INTRINSIC_1, (value -- res)) {
assert(oparg <= MAX_INTRINSIC_1);
res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value);
res = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, value);
DECREF_INPUTS();
ERROR_IF(res == NULL, error);
}

inst(CALL_INTRINSIC_2, (value2, value1 -- res)) {
assert(oparg <= MAX_INTRINSIC_2);
res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1);
res = _PyIntrinsics_BinaryFunctions[oparg].func(tstate, value2, value1);
DECREF_INPUTS();
ERROR_IF(res == NULL, error);
}
Expand Down
4 changes: 2 additions & 2 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 50 additions & 19 deletions Python/intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/******** Unary functions ********/

static PyObject *
no_intrinsic(PyThreadState* tstate, PyObject *unused)
no_intrinsic1(PyThreadState* tstate, PyObject *unused)
{
_PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function");
return NULL;
Expand Down Expand Up @@ -203,25 +203,35 @@ make_typevar(PyThreadState* Py_UNUSED(ignored), PyObject *v)
return _Py_make_typevar(v, NULL, NULL);
}

const instrinsic_func1

#define INTRINSIC_FUNC_ENTRY(N, F) \
[N] = {F, #N},

const intrinsic_func1_info
_PyIntrinsics_UnaryFunctions[] = {
[0] = no_intrinsic,
[INTRINSIC_PRINT] = print_expr,
[INTRINSIC_IMPORT_STAR] = import_star,
[INTRINSIC_STOPITERATION_ERROR] = stopiteration_error,
[INTRINSIC_ASYNC_GEN_WRAP] = _PyAsyncGenValueWrapperNew,
[INTRINSIC_UNARY_POSITIVE] = unary_pos,
[INTRINSIC_LIST_TO_TUPLE] = list_to_tuple,
[INTRINSIC_TYPEVAR] = make_typevar,
[INTRINSIC_PARAMSPEC] = _Py_make_paramspec,
[INTRINSIC_TYPEVARTUPLE] = _Py_make_typevartuple,
[INTRINSIC_SUBSCRIPT_GENERIC] = _Py_subscript_generic,
[INTRINSIC_TYPEALIAS] = _Py_make_typealias,
INTRINSIC_FUNC_ENTRY(INTRINSIC_1_INVALID, no_intrinsic1)
INTRINSIC_FUNC_ENTRY(INTRINSIC_PRINT, print_expr)
INTRINSIC_FUNC_ENTRY(INTRINSIC_IMPORT_STAR, import_star)
INTRINSIC_FUNC_ENTRY(INTRINSIC_STOPITERATION_ERROR, stopiteration_error)
INTRINSIC_FUNC_ENTRY(INTRINSIC_ASYNC_GEN_WRAP, _PyAsyncGenValueWrapperNew)
INTRINSIC_FUNC_ENTRY(INTRINSIC_UNARY_POSITIVE, unary_pos)
INTRINSIC_FUNC_ENTRY(INTRINSIC_LIST_TO_TUPLE, list_to_tuple)
INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR, make_typevar)
INTRINSIC_FUNC_ENTRY(INTRINSIC_PARAMSPEC, _Py_make_paramspec)
INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVARTUPLE, _Py_make_typevartuple)
INTRINSIC_FUNC_ENTRY(INTRINSIC_SUBSCRIPT_GENERIC, _Py_subscript_generic)
INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEALIAS, _Py_make_typealias)
};


/******** Binary functions ********/

static PyObject *
no_intrinsic2(PyThreadState* tstate, PyObject *unused1, PyObject *unused2)
{
_PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function");
return NULL;
}

static PyObject *
prep_reraise_star(PyThreadState* unused, PyObject *orig, PyObject *excs)
Expand All @@ -246,10 +256,31 @@ make_typevar_with_constraints(PyThreadState* Py_UNUSED(ignored), PyObject *name,
return _Py_make_typevar(name, NULL, evaluate_constraints);
}

const instrinsic_func2
const intrinsic_func2_info
_PyIntrinsics_BinaryFunctions[] = {
[INTRINSIC_PREP_RERAISE_STAR] = prep_reraise_star,
[INTRINSIC_TYPEVAR_WITH_BOUND] = make_typevar_with_bound,
[INTRINSIC_TYPEVAR_WITH_CONSTRAINTS] = make_typevar_with_constraints,
[INTRINSIC_SET_FUNCTION_TYPE_PARAMS] = _Py_set_function_type_params,
INTRINSIC_FUNC_ENTRY(INTRINSIC_2_INVALID, no_intrinsic2)
INTRINSIC_FUNC_ENTRY(INTRINSIC_PREP_RERAISE_STAR, prep_reraise_star)
INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR_WITH_BOUND, make_typevar_with_bound)
INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR_WITH_CONSTRAINTS, make_typevar_with_constraints)
INTRINSIC_FUNC_ENTRY(INTRINSIC_SET_FUNCTION_TYPE_PARAMS, _Py_set_function_type_params)
};

#undef INTRINSIC_FUNC_ENTRY

PyObject*
_PyUnstable_GetUnaryIntrinsicName(int index)
{
if (index < 0 || index > MAX_INTRINSIC_1) {
return NULL;
}
return PyUnicode_FromString(_PyIntrinsics_UnaryFunctions[index].name);
}

PyObject*
_PyUnstable_GetBinaryIntrinsicName(int index)
{
if (index < 0 || index > MAX_INTRINSIC_2) {
return NULL;
}
return PyUnicode_FromString(_PyIntrinsics_BinaryFunctions[index].name);
}
Loading