Skip to content

Commit 56c6349

Browse files
Fix tests, move entry_frame into frame
1 parent a27ee2d commit 56c6349

File tree

8 files changed

+74
-70
lines changed

8 files changed

+74
-70
lines changed

Include/internal/pycore_frame.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ typedef struct _PyInterpreterFrame {
7575
_PyStackRef *stackpointer;
7676
uint16_t return_offset; /* Only relevant during a function call */
7777
char owner;
78-
char visited;
78+
char visited:4;
79+
char is_entry_frame:4;
7980
/* Locals and stack */
8081
_PyStackRef localsplus[1];
8182
} _PyInterpreterFrame;
@@ -214,6 +215,8 @@ _PyFrame_Initialize(
214215
frame->localsplus[i] = PyStackRef_NULL;
215216
}
216217

218+
frame->is_entry_frame = 0;
219+
217220
#ifdef Py_GIL_DISABLED
218221
// On GIL disabled, we walk the entire stack in GC. Since stacktop
219222
// is not always in sync with the real stack pointer, we have
@@ -394,6 +397,8 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int
394397
frame->visited = 0;
395398
frame->return_offset = 0;
396399

400+
frame->is_entry_frame = 0;
401+
397402
#ifdef Py_GIL_DISABLED
398403
assert(code->co_nlocalsplus == 0);
399404
for (int i = 0; i < code->co_stacksize; i++) {

Lib/test/test_generated_cases.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ def test_error_if_plain(self):
538538
frame->instr_ptr = next_instr;
539539
next_instr += 1;
540540
INSTRUCTION_STATS(OP);
541-
if (cond) goto label;
541+
if (cond) CEVAL_GOTO(label);
542542
DISPATCH();
543543
}
544544
"""
@@ -555,7 +555,7 @@ def test_error_if_plain_with_comment(self):
555555
frame->instr_ptr = next_instr;
556556
next_instr += 1;
557557
INSTRUCTION_STATS(OP);
558-
if (cond) goto label;
558+
if (cond) CEVAL_GOTO(label);
559559
// Comment is ok
560560
DISPATCH();
561561
}
@@ -582,7 +582,7 @@ def test_error_if_pop(self):
582582
right = stack_pointer[-1];
583583
left = stack_pointer[-2];
584584
SPAM(left, right);
585-
if (cond) goto pop_2_label;
585+
if (cond) CEVAL_GOTO(pop_2_label);
586586
res = 0;
587587
stack_pointer[-2] = res;
588588
stack_pointer += -1;
@@ -611,7 +611,7 @@ def test_error_if_pop_with_result(self):
611611
right = stack_pointer[-1];
612612
left = stack_pointer[-2];
613613
res = SPAM(left, right);
614-
if (cond) goto pop_2_label;
614+
if (cond) CEVAL_GOTO(pop_2_label);
615615
stack_pointer[-2] = res;
616616
stack_pointer += -1;
617617
assert(WITHIN_STACK_BOUNDS());
@@ -929,7 +929,7 @@ def test_array_error_if(self):
929929
if (oparg == 0) {
930930
stack_pointer += -1 - oparg;
931931
assert(WITHIN_STACK_BOUNDS());
932-
goto somewhere;
932+
CEVAL_GOTO(somewhere);
933933
}
934934
stack_pointer += -1 - oparg;
935935
assert(WITHIN_STACK_BOUNDS());
@@ -1392,7 +1392,7 @@ def test_pop_on_error_peeks(self):
13921392
// THIRD
13931393
{
13941394
// Mark j and k as used
1395-
if (cond) goto pop_2_error;
1395+
if (cond) CEVAL_GOTO(pop_2_error);
13961396
}
13971397
stack_pointer += -2;
13981398
assert(WITHIN_STACK_BOUNDS());
@@ -1435,7 +1435,7 @@ def test_push_then_error(self):
14351435
stack_pointer[1] = b;
14361436
stack_pointer += 2;
14371437
assert(WITHIN_STACK_BOUNDS());
1438-
goto error;
1438+
CEVAL_GOTO(error);
14391439
}
14401440
}
14411441
stack_pointer[0] = a;
@@ -1462,14 +1462,14 @@ def test_error_if_true(self):
14621462
frame->instr_ptr = next_instr;
14631463
next_instr += 1;
14641464
INSTRUCTION_STATS(OP1);
1465-
goto here;
1465+
CEVAL_GOTO(here);
14661466
}
14671467
14681468
TARGET(OP2) {
14691469
frame->instr_ptr = next_instr;
14701470
next_instr += 1;
14711471
INSTRUCTION_STATS(OP2);
1472-
goto there;
1472+
CEVAL_GOTO(there);
14731473
}
14741474
"""
14751475
self.run_cases_test(input, output)

Python/bytecodes.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ dummy_func(
101101
PyObject *codeobj;
102102
PyObject *cond;
103103
PyObject *descr;
104-
_PyInterpreterFrame entry_frame;
105104
PyObject *exc;
106105
PyObject *exit;
107106
PyObject *fget;
@@ -1018,7 +1017,7 @@ dummy_func(
10181017
}
10191018

10201019
tier1 inst(INTERPRETER_EXIT, (retval --)) {
1021-
assert(frame == entry_frame);
1020+
assert(frame->is_entry_frame);
10221021
assert(_PyFrame_IsIncomplete(frame));
10231022
/* Restore previous frame and return. */
10241023
tstate->current_frame = frame->previous;
@@ -1034,7 +1033,7 @@ dummy_func(
10341033
// is pushed to a different frame, the callers' frame.
10351034
inst(RETURN_VALUE, (retval -- res)) {
10361035
#if TIER_ONE
1037-
assert(frame != entry_frame);
1036+
assert(!frame->is_entry_frame);
10381037
#endif
10391038
_PyStackRef temp = retval;
10401039
DEAD(retval);
@@ -1133,7 +1132,7 @@ dummy_func(
11331132
PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
11341133

11351134
PyObject *retval_o;
1136-
assert(frame != entry_frame);
1135+
assert(!frame->is_entry_frame);
11371136
if ((tstate->interp->eval_frame == NULL) &&
11381137
(Py_TYPE(receiver_o) == &PyGen_Type || Py_TYPE(receiver_o) == &PyCoro_Type) &&
11391138
((PyGenObject *)receiver_o)->gi_frame_state < FRAME_EXECUTING)
@@ -1207,7 +1206,7 @@ dummy_func(
12071206
// The compiler treats any exception raised here as a failed close()
12081207
// or throw() call.
12091208
#if TIER_ONE
1210-
assert(frame != entry_frame);
1209+
assert(!frame->is_entry_frame);
12111210
#endif
12121211
frame->instr_ptr++;
12131212
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);

Python/ceval.c

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,12 @@ lltrace_resume_frame(_PyInterpreterFrame *frame)
229229
}
230230

231231
static int
232-
maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, _PyInterpreterFrame *skip_frame, PyObject *globals)
232+
maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, PyObject *globals)
233233
{
234234
if (globals == NULL) {
235235
return 0;
236236
}
237-
if (frame == skip_frame) {
237+
if (frame->is_entry_frame) {
238238
return 0;
239239
}
240240
int r = PyDict_Contains(globals, &_Py_ID(__lltrace__));
@@ -787,9 +787,9 @@ static inline PyObject *_TAIL_CALL_shim(TAIL_CALL_PARAMS)
787787
{
788788
opcode = next_instr->op.code;
789789
#ifdef LLTRACE
790-
return (INSTRUCTION_TABLE[opcode])(frame, stack_pointer, tstate, next_instr, opcode, next_instr->op.arg, entry_frame, lltrace);
790+
return (INSTRUCTION_TABLE[opcode])(frame, stack_pointer, tstate, next_instr, opcode, next_instr->op.arg, lltrace);
791791
#else
792-
return (INSTRUCTION_TABLE[opcode])(frame, stack_pointer, tstate, next_instr, opcode, next_instr->op.arg, entry_frame);
792+
return (INSTRUCTION_TABLE[opcode])(frame, stack_pointer, tstate, next_instr, opcode, next_instr->op.arg);
793793
#endif
794794
}
795795
#endif
@@ -816,28 +816,28 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
816816
int lltrace = 0;
817817
#endif
818818

819-
_PyInterpreterFrame entry_f;
820-
_PyInterpreterFrame *entry_frame = &entry_f;
819+
_PyInterpreterFrame entry_frame;
821820

822821

823822

824823
#if defined(Py_DEBUG) && !defined(Py_STACKREF_DEBUG)
825824
/* Set these to invalid but identifiable values for debugging. */
826-
entry_f.f_funcobj = (_PyStackRef){.bits = 0xaaa0};
827-
entry_f.f_locals = (PyObject*)0xaaa1;
828-
entry_f.frame_obj = (PyFrameObject*)0xaaa2;
829-
entry_f.f_globals = (PyObject*)0xaaa3;
830-
entry_f.f_builtins = (PyObject*)0xaaa4;
825+
entry_frame.f_funcobj = (_PyStackRef){.bits = 0xaaa0};
826+
entry_frame.f_locals = (PyObject*)0xaaa1;
827+
entry_frame.frame_obj = (PyFrameObject*)0xaaa2;
828+
entry_frame.f_globals = (PyObject*)0xaaa3;
829+
entry_frame.f_builtins = (PyObject*)0xaaa4;
831830
#endif
832-
entry_f.f_executable = PyStackRef_None;
833-
entry_f.instr_ptr = (_Py_CODEUNIT *)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS + 1;
834-
entry_f.stackpointer = entry_f.localsplus;
835-
entry_f.owner = FRAME_OWNED_BY_CSTACK;
836-
entry_f.visited = 0;
837-
entry_f.return_offset = 0;
831+
entry_frame.f_executable = PyStackRef_None;
832+
entry_frame.instr_ptr = (_Py_CODEUNIT *)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS + 1;
833+
entry_frame.stackpointer = entry_frame.localsplus;
834+
entry_frame.owner = FRAME_OWNED_BY_CSTACK;
835+
entry_frame.visited = 0;
836+
entry_frame.return_offset = 0;
838837
/* Push frame */
839-
entry_f.previous = tstate->current_frame;
840-
frame->previous = entry_frame;
838+
entry_frame.previous = tstate->current_frame;
839+
entry_frame.is_entry_frame = 1;
840+
frame->previous = &entry_frame;
841841
tstate->current_frame = frame;
842842

843843
tstate->c_recursion_remaining -= (PY_EVAL_C_STACK_UNITS - 1);
@@ -894,7 +894,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
894894
stack_pointer = _PyFrame_GetStackPointer(frame);
895895

896896
#ifdef LLTRACE
897-
lltrace = maybe_lltrace_resume_frame(frame, entry_frame, GLOBALS());
897+
lltrace = maybe_lltrace_resume_frame(frame, GLOBALS());
898898
if (lltrace < 0) {
899899
goto exit_unwind;
900900
}
@@ -909,9 +909,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
909909

910910
#ifdef Py_TAIL_CALL_INTERP
911911
#ifdef LLTRACE
912-
return _TAIL_CALL_shim(frame, stack_pointer, tstate, next_instr, 0, 0, entry_frame, lltrace);
912+
return _TAIL_CALL_shim(frame, stack_pointer, tstate, next_instr, 0, 0, lltrace);
913913
#else
914-
return _TAIL_CALL_shim(frame, stack_pointer, tstate, next_instr, 0, 0, entry_frame);
914+
return _TAIL_CALL_shim(frame, stack_pointer, tstate, next_instr, 0, 0);
915915
#endif
916916
#else
917917
DISPATCH();
@@ -968,7 +968,7 @@ TAIL_CALL_TARGET(error):
968968
#endif
969969

970970
/* Log traceback info. */
971-
assert(frame != entry_frame);
971+
assert(!frame->is_entry_frame);
972972
if (!_PyFrame_IsIncomplete(frame)) {
973973
PyFrameObject *f = _PyFrame_GetFrameObject(frame);
974974
if (f != NULL) {
@@ -1033,9 +1033,9 @@ TAIL_CALL_TARGET(exception_unwind):
10331033
DISPATCH();
10341034
# else
10351035
# ifdef LLTRACE
1036-
return _TAIL_CALL_shim(frame, stack_pointer, tstate, next_instr, 0, 0, entry_frame, lltrace);
1036+
return _TAIL_CALL_shim(frame, stack_pointer, tstate, next_instr, 0, 0, lltrace);
10371037
# else
1038-
return _TAIL_CALL_shim(frame, stack_pointer, tstate, next_instr, 0, 0, entry_frame);
1038+
return _TAIL_CALL_shim(frame, stack_pointer, tstate, next_instr, 0, 0);
10391039
# endif
10401040
# endif
10411041
#else
@@ -1046,13 +1046,13 @@ TAIL_CALL_TARGET(exception_unwind):
10461046
TAIL_CALL_TARGET(exit_unwind):
10471047
assert(_PyErr_Occurred(tstate));
10481048
_Py_LeaveRecursiveCallPy(tstate);
1049-
assert(frame != entry_frame);
1049+
assert(!frame->is_entry_frame);
10501050
// GH-99729: We need to unlink the frame *before* clearing it:
10511051
_PyInterpreterFrame *dying = frame;
10521052
frame = tstate->current_frame = dying->previous;
10531053
_PyEval_FrameClearAndPop(tstate, dying);
10541054
frame->return_offset = 0;
1055-
if (frame == entry_frame) {
1055+
if (frame->is_entry_frame) {
10561056
/* Restore previous frame and exit */
10571057
tstate->current_frame = frame->previous;
10581058
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;

Python/ceval_macros.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@
7171
#endif
7272

7373
#ifdef LLTRACE
74-
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int opcode, int oparg, _PyInterpreterFrame *entry_frame, int lltrace
75-
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, opcode, oparg, entry_frame, lltrace
74+
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int opcode, int oparg, int lltrace
75+
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, opcode, oparg, lltrace
7676
#else
77-
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int opcode, int oparg, _PyInterpreterFrame *entry_frame
78-
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, opcode, oparg, entry_frame
77+
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int opcode, int oparg
78+
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, opcode, oparg
7979
#endif
8080

8181
#ifdef Py_TAIL_CALL_INTERP
@@ -116,7 +116,7 @@
116116
#if LLTRACE
117117
#define LLTRACE_RESUME_FRAME() \
118118
do { \
119-
lltrace = maybe_lltrace_resume_frame(frame, entry_frame, GLOBALS()); \
119+
lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); \
120120
if (lltrace < 0) { \
121121
CEVAL_GOTO(exit_unwind); \
122122
} \
@@ -162,7 +162,7 @@ do { \
162162
} \
163163
next_instr = frame->instr_ptr; \
164164
stack_pointer = _PyFrame_GetStackPointer(frame); \
165-
lltrace = maybe_lltrace_resume_frame(frame, entry_frame, GLOBALS()); \
165+
lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); \
166166
if (lltrace < 0) { \
167167
CEVAL_GOTO(exit_unwind); \
168168
} \
@@ -307,7 +307,7 @@ GETITEM(PyObject *v, Py_ssize_t i) {
307307
#endif
308308

309309
#define WITHIN_STACK_BOUNDS() \
310-
(frame == entry_frame || (STACK_LEVEL() >= 0 && STACK_LEVEL() <= STACK_SIZE()))
310+
(frame->is_entry_frame || (STACK_LEVEL() >= 0 && STACK_LEVEL() <= STACK_SIZE()))
311311

312312
/* Data access macros */
313313
#define FRAME_CO_CONSTS (_PyFrame_GetCode(frame)->co_consts)
@@ -331,12 +331,12 @@ GETITEM(PyObject *v, Py_ssize_t i) {
331331
#ifdef LLTRACE
332332
#define GO_TO_INSTRUCTION(op) do { \
333333
Py_MUSTTAIL \
334-
return (INSTRUCTION_TABLE[op])(frame, stack_pointer, tstate, next_instr - 1 - _PyOpcode_Caches[_PyOpcode_Deopt[op]], opcode, oparg, entry_frame, lltrace); \
334+
return (INSTRUCTION_TABLE[op])(frame, stack_pointer, tstate, next_instr - 1 - _PyOpcode_Caches[_PyOpcode_Deopt[op]], opcode, oparg, lltrace); \
335335
} while (0)
336336
#else
337337
#define GO_TO_INSTRUCTION(op) do { \
338338
Py_MUSTTAIL \
339-
return (INSTRUCTION_TABLE[op])(frame, stack_pointer, tstate, next_instr - 1 - _PyOpcode_Caches[_PyOpcode_Deopt[op]], opcode, oparg, entry_frame); \
339+
return (INSTRUCTION_TABLE[op])(frame, stack_pointer, tstate, next_instr - 1 - _PyOpcode_Caches[_PyOpcode_Deopt[op]], opcode, oparg); \
340340
} while (0)
341341
#endif
342342
#else

Python/executor_cases.c.h

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

0 commit comments

Comments
 (0)