forked from python/cpython
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
24df49f
commit bd97afa
Showing
4 changed files
with
173 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// This file is generated by Tools/cases_generator/tier1_tail_call_generator.py | ||
// from: | ||
// Python/bytecodes.c | ||
// Do not edit! | ||
|
||
#ifndef Py_TAIL_CALL_INTERP | ||
#error "This file is for tail-calling interpreter only." | ||
#endif | ||
#define TIER_ONE 1 | ||
|
||
error: | ||
{ | ||
/* Double-check exception status. */ | ||
#ifdef NDEBUG | ||
if (!_PyErr_Occurred(tstate)) { | ||
_PyErr_SetString(tstate, PyExc_SystemError, | ||
"error return without exception set"); | ||
} | ||
#else | ||
assert(_PyErr_Occurred(tstate)); | ||
#endif | ||
|
||
/* Log traceback info. */ | ||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); | ||
if (!_PyFrame_IsIncomplete(frame)) { | ||
PyFrameObject *f = _PyFrame_GetFrameObject(frame); | ||
if (f != NULL) { | ||
PyTraceBack_Here(f); | ||
} | ||
} | ||
_PyEval_MonitorRaise(tstate, frame, next_instr-1); | ||
goto exception_unwind; | ||
} | ||
|
||
exception_unwind: | ||
{ | ||
/* We can't use frame->instr_ptr here, as RERAISE may have set it */ | ||
int offset = INSTR_OFFSET()-1; | ||
int level, handler, lasti; | ||
if (get_exception_handler(_PyFrame_GetCode(frame), offset, &level, &handler, &lasti) == 0) { | ||
// No handlers, so exit. | ||
assert(_PyErr_Occurred(tstate)); | ||
/* Pop remaining stack entries. */ | ||
_PyStackRef *stackbase = _PyFrame_Stackbase(frame); | ||
while (stack_pointer > stackbase) { | ||
PyStackRef_XCLOSE(POP()); | ||
} | ||
assert(STACK_LEVEL() == 0); | ||
_PyFrame_SetStackPointer(frame, stack_pointer); | ||
monitor_unwind(tstate, frame, next_instr-1); | ||
goto exit_unwind; | ||
} | ||
assert(STACK_LEVEL() >= level); | ||
_PyStackRef *new_top = _PyFrame_Stackbase(frame) + level; | ||
while (stack_pointer > new_top) { | ||
PyStackRef_XCLOSE(POP()); | ||
} | ||
if (lasti) { | ||
int frame_lasti = _PyInterpreterFrame_LASTI(frame); | ||
PyObject *lasti = PyLong_FromLong(frame_lasti); | ||
if (lasti == NULL) { | ||
goto exception_unwind; | ||
} | ||
PUSH(PyStackRef_FromPyObjectSteal(lasti)); | ||
} | ||
/* Make the raw exception data | ||
available to the handler, | ||
so a program can emulate the | ||
Python main loop. */ | ||
PyObject *exc = _PyErr_GetRaisedException(tstate); | ||
PUSH(PyStackRef_FromPyObjectSteal(exc)); | ||
next_instr = _PyFrame_GetBytecode(frame) + handler; | ||
if (monitor_handled(tstate, frame, next_instr, exc) < 0) { | ||
goto exception_unwind; | ||
} | ||
/* Resume normal execution */ | ||
#ifdef LLTRACE | ||
if (frame->lltrace >= 5) { | ||
lltrace_resume_frame(frame); | ||
} | ||
#endif | ||
_TAIL_CALL_entry(frame, stack_pointer, tstate, next_instr, 0, 0); | ||
; | ||
} | ||
|
||
exit_unwind: | ||
{ | ||
assert(_PyErr_Occurred(tstate)); | ||
_Py_LeaveRecursiveCallPy(tstate); | ||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); | ||
// GH-99729: We need to unlink the frame *before* clearing it: | ||
_PyInterpreterFrame *dying = frame; | ||
frame = tstate->current_frame = dying->previous; | ||
_PyEval_FrameClearAndPop(tstate, dying); | ||
frame->return_offset = 0; | ||
if (frame->owner == FRAME_OWNED_BY_INTERPRETER) { | ||
/* Restore previous frame and exit */ | ||
tstate->current_frame = frame->previous; | ||
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; | ||
return NULL; | ||
} | ||
next_instr = frame->instr_ptr; | ||
stack_pointer = _PyFrame_GetStackPointer(frame); | ||
goto error; | ||
} | ||
|
||
#undef TIER_ONE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters