|
14 | 14 | #include "pycore_modsupport.h" // _PyArg_NoKeywords() |
15 | 15 | #include "pycore_moduleobject.h" // _PyModule_GetState() |
16 | 16 |
|
| 17 | +#include "opcode.h" // binary op opargs (NB_*) |
| 18 | + |
17 | 19 | #include <stddef.h> // offsetof() |
18 | 20 | #include <stdbool.h> |
19 | 21 |
|
@@ -848,6 +850,10 @@ array_richcompare(PyObject *v, PyObject *w, int op) |
848 | 850 | return res; |
849 | 851 | } |
850 | 852 |
|
| 853 | +static int |
| 854 | +array_binop_specialize(PyObject *v, PyObject *w, int oparg, |
| 855 | + _PyBinaryOpSpecializationDescr **descr); |
| 856 | + |
851 | 857 | static Py_ssize_t |
852 | 858 | array_length(PyObject *op) |
853 | 859 | { |
@@ -2963,6 +2969,8 @@ static PyType_Slot array_slots[] = { |
2963 | 2969 | {Py_tp_alloc, PyType_GenericAlloc}, |
2964 | 2970 | {Py_tp_new, array_new}, |
2965 | 2971 | {Py_tp_traverse, array_tp_traverse}, |
| 2972 | + {Py_tp_token, Py_TP_USE_SPEC}, |
| 2973 | + {Py_tp_binop_specialize, array_binop_specialize}, |
2966 | 2974 |
|
2967 | 2975 | /* as sequence */ |
2968 | 2976 | {Py_sq_length, array_length}, |
@@ -2995,6 +3003,70 @@ static PyType_Spec array_spec = { |
2995 | 3003 | .slots = array_slots, |
2996 | 3004 | }; |
2997 | 3005 |
|
| 3006 | +static inline int |
| 3007 | +array_subscr_guard(PyObject *lhs, PyObject *rhs) |
| 3008 | +{ |
| 3009 | + PyObject *exc = PyErr_GetRaisedException(); |
| 3010 | + int ret = PyType_GetBaseByToken(Py_TYPE(lhs), &array_spec, NULL); |
| 3011 | + if (ret < 0) { |
| 3012 | + if (PyErr_ExceptionMatches(PyExc_TypeError)) { |
| 3013 | + PyErr_Clear(); |
| 3014 | + ret = 0; |
| 3015 | + } |
| 3016 | + } |
| 3017 | + _PyErr_ChainExceptions1(exc); |
| 3018 | + return ret; |
| 3019 | +} |
| 3020 | + |
| 3021 | +static PyObject * |
| 3022 | +array_subscr_action(PyObject *lhs, PyObject *rhs) |
| 3023 | +{ |
| 3024 | + return array_subscr(lhs, rhs); |
| 3025 | +} |
| 3026 | + |
| 3027 | +static void |
| 3028 | +array_subscr_free(_PyBinaryOpSpecializationDescr* descr) |
| 3029 | +{ |
| 3030 | + if (descr != NULL) { |
| 3031 | + PyMem_Free(descr); |
| 3032 | + } |
| 3033 | +} |
| 3034 | + |
| 3035 | +static int |
| 3036 | +array_binop_specialize(PyObject *v, PyObject *w, int oparg, |
| 3037 | + _PyBinaryOpSpecializationDescr **descr) |
| 3038 | +{ |
| 3039 | + array_state *state = find_array_state_by_type(Py_TYPE(v)); |
| 3040 | + |
| 3041 | + if (!array_Check(v, state)) { |
| 3042 | + return 0; |
| 3043 | + } |
| 3044 | + |
| 3045 | + *descr = NULL; |
| 3046 | + switch(oparg) { |
| 3047 | + case NB_SUBSCR: |
| 3048 | + if (array_subscr_guard(v, w)) { |
| 3049 | + *descr = (_PyBinaryOpSpecializationDescr*)PyMem_Malloc( |
| 3050 | + sizeof(_PyBinaryOpSpecializationDescr)); |
| 3051 | + if (*descr == NULL) { |
| 3052 | + PyErr_NoMemory(); |
| 3053 | + return -1; |
| 3054 | + } |
| 3055 | + **descr = (_PyBinaryOpSpecializationDescr) { |
| 3056 | + .oparg = oparg, |
| 3057 | + .guard = array_subscr_guard, |
| 3058 | + .action = array_subscr_action, |
| 3059 | + .free = array_subscr_free, |
| 3060 | + }; |
| 3061 | + return 1; |
| 3062 | + } |
| 3063 | + break; |
| 3064 | + } |
| 3065 | + |
| 3066 | + return 0; |
| 3067 | +} |
| 3068 | + |
| 3069 | + |
2998 | 3070 | /*********************** Array Iterator **************************/ |
2999 | 3071 |
|
3000 | 3072 | /*[clinic input] |
|
0 commit comments