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

``

`-

`

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

`+

`

``

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;

`