Skip to content

Commit 919b741

Browse files
authored
Merge pull request #16 from markshannon/simple_cframe
Drop test for tracing and inline coroutine creation
2 parents 832bccf + 9a63ee1 commit 919b741

File tree

1 file changed

+35
-25
lines changed

1 file changed

+35
-25
lines changed

Python/ceval.c

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,6 +1541,12 @@ _PyEval_FrameFromPyFunctionAndArgs(PyThreadState *tstate, PyObject* const *args,
15411541
return _PyEvalFramePushAndInit(tstate, con, locals, args, vector_nargs, NULL, 1);
15421542
}
15431543

1544+
static PyObject *
1545+
make_coro(PyThreadState *tstate, PyFrameConstructor *con,
1546+
PyObject *locals,
1547+
PyObject* const* args, size_t argcount,
1548+
PyObject *kwnames);
1549+
15441550
PyObject* _Py_HOT_FUNCTION
15451551
_PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int throwflag)
15461552
{
@@ -4637,40 +4643,44 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
46374643

46384644
// Check if the call can be inlined or not
46394645
PyObject *function = PEEK(oparg + 1);
4640-
int inline_call = 0;
46414646
if (Py_TYPE(function) == &PyFunction_Type) {
46424647
PyCodeObject *code = (PyCodeObject*)PyFunction_GET_CODE(function);
4643-
int is_coro = code->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR);
4644-
inline_call = (is_coro || cframe.use_tracing) ? 0 : 1;
4648+
STACK_SHRINK(oparg + 1);
4649+
if ((code->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) == 0) {
4650+
InterpreterFrame *new_frame = _PyEval_FrameFromPyFunctionAndArgs(tstate, stack_pointer+1, oparg, function);
4651+
if (new_frame == NULL) {
4652+
// When we exit here, we own all variables in the stack (the frame creation has not stolen
4653+
// any variable) so we need to clean the whole stack (done in the "error" label).
4654+
goto error;
4655+
}
4656+
assert(tstate->interp->eval_frame != NULL);
4657+
// The frame has stolen all the arguments from the stack, so there is no need to clean up them
4658+
Py_DECREF(function);
4659+
_PyFrame_SetStackPointer(frame, stack_pointer);
4660+
new_frame->depth = frame->depth + 1;
4661+
tstate->frame = frame = new_frame;
4662+
goto start_frame;
4663+
}
4664+
else {
4665+
/* Callable is a generator or coroutine function: create coroutine or generator. */
4666+
PyObject *locals = code->co_flags & CO_OPTIMIZED ? NULL : PyFunction_GET_GLOBALS(function);
4667+
res = make_coro(tstate, PyFunction_AS_FRAME_CONSTRUCTOR(function), locals, stack_pointer+1, oparg, NULL);
4668+
for (int i = 0; i < oparg+1; i++) {
4669+
Py_DECREF(stack_pointer[i]);
4670+
}
4671+
}
46454672
}
4646-
4647-
if (!inline_call) {
4673+
else {
46484674
PyObject **sp = stack_pointer;
46494675
res = call_function(tstate, &sp, oparg, NULL, cframe.use_tracing);
46504676
stack_pointer = sp;
4651-
PUSH(res);
4652-
if (res == NULL) {
4653-
goto error;
4654-
}
4655-
CHECK_EVAL_BREAKER();
4656-
DISPATCH();
46574677
}
4658-
4659-
assert(!cframe.use_tracing);
4660-
InterpreterFrame *new_frame = _PyEval_FrameFromPyFunctionAndArgs(tstate, stack_pointer-oparg, oparg, function);
4661-
if (new_frame == NULL) {
4662-
// When we exit here, we own all variables in the stack (the frame creation has not stolen
4663-
// any variable) so we need to clean the whole stack (done in the "error" label).
4678+
PUSH(res);
4679+
if (res == NULL) {
46644680
goto error;
46654681
}
4666-
assert(tstate->interp->eval_frame != NULL);
4667-
// The frame has stolen all the arguments from the stack, so there is no need to clean up them
4668-
STACK_SHRINK(oparg + 1);
4669-
Py_DECREF(function);
4670-
_PyFrame_SetStackPointer(frame, stack_pointer);
4671-
new_frame->depth = frame->depth + 1;
4672-
tstate->frame = frame = new_frame;
4673-
goto start_frame;
4682+
CHECK_EVAL_BREAKER();
4683+
DISPATCH();
46744684
}
46754685

46764686
TARGET(CALL_FUNCTION_KW): {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy