mirror of
https://github.com/python/cpython.git
synced 2026-01-04 14:32:21 +00:00
gh-133395: add option for extension modules to specialize BINARY_OP/SUBSCR, apply to arrays (#133396)
This commit is contained in:
parent
07f416a3f0
commit
082dbf7788
14 changed files with 172 additions and 45 deletions
|
|
@ -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)
|
||||
{
|
||||
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)) {
|
||||
*descr = (_PyBinaryOpSpecializationDescr*)PyMem_Malloc(
|
||||
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]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue