summaryrefslogtreecommitdiffstats
path: root/Modules/arraymodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/arraymodule.c')
-rw-r--r--Modules/arraymodule.c72
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]