Skip to content

Commit 46ef280

Browse files
committed
Handle tail-calling interpreter
1 parent 3a2ccda commit 46ef280

File tree

4 files changed

+20
-6
lines changed

4 files changed

+20
-6
lines changed

Python/bytecodes.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,12 +1169,14 @@ dummy_func(
11691169
tstate->current_frame = frame->previous;
11701170
assert(!_PyErr_Occurred(tstate));
11711171
PyObject *result = PyStackRef_AsPyObjectSteal(retval);
1172+
#if !Py_TAIL_CALL_INTERP && defined(_Py_TIER2)
11721173
_PyStackRef executor = entry.frame.localsplus[0];
11731174
assert(tstate->current_executor == NULL);
11741175
if (!PyStackRef_IsNull(executor)) {
11751176
tstate->current_executor = PyStackRef_AsPyObjectBorrow(executor);
11761177
PyStackRef_CLOSE(executor);
11771178
}
1179+
#endif
11781180
LLTRACE_RESUME_FRAME();
11791181
return result;
11801182
}

Python/ceval.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,14 +1050,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10501050
entry.frame.previous = tstate->current_frame;
10511051
frame->previous = &entry.frame;
10521052
tstate->current_frame = frame;
1053-
1053+
entry.frame.localsplus[0] = PyStackRef_NULL;
1054+
#ifdef _Py_TIER2
10541055
if (tstate->current_executor != NULL) {
10551056
entry.frame.localsplus[0] = PyStackRef_FromPyObjectNew(tstate->current_executor);
10561057
tstate->current_executor = NULL;
10571058
}
1058-
else {
1059-
entry.frame.localsplus[0] = PyStackRef_NULL;
1060-
}
1059+
#endif
10611060

10621061
/* support for generator.throw() */
10631062
if (throwflag) {
@@ -1084,10 +1083,19 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10841083
stack_pointer = _PyFrame_GetStackPointer(frame);
10851084
#if Py_TAIL_CALL_INTERP
10861085
# if Py_STATS
1087-
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0, lastopcode);
1086+
PyObject *res = _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0, lastopcode);
10881087
# else
1089-
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0);
1088+
PyObject *res = _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0);
1089+
# endif
1090+
# ifdef _Py_TIER2
1091+
_PyStackRef executor = entry.frame.localsplus[0];
1092+
assert(tstate->current_executor == NULL);
1093+
if (!PyStackRef_IsNull(executor)) {
1094+
tstate->current_executor = PyStackRef_AsPyObjectBorrow(executor);
1095+
PyStackRef_CLOSE(executor);
1096+
}
10901097
# endif
1098+
return res;
10911099
#else
10921100
goto error;
10931101
#endif

Python/generated_cases.c.h

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ uop_dealloc(PyObject *op) {
267267
_PyObject_GC_UNTRACK(self);
268268
assert(self->vm_data.code == NULL);
269269
unlink_executor(self);
270+
// Once unlinked it becomes impossible to invalidate an executor, so do it here.
271+
self->vm_data.valid = 0;
270272
add_to_pending_deletion_list(self);
271273
}
272274

0 commit comments

Comments
 (0)