mirror of
https://github.com/python/cpython.git
synced 2025-10-17 12:18:23 +00:00
gh-128563: Move labels in ceval.c to bytecodes.c (GH-129112)
This commit is contained in:
parent
7d275611f6
commit
87fb8b198c
9 changed files with 435 additions and 145 deletions
156
Python/generated_cases.c.h
generated
156
Python/generated_cases.c.h
generated
|
@ -8,6 +8,13 @@
|
|||
#endif
|
||||
#define TIER_ONE 1
|
||||
|
||||
#if !USE_COMPUTED_GOTOS
|
||||
dispatch_opcode:
|
||||
switch (opcode)
|
||||
#endif
|
||||
{
|
||||
/* BEGIN INSTRUCTIONS */
|
||||
|
||||
|
||||
TARGET(BINARY_OP) {
|
||||
frame->instr_ptr = next_instr;
|
||||
|
@ -8421,4 +8428,153 @@
|
|||
assert(WITHIN_STACK_BOUNDS());
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
/* END INSTRUCTIONS */
|
||||
#if USE_COMPUTED_GOTOS
|
||||
_unknown_opcode:
|
||||
#else
|
||||
EXTRA_CASES // From pycore_opcode_metadata.h, a 'case' for each unused opcode
|
||||
#endif
|
||||
/* Tell C compilers not to hold the opcode variable in the loop.
|
||||
next_instr points the current instruction without TARGET(). */
|
||||
opcode = next_instr->op.code;
|
||||
_PyErr_Format(tstate, PyExc_SystemError,
|
||||
"%U:%d: unknown opcode %d",
|
||||
_PyFrame_GetCode(frame)->co_filename,
|
||||
PyUnstable_InterpreterFrame_GetLine(frame),
|
||||
opcode);
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
/* This should never be reached. Every opcode should end with DISPATCH()
|
||||
or goto error. */
|
||||
Py_UNREACHABLE();
|
||||
/* BEGIN LABELS */
|
||||
|
||||
pop_4_error:
|
||||
{
|
||||
STACK_SHRINK(1);
|
||||
goto pop_3_error;
|
||||
}
|
||||
|
||||
pop_3_error:
|
||||
{
|
||||
STACK_SHRINK(1);
|
||||
goto pop_2_error;
|
||||
}
|
||||
|
||||
pop_2_error:
|
||||
{
|
||||
STACK_SHRINK(1);
|
||||
goto pop_1_error;
|
||||
}
|
||||
|
||||
pop_1_error:
|
||||
{
|
||||
STACK_SHRINK(1);
|
||||
goto error;
|
||||
}
|
||||
|
||||
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
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
goto resume_with_error;
|
||||
}
|
||||
|
||||
resume_with_error:
|
||||
{
|
||||
next_instr = frame->instr_ptr;
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* END LABELS */
|
||||
#undef TIER_ONE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue