https://github.com/python/cpython/commit/b3bf2128989e550a7a02acbaa47389023b2c6bc9
commit: b3bf2128989e550a7a02acbaa47389023b2c6bc9
branch: main
author: Ken Jin <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2025-12-04T20:28:08Z
summary:
gh-141976: Check stack bounds in JIT optimizer (GH-142201)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2025-12-02-21-11-46.gh-issue-141976.yu7pDV.rst
M Lib/test/test_generated_cases.py
M Python/optimizer_analysis.c
M Python/optimizer_cases.c.h
M Tools/cases_generator/optimizer_generator.py
M Tools/cases_generator/stack.py
diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py
index ac62e11c274fab..de0dbab480f5e5 100644
--- a/Lib/test/test_generated_cases.py
+++ b/Lib/test/test_generated_cases.py
@@ -2115,6 +2115,7 @@ def test_validate_uop_unused_input(self):
"""
output = """
case OP: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -2132,6 +2133,7 @@ def test_validate_uop_unused_input(self):
"""
output = """
case OP: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -2153,6 +2155,7 @@ def test_validate_uop_unused_output(self):
case OP: {
JitOptRef foo;
foo = NULL;
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = foo;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2172,6 +2175,7 @@ def test_validate_uop_unused_output(self):
"""
output = """
case OP: {
+ CHECK_STACK_BOUNDS(1);
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-02-21-11-46.gh-issue-141976.yu7pDV.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-02-21-11-46.gh-issue-141976.yu7pDV.rst
new file mode 100644
index 00000000000000..f77315b7c37d80
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-02-21-11-46.gh-issue-141976.yu7pDV.rst
@@ -0,0 +1 @@
+Check against abstract stack overflow in the JIT optimizer.
diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c
index 685659ef7c46ef..51722556554609 100644
--- a/Python/optimizer_analysis.c
+++ b/Python/optimizer_analysis.c
@@ -144,10 +144,6 @@ incorrect_keys(PyObject *obj, uint32_t version)
#define CURRENT_FRAME_IS_INIT_SHIM() (ctx->frame->code == ((PyCodeObject
*)&_Py_InitCleanup))
-#define WITHIN_STACK_BOUNDS() \
- (CURRENT_FRAME_IS_INIT_SHIM() || (STACK_LEVEL() >= 0 && STACK_LEVEL() <=
STACK_SIZE()))
-
-
#define GETLOCAL(idx) ((ctx->frame->locals[idx]))
#define REPLACE_OP(INST, OP, ARG, OPERAND) \
@@ -192,6 +188,27 @@ incorrect_keys(PyObject *obj, uint32_t version)
#define JUMP_TO_LABEL(label) goto label;
+static int
+check_stack_bounds(JitOptContext *ctx, JitOptRef *stack_pointer, int offset,
int opcode)
+{
+ int stack_level = (int)(stack_pointer + (offset) - ctx->frame->stack);
+ int should_check = !CURRENT_FRAME_IS_INIT_SHIM() ||
+ (opcode == _RETURN_VALUE) ||
+ (opcode == _RETURN_GENERATOR) ||
+ (opcode == _YIELD_VALUE);
+ if (should_check && (stack_level < 0 || stack_level > STACK_SIZE())) {
+ ctx->contradiction = true;
+ ctx->done = true;
+ return 1;
+ }
+ return 0;
+}
+
+#define CHECK_STACK_BOUNDS(offset) \
+ if (check_stack_bounds(ctx, stack_pointer, offset, opcode)) { \
+ break; \
+ } \
+
static int
optimize_to_bool(
_PyUOpInstruction *this_instr,
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 0c2d34d2e640a3..85bebed58677ed 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -33,6 +33,7 @@
if (sym_is_null(value)) {
ctx->done = true;
}
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -42,6 +43,7 @@
case _LOAD_FAST: {
JitOptRef value;
value = GETLOCAL(oparg);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -51,6 +53,7 @@
case _LOAD_FAST_BORROW: {
JitOptRef value;
value = PyJitRef_Borrow(GETLOCAL(oparg));
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -62,6 +65,7 @@
value = GETLOCAL(oparg);
JitOptRef temp = sym_new_null(ctx);
GETLOCAL(oparg) = temp;
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -74,6 +78,7 @@
PyObject *val = PyTuple_GET_ITEM(co->co_consts, oparg);
REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0,
(uintptr_t)val);
value = PyJitRef_Borrow(sym_new_const(ctx, val));
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -87,6 +92,7 @@
assert(_Py_IsImmortal(val));
REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0,
(uintptr_t)val);
value = PyJitRef_Borrow(sym_new_const(ctx, val));
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -97,6 +103,7 @@
JitOptRef value;
value = stack_pointer[-1];
GETLOCAL(oparg) = value;
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -120,36 +127,42 @@
else if (typ == &PyUnicode_Type) {
REPLACE_OP(this_instr, _POP_TOP_UNICODE, 0, 0);
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _POP_TOP_NOP: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _POP_TOP_INT: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _POP_TOP_FLOAT: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _POP_TOP_UNICODE: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _POP_TWO: {
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -158,6 +171,7 @@
case _PUSH_NULL: {
JitOptRef res;
res = sym_new_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -165,12 +179,14 @@
}
case _END_FOR: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _POP_ITER: {
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -179,6 +195,7 @@
case _END_SEND: {
JitOptRef val;
val = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = val;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -504,12 +521,14 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_compact_int(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -554,12 +573,14 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_compact_int(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -604,12 +625,14 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_compact_int(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -673,6 +696,7 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -682,6 +706,7 @@
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
REPLACE_OP(this_instr, op_without_decref_inputs[opcode],
oparg, 0);
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -725,6 +750,7 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -734,6 +760,7 @@
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
REPLACE_OP(this_instr, op_without_decref_inputs[opcode],
oparg, 0);
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -777,6 +804,7 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -786,6 +814,7 @@
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
REPLACE_OP(this_instr, op_without_decref_inputs[opcode],
oparg, 0);
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -795,6 +824,7 @@
case _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -804,6 +834,7 @@
case _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -813,6 +844,7 @@
case _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -856,12 +888,14 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyUnicode_Type);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -888,6 +922,7 @@
res = sym_new_type(ctx, &PyUnicode_Type);
}
GETLOCAL(this_instr->operand0) = res;
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -900,6 +935,7 @@
case _BINARY_OP_EXTEND: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -920,6 +956,7 @@
else {
res = sym_new_not_null(ctx);
}
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = res;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -927,6 +964,7 @@
}
case _STORE_SLICE: {
+ CHECK_STACK_BOUNDS(-4);
stack_pointer += -4;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -935,6 +973,7 @@
case _BINARY_OP_SUBSCR_LIST_INT: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -944,6 +983,7 @@
case _BINARY_OP_SUBSCR_LIST_SLICE: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -953,6 +993,7 @@
case _BINARY_OP_SUBSCR_STR_INT: {
JitOptRef res;
res = sym_new_type(ctx, &PyUnicode_Type);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1002,6 +1043,7 @@
else {
res = sym_new_not_null(ctx);
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1031,6 +1073,7 @@
case _BINARY_OP_SUBSCR_DICT: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1040,6 +1083,7 @@
case _BINARY_OP_SUBSCR_CHECK_FUNC: {
JitOptRef getitem;
getitem = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = getitem;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1050,6 +1094,7 @@
JitOptRef new_frame;
new_frame = PyJitRef_NULL;
ctx->done = true;
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = new_frame;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1057,36 +1102,42 @@
}
case _LIST_APPEND: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _SET_ADD: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _STORE_SUBSCR: {
+ CHECK_STACK_BOUNDS(-3);
stack_pointer += -3;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _STORE_SUBSCR_LIST_INT: {
+ CHECK_STACK_BOUNDS(-3);
stack_pointer += -3;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _STORE_SUBSCR_DICT: {
+ CHECK_STACK_BOUNDS(-3);
stack_pointer += -3;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _DELETE_SUBSCR: {
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1102,6 +1153,7 @@
case _CALL_INTRINSIC_2: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1113,6 +1165,7 @@
JitOptRef res;
retval = stack_pointer[-1];
JitOptRef temp = PyJitRef_StripReferenceInfo(retval);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
ctx->frame->stack_pointer = stack_pointer;
@@ -1134,6 +1187,7 @@
}
stack_pointer = ctx->frame->stack_pointer;
res = temp;
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1150,6 +1204,7 @@
case _GET_ANEXT: {
JitOptRef awaitable;
awaitable = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = awaitable;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1178,6 +1233,7 @@
JitOptRef value;
retval = stack_pointer[-1];
JitOptRef temp = PyJitRef_StripReferenceInfo(retval);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
ctx->frame->stack_pointer = stack_pointer;
@@ -1193,6 +1249,7 @@
}
stack_pointer = ctx->frame->stack_pointer;
value = temp;
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1200,6 +1257,7 @@
}
case _POP_EXCEPT: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1208,6 +1266,7 @@
case _LOAD_COMMON_CONSTANT: {
JitOptRef value;
value = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1217,6 +1276,7 @@
case _LOAD_BUILD_CLASS: {
JitOptRef bc;
bc = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = bc;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1224,6 +1284,7 @@
}
case _STORE_NAME: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1242,6 +1303,7 @@
for (int i = 0; i < oparg; i++) {
values[i] = sym_new_unknown(ctx);
}
+ CHECK_STACK_BOUNDS(-1 + oparg);
stack_pointer += -1 + oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1254,6 +1316,7 @@
seq = stack_pointer[-1];
val0 = sym_tuple_getitem(ctx, seq, 0);
val1 = sym_tuple_getitem(ctx, seq, 1);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = val1;
stack_pointer[0] = val0;
stack_pointer += 1;
@@ -1269,6 +1332,7 @@
for (int i = 0; i < oparg; i++) {
values[i] = sym_tuple_getitem(ctx, seq, oparg - i - 1);
}
+ CHECK_STACK_BOUNDS(-1 + oparg);
stack_pointer += -1 + oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1280,6 +1344,7 @@
for (int _i = oparg; --_i >= 0;) {
values[_i] = sym_new_not_null(ctx);
}
+ CHECK_STACK_BOUNDS(-1 + oparg);
stack_pointer += -1 + oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1295,24 +1360,28 @@
for (int i = 0; i < totalargs; i++) {
values[i] = sym_new_unknown(ctx);
}
+ CHECK_STACK_BOUNDS((oparg & 0xFF) + (oparg >> 8));
stack_pointer += (oparg & 0xFF) + (oparg >> 8);
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _STORE_ATTR: {
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _DELETE_ATTR: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _STORE_GLOBAL: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1325,6 +1394,7 @@
case _LOAD_LOCALS: {
JitOptRef locals;
locals = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = locals;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1336,6 +1406,7 @@
case _LOAD_NAME: {
JitOptRef v;
v = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = v;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1346,6 +1417,7 @@
JitOptRef *res;
res = &stack_pointer[0];
res[0] = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1361,6 +1433,7 @@
else {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
+ CHECK_STACK_BOUNDS((oparg & 1));
stack_pointer += (oparg & 1);
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1426,6 +1499,7 @@
else {
res = sym_new_const(ctx, cnst);
}
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1462,6 +1536,7 @@
else {
res = sym_new_const(ctx, cnst);
}
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1490,6 +1565,7 @@
case _LOAD_DEREF: {
JitOptRef value;
value = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1497,6 +1573,7 @@
}
case _STORE_DEREF: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1509,6 +1586,7 @@
case _BUILD_STRING: {
JitOptRef str;
str = sym_new_type(ctx, &PyUnicode_Type);
+ CHECK_STACK_BOUNDS(1 - oparg);
stack_pointer[-oparg] = str;
stack_pointer += 1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1518,6 +1596,7 @@
case _BUILD_INTERPOLATION: {
JitOptRef interpolation;
interpolation = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - (oparg & 1));
stack_pointer[-2 - (oparg & 1)] = interpolation;
stack_pointer += -1 - (oparg & 1);
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1527,6 +1606,7 @@
case _BUILD_TEMPLATE: {
JitOptRef template;
template = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = template;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1538,6 +1618,7 @@
JitOptRef tup;
values = &stack_pointer[-oparg];
tup = sym_new_tuple(ctx, oparg, values);
+ CHECK_STACK_BOUNDS(1 - oparg);
stack_pointer[-oparg] = tup;
stack_pointer += 1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1547,6 +1628,7 @@
case _BUILD_LIST: {
JitOptRef list;
list = sym_new_type(ctx, &PyList_Type);
+ CHECK_STACK_BOUNDS(1 - oparg);
stack_pointer[-oparg] = list;
stack_pointer += 1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1554,12 +1636,14 @@
}
case _LIST_EXTEND: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _SET_UPDATE: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1568,6 +1652,7 @@
case _BUILD_SET: {
JitOptRef set;
set = sym_new_type(ctx, &PySet_Type);
+ CHECK_STACK_BOUNDS(1 - oparg);
stack_pointer[-oparg] = set;
stack_pointer += 1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1577,6 +1662,7 @@
case _BUILD_MAP: {
JitOptRef map;
map = sym_new_type(ctx, &PyDict_Type);
+ CHECK_STACK_BOUNDS(1 - oparg*2);
stack_pointer[-oparg*2] = map;
stack_pointer += 1 - oparg*2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1588,18 +1674,21 @@
}
case _DICT_UPDATE: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _DICT_MERGE: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _MAP_ADD: {
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1608,6 +1697,7 @@
case _LOAD_SUPER_ATTR_ATTR: {
JitOptRef attr_st;
attr_st = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = attr_st;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1619,6 +1709,7 @@
JitOptRef self_or_null;
attr = sym_new_not_null(ctx);
self_or_null = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-3] = attr;
stack_pointer[-2] = self_or_null;
stack_pointer += -1;
@@ -1638,6 +1729,7 @@
if (oparg & 1) {
self_or_null[0] = sym_new_unknown(ctx);
}
+ CHECK_STACK_BOUNDS((oparg&1));
stack_pointer += (oparg&1);
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1780,18 +1872,21 @@
}
case _STORE_ATTR_INSTANCE_VALUE: {
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _STORE_ATTR_WITH_HINT: {
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _STORE_ATTR_SLOT: {
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -1840,6 +1935,7 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1851,6 +1947,7 @@
else {
res = _Py_uop_sym_new_not_null(ctx);
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1891,12 +1988,14 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyBool_Type);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1941,12 +2040,14 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyBool_Type);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -1989,12 +2090,14 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyBool_Type);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2004,6 +2107,7 @@
case _IS_OP: {
JitOptRef b;
b = sym_new_type(ctx, &PyBool_Type);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = b;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2042,12 +2146,14 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = b;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
b = sym_new_type(ctx, &PyBool_Type);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = b;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2068,6 +2174,7 @@
case _CONTAINS_OP_SET: {
JitOptRef b;
b = sym_new_type(ctx, &PyBool_Type);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = b;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2077,6 +2184,7 @@
case _CONTAINS_OP_DICT: {
JitOptRef b;
b = sym_new_type(ctx, &PyBool_Type);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = b;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2103,6 +2211,7 @@
case _IMPORT_NAME: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2112,6 +2221,7 @@
case _IMPORT_FROM: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2149,12 +2259,14 @@
REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0,
(uintptr_t)temp);
}
len = sym_new_const(ctx, temp);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = len;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
Py_DECREF(temp);
stack_pointer += -1;
}
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = len;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2164,6 +2276,7 @@
case _MATCH_CLASS: {
JitOptRef attrs;
attrs = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = attrs;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2173,6 +2286,7 @@
case _MATCH_MAPPING: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2182,6 +2296,7 @@
case _MATCH_SEQUENCE: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2191,6 +2306,7 @@
case _MATCH_KEYS: {
JitOptRef values_or_none;
values_or_none = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = values_or_none;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2210,6 +2326,7 @@
iter = sym_new_not_null(ctx);
index_or_null = sym_new_unknown(ctx);
}
+ CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = iter;
stack_pointer[0] = index_or_null;
stack_pointer += 1;
@@ -2229,6 +2346,7 @@
case _FOR_ITER_TIER_TWO: {
JitOptRef next;
next = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = next;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2252,6 +2370,7 @@
case _ITER_NEXT_LIST_TIER_TWO: {
JitOptRef next;
next = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = next;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2277,6 +2396,7 @@
case _ITER_NEXT_TUPLE: {
JitOptRef next;
next = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = next;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2296,6 +2416,7 @@
case _ITER_NEXT_RANGE: {
JitOptRef next;
next = sym_new_type(ctx, &PyLong_Type);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = next;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2306,6 +2427,7 @@
JitOptRef gen_frame;
gen_frame = PyJitRef_NULL;
ctx->done = true;
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = gen_frame;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2319,6 +2441,7 @@
method_and_self = &stack_pointer[-1];
method_and_self[0] = sym_new_null(ctx);
method_and_self[1] = self;
+ CHECK_STACK_BOUNDS(1);
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -2335,6 +2458,7 @@
case _WITH_EXCEPT_START: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2346,6 +2470,7 @@
JitOptRef new_exc;
prev_exc = sym_new_not_null(ctx);
new_exc = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = prev_exc;
stack_pointer[0] = new_exc;
stack_pointer += 1;
@@ -2374,6 +2499,7 @@
_LOAD_CONST_UNDER_INLINE_BORROW,
_LOAD_CONST_UNDER_INLINE);
self = owner;
+ CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = attr;
stack_pointer[0] = self;
stack_pointer += 1;
@@ -2394,6 +2520,7 @@
_LOAD_CONST_UNDER_INLINE_BORROW,
_LOAD_CONST_UNDER_INLINE);
self = owner;
+ CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = attr;
stack_pointer[0] = self;
stack_pointer += 1;
@@ -2448,6 +2575,7 @@
_LOAD_CONST_UNDER_INLINE_BORROW,
_LOAD_CONST_UNDER_INLINE);
self = owner;
+ CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = attr;
stack_pointer[0] = self;
stack_pointer += 1;
@@ -2483,6 +2611,7 @@
break;
}
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0,
NULL, 0));
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = new_frame;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2531,6 +2660,7 @@
case _CALL_NON_PY_GENERAL: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2616,6 +2746,7 @@
} else {
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co,
0, NULL, 0));
}
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = new_frame;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2625,6 +2756,7 @@
case _PUSH_FRAME: {
JitOptRef new_frame;
new_frame = stack_pointer[-1];
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
if (!CURRENT_FRAME_IS_INIT_SHIM()) {
@@ -2703,6 +2835,7 @@
else {
res = sym_new_not_null(ctx);
}
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = res;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2729,6 +2862,7 @@
else {
res = sym_new_type(ctx, &PyUnicode_Type);
}
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = res;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2755,6 +2889,7 @@
else {
res = sym_new_type(ctx, &PyTuple_Type);
}
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = res;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2797,6 +2932,7 @@
assert((this_instr + 1)->opcode == _PUSH_FRAME);
PyCodeObject *co = get_code_with_logging((this_instr + 1));
init_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0,
args-1, oparg+1));
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = init_frame;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2804,6 +2940,7 @@
}
case _EXIT_INIT_CHECK: {
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -2812,6 +2949,7 @@
case _CALL_BUILTIN_CLASS: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2821,6 +2959,7 @@
case _CALL_BUILTIN_O: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2830,6 +2969,7 @@
case _CALL_BUILTIN_FAST: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2839,6 +2979,7 @@
case _CALL_BUILTIN_FAST_WITH_KEYWORDS: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2872,12 +3013,14 @@
0, (uintptr_t)temp);
}
res = sym_new_const(ctx, temp);
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = res;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
Py_DECREF(temp);
stack_pointer += 2;
}
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = res;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2912,6 +3055,7 @@
sym_set_const(res, out);
REPLACE_OP(this_instr, _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW,
0, (uintptr_t)out);
}
+ CHECK_STACK_BOUNDS(-3);
stack_pointer[-4] = res;
stack_pointer += -3;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2930,6 +3074,7 @@
}
case _CALL_LIST_APPEND: {
+ CHECK_STACK_BOUNDS(-3);
stack_pointer += -3;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -2938,6 +3083,7 @@
case _CALL_METHOD_DESCRIPTOR_O: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2947,6 +3093,7 @@
case _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2956,6 +3103,7 @@
case _CALL_METHOD_DESCRIPTOR_NOARGS: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2965,6 +3113,7 @@
case _CALL_METHOD_DESCRIPTOR_FAST: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1 - oparg);
stack_pointer[-2 - oparg] = res;
stack_pointer += -1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -2988,6 +3137,7 @@
break;
}
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0,
NULL, 0));
+ CHECK_STACK_BOUNDS(-2 - oparg);
stack_pointer[-3 - oparg] = new_frame;
stack_pointer += -2 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3013,6 +3163,7 @@
case _CALL_KW_NON_PY: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-2 - oparg);
stack_pointer[-3 - oparg] = res;
stack_pointer += -2 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3035,6 +3186,7 @@
case _SET_FUNCTION_ATTRIBUTE: {
JitOptRef func_out;
func_out = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = func_out;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3056,6 +3208,7 @@
}
stack_pointer = ctx->frame->stack_pointer;
res = sym_new_unknown(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3065,6 +3218,7 @@
case _BUILD_SLICE: {
JitOptRef slice;
slice = sym_new_type(ctx, &PySlice_Type);
+ CHECK_STACK_BOUNDS(1 - oparg);
stack_pointer[-oparg] = slice;
stack_pointer += 1 - oparg;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3088,6 +3242,7 @@
case _FORMAT_WITH_SPEC: {
JitOptRef res;
res = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3100,6 +3255,7 @@
bottom = stack_pointer[-1 - (oparg-1)];
assert(oparg > 0);
top = bottom;
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = top;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3139,6 +3295,7 @@
REPLACE_OP(this_instr,
_POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3177,6 +3334,7 @@
else {
res = sym_new_type(ctx, &PyFloat_Type);
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3224,6 +3382,7 @@
eliminate_pop_guard(this_instr, value != Py_True);
}
sym_set_const(flag, Py_True);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -3238,6 +3397,7 @@
eliminate_pop_guard(this_instr, value != Py_False);
}
sym_set_const(flag, Py_False);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -3256,6 +3416,7 @@
eliminate_pop_guard(this_instr, true);
}
sym_set_const(val, Py_None);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -3273,6 +3434,7 @@
assert(!sym_matches_type(val, &_PyNone_Type));
eliminate_pop_guard(this_instr, false);
}
+ CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -3317,6 +3479,7 @@
JitOptRef value;
PyObject *ptr = (PyObject *)this_instr->operand0;
value = sym_new_const(ctx, ptr);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3335,6 +3498,7 @@
JitOptRef value;
PyObject *ptr = (PyObject *)this_instr->operand0;
value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
+ CHECK_STACK_BOUNDS(1);
stack_pointer[0] = value;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3342,18 +3506,21 @@
}
case _POP_CALL: {
+ CHECK_STACK_BOUNDS(-2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _POP_CALL_ONE: {
+ CHECK_STACK_BOUNDS(-3);
stack_pointer += -3;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
case _POP_CALL_TWO: {
+ CHECK_STACK_BOUNDS(-4);
stack_pointer += -4;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
@@ -3370,6 +3537,7 @@
case _POP_TWO_LOAD_CONST_INLINE_BORROW: {
JitOptRef value;
value = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = value;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3380,6 +3548,7 @@
JitOptRef value;
PyObject *ptr = (PyObject *)this_instr->operand0;
value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
+ CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = value;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3390,6 +3559,7 @@
JitOptRef value;
PyObject *ptr = (PyObject *)this_instr->operand0;
value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
+ CHECK_STACK_BOUNDS(-2);
stack_pointer[-3] = value;
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3400,6 +3570,7 @@
JitOptRef value;
PyObject *ptr = (PyObject *)this_instr->operand0;
value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
+ CHECK_STACK_BOUNDS(-3);
stack_pointer[-4] = value;
stack_pointer += -3;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@@ -3411,6 +3582,7 @@
JitOptRef new;
value = sym_new_not_null(ctx);
new = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = value;
stack_pointer[0] = new;
stack_pointer += 1;
@@ -3423,6 +3595,7 @@
JitOptRef new;
value = sym_new_not_null(ctx);
new = sym_new_not_null(ctx);
+ CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = value;
stack_pointer[0] = new;
stack_pointer += 1;
diff --git a/Tools/cases_generator/optimizer_generator.py
b/Tools/cases_generator/optimizer_generator.py
index 41df073cf6df23..ab0a90e234b124 100644
--- a/Tools/cases_generator/optimizer_generator.py
+++ b/Tools/cases_generator/optimizer_generator.py
@@ -445,7 +445,7 @@ def generate_abstract_interpreter(
declare_variables(override, out, skip_inputs=False)
else:
declare_variables(uop, out, skip_inputs=True)
- stack = Stack()
+ stack = Stack(check_stack_bounds=True)
write_uop(override, uop, out, stack, debug, skip_inputs=(override is
None))
out.start_line()
out.emit("break;\n")
diff --git a/Tools/cases_generator/stack.py b/Tools/cases_generator/stack.py
index 6519e8e4f3ed36..53499558aed876 100644
--- a/Tools/cases_generator/stack.py
+++ b/Tools/cases_generator/stack.py
@@ -216,11 +216,12 @@ def array_or_scalar(var: StackItem | Local) -> str:
return "array" if var.is_array() else "scalar"
class Stack:
- def __init__(self) -> None:
+ def __init__(self, check_stack_bounds: bool = False) -> None:
self.base_offset = PointerOffset.zero()
self.physical_sp = PointerOffset.zero()
self.logical_sp = PointerOffset.zero()
self.variables: list[Local] = []
+ self.check_stack_bounds = check_stack_bounds
def drop(self, var: StackItem, check_liveness: bool) -> None:
self.logical_sp = self.logical_sp.pop(var)
@@ -316,8 +317,17 @@ def save_variables(self, out: CWriter) -> None:
self._print(out)
var_offset = var_offset.push(var.item)
+ def stack_bound_check(self, out: CWriter) -> None:
+ if not self.check_stack_bounds:
+ return
+ if self.physical_sp != self.logical_sp:
+ diff = self.logical_sp - self.physical_sp
+ out.start_line()
+ out.emit(f"CHECK_STACK_BOUNDS({diff});\n")
+
def flush(self, out: CWriter) -> None:
self._print(out)
+ self.stack_bound_check(out)
self.save_variables(out)
self._save_physical_sp(out)
out.start_line()
@@ -347,6 +357,7 @@ def copy(self) -> "Stack":
other.physical_sp = self.physical_sp
other.logical_sp = self.logical_sp
other.variables = [var.copy() for var in self.variables]
+ other.check_stack_bounds = self.check_stack_bounds
return other
def __eq__(self, other: object) -> bool:
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]