GH-131498: Cases generator: manage stacks automatically (GH-132074)

This commit is contained in:
Mark Shannon 2025-04-04 17:59:36 +01:00 committed by GitHub
parent 305be5fb1a
commit 7099c75550
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 216 additions and 251 deletions

View file

@ -204,7 +204,7 @@ dummy_func(
ptrdiff_t off = this_instr - _PyFrame_GetBytecode(frame);
frame->tlbc_index = ((_PyThreadStateImpl *)tstate)->tlbc_index;
frame->instr_ptr = bytecode + off;
// Make sure this_instr gets reset correctley for any uops that
// Make sure this_instr gets reset correctly for any uops that
// follow
next_instr = frame->instr_ptr;
DISPATCH();
@ -1111,7 +1111,7 @@ dummy_func(
tstate->current_frame = frame->previous;
assert(!_PyErr_Occurred(tstate));
PyObject *result = PyStackRef_AsPyObjectSteal(retval);
SYNC_SP(); /* Not strictly necessary, but prevents warnings */
LLTRACE_RESUME_FRAME();
return result;
}
@ -1123,7 +1123,7 @@ dummy_func(
_PyStackRef temp = PyStackRef_MakeHeapSafe(retval);
DEAD(retval);
SAVE_STACK();
assert(EMPTY());
assert(STACK_LEVEL() == 0);
_Py_LeaveRecursiveCallPy(tstate);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
@ -1223,8 +1223,9 @@ dummy_func(
{
PyGenObject *gen = (PyGenObject *)receiver_o;
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
STACK_SHRINK(1);
_PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v));
DEAD(v);
SYNC_SP();
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
@ -2436,10 +2437,10 @@ dummy_func(
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(
tstate, PyStackRef_FromPyObjectNew(f), 2, frame);
// Manipulate stack directly because we exit with DISPATCH_INLINED().
STACK_SHRINK(1);
new_frame->localsplus[0] = owner;
DEAD(owner);
// Manipulate stack directly because we exit with DISPATCH_INLINED().
SYNC_SP();
new_frame->localsplus[1] = PyStackRef_FromPyObjectNew(name);
frame->return_offset = INSTRUCTION_SIZE;
DISPATCH_INLINED(new_frame);
@ -3083,12 +3084,11 @@ dummy_func(
macro(FOR_ITER) = _SPECIALIZE_FOR_ITER + _FOR_ITER;
inst(INSTRUMENTED_FOR_ITER, (unused/1 -- )) {
_PyStackRef iter_stackref = TOP();
PyObject *iter = PyStackRef_AsPyObjectBorrow(iter_stackref);
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
if (next != NULL) {
PUSH(PyStackRef_FromPyObjectSteal(next));
inst(INSTRUMENTED_FOR_ITER, (unused/1, iter -- iter, next)) {
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
PyObject *next_o = (*Py_TYPE(iter_o)->tp_iternext)(iter_o);
if (next_o != NULL) {
next = PyStackRef_FromPyObjectSteal(next_o);
INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
}
else {
@ -3105,6 +3105,7 @@ dummy_func(
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
/* Skip END_FOR */
JUMPBY(oparg + 1);
DISPATCH();
}
}
@ -4022,7 +4023,6 @@ dummy_func(
_PUSH_FRAME;
inst(EXIT_INIT_CHECK, (should_be_none -- )) {
assert(STACK_LEVEL() == 2);
if (!PyStackRef_IsNone(should_be_none)) {
PyErr_Format(PyExc_TypeError,
"__init__() should return None, not '%.200s'",
@ -4813,7 +4813,7 @@ dummy_func(
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
ERROR_IF(gen == NULL, error);
assert(EMPTY());
assert(STACK_LEVEL() == 0);
SAVE_STACK();
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
frame->instr_ptr++;
@ -4932,6 +4932,7 @@ dummy_func(
}
next_instr = frame->instr_ptr;
if (next_instr != this_instr) {
SYNC_SP();
DISPATCH();
}
}
@ -4976,46 +4977,48 @@ dummy_func(
_CHECK_PERIODIC +
_MONITOR_JUMP_BACKWARD;
inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
_PyStackRef cond = POP();
inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1, cond -- )) {
assert(PyStackRef_BoolCheck(cond));
int jump = PyStackRef_IsTrue(cond);
DEAD(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
if (jump) {
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
}
inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1 -- )) {
_PyStackRef cond = POP();
inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1, cond -- )) {
assert(PyStackRef_BoolCheck(cond));
int jump = PyStackRef_IsFalse(cond);
DEAD(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
if (jump) {
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
}
inst(INSTRUMENTED_POP_JUMP_IF_NONE, (unused/1 -- )) {
_PyStackRef value_stackref = POP();
int jump = PyStackRef_IsNone(value_stackref);
inst(INSTRUMENTED_POP_JUMP_IF_NONE, (unused/1, value -- )) {
int jump = PyStackRef_IsNone(value);
RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
if (jump) {
DEAD(value);
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
else {
PyStackRef_CLOSE(value_stackref);
PyStackRef_CLOSE(value);
}
}
inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, (unused/1 -- )) {
_PyStackRef value_stackref = POP();
int jump = !PyStackRef_IsNone(value_stackref);
inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, (unused/1, value -- )) {
int jump = !PyStackRef_IsNone(value);
RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
if (jump) {
PyStackRef_CLOSE(value_stackref);
PyStackRef_CLOSE(value);
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
else {
DEAD(value);
}
}
tier1 inst(EXTENDED_ARG, ( -- )) {
@ -5219,22 +5222,26 @@ dummy_func(
}
label(pop_4_error) {
STACK_SHRINK(4);
stack_pointer -= 4;
assert(WITHIN_STACK_BOUNDS());
goto error;
}
label(pop_3_error) {
STACK_SHRINK(3);
stack_pointer -= 3;
assert(WITHIN_STACK_BOUNDS());
goto error;
}
label(pop_2_error) {
STACK_SHRINK(2);
stack_pointer -= 2;
assert(WITHIN_STACK_BOUNDS());
goto error;
}
label(pop_1_error) {
STACK_SHRINK(1);
stack_pointer -= 1;
assert(WITHIN_STACK_BOUNDS());
goto error;
}

View file

@ -151,18 +151,6 @@ dump_item(_PyStackRef item)
printf("<nil>");
return;
}
if (
obj == Py_None
|| PyBool_Check(obj)
|| PyLong_CheckExact(obj)
|| PyFloat_CheckExact(obj)
|| PyUnicode_CheckExact(obj)
) {
if (PyObject_Print(obj, stdout, 0) == 0) {
return;
}
PyErr_Clear();
}
// Don't call __repr__(), it might recurse into the interpreter.
printf("<%s at %p>", Py_TYPE(obj)->tp_name, (void *)obj);
}
@ -182,14 +170,19 @@ dump_stack(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer)
dump_item(*ptr);
}
printf("]\n");
printf(" stack=[");
for (_PyStackRef *ptr = stack_base; ptr < stack_pointer; ptr++) {
if (ptr != stack_base) {
printf(", ");
}
dump_item(*ptr);
if (stack_pointer < stack_base) {
printf(" stack=%d\n", (int)(stack_pointer-stack_base));
}
else {
printf(" stack=[");
for (_PyStackRef *ptr = stack_base; ptr < stack_pointer; ptr++) {
if (ptr != stack_base) {
printf(", ");
}
dump_item(*ptr);
}
printf("]\n");
}
printf("]\n");
fflush(stdout);
PyErr_SetRaisedException(exc);
_PyFrame_GetStackPointer(frame);
@ -202,13 +195,13 @@ lltrace_instruction(_PyInterpreterFrame *frame,
int opcode,
int oparg)
{
if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) {
return;
int offset = 0;
if (frame->owner < FRAME_OWNED_BY_INTERPRETER) {
dump_stack(frame, stack_pointer);
offset = (int)(next_instr - _PyFrame_GetBytecode(frame));
}
dump_stack(frame, stack_pointer);
const char *opname = _PyOpcode_OpName[opcode];
assert(opname != NULL);
int offset = (int)(next_instr - _PyFrame_GetBytecode(frame));
if (OPCODE_HAS_ARG((int)_PyOpcode_Deopt[opcode])) {
printf("%d: %s %d\n", offset * 2, opname, oparg);
}
@ -986,8 +979,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
* These are cached values from the frame and code object. */
_Py_CODEUNIT *next_instr;
_PyStackRef *stack_pointer;
#if defined(Py_DEBUG) && !defined(Py_STACKREF_DEBUG)
entry_frame.localsplus[0] = PyStackRef_NULL;
#ifdef Py_STACKREF_DEBUG
entry_frame.f_funcobj = PyStackRef_None;
#elif defined(Py_DEBUG)
/* Set these to invalid but identifiable values for debugging. */
entry_frame.f_funcobj = (_PyStackRef){.bits = 0xaaa0};
entry_frame.f_locals = (PyObject*)0xaaa1;
@ -1044,7 +1039,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
_PyExecutorObject *current_executor = NULL;
const _PyUOpInstruction *next_uop = NULL;
#endif
#if Py_TAIL_CALL_INTERP
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, 0);
#else

View file

@ -194,48 +194,8 @@ GETITEM(PyObject *v, Py_ssize_t i) {
#define JUMPBY(x) (next_instr += (x))
#define SKIP_OVER(x) (next_instr += (x))
/* Stack manipulation macros */
/* The stack can grow at most MAXINT deep, as co_nlocals and
co_stacksize are ints. */
#define STACK_LEVEL() ((int)(stack_pointer - _PyFrame_Stackbase(frame)))
#define STACK_SIZE() (_PyFrame_GetCode(frame)->co_stacksize)
#define EMPTY() (STACK_LEVEL() == 0)
#define TOP() (stack_pointer[-1])
#define SECOND() (stack_pointer[-2])
#define THIRD() (stack_pointer[-3])
#define FOURTH() (stack_pointer[-4])
#define PEEK(n) (stack_pointer[-(n)])
#define POKE(n, v) (stack_pointer[-(n)] = (v))
#define SET_TOP(v) (stack_pointer[-1] = (v))
#define SET_SECOND(v) (stack_pointer[-2] = (v))
#define BASIC_STACKADJ(n) (stack_pointer += n)
#define BASIC_PUSH(v) (*stack_pointer++ = (v))
#define BASIC_POP() (*--stack_pointer)
#ifdef Py_DEBUG
#define PUSH(v) do { \
BASIC_PUSH(v); \
assert(STACK_LEVEL() <= STACK_SIZE()); \
} while (0)
#define POP() (assert(STACK_LEVEL() > 0), BASIC_POP())
#define STACK_GROW(n) do { \
assert(n >= 0); \
BASIC_STACKADJ(n); \
assert(STACK_LEVEL() <= STACK_SIZE()); \
} while (0)
#define STACK_SHRINK(n) do { \
assert(n >= 0); \
assert(STACK_LEVEL() >= n); \
BASIC_STACKADJ(-(n)); \
} while (0)
#else
#define PUSH(v) BASIC_PUSH(v)
#define POP() BASIC_POP()
#define STACK_GROW(n) BASIC_STACKADJ(n)
#define STACK_SHRINK(n) BASIC_STACKADJ(-(n))
#endif
#define WITHIN_STACK_BOUNDS() \
(frame->owner == FRAME_OWNED_BY_INTERPRETER || (STACK_LEVEL() >= 0 && STACK_LEVEL() <= STACK_SIZE()))

View file

@ -714,7 +714,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
res = PyStackRef_True;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -798,7 +797,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
res = PyStackRef_True;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -1206,7 +1204,6 @@
Py_DECREF(slice);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += 2;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer += -3;
assert(WITHIN_STACK_BOUNDS());
@ -1248,21 +1245,18 @@
Py_DECREF(slice);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += 2;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer += -2;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyStackRef tmp = container;
container = PyStackRef_NULL;
stack_pointer[-1] = container;
stack_pointer[-3] = container;
PyStackRef_CLOSE(tmp);
tmp = v;
v = PyStackRef_NULL;
stack_pointer[-2] = v;
stack_pointer[-4] = v;
PyStackRef_CLOSE(tmp);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -2;
stack_pointer += -4;
assert(WITHIN_STACK_BOUNDS());
if (err) {
JUMP_TO_ERROR();
@ -1732,7 +1726,7 @@
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
assert(EMPTY());
assert(STACK_LEVEL() == 0);
_Py_LeaveRecursiveCallPy(tstate);
_PyInterpreterFrame *dying = frame;
frame = tstate->current_frame = dying->previous;
@ -2073,7 +2067,6 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer[-1] = val0;
break;
}
@ -3004,7 +2997,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
self_or_null = PyStackRef_NULL;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
@ -3057,7 +3049,6 @@
}
self_or_null[0] = PyStackRef_NULL;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
}
else {
@ -3073,7 +3064,6 @@
JUMP_TO_ERROR();
}
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
attr = PyStackRef_FromPyObjectSteal(attr_o);
stack_pointer[-1] = attr;
@ -5289,7 +5279,6 @@
case _EXIT_INIT_CHECK: {
_PyStackRef should_be_none;
should_be_none = stack_pointer[-1];
assert(STACK_LEVEL() == 2);
if (!PyStackRef_IsNone(should_be_none)) {
_PyFrame_SetStackPointer(frame, stack_pointer);
PyErr_Format(PyExc_TypeError,
@ -6347,7 +6336,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
stack_pointer += 2;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-2] = tuple;
stack_pointer[-1] = kwargs_out;
@ -6414,7 +6402,7 @@
if (gen == NULL) {
JUMP_TO_ERROR();
}
assert(EMPTY());
assert(STACK_LEVEL() == 0);
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
frame->instr_ptr++;
@ -6513,7 +6501,6 @@
else {
res = value;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[0] = res;
stack_pointer += 1;

View file

@ -1062,7 +1062,6 @@
Py_DECREF(slice);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += 2;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer += -3;
assert(WITHIN_STACK_BOUNDS());
@ -1498,7 +1497,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -1983,7 +1981,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -2097,7 +2094,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -2212,7 +2208,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -2305,7 +2300,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -2366,7 +2360,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
stack_pointer += 2;
assert(WITHIN_STACK_BOUNDS());
}
}
// _DO_CALL_FUNCTION_EX
@ -2494,7 +2487,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = result;
@ -2736,7 +2728,6 @@
}
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
if (CONVERSION_FAILED(args_o)) {
stack_pointer[-1] = kwnames;
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyStackRef tmp = kwnames;
kwnames = PyStackRef_NULL;
@ -3070,7 +3061,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -3422,7 +3412,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -3544,7 +3533,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -3646,7 +3634,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -3759,7 +3746,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -3879,7 +3865,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -4154,7 +4139,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -4227,7 +4211,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -5310,7 +5293,6 @@
INSTRUCTION_STATS(EXIT_INIT_CHECK);
_PyStackRef should_be_none;
should_be_none = stack_pointer[-1];
assert(STACK_LEVEL() == 2);
if (!PyStackRef_IsNone(should_be_none)) {
_PyFrame_SetStackPointer(frame, stack_pointer);
PyErr_Format(PyExc_TypeError,
@ -5369,7 +5351,6 @@
else {
res = value;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[0] = res;
stack_pointer += 1;
@ -6130,8 +6111,9 @@
}
// _DO_CALL
{
self_or_null = maybe_self;
callable = func;
args = &stack_pointer[-oparg];
self_or_null = &stack_pointer[-1 - oparg];
callable = &stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
int total_args = oparg;
_PyStackRef *arguments = args;
@ -6246,7 +6228,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = res;
@ -6307,7 +6288,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
stack_pointer += 2;
assert(WITHIN_STACK_BOUNDS());
}
}
// _DO_CALL_FUNCTION_EX
@ -6435,7 +6415,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[0] = result;
@ -6753,14 +6732,16 @@
frame->instr_ptr = next_instr;
next_instr += 2;
INSTRUCTION_STATS(INSTRUMENTED_FOR_ITER);
_PyStackRef iter;
_PyStackRef next;
/* Skip 1 cache entry */
_PyStackRef iter_stackref = TOP();
PyObject *iter = PyStackRef_AsPyObjectBorrow(iter_stackref);
iter = stack_pointer[-1];
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
PyObject *next_o = (*Py_TYPE(iter_o)->tp_iternext)(iter_o);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (next != NULL) {
PUSH(PyStackRef_FromPyObjectSteal(next));
if (next_o != NULL) {
next = PyStackRef_FromPyObjectSteal(next_o);
INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
}
else {
@ -6779,7 +6760,11 @@
assert(next_instr[oparg].op.code == END_FOR ||
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
JUMPBY(oparg + 1);
DISPATCH();
}
stack_pointer[0] = next;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@ -7063,14 +7048,17 @@
frame->instr_ptr = next_instr;
next_instr += 2;
INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_FALSE);
_PyStackRef cond;
/* Skip 1 cache entry */
_PyStackRef cond = POP();
cond = stack_pointer[-1];
assert(PyStackRef_BoolCheck(cond));
int jump = PyStackRef_IsFalse(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
if (jump) {
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@ -7084,18 +7072,24 @@
frame->instr_ptr = next_instr;
next_instr += 2;
INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NONE);
_PyStackRef value;
/* Skip 1 cache entry */
_PyStackRef value_stackref = POP();
int jump = PyStackRef_IsNone(value_stackref);
value = stack_pointer[-1];
int jump = PyStackRef_IsNone(value);
RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
if (jump) {
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
else {
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value_stackref);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += 1;
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@ -7109,16 +7103,22 @@
frame->instr_ptr = next_instr;
next_instr += 2;
INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NOT_NONE);
_PyStackRef value;
/* Skip 1 cache entry */
_PyStackRef value_stackref = POP();
int jump = !PyStackRef_IsNone(value_stackref);
value = stack_pointer[-1];
int jump = !PyStackRef_IsNone(value);
RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
if (jump) {
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value_stackref);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
else {
stack_pointer += -1;
}
DISPATCH();
}
@ -7132,14 +7132,17 @@
frame->instr_ptr = next_instr;
next_instr += 2;
INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_TRUE);
_PyStackRef cond;
/* Skip 1 cache entry */
_PyStackRef cond = POP();
cond = stack_pointer[-1];
assert(PyStackRef_BoolCheck(cond));
int jump = PyStackRef_IsTrue(cond);
RECORD_BRANCH_TAKEN(this_instr[1].cache, jump);
if (jump) {
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_BRANCH_RIGHT);
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@ -7254,7 +7257,7 @@
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
assert(EMPTY());
assert(STACK_LEVEL() == 0);
_Py_LeaveRecursiveCallPy(tstate);
_PyInterpreterFrame *dying = frame;
frame = tstate->current_frame = dying->previous;
@ -7353,9 +7356,11 @@
tstate->current_frame = frame->previous;
assert(!_PyErr_Occurred(tstate));
PyObject *result = PyStackRef_AsPyObjectSteal(retval);
LLTRACE_RESUME_FRAME();
return result;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
return result;
DISPATCH();
}
TARGET(IS_OP) {
@ -7684,7 +7689,6 @@
}
self_or_null[0] = PyStackRef_NULL;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
}
else {
@ -7700,7 +7704,6 @@
JUMP_TO_LABEL(error);
}
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
attr = PyStackRef_FromPyObjectSteal(attr_o);
}
@ -7886,8 +7889,9 @@
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(
tstate, PyStackRef_FromPyObjectNew(f), 2, frame);
STACK_SHRINK(1);
new_frame->localsplus[0] = owner;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
new_frame->localsplus[1] = PyStackRef_FromPyObjectNew(name);
frame->return_offset = 10 ;
DISPATCH_INLINED(new_frame);
@ -9551,7 +9555,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
self_or_null = PyStackRef_NULL;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
@ -10243,7 +10246,7 @@
if (gen == NULL) {
JUMP_TO_LABEL(error);
}
assert(EMPTY());
assert(STACK_LEVEL() == 0);
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
frame->instr_ptr++;
@ -10281,7 +10284,7 @@
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
assert(EMPTY());
assert(STACK_LEVEL() == 0);
_Py_LeaveRecursiveCallPy(tstate);
_PyInterpreterFrame *dying = frame;
frame = tstate->current_frame = dying->previous;
@ -10339,8 +10342,9 @@
{
PyGenObject *gen = (PyGenObject *)receiver_o;
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
STACK_SHRINK(1);
_PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v));
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
@ -11095,21 +11099,18 @@
Py_DECREF(slice);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += 2;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer += -2;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyStackRef tmp = container;
container = PyStackRef_NULL;
stack_pointer[-1] = container;
stack_pointer[-3] = container;
PyStackRef_CLOSE(tmp);
tmp = v;
v = PyStackRef_NULL;
stack_pointer[-2] = v;
stack_pointer[-4] = v;
PyStackRef_CLOSE(tmp);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -2;
stack_pointer += -4;
assert(WITHIN_STACK_BOUNDS());
if (err) {
JUMP_TO_LABEL(error);
@ -11465,7 +11466,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
res = PyStackRef_True;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
DISPATCH();
@ -11573,7 +11573,6 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
res = PyStackRef_True;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
}
}
stack_pointer[-1] = res;
@ -11861,7 +11860,6 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(seq);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer[-1] = val0;
DISPATCH();
}
@ -11984,25 +11982,29 @@ JUMP_TO_LABEL(error);
LABEL(pop_4_error)
{
STACK_SHRINK(4);
stack_pointer -= 4;
assert(WITHIN_STACK_BOUNDS());
JUMP_TO_LABEL(error);
}
LABEL(pop_3_error)
{
STACK_SHRINK(3);
stack_pointer -= 3;
assert(WITHIN_STACK_BOUNDS());
JUMP_TO_LABEL(error);
}
LABEL(pop_2_error)
{
STACK_SHRINK(2);
stack_pointer -= 2;
assert(WITHIN_STACK_BOUNDS());
JUMP_TO_LABEL(error);
}
LABEL(pop_1_error)
{
STACK_SHRINK(1);
stack_pointer -= 1;
assert(WITHIN_STACK_BOUNDS());
JUMP_TO_LABEL(error);
}

View file

@ -310,7 +310,6 @@
else {
res = sym_new_type(ctx, &PyLong_Type);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -339,7 +338,6 @@
else {
res = sym_new_type(ctx, &PyLong_Type);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -368,7 +366,6 @@
else {
res = sym_new_type(ctx, &PyLong_Type);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -418,7 +415,6 @@
else {
res = sym_new_type(ctx, &PyFloat_Type);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -448,7 +444,6 @@
else {
res = sym_new_type(ctx, &PyFloat_Type);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -478,7 +473,6 @@
else {
res = sym_new_type(ctx, &PyFloat_Type);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -506,7 +500,6 @@
else {
res = sym_new_type(ctx, &PyUnicode_Type);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -1257,7 +1250,6 @@
else {
res = sym_new_type(ctx, &PyBool_Type);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
stack_pointer[-1] = res;
break;
@ -2031,7 +2023,6 @@
if (co == NULL) {
ctx->done = true;
}
stack_pointer[-1] = res;
break;
}

View file

@ -71,6 +71,9 @@ _Py_stackref_close(_PyStackRef ref, const char *filename, int linenumber)
}
PyObject *obj;
if (ref.index <= LAST_PREDEFINED_STACKREF_INDEX) {
if (ref.index == 0) {
_Py_FatalErrorFormat(__func__, "Passing NULL to PyStackRef_CLOSE at %s:%d\n", filename, linenumber);
}
// Pre-allocated reference to None, False or True -- Do not clear
TableEntry *entry = _Py_hashtable_get(interp->open_stackrefs_table, (void *)ref.index);
obj = entry->obj;