Skip to content

Commit 8014514

Browse files
committed
Revert "pythongh-128563: Move labels in ceval.c to bytecodes.c (pythonGH-129112)"
This reverts commit 87fb8b1.
1 parent 99ed302 commit 8014514

File tree

9 files changed

+145
-435
lines changed

9 files changed

+145
-435
lines changed

Lib/test/test_generated_cases.py

Lines changed: 6 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,12 @@ def run_cases_test(self, input: str, expected: str):
281281
)
282282

283283
with open(self.temp_output_filename) as temp_output:
284-
lines = temp_output.read()
285-
_, rest = lines.split(tier1_generator.INSTRUCTION_START_MARKER)
286-
instructions, labels_with_prelude_and_postlude = rest.split(tier1_generator.INSTRUCTION_END_MARKER)
287-
_, labels_with_postlude = labels_with_prelude_and_postlude.split(tier1_generator.LABEL_START_MARKER)
288-
labels, _ = labels_with_postlude.split(tier1_generator.LABEL_END_MARKER)
289-
actual = instructions + labels
284+
lines = temp_output.readlines()
285+
while lines and lines[0].startswith(("// ", "#", " #", "\n")):
286+
lines.pop(0)
287+
while lines and lines[-1].startswith(("#", "\n")):
288+
lines.pop(-1)
289+
actual = "".join(lines)
290290
# if actual.strip() != expected.strip():
291291
# print("Actual:")
292292
# print(actual)
@@ -1756,61 +1756,6 @@ def test_kill_in_wrong_order(self):
17561756
with self.assertRaises(SyntaxError):
17571757
self.run_cases_test(input, "")
17581758

1759-
def test_complex_label(self):
1760-
input = """
1761-
label(my_label) {
1762-
// Comment
1763-
do_thing()
1764-
if (complex) {
1765-
goto other_label;
1766-
}
1767-
goto other_label2;
1768-
}
1769-
"""
1770-
1771-
output = """
1772-
my_label:
1773-
{
1774-
// Comment
1775-
do_thing()
1776-
if (complex) {
1777-
goto other_label;
1778-
}
1779-
goto other_label2;
1780-
}
1781-
"""
1782-
self.run_cases_test(input, output)
1783-
1784-
def test_multiple_labels(self):
1785-
input = """
1786-
label(my_label_1) {
1787-
// Comment
1788-
do_thing1();
1789-
goto my_label_2;
1790-
}
1791-
1792-
label(my_label_2) {
1793-
// Comment
1794-
do_thing2();
1795-
goto my_label_3;
1796-
}
1797-
"""
1798-
1799-
output = """
1800-
my_label_1:
1801-
{
1802-
// Comment
1803-
do_thing1();
1804-
goto my_label_2;
1805-
}
1806-
1807-
my_label_2:
1808-
{
1809-
// Comment
1810-
do_thing2();
1811-
goto my_label_3;
1812-
}
1813-
"""
18141759

18151760
class TestGeneratedAbstractCases(unittest.TestCase):
18161761
def setUp(self) -> None:

Python/bytecodes.c

Lines changed: 1 addition & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
#define super(name) static int SUPER_##name
5454
#define family(name, ...) static int family_##name
5555
#define pseudo(name) static int pseudo_##name
56-
#define label(name) name:
5756

5857
/* Annotations */
5958
#define guard
@@ -104,6 +103,7 @@ dummy_func(
104103
PyObject *codeobj;
105104
PyObject *cond;
106105
PyObject *descr;
106+
_PyInterpreterFrame entry_frame;
107107
PyObject *exc;
108108
PyObject *exit;
109109
PyObject *fget;
@@ -5192,125 +5192,6 @@ dummy_func(
51925192
assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version));
51935193
}
51945194

5195-
label(pop_4_error) {
5196-
STACK_SHRINK(1);
5197-
goto pop_3_error;
5198-
}
5199-
5200-
label(pop_3_error) {
5201-
STACK_SHRINK(1);
5202-
goto pop_2_error;
5203-
}
5204-
5205-
label(pop_2_error) {
5206-
STACK_SHRINK(1);
5207-
goto pop_1_error;
5208-
}
5209-
5210-
label(pop_1_error) {
5211-
STACK_SHRINK(1);
5212-
goto error;
5213-
}
5214-
5215-
label(error) {
5216-
/* Double-check exception status. */
5217-
#ifdef NDEBUG
5218-
if (!_PyErr_Occurred(tstate)) {
5219-
_PyErr_SetString(tstate, PyExc_SystemError,
5220-
"error return without exception set");
5221-
}
5222-
#else
5223-
assert(_PyErr_Occurred(tstate));
5224-
#endif
5225-
5226-
/* Log traceback info. */
5227-
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
5228-
if (!_PyFrame_IsIncomplete(frame)) {
5229-
PyFrameObject *f = _PyFrame_GetFrameObject(frame);
5230-
if (f != NULL) {
5231-
PyTraceBack_Here(f);
5232-
}
5233-
}
5234-
_PyEval_MonitorRaise(tstate, frame, next_instr-1);
5235-
goto exception_unwind;
5236-
}
5237-
5238-
label(exception_unwind) {
5239-
/* We can't use frame->instr_ptr here, as RERAISE may have set it */
5240-
int offset = INSTR_OFFSET()-1;
5241-
int level, handler, lasti;
5242-
if (get_exception_handler(_PyFrame_GetCode(frame), offset, &level, &handler, &lasti) == 0) {
5243-
// No handlers, so exit.
5244-
assert(_PyErr_Occurred(tstate));
5245-
5246-
/* Pop remaining stack entries. */
5247-
_PyStackRef *stackbase = _PyFrame_Stackbase(frame);
5248-
while (stack_pointer > stackbase) {
5249-
PyStackRef_XCLOSE(POP());
5250-
}
5251-
assert(STACK_LEVEL() == 0);
5252-
_PyFrame_SetStackPointer(frame, stack_pointer);
5253-
monitor_unwind(tstate, frame, next_instr-1);
5254-
goto exit_unwind;
5255-
}
5256-
5257-
assert(STACK_LEVEL() >= level);
5258-
_PyStackRef *new_top = _PyFrame_Stackbase(frame) + level;
5259-
while (stack_pointer > new_top) {
5260-
PyStackRef_XCLOSE(POP());
5261-
}
5262-
if (lasti) {
5263-
int frame_lasti = _PyInterpreterFrame_LASTI(frame);
5264-
PyObject *lasti = PyLong_FromLong(frame_lasti);
5265-
if (lasti == NULL) {
5266-
goto exception_unwind;
5267-
}
5268-
PUSH(PyStackRef_FromPyObjectSteal(lasti));
5269-
}
5270-
5271-
/* Make the raw exception data
5272-
available to the handler,
5273-
so a program can emulate the
5274-
Python main loop. */
5275-
PyObject *exc = _PyErr_GetRaisedException(tstate);
5276-
PUSH(PyStackRef_FromPyObjectSteal(exc));
5277-
next_instr = _PyFrame_GetBytecode(frame) + handler;
5278-
5279-
if (monitor_handled(tstate, frame, next_instr, exc) < 0) {
5280-
goto exception_unwind;
5281-
}
5282-
/* Resume normal execution */
5283-
#ifdef LLTRACE
5284-
if (frame->lltrace >= 5) {
5285-
lltrace_resume_frame(frame);
5286-
}
5287-
#endif
5288-
DISPATCH();
5289-
}
5290-
5291-
label(exit_unwind) {
5292-
assert(_PyErr_Occurred(tstate));
5293-
_Py_LeaveRecursiveCallPy(tstate);
5294-
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
5295-
// GH-99729: We need to unlink the frame *before* clearing it:
5296-
_PyInterpreterFrame *dying = frame;
5297-
frame = tstate->current_frame = dying->previous;
5298-
_PyEval_FrameClearAndPop(tstate, dying);
5299-
frame->return_offset = 0;
5300-
if (frame->owner == FRAME_OWNED_BY_INTERPRETER) {
5301-
/* Restore previous frame and exit */
5302-
tstate->current_frame = frame->previous;
5303-
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;
5304-
return NULL;
5305-
}
5306-
goto resume_with_error;
5307-
}
5308-
5309-
label(resume_with_error) {
5310-
next_instr = frame->instr_ptr;
5311-
stack_pointer = _PyFrame_GetStackPointer(frame);
5312-
goto error;
5313-
}
53145195
// END BYTECODES //
53155196

53165197
}

Python/ceval.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,9 +882,143 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
882882

883883
DISPATCH();
884884

885+
{
886+
/* Start instructions */
887+
#if !USE_COMPUTED_GOTOS
888+
dispatch_opcode:
889+
switch (opcode)
890+
#endif
891+
{
892+
885893
#include "generated_cases.c.h"
886894

887895

896+
#if USE_COMPUTED_GOTOS
897+
_unknown_opcode:
898+
#else
899+
EXTRA_CASES // From pycore_opcode_metadata.h, a 'case' for each unused opcode
900+
#endif
901+
/* Tell C compilers not to hold the opcode variable in the loop.
902+
next_instr points the current instruction without TARGET(). */
903+
opcode = next_instr->op.code;
904+
_PyErr_Format(tstate, PyExc_SystemError,
905+
"%U:%d: unknown opcode %d",
906+
_PyFrame_GetCode(frame)->co_filename,
907+
PyUnstable_InterpreterFrame_GetLine(frame),
908+
opcode);
909+
goto error;
910+
911+
} /* End instructions */
912+
913+
/* This should never be reached. Every opcode should end with DISPATCH()
914+
or goto error. */
915+
Py_UNREACHABLE();
916+
917+
pop_4_error:
918+
STACK_SHRINK(1);
919+
pop_3_error:
920+
STACK_SHRINK(1);
921+
pop_2_error:
922+
STACK_SHRINK(1);
923+
pop_1_error:
924+
STACK_SHRINK(1);
925+
error:
926+
/* Double-check exception status. */
927+
#ifdef NDEBUG
928+
if (!_PyErr_Occurred(tstate)) {
929+
_PyErr_SetString(tstate, PyExc_SystemError,
930+
"error return without exception set");
931+
}
932+
#else
933+
assert(_PyErr_Occurred(tstate));
934+
#endif
935+
936+
/* Log traceback info. */
937+
assert(frame != &entry_frame);
938+
if (!_PyFrame_IsIncomplete(frame)) {
939+
PyFrameObject *f = _PyFrame_GetFrameObject(frame);
940+
if (f != NULL) {
941+
PyTraceBack_Here(f);
942+
}
943+
}
944+
_PyEval_MonitorRaise(tstate, frame, next_instr-1);
945+
exception_unwind:
946+
{
947+
/* We can't use frame->instr_ptr here, as RERAISE may have set it */
948+
int offset = INSTR_OFFSET()-1;
949+
int level, handler, lasti;
950+
if (get_exception_handler(_PyFrame_GetCode(frame), offset, &level, &handler, &lasti) == 0) {
951+
// No handlers, so exit.
952+
assert(_PyErr_Occurred(tstate));
953+
954+
/* Pop remaining stack entries. */
955+
_PyStackRef *stackbase = _PyFrame_Stackbase(frame);
956+
while (stack_pointer > stackbase) {
957+
PyStackRef_XCLOSE(POP());
958+
}
959+
assert(STACK_LEVEL() == 0);
960+
_PyFrame_SetStackPointer(frame, stack_pointer);
961+
monitor_unwind(tstate, frame, next_instr-1);
962+
goto exit_unwind;
963+
}
964+
965+
assert(STACK_LEVEL() >= level);
966+
_PyStackRef *new_top = _PyFrame_Stackbase(frame) + level;
967+
while (stack_pointer > new_top) {
968+
PyStackRef_XCLOSE(POP());
969+
}
970+
if (lasti) {
971+
int frame_lasti = _PyInterpreterFrame_LASTI(frame);
972+
PyObject *lasti = PyLong_FromLong(frame_lasti);
973+
if (lasti == NULL) {
974+
goto exception_unwind;
975+
}
976+
PUSH(PyStackRef_FromPyObjectSteal(lasti));
977+
}
978+
979+
/* Make the raw exception data
980+
available to the handler,
981+
so a program can emulate the
982+
Python main loop. */
983+
PyObject *exc = _PyErr_GetRaisedException(tstate);
984+
PUSH(PyStackRef_FromPyObjectSteal(exc));
985+
next_instr = _PyFrame_GetBytecode(frame) + handler;
986+
987+
if (monitor_handled(tstate, frame, next_instr, exc) < 0) {
988+
goto exception_unwind;
989+
}
990+
/* Resume normal execution */
991+
#ifdef LLTRACE
992+
if (frame->lltrace >= 5) {
993+
lltrace_resume_frame(frame);
994+
}
995+
#endif
996+
DISPATCH();
997+
}
998+
}
999+
1000+
exit_unwind:
1001+
assert(_PyErr_Occurred(tstate));
1002+
_Py_LeaveRecursiveCallPy(tstate);
1003+
assert(frame != &entry_frame);
1004+
// GH-99729: We need to unlink the frame *before* clearing it:
1005+
_PyInterpreterFrame *dying = frame;
1006+
frame = tstate->current_frame = dying->previous;
1007+
_PyEval_FrameClearAndPop(tstate, dying);
1008+
frame->return_offset = 0;
1009+
if (frame == &entry_frame) {
1010+
/* Restore previous frame and exit */
1011+
tstate->current_frame = frame->previous;
1012+
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;
1013+
return NULL;
1014+
}
1015+
1016+
resume_with_error:
1017+
next_instr = frame->instr_ptr;
1018+
stack_pointer = _PyFrame_GetStackPointer(frame);
1019+
goto error;
1020+
1021+
8881022
#ifdef _Py_TIER2
8891023

8901024
// Tier 2 is also here!

0 commit comments

Comments
 (0)