diff options
Diffstat (limited to 'Modules/arraymodule.c')
-rw-r--r-- | Modules/arraymodule.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 401a3a7..4d2ff32 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -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] |