Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
gh-133395: add option for extension modules to specialize BINARY_OP/SUBSCR, apply to arrays#133396
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
79e45a172dfba470ebe71d42d2a68fda407726fa81b47c1490abb5092b4c61089b6c376630a95f42d42f509b27f5c1ed68fd24d7bb15ad6181a30080190ecfd8b584878f057690fb993454bfc5File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Add option for extension modules to specialize ``BINARY_OP`` instructions. | ||
| Applied to ``array`` objects. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -14,6 +14,8 @@ | ||
| #include "pycore_modsupport.h" // _PyArg_NoKeywords() | ||
| #include "pycore_moduleobject.h" // _PyModule_GetState() | ||
| #include "opcode.h" // binary op opargs (NB_*) | ||
| #include <stddef.h> // offsetof() | ||
| #include <stdbool.h> | ||
| @@ -848,6 +850,10 @@ array_richcompare(PyObject *v, PyObject *w, int op) | ||
| return res; | ||
| } | ||
| static int | ||
| array_binop_specialize(PyObject *v, PyObject *w, int oparg, | ||
| _PyBinaryOpSpecializationDescr **descr); | ||
| static Py_ssize_t | ||
| array_length(PyObject *op) | ||
| { | ||
| @@ -2963,6 +2969,8 @@ static PyType_Slot array_slots[] ={ | ||
| {Py_tp_alloc, PyType_GenericAlloc}, | ||
| {Py_tp_new, array_new}, | ||
| {Py_tp_traverse, array_tp_traverse}, | ||
| {Py_tp_token, Py_TP_USE_SPEC}, | ||
| {Py_tp_binop_specialize, array_binop_specialize}, | ||
| /* as sequence */ | ||
| {Py_sq_length, array_length}, | ||
| @@ -2995,6 +3003,70 @@ static PyType_Spec array_spec ={ | ||
| .slots = array_slots, | ||
| }; | ||
| static inline int | ||
| array_subscr_guard(PyObject *lhs, PyObject *rhs) | ||
iritkatriel marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| { | ||
| PyObject *exc = PyErr_GetRaisedException(); | ||
| int ret = PyType_GetBaseByToken(Py_TYPE(lhs), &array_spec, NULL); | ||
| if (ret < 0){ | ||
| if (PyErr_ExceptionMatches(PyExc_TypeError)){ | ||
| PyErr_Clear(); | ||
| ret = 0; | ||
| } | ||
| } | ||
| _PyErr_ChainExceptions1(exc); | ||
| return ret; | ||
| } | ||
| static PyObject * | ||
| array_subscr_action(PyObject *lhs, PyObject *rhs) | ||
| { | ||
| return array_subscr(lhs, rhs); | ||
| } | ||
| static void | ||
| array_subscr_free(_PyBinaryOpSpecializationDescr* descr) | ||
| { | ||
| if (descr != NULL){ | ||
| PyMem_Free(descr); | ||
| } | ||
| } | ||
| static int | ||
| array_binop_specialize(PyObject *v, PyObject *w, int oparg, | ||
| _PyBinaryOpSpecializationDescr **descr) | ||
| { | ||
| array_state *state = find_array_state_by_type(Py_TYPE(v)); | ||
| if (!array_Check(v, state)){ | ||
| return 0; | ||
| } | ||
| *descr = NULL; | ||
| switch(oparg){ | ||
| case NB_SUBSCR: | ||
| if (array_subscr_guard(v, w)){ | ||
iritkatriel marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| *descr = (_PyBinaryOpSpecializationDescr*)PyMem_Malloc( | ||
iritkatriel marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| sizeof(_PyBinaryOpSpecializationDescr)); | ||
| if (*descr == NULL){ | ||
| PyErr_NoMemory(); | ||
| return -1; | ||
| } | ||
| **descr = (_PyBinaryOpSpecializationDescr){ | ||
| .oparg = oparg, | ||
| .guard = array_subscr_guard, | ||
| .action = array_subscr_action, | ||
| .free = array_subscr_free, | ||
| }; | ||
| return 1; | ||
| } | ||
| break; | ||
| } | ||
| return 0; | ||
| } | ||
| /*********************** Array Iterator **************************/ | ||
| /*[clinic input] | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2534,7 +2534,7 @@ LONG_FLOAT_ACTION(compactlong_float_multiply, *) | ||
| LONG_FLOAT_ACTION(compactlong_float_true_div, /) | ||
| #undef LONG_FLOAT_ACTION | ||
| static _PyBinaryOpSpecializationDescr binaryop_extend_descrs[] ={ | ||
| static const _PyBinaryOpSpecializationDescr binaryop_extend_builtins[] ={ | ||
| /* long-long arithmetic */ | ||
| {NB_OR, compactlongs_guard, compactlongs_or}, | ||
| {NB_AND, compactlongs_guard, compactlongs_and}, | ||
| @@ -2560,14 +2560,41 @@ static int | ||
| binary_op_extended_specialization(PyObject *lhs, PyObject *rhs, int oparg, | ||
| _PyBinaryOpSpecializationDescr **descr) | ||
| { | ||
| size_t n = sizeof(binaryop_extend_descrs)/sizeof(_PyBinaryOpSpecializationDescr); | ||
| for (size_t i = 0; i < n; i++){ | ||
| _PyBinaryOpSpecializationDescr *d = &binaryop_extend_descrs[i]; | ||
| /* We are currently using this only for NB_SUBSCR, which is not | ||
| * commutative. Will need to revisit this function when we use | ||
| * this for operators which are. | ||
| */ | ||
| typedef _PyBinaryOpSpecializationDescr descr_type; | ||
| size_t size = Py_ARRAY_LENGTH(binaryop_extend_builtins); | ||
| for (size_t i = 0; i < size; i++){ | ||
| descr_type *d = (descr_type *)&binaryop_extend_builtins[i]; | ||
| assert(d != NULL); | ||
| assert(d->guard != NULL); | ||
| if (d->oparg == oparg && d->guard(lhs, rhs)){ | ||
| *descr = d; | ||
| return 1; | ||
| } | ||
| } | ||
| PyTypeObject *lhs_type = Py_TYPE(lhs); | ||
iritkatriel marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| if (lhs_type->tp_binop_specialize != NULL){ | ||
| int ret = lhs_type->tp_binop_specialize(lhs, rhs, oparg, descr); | ||
| if (ret < 0){ | ||
| return -1; | ||
| } | ||
| if (ret == 1){ | ||
| if (*descr == NULL){ | ||
| PyErr_Format( | ||
iritkatriel marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| PyExc_ValueError, | ||
| "tp_binop_specialize of '%T' returned 1 with *descr == NULL", | ||
picnixz marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| lhs); | ||
| return -1; | ||
| } | ||
| (*descr)->oparg = oparg; | ||
| } | ||
| return ret; | ||
| } | ||
| return 0; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.