@@ -271,10 +271,18 @@ method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObj
271
271
return 0 ;
272
272
}
273
273
274
+ #ifdef STACKLESS
275
+ static int
276
+ get_stackless (PyObject * func ) {
277
+ assert (PyObject_TypeCheck (func , & PyMethodDescr_Type ));
278
+ return ((PyMethodDescrObject * )func )-> d_method -> ml_flags & METH_STACKLESS ;
279
+ }
280
+ #endif
281
+
274
282
static inline funcptr
275
- method_enter_call (PyObject * func )
283
+ method_enter_call (PyObject * func , int stackless )
276
284
{
277
- if (Py_EnterRecursiveCall (" while calling a Python object" )) {
285
+ if (! stackless && Py_EnterRecursiveCall (" while calling a Python object" )) {
278
286
return NULL ;
279
287
}
280
288
return (funcptr )((PyMethodDescrObject * )func )-> d_method -> ml_meth ;
@@ -285,6 +293,7 @@ static PyObject *
285
293
method_vectorcall_VARARGS (
286
294
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
287
295
{
296
+ STACKLESS_VECTORCALL_GETARG (method_vectorcall_VARARGS );
288
297
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
289
298
if (method_check_args (func , args , nargs , kwnames )) {
290
299
return NULL ;
@@ -293,21 +302,27 @@ method_vectorcall_VARARGS(
293
302
if (argstuple == NULL ) {
294
303
return NULL ;
295
304
}
296
- PyCFunction meth = (PyCFunction )method_enter_call (func );
305
+ STACKLESS_PROMOTE_FLAG (get_stackless (func ));
306
+ stackless = !!_PyStackless_TRY_STACKLESS ; /* reuse variable stackless */
307
+ PyCFunction meth = (PyCFunction )method_enter_call (func , stackless );
297
308
if (meth == NULL ) {
309
+ STACKLESS_RETRACT ();
298
310
Py_DECREF (argstuple );
299
311
return NULL ;
300
312
}
301
313
PyObject * result = meth (args [0 ], argstuple );
314
+ STACKLESS_ASSERT ();
302
315
Py_DECREF (argstuple );
303
- Py_LeaveRecursiveCall ();
316
+ if (!stackless )
317
+ Py_LeaveRecursiveCall ();
304
318
return result ;
305
319
}
306
320
307
321
static PyObject *
308
322
method_vectorcall_VARARGS_KEYWORDS (
309
323
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
310
324
{
325
+ STACKLESS_VECTORCALL_GETARG (method_vectorcall_VARARGS_KEYWORDS );
311
326
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
312
327
if (method_check_args (func , args , nargs , NULL )) {
313
328
return NULL ;
@@ -325,13 +340,18 @@ method_vectorcall_VARARGS_KEYWORDS(
325
340
goto exit ;
326
341
}
327
342
}
343
+ STACKLESS_PROMOTE_FLAG (get_stackless (func ));
344
+ stackless = !!_PyStackless_TRY_STACKLESS ; /* reuse variable stackless */
328
345
PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords )
329
- method_enter_call (func );
346
+ method_enter_call (func , stackless );
330
347
if (meth == NULL ) {
348
+ STACKLESS_RETRACT ();
331
349
goto exit ;
332
350
}
333
351
result = meth (args [0 ], argstuple , kwdict );
334
- Py_LeaveRecursiveCall ();
352
+ STACKLESS_ASSERT ();
353
+ if (!stackless )
354
+ Py_LeaveRecursiveCall ();
335
355
exit :
336
356
Py_DECREF (argstuple );
337
357
Py_XDECREF (kwdict );
@@ -342,42 +362,55 @@ static PyObject *
342
362
method_vectorcall_FASTCALL (
343
363
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
344
364
{
365
+ STACKLESS_VECTORCALL_GETARG (method_vectorcall_FASTCALL );
345
366
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
346
367
if (method_check_args (func , args , nargs , kwnames )) {
347
368
return NULL ;
348
369
}
370
+ STACKLESS_PROMOTE_FLAG (get_stackless (func ));
371
+ stackless = !!_PyStackless_TRY_STACKLESS ; /* reuse variable stackless */
349
372
_PyCFunctionFast meth = (_PyCFunctionFast )
350
- method_enter_call (func );
373
+ method_enter_call (func , stackless );
351
374
if (meth == NULL ) {
375
+ STACKLESS_RETRACT ();
352
376
return NULL ;
353
377
}
354
378
PyObject * result = meth (args [0 ], args + 1 , nargs - 1 );
355
- Py_LeaveRecursiveCall ();
379
+ STACKLESS_ASSERT ();
380
+ if (!stackless )
381
+ Py_LeaveRecursiveCall ();
356
382
return result ;
357
383
}
358
384
359
385
static PyObject *
360
386
method_vectorcall_FASTCALL_KEYWORDS (
361
387
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
362
388
{
389
+ STACKLESS_VECTORCALL_GETARG (method_vectorcall_FASTCALL_KEYWORDS );
363
390
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
364
391
if (method_check_args (func , args , nargs , NULL )) {
365
392
return NULL ;
366
393
}
394
+ STACKLESS_PROMOTE_FLAG (get_stackless (func ));
395
+ stackless = !!_PyStackless_TRY_STACKLESS ; /* reuse variable stackless */
367
396
_PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords )
368
- method_enter_call (func );
397
+ method_enter_call (func , stackless );
369
398
if (meth == NULL ) {
399
+ STACKLESS_RETRACT ();
370
400
return NULL ;
371
401
}
372
402
PyObject * result = meth (args [0 ], args + 1 , nargs - 1 , kwnames );
373
- Py_LeaveRecursiveCall ();
403
+ STACKLESS_ASSERT ();
404
+ if (!stackless )
405
+ Py_LeaveRecursiveCall ();
374
406
return result ;
375
407
}
376
408
377
409
static PyObject *
378
410
method_vectorcall_NOARGS (
379
411
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
380
412
{
413
+ STACKLESS_VECTORCALL_GETARG (method_vectorcall_NOARGS );
381
414
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
382
415
if (method_check_args (func , args , nargs , kwnames )) {
383
416
return NULL ;
@@ -387,19 +420,25 @@ method_vectorcall_NOARGS(
387
420
"%.200s() takes no arguments (%zd given)" , get_name (func ), nargs - 1 );
388
421
return NULL ;
389
422
}
390
- PyCFunction meth = (PyCFunction )method_enter_call (func );
423
+ STACKLESS_PROMOTE_FLAG (get_stackless (func ));
424
+ stackless = !!_PyStackless_TRY_STACKLESS ; /* reuse variable stackless */
425
+ PyCFunction meth = (PyCFunction )method_enter_call (func , stackless );
391
426
if (meth == NULL ) {
427
+ STACKLESS_RETRACT ();
392
428
return NULL ;
393
429
}
394
430
PyObject * result = meth (args [0 ], NULL );
395
- Py_LeaveRecursiveCall ();
431
+ STACKLESS_ASSERT ();
432
+ if (!stackless )
433
+ Py_LeaveRecursiveCall ();
396
434
return result ;
397
435
}
398
436
399
437
static PyObject *
400
438
method_vectorcall_O (
401
439
PyObject * func , PyObject * const * args , size_t nargsf , PyObject * kwnames )
402
440
{
441
+ STACKLESS_VECTORCALL_GETARG (method_vectorcall_O );
403
442
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
404
443
if (method_check_args (func , args , nargs , kwnames )) {
405
444
return NULL ;
@@ -410,12 +449,17 @@ method_vectorcall_O(
410
449
get_name (func ), nargs - 1 );
411
450
return NULL ;
412
451
}
413
- PyCFunction meth = (PyCFunction )method_enter_call (func );
452
+ STACKLESS_PROMOTE_FLAG (get_stackless (func ));
453
+ stackless = !!_PyStackless_TRY_STACKLESS ; /* reuse variable stackless */
454
+ PyCFunction meth = (PyCFunction )method_enter_call (func , stackless );
414
455
if (meth == NULL ) {
456
+ STACKLESS_RETRACT ();
415
457
return NULL ;
416
458
}
417
459
PyObject * result = meth (args [0 ], args [1 ]);
418
- Py_LeaveRecursiveCall ();
460
+ STACKLESS_ASSERT ();
461
+ if (!stackless )
462
+ Py_LeaveRecursiveCall ();
419
463
return result ;
420
464
}
421
465
0 commit comments