@@ -231,29 +231,25 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
231
231
*
232
232
* First, common helpers
233
233
*/
234
- static inline const char *
234
+ static const char *
235
235
get_name (PyObject * func ) {
236
+ assert (PyObject_TypeCheck (func , & PyMethodDescr_Type ));
236
237
return ((PyMethodDescrObject * )func )-> d_method -> ml_name ;
237
238
}
238
239
239
240
typedef void (* funcptr )(void );
240
241
241
- static inline funcptr
242
- get_meth (PyObject * func ) {
243
- PyMethodDef * method = ((PyMethodDescrObject * )func )-> d_method ;
244
- return (funcptr )method -> ml_meth ;
245
- }
246
-
247
242
static inline int
248
- vectorcall_check (PyObject * func , size_t nargs , PyObject * const * args ) {
243
+ method_check_args (PyObject * func , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
244
+ {
249
245
assert (!PyErr_Occurred ());
250
246
assert (PyObject_TypeCheck (func , & PyMethodDescr_Type ));
251
247
if (nargs < 1 ) {
252
248
PyErr_Format (PyExc_TypeError ,
253
249
"descriptor '%.200s' of '%.100s' "
254
250
"object needs an argument" ,
255
251
get_name (func ), PyDescr_TYPE (func )-> tp_name );
256
- return 0 ;
252
+ return -1 ;
257
253
}
258
254
PyObject * self = args [0 ];
259
255
if (!_PyObject_RealIsSubclass ((PyObject * )Py_TYPE (self ),
@@ -264,66 +260,55 @@ vectorcall_check(PyObject *func, size_t nargs, PyObject *const *args) {
264
260
"doesn't apply to a '%.100s' object" ,
265
261
get_name (func ), PyDescr_TYPE (func )-> tp_name ,
266
262
Py_TYPE (self )-> tp_name );
267
- return 0 ;
263
+ return -1 ;
268
264
}
269
- return 1 ;
270
- }
271
-
272
- static inline int
273
- check_no_kwargs (PyObject * func , PyObject * kwnames ) {
274
- if (kwnames && PyTuple_GET_SIZE (kwnames ) > 0 ) {
265
+ if (kwnames && PyTuple_GET_SIZE (kwnames )) {
275
266
PyErr_Format (PyExc_TypeError ,
276
267
"%.200s() takes no keyword arguments" , get_name (func ));
277
- return 0 ;
268
+ return -1 ;
278
269
}
279
- return 1 ;
270
+ return 0 ;
280
271
}
281
272
282
- static inline int
283
- vectorcall_begin () {
273
+ static inline funcptr
274
+ method_enter_call (PyObject * func )
275
+ {
284
276
if (Py_EnterRecursiveCall (" while calling a Python object" )) {
285
- return 0 ;
277
+ return NULL ;
286
278
}
287
- return 1 ;
288
- }
289
-
290
- static inline PyObject *
291
- vectorcall_end (PyObject * func , PyObject * result ) {
292
- Py_LeaveRecursiveCall ();
293
- return _Py_CheckFunctionResult (func , result , NULL );
279
+ return (funcptr )((PyMethodDescrObject * )func )-> d_method -> ml_meth ;
294
280
}
295
281
296
282
/* Now the actual vectorcall functions */
297
283
static PyObject *
298
- _PyMethodDescr_Vectorcall_VARARGS (
284
+ method_vectorcall_VARARGS (
299
285
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
300
286
{
301
287
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
302
- if (!vectorcall_check (func , nargs , args )) {
303
- return NULL ;
304
- }
305
- if (!check_no_kwargs (func , kwnames )) {
288
+ if (method_check_args (func , args , nargs , kwnames )) {
306
289
return NULL ;
307
290
}
308
291
PyObject * argstuple = _PyTuple_FromArray (args + 1 , nargs - 1 );
309
292
if (argstuple == NULL ) {
310
293
return NULL ;
311
294
}
312
- if (!vectorcall_begin ()) {
295
+ PyCFunction meth = (PyCFunction )method_enter_call (func );
296
+ if (meth == NULL ) {
297
+ Py_DECREF (argstuple );
313
298
return NULL ;
314
299
}
315
- PyCFunction meth = (PyCFunction )get_meth (func );
316
300
PyObject * result = meth (args [0 ], argstuple );
317
301
Py_DECREF (argstuple );
318
- return vectorcall_end (func , result );
302
+ Py_LeaveRecursiveCall ();
303
+ return result ;
319
304
}
320
305
321
306
static PyObject *
322
- _PyMethodDescr_Vectorcall_VARARGS_KEYWORDS (
307
+ method_vectorcall_VARARGS_KEYWORDS (
323
308
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
324
309
{
325
310
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
326
- if (! vectorcall_check (func , nargs , args )) {
311
+ if (method_check_args (func , args , nargs , NULL )) {
327
312
return NULL ;
328
313
}
329
314
PyObject * argstuple = _PyTuple_FromArray (args + 1 , nargs - 1 );
@@ -332,93 +317,90 @@ _PyMethodDescr_Vectorcall_VARARGS_KEYWORDS(
332
317
}
333
318
PyObject * result = NULL ;
334
319
/* Create a temporary dict for keyword arguments */
335
- PyObject * kwdict ;
336
- if (kwnames == NULL || PyTuple_GET_SIZE (kwnames ) == 0 ) {
337
- kwdict = NULL ;
338
- }
339
- else {
340
- kwdict = _PyStack_AsDict (args + 1 + nargs , kwnames );
320
+ PyObject * kwdict = NULL ;
321
+ if (kwnames != NULL && PyTuple_GET_SIZE (kwnames ) > 0 ) {
322
+ kwdict = _PyStack_AsDict (args + nargs , kwnames );
341
323
if (kwdict == NULL ) {
342
- Py_DECREF (argstuple );
343
- return NULL ;
324
+ goto exit ;
344
325
}
345
326
}
346
- if (!vectorcall_begin ()) {
347
- return NULL ;
327
+ PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords )
328
+ method_enter_call (func );
329
+ if (meth == NULL ) {
330
+ goto exit ;
348
331
}
349
- PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords )get_meth (func );
350
332
result = meth (args [0 ], argstuple , kwdict );
333
+ Py_LeaveRecursiveCall ();
334
+ exit :
351
335
Py_DECREF (argstuple );
352
336
Py_XDECREF (kwdict );
353
- return vectorcall_end ( func , result ) ;
337
+ return result ;
354
338
}
355
339
356
340
static PyObject *
357
- _PyMethodDescr_Vectorcall_FASTCALL (
341
+ method_vectorcall_FASTCALL (
358
342
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
359
343
{
360
344
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
361
- if (! vectorcall_check (func , nargs , args )) {
345
+ if (method_check_args (func , args , nargs , kwnames )) {
362
346
return NULL ;
363
347
}
364
- if (!check_no_kwargs (func , kwnames )) {
348
+ _PyCFunctionFast meth = (_PyCFunctionFast )
349
+ method_enter_call (func );
350
+ if (meth == NULL ) {
365
351
return NULL ;
366
352
}
367
- if (!vectorcall_begin ()) {
368
- return NULL ;
369
- }
370
- _PyCFunctionFast meth = (_PyCFunctionFast )get_meth (func );
371
353
PyObject * result = meth (args [0 ], args + 1 , nargs - 1 );
372
- return vectorcall_end (func , result );
354
+ Py_LeaveRecursiveCall ();
355
+ return result ;
373
356
}
374
357
375
358
static PyObject *
376
- _PyMethodDescr_Vectorcall_FASTCALL_KEYWORDS (
359
+ method_vectorcall_FASTCALL_KEYWORDS (
377
360
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
378
361
{
379
362
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
380
- if (!vectorcall_check (func , nargs , args )) {
363
+ if (method_check_args (func , args , nargs , NULL )) {
364
+ return NULL ;
365
+ }
366
+ _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords )
367
+ method_enter_call (func );
368
+ if (meth == NULL ) {
381
369
return NULL ;
382
370
}
383
- vectorcall_begin ();
384
- _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords )get_meth (func );
385
371
PyObject * result = meth (args [0 ], args + 1 , nargs - 1 , kwnames );
386
- return vectorcall_end (func , result );
372
+ Py_LeaveRecursiveCall ();
373
+ return result ;
387
374
}
388
375
389
376
static PyObject *
390
- _PyMethodDescr_Vectorcall_NOARGS (
377
+ method_vectorcall_NOARGS (
391
378
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
392
379
{
393
380
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
394
- if (!vectorcall_check (func , nargs , args )) {
395
- return NULL ;
396
- }
397
- if (!check_no_kwargs (func , kwnames )) {
381
+ if (method_check_args (func , args , nargs , kwnames )) {
398
382
return NULL ;
399
383
}
400
384
if (nargs != 1 ) {
401
385
PyErr_Format (PyExc_TypeError ,
402
386
"%.200s() takes no arguments (%zd given)" , get_name (func ), nargs - 1 );
403
387
return NULL ;
404
388
}
405
- if (!vectorcall_begin ()) {
389
+ PyCFunction meth = (PyCFunction )method_enter_call (func );
390
+ if (meth == NULL ) {
406
391
return NULL ;
407
392
}
408
- PyCFunction meth = (PyCFunction )get_meth (func );
409
393
PyObject * result = meth (args [0 ], NULL );
410
- return vectorcall_end (func , result );
394
+ Py_LeaveRecursiveCall ();
395
+ return result ;
411
396
}
412
397
413
398
static PyObject *
414
- _PyMethodDescr_Vectorcall_O (
399
+ method_vectorcall_O (
415
400
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
416
401
{
417
402
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
418
- if (!vectorcall_check (func , nargs , args )) {
419
- return NULL ;
420
- }
421
- if (!check_no_kwargs (func , kwnames )) {
403
+ if (method_check_args (func , args , nargs , kwnames )) {
422
404
return NULL ;
423
405
}
424
406
if (nargs != 2 ) {
@@ -427,12 +409,13 @@ _PyMethodDescr_Vectorcall_O(
427
409
get_name (func ), nargs - 1 );
428
410
return NULL ;
429
411
}
430
- if (!vectorcall_begin ()) {
412
+ PyCFunction meth = (PyCFunction )method_enter_call (func );
413
+ if (meth == NULL ) {
431
414
return NULL ;
432
415
}
433
- PyCFunction meth = (PyCFunction )get_meth (func );
434
416
PyObject * result = meth (args [0 ], args [1 ]);
435
- return vectorcall_end (func , result );
417
+ Py_LeaveRecursiveCall ();
418
+ return result ;
436
419
}
437
420
438
421
@@ -879,22 +862,22 @@ PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
879
862
switch (method -> ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS ))
880
863
{
881
864
case METH_VARARGS :
882
- vectorcall = _PyMethodDescr_Vectorcall_VARARGS ;
865
+ vectorcall = method_vectorcall_VARARGS ;
883
866
break ;
884
867
case METH_VARARGS | METH_KEYWORDS :
885
- vectorcall = _PyMethodDescr_Vectorcall_VARARGS_KEYWORDS ;
868
+ vectorcall = method_vectorcall_VARARGS_KEYWORDS ;
886
869
break ;
887
870
case METH_FASTCALL :
888
- vectorcall = _PyMethodDescr_Vectorcall_FASTCALL ;
871
+ vectorcall = method_vectorcall_FASTCALL ;
889
872
break ;
890
873
case METH_FASTCALL | METH_KEYWORDS :
891
- vectorcall = _PyMethodDescr_Vectorcall_FASTCALL_KEYWORDS ;
874
+ vectorcall = method_vectorcall_FASTCALL_KEYWORDS ;
892
875
break ;
893
876
case METH_NOARGS :
894
- vectorcall = _PyMethodDescr_Vectorcall_NOARGS ;
877
+ vectorcall = method_vectorcall_NOARGS ;
895
878
break ;
896
879
case METH_O :
897
- vectorcall = _PyMethodDescr_Vectorcall_O ;
880
+ vectorcall = method_vectorcall_O ;
898
881
break ;
899
882
default :
900
883
PyErr_SetString (PyExc_SystemError , "bad call flags" );
0 commit comments