Repository navigation
gh-91049: Introduce set vectorcall field API for PyFunctionObject #92257
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
Changes from 3 commits
9cf96ec
282e3dc
edcdcf1
debf5a9
473d18d
76e8c9d
3337459
1543f44
08082bd
ed93327
24ffd30
89cb4b2
3387d4a
b0cc28a
99e4085
24353c8
60f7769
376ee75
56ffc70
5340e87
a5e9d13
12faf52
6623470
9149f14
e732d7e
84874fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| CPython extensions providing optimized execution of Python bytecode (like Cinder JIT and Pyjion) | ||
| can benefit from being able to modify the vectorcall field on instances of PyFunctionObject to allow calling the optimized path (e.g. JIT-compiled) directly. | ||
|
|
||
| This PR introduces an API call where vectorcall field can be modified like so: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This text lands into https://docs.python.org/dev/whatsnew/changelog.html#changelog which is a changlog, you should not mention "a PR" there. I suggest to just copy/paste what you wrote in whatsnew. |
||
|
|
||
| `void PyFunction_SetVectorcall(PyFunctionObject *func, vectorcallfunc vectorcall);` | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please document the function in Doc/c-api/function.rst and in the NEWS entry, refer to use with: New public functions should also be documented in What's New in Python 3.11 > C API > New features: Doc/whatsnew/3.11.rst. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5285,6 +5285,26 @@ test_pyobject_vectorcall(PyObject *self, PyObject *args) | |
| } | ||
|
|
||
|
|
||
| static PyObject * | ||
| override_vectorcall( | ||
| PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) { | ||
| Py_RETURN_NONE; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you modify the test to return the string "overridden" instead of just returning None? |
||
| } | ||
|
|
||
| static PyObject * | ||
| test_pyobject_setvectorcall(PyObject *self, PyObject *args) | ||
| { | ||
| PyFunctionObject *func = NULL; | ||
| if (!PyArg_ParseTuple(args, "O", &func)) { | ||
|
adphrost marked this conversation as resolved.
Resolved
|
||
| return NULL; | ||
| } | ||
| if(PyFunction_SetVectorcall(func, (vectorcallfunc)override_vectorcall) != 0) { | ||
| PyErr_SetString(PyExc_TypeError, "Something went wrong setting vectorcall field"); | ||
| return NULL; | ||
| } | ||
| Py_RETURN_NONE; | ||
| } | ||
|
|
||
| static PyObject * | ||
| test_pyvectorcall_call(PyObject *self, PyObject *args) | ||
| { | ||
|
|
@@ -6186,6 +6206,7 @@ static PyMethodDef TestMethods[] = { | |
| {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS}, | ||
| {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS}, | ||
| {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS}, | ||
| {"pyobject_setvectorcall", test_pyobject_setvectorcall, METH_VARARGS}, | ||
|
adphrost marked this conversation as resolved.
Resolved
|
||
| {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS}, | ||
| {"stack_pointer", stack_pointer, METH_NOARGS}, | ||
| #ifdef W_STOPCODE | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4792,7 +4792,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int | |
| PyObject *function = PEEK(total_args + 1); | ||
| int positional_args = total_args - KWNAMES_LEN(); | ||
| // Check if the call can be inlined or not | ||
| if (Py_TYPE(function) == &PyFunction_Type && tstate->interp->eval_frame == NULL) { | ||
| if (Py_TYPE(function) == &PyFunction_Type && tstate->interp->eval_frame == NULL && ((PyFunctionObject *)function)->vectorcall == _PyFunction_Vectorcall) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this probably exceeds line length
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the max line length allowed? And is there a linter I can run to handle this for me? |
||
| int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(function))->co_flags; | ||
| PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : PyFunction_GET_GLOBALS(function); | ||
| STACK_SHRINK(total_args); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.