bpo-45439: _PyObject_Call() only checks tp_vectorcall_offset once (GH… · python/cpython@fb8f208 (original) (raw)
`@@ -225,28 +225,11 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable,
`
225
225
`}
`
226
226
``
227
227
``
228
``
`-
PyObject *
`
229
``
`-
PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
`
``
228
`+
static PyObject *
`
``
229
`+
_PyVectorcall_Call(PyThreadState *tstate, vectorcallfunc func,
`
``
230
`+
PyObject *callable, PyObject *tuple, PyObject *kwargs)
`
230
231
`{
`
231
``
`-
PyThreadState *tstate = _PyThreadState_GET();
`
232
``
`-
vectorcallfunc func;
`
233
``
-
234
``
`-
/* get vectorcallfunc as in PyVectorcall_Function, but without
`
235
``
`-
- the Py_TPFLAGS_HAVE_VECTORCALL check */
`
236
``
`-
Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset;
`
237
``
`-
if (offset <= 0) {
`
238
``
`-
_PyErr_Format(tstate, PyExc_TypeError,
`
239
``
`-
"'%.200s' object does not support vectorcall",
`
240
``
`-
Py_TYPE(callable)->tp_name);
`
241
``
`-
return NULL;
`
242
``
`-
}
`
243
``
`-
memcpy(&func, (char *) callable + offset, sizeof(func));
`
244
``
`-
if (func == NULL) {
`
245
``
`-
_PyErr_Format(tstate, PyExc_TypeError,
`
246
``
`-
"'%.200s' object does not support vectorcall",
`
247
``
`-
Py_TYPE(callable)->tp_name);
`
248
``
`-
return NULL;
`
249
``
`-
}
`
``
232
`+
assert(func != NULL);
`
250
233
``
251
234
`Py_ssize_t nargs = PyTuple_GET_SIZE(tuple);
`
252
235
``
`@@ -272,6 +255,35 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
`
272
255
`}
`
273
256
``
274
257
``
``
258
`+
PyObject *
`
``
259
`+
PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
`
``
260
`+
{
`
``
261
`+
PyThreadState *tstate = _PyThreadState_GET();
`
``
262
+
``
263
`+
/* get vectorcallfunc as in PyVectorcall_Function, but without
`
``
264
`+
- the Py_TPFLAGS_HAVE_VECTORCALL check */
`
``
265
`+
Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset;
`
``
266
`+
if (offset <= 0) {
`
``
267
`+
_PyErr_Format(tstate, PyExc_TypeError,
`
``
268
`+
"'%.200s' object does not support vectorcall",
`
``
269
`+
Py_TYPE(callable)->tp_name);
`
``
270
`+
return NULL;
`
``
271
`+
}
`
``
272
`+
assert(PyCallable_Check(callable));
`
``
273
+
``
274
`+
vectorcallfunc func;
`
``
275
`+
memcpy(&func, (char *) callable + offset, sizeof(func));
`
``
276
`+
if (func == NULL) {
`
``
277
`+
_PyErr_Format(tstate, PyExc_TypeError,
`
``
278
`+
"'%.200s' object does not support vectorcall",
`
``
279
`+
Py_TYPE(callable)->tp_name);
`
``
280
`+
return NULL;
`
``
281
`+
}
`
``
282
+
``
283
`+
return _PyVectorcall_Call(tstate, func, callable, tuple, kwargs);
`
``
284
`+
}
`
``
285
+
``
286
+
275
287
`PyObject *
`
276
288
`_PyObject_Call(PyThreadState *tstate, PyObject *callable,
`
277
289
`PyObject *args, PyObject *kwargs)
`
`@@ -286,8 +298,9 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable,
`
286
298
`assert(PyTuple_Check(args));
`
287
299
`assert(kwargs == NULL || PyDict_Check(kwargs));
`
288
300
``
289
``
`-
if (PyVectorcall_Function(callable) != NULL) {
`
290
``
`-
return PyVectorcall_Call(callable, args, kwargs);
`
``
301
`+
vectorcallfunc vector_func = PyVectorcall_Function(callable);
`
``
302
`+
if (vector_func != NULL) {
`
``
303
`+
return _PyVectorcall_Call(tstate, vector_func, callable, args, kwargs);
`
291
304
` }
`
292
305
`else {
`
293
306
`call = Py_TYPE(callable)->tp_call;
`