summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/call.c12
-rw-r--r--Objects/typeobject.c24
2 files changed, 25 insertions, 11 deletions
diff --git a/Objects/call.c b/Objects/call.c
index c0d1456..578e1b3 100644
--- a/Objects/call.c
+++ b/Objects/call.c
@@ -173,12 +173,22 @@ _PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs
PyObject *
PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
{
- vectorcallfunc func = _PyVectorcall_Function(callable);
+ /* get vectorcallfunc as in _PyVectorcall_Function, but without
+ * the _Py_TPFLAGS_HAVE_VECTORCALL check */
+ Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset;
+ if ((offset <= 0) || (!Py_TYPE(callable)->tp_call)) {
+ PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall",
+ Py_TYPE(callable)->tp_name);
+ return NULL;
+ }
+ vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset);
if (func == NULL) {
PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall",
Py_TYPE(callable)->tp_name);
return NULL;
}
+
+ /* Convert arguments & call */
PyObject *const *args;
Py_ssize_t nargs = PyTuple_GET_SIZE(tuple);
PyObject *kwnames;
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index b6d925c..76e06aa 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -5145,17 +5145,21 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
}
COPYSLOT(tp_repr);
/* tp_hash see tp_richcompare */
- COPYSLOT(tp_call);
- /* Inherit tp_vectorcall_offset and _Py_TPFLAGS_HAVE_VECTORCALL if tp_call
- * was inherited, but only for extension types */
- if ((base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
- !(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
- !(type->tp_flags & Py_TPFLAGS_HEAPTYPE) &&
- base->tp_call &&
- type->tp_call == base->tp_call)
{
- type->tp_vectorcall_offset = base->tp_vectorcall_offset;
- type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL;
+ /* Inherit tp_vectorcall_offset only if tp_call is not overridden */
+ if (!type->tp_call) {
+ COPYSLOT(tp_vectorcall_offset);
+ }
+ /* Inherit_Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
+ * if tp_call is not overridden */
+ if (!type->tp_call &&
+ (base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
+ !(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
+ !(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
+ {
+ type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL;
+ }
+ COPYSLOT(tp_call);
}
COPYSLOT(tp_str);
{