Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit 76e52f4

Browse files
author
Anselm Kruis
committed
Stackless issue #133: make the fast-call functions Stackless aware.
Add the usual STACKLESS_GETARG(), ... stuff to the new fast-call functions.
1 parent 05231ec commit 76e52f4

File tree

3 files changed

+70
-11
lines changed

3 files changed

+70
-11
lines changed

Objects/abstract.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,8 +2187,8 @@ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
21872187

21882188
#ifdef STACKLESS
21892189
/* only do recursion adjustment if there is no danger
2190-
* of softswitching, i.e. if we are not being called by
2191-
* run_cframe. Were a softswitch to occur, the readjustment
2190+
* of soft-switching, i.e. if we are not being called by
2191+
* run_cframe. Were a soft-switch to occur, the re-adjustment
21922192
* of the recursion depth would happen for the wrong frame.
21932193
*/
21942194
if (!stackless)
@@ -2230,6 +2230,7 @@ _PyStack_AsTuple(PyObject **stack, Py_ssize_t nargs)
22302230
PyObject *
22312231
_PyObject_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwargs)
22322232
{
2233+
STACKLESS_GETARG();
22332234
ternaryfunc call;
22342235
PyObject *result = NULL;
22352236

@@ -2245,14 +2246,24 @@ _PyObject_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwargs)
22452246
_PyFunction_FastCall() doesn't support keyword arguments yet */
22462247
assert(kwargs == NULL);
22472248

2249+
#ifdef STACKLESS
2250+
/* only do recursion adjustment if there is no danger
2251+
* of soft-switching, i.e. if we are not being called by
2252+
* run_cframe. Were a soft-switch to occur, the re-adjustment
2253+
* of the recursion depth would happen for the wrong frame.
2254+
*/
2255+
if (!stackless)
2256+
#endif
22482257
if (Py_EnterRecursiveCall(" while calling a Python object")) {
22492258
return NULL;
22502259
}
22512260

22522261
if (PyFunction_Check(func)) {
2262+
STACKLESS_PROMOTE_ALL();
22532263
result = _PyFunction_FastCall(func, args, nargs, kwargs);
22542264
}
22552265
else if (PyCFunction_Check(func)) {
2266+
STACKLESS_PROMOTE_ALL();
22562267
result = _PyCFunction_FastCall(func, args, nargs, kwargs);
22572268
}
22582269
else {
@@ -2271,13 +2282,18 @@ _PyObject_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwargs)
22712282
goto exit;
22722283
}
22732284

2285+
STACKLESS_PROMOTE(func);
22742286
result = (*call)(func, tuple, kwargs);
22752287
Py_DECREF(tuple);
22762288
}
2289+
STACKLESS_ASSERT();
22772290

22782291
result = _Py_CheckFunctionResult(func, result, NULL);
22792292

22802293
exit:
2294+
#ifdef STACKLESS
2295+
if (!stackless)
2296+
#endif
22812297
Py_LeaveRecursiveCall();
22822298

22832299
return result;

Objects/methodobject.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ PyObject *
156156
_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, int nargs,
157157
PyObject *kwargs)
158158
{
159+
STACKLESS_GETARG();
159160
PyCFunctionObject* func = (PyCFunctionObject*)func_obj;
160161
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
161162
PyObject *self = PyCFunction_GET_SELF(func);
@@ -167,7 +168,7 @@ _PyCFunction_FastCall(PyObject *func_obj, PyObject **args, int nargs,
167168
caller loses its exception */
168169
assert(!PyErr_Occurred());
169170

170-
flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
171+
flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS);
171172

172173
switch (flags)
173174
{
@@ -185,6 +186,7 @@ _PyCFunction_FastCall(PyObject *func_obj, PyObject **args, int nargs,
185186
return NULL;
186187
}
187188

189+
STACKLESS_PROMOTE_FLAG(PyCFunction_GET_FLAGS(func) & METH_STACKLESS);
188190
result = (*meth) (self, NULL);
189191
break;
190192

@@ -202,6 +204,7 @@ _PyCFunction_FastCall(PyObject *func_obj, PyObject **args, int nargs,
202204
return NULL;
203205
}
204206

207+
STACKLESS_PROMOTE_FLAG(PyCFunction_GET_FLAGS(func) & METH_STACKLESS);
205208
result = (*meth) (self, args[0]);
206209
break;
207210

@@ -223,6 +226,7 @@ _PyCFunction_FastCall(PyObject *func_obj, PyObject **args, int nargs,
223226
return NULL;
224227
}
225228

229+
STACKLESS_PROMOTE_FLAG(PyCFunction_GET_FLAGS(func) & METH_STACKLESS);
226230
if (flags & METH_KEYWORDS) {
227231
result = (*(PyCFunctionWithKeywords)meth) (self, tuple, kwargs);
228232
}
@@ -239,6 +243,7 @@ _PyCFunction_FastCall(PyObject *func_obj, PyObject **args, int nargs,
239243
"METH_OLDARGS is no longer supported!");
240244
return NULL;
241245
}
246+
STACKLESS_ASSERT();
242247

243248
result = _Py_CheckFunctionResult(func_obj, result, NULL);
244249

Python/ceval.c

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5224,7 +5224,7 @@ call_function(PyObject ***pp_stack, int oparg
52245224
callargs = load_args(pp_stack, na);
52255225
if (callargs != NULL) {
52265226
READ_TIMESTAMP(*pintr0);
5227-
STACKLESS_PROPOSE_ALL();
5227+
STACKLESS_PROPOSE_ALL();
52285228
C_TRACE(x, PyCFunction_Call(func,callargs,NULL));
52295229
READ_TIMESTAMP(*pintr1);
52305230
Py_XDECREF(callargs);
@@ -5289,6 +5289,7 @@ static PyObject*
52895289
_PyFunction_FastCallNoKw(PyObject **args, Py_ssize_t na,
52905290
PyCodeObject *co, PyObject *globals)
52915291
{
5292+
STACKLESS_GETARG();
52925293
PyFrameObject *f;
52935294
PyThreadState *tstate = PyThreadState_GET();
52945295
PyObject **fastlocals;
@@ -5313,7 +5314,30 @@ _PyFunction_FastCallNoKw(PyObject **args, Py_ssize_t na,
53135314
Py_INCREF(*args);
53145315
fastlocals[i] = *args++;
53155316
}
5317+
5318+
#ifdef STACKLESS
5319+
f->f_execute = PyEval_EvalFrameEx_slp;
5320+
if (stackless) {
5321+
Py_INCREF(Py_None);
5322+
result = Py_None;
5323+
SLP_STORE_NEXT_FRAME(tstate, f);
5324+
Py_DECREF(f);
5325+
return STACKLESS_PACK(tstate, result);
5326+
}
5327+
if (f->f_back != NULL) {
5328+
/* use the faster path */
5329+
PyFrameObject *back = f->f_back;
5330+
Py_INCREF(Py_None);
5331+
Py_INCREF(back);
5332+
result = slp_frame_dispatch(f, back, 0, Py_None);
5333+
Py_DECREF(back);
5334+
}
5335+
else {
5336+
result = slp_eval_frame(f);
5337+
}
5338+
#else /* #ifdef STACKLESS */
53165339
result = PyEval_EvalFrameEx(f,0);
5340+
#endif /* #ifdef STACKLESS */
53175341

53185342
++tstate->recursion_depth;
53195343
Py_DECREF(f);
@@ -5331,15 +5355,19 @@ fast_function(PyObject *func, PyObject **stack, int n, int na, int nk)
53315355
PyObject *kwdefs, *closure, *name, *qualname;
53325356
PyObject **d;
53335357
int nd;
5358+
PyObject *result;
53345359

53355360
PCALL(PCALL_FUNCTION);
53365361
PCALL(PCALL_FAST_FUNCTION);
53375362

53385363
if (argdefs == NULL && co->co_argcount == na &&
53395364
co->co_kwonlyargcount == 0 && nk == 0 &&
5340-
co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
5365+
(co->co_flags & (~PyCF_MASK)) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
53415366
{
5342-
return _PyFunction_FastCallNoKw(stack, na, co, globals);
5367+
STACKLESS_PROPOSE_ALL();
5368+
result = _PyFunction_FastCallNoKw(stack, na, co, globals);
5369+
STACKLESS_ASSERT();
5370+
return result;
53435371
}
53445372

53455373
kwdefs = PyFunction_GET_KW_DEFAULTS(func);
@@ -5356,22 +5384,26 @@ fast_function(PyObject *func, PyObject **stack, int n, int na, int nk)
53565384
nd = 0;
53575385
}
53585386
STACKLESS_PROPOSE_ALL();
5359-
return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
5387+
result = _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
53605388
stack, na,
53615389
stack + na, nk,
53625390
d, nd, kwdefs,
53635391
closure, name, qualname);
5392+
STACKLESS_ASSERT();
5393+
return result;
53645394
}
53655395

53665396
PyObject *
53675397
_PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwargs)
53685398
{
5399+
STACKLESS_GETARG();
53695400
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
53705401
PyObject *globals = PyFunction_GET_GLOBALS(func);
53715402
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
53725403
PyObject *kwdefs, *closure, *name, *qualname;
53735404
PyObject **d;
53745405
int nd;
5406+
PyObject *result;
53755407

53765408
PCALL(PCALL_FUNCTION);
53775409
PCALL(PCALL_FAST_FUNCTION);
@@ -5381,9 +5413,12 @@ _PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwarg
53815413

53825414
if (argdefs == NULL && co->co_argcount == nargs &&
53835415
co->co_kwonlyargcount == 0 &&
5384-
co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
5416+
(co->co_flags & (~PyCF_MASK)) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
53855417
{
5386-
return _PyFunction_FastCallNoKw(args, nargs, co, globals);
5418+
STACKLESS_PROMOTE_ALL();
5419+
result = _PyFunction_FastCallNoKw(args, nargs, co, globals);
5420+
STACKLESS_ASSERT();
5421+
return result;
53875422
}
53885423

53895424
kwdefs = PyFunction_GET_KW_DEFAULTS(func);
@@ -5399,11 +5434,14 @@ _PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwarg
53995434
d = NULL;
54005435
nd = 0;
54015436
}
5402-
return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
5403-
args, nargs,
5437+
STACKLESS_PROMOTE_ALL();
5438+
result = _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
5439+
args, nargs,
54045440
NULL, 0,
54055441
d, nd, kwdefs,
54065442
closure, name, qualname);
5443+
STACKLESS_ASSERT();
5444+
return result;
54075445
}
54085446

54095447
static PyObject *

0 commit comments

Comments
 (0)