gh-134584: JIT: Remove redundant refcounting for UNARY_{INVERT|NEGATIVE} (GH-143704)

This commit is contained in:
Ken Jin 2026-01-12 04:42:55 +08:00 committed by GitHub
parent 9d13ca97c1
commit 548526bbbe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 976 additions and 899 deletions

View file

@ -1309,9 +1309,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[TO_BOOL_NONE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
[TO_BOOL_STR] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
[TRACE_RECORD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNARY_NOT] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
[UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[UNARY_NOT] = { true, INSTR_FMT_IX, 0 },
[UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
@ -1521,8 +1521,8 @@ _PyOpcode_macro_expansion[256] = {
[TO_BOOL_LIST] = { .nuops = 2, .uops = { { _GUARD_TOS_LIST, OPARG_SIMPLE, 0 }, { _TO_BOOL_LIST, OPARG_SIMPLE, 3 } } },
[TO_BOOL_NONE] = { .nuops = 1, .uops = { { _TO_BOOL_NONE, OPARG_SIMPLE, 3 } } },
[TO_BOOL_STR] = { .nuops = 3, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _TO_BOOL_STR, OPARG_SIMPLE, 3 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 3 } } },
[UNARY_INVERT] = { .nuops = 1, .uops = { { _UNARY_INVERT, OPARG_SIMPLE, 0 } } },
[UNARY_NEGATIVE] = { .nuops = 1, .uops = { { _UNARY_NEGATIVE, OPARG_SIMPLE, 0 } } },
[UNARY_INVERT] = { .nuops = 2, .uops = { { _UNARY_INVERT, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
[UNARY_NEGATIVE] = { .nuops = 2, .uops = { { _UNARY_NEGATIVE, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
[UNARY_NOT] = { .nuops = 1, .uops = { { _UNARY_NOT, OPARG_SIMPLE, 0 } } },
[UNPACK_EX] = { .nuops = 1, .uops = { { _UNPACK_EX, OPARG_SIMPLE, 0 } } },
[UNPACK_SEQUENCE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE, OPARG_SIMPLE, 0 } } },

File diff suppressed because it is too large Load diff

View file

@ -84,8 +84,8 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_END_FOR] = HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG,
[_POP_ITER] = HAS_ESCAPES_FLAG,
[_END_SEND] = HAS_ESCAPES_FLAG | HAS_PURE_FLAG,
[_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_UNARY_NOT] = HAS_PURE_FLAG,
[_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_UNARY_NOT] = 0,
[_TO_BOOL] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_TO_BOOL_BOOL] = HAS_EXIT_FLAG,
[_TO_BOOL_INT] = HAS_EXIT_FLAG | HAS_ESCAPES_FLAG,
@ -99,7 +99,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_GUARD_TOS_UNICODE] = HAS_EXIT_FLAG,
[_TO_BOOL_STR] = 0,
[_REPLACE_WITH_TRUE] = 0,
[_UNARY_INVERT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_UNARY_INVERT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_NOS_INT] = HAS_EXIT_FLAG,
[_GUARD_TOS_INT] = HAS_EXIT_FLAG,
[_GUARD_NOS_OVERFLOWED] = HAS_EXIT_FLAG,
@ -821,7 +821,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
{ 1, 1, _UNARY_NEGATIVE_r11 },
{ 2, 1, _UNARY_NEGATIVE_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@ -956,7 +956,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.best = { 1, 1, 1, 1 },
.entries = {
{ -1, -1, -1 },
{ 1, 1, _UNARY_INVERT_r11 },
{ 2, 1, _UNARY_INVERT_r12 },
{ -1, -1, -1 },
{ -1, -1, -1 },
},
@ -3470,7 +3470,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_END_FOR_r10] = _END_FOR,
[_POP_ITER_r20] = _POP_ITER,
[_END_SEND_r21] = _END_SEND,
[_UNARY_NEGATIVE_r11] = _UNARY_NEGATIVE,
[_UNARY_NEGATIVE_r12] = _UNARY_NEGATIVE,
[_UNARY_NOT_r01] = _UNARY_NOT,
[_UNARY_NOT_r11] = _UNARY_NOT,
[_UNARY_NOT_r22] = _UNARY_NOT,
@ -3516,7 +3516,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_REPLACE_WITH_TRUE_r02] = _REPLACE_WITH_TRUE,
[_REPLACE_WITH_TRUE_r12] = _REPLACE_WITH_TRUE,
[_REPLACE_WITH_TRUE_r23] = _REPLACE_WITH_TRUE,
[_UNARY_INVERT_r11] = _UNARY_INVERT,
[_UNARY_INVERT_r12] = _UNARY_INVERT,
[_GUARD_NOS_INT_r02] = _GUARD_NOS_INT,
[_GUARD_NOS_INT_r12] = _GUARD_NOS_INT,
[_GUARD_NOS_INT_r22] = _GUARD_NOS_INT,
@ -5122,9 +5122,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_TO_BOOL_STR_r12] = "_TO_BOOL_STR_r12",
[_TO_BOOL_STR_r23] = "_TO_BOOL_STR_r23",
[_UNARY_INVERT] = "_UNARY_INVERT",
[_UNARY_INVERT_r11] = "_UNARY_INVERT_r11",
[_UNARY_INVERT_r12] = "_UNARY_INVERT_r12",
[_UNARY_NEGATIVE] = "_UNARY_NEGATIVE",
[_UNARY_NEGATIVE_r11] = "_UNARY_NEGATIVE_r11",
[_UNARY_NEGATIVE_r12] = "_UNARY_NEGATIVE_r12",
[_UNARY_NOT] = "_UNARY_NOT",
[_UNARY_NOT_r01] = "_UNARY_NOT_r01",
[_UNARY_NOT_r11] = "_UNARY_NOT_r11",

View file

@ -1636,7 +1636,7 @@ def testfunc(n):
self.assertNotIn("_UNARY_NOT", uops)
self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops)
def test_unary_invert_pop_top_load_const_inline_borrow(self):
def test_unary_invert_insert_1_load_const_inline_borrow(self):
def testfunc(n):
x = 0
for i in range(n):
@ -1651,7 +1651,7 @@ def testfunc(n):
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertNotIn("_UNARY_INVERT", uops)
self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops)
self.assertIn("_INSERT_1_LOAD_CONST_INLINE_BORROW", uops)
def test_compare_op_pop_two_load_const_inline_borrow(self):
def testfunc(n):
@ -3470,6 +3470,39 @@ def testfunc(n):
# _POP_TOP_NOP is a sign the optimizer ran and didn't hit bottom.
self.assertGreaterEqual(count_ops(ex, "_POP_TOP_NOP"), 1)
def test_unary_negative(self):
def testfunc(n):
a = 3
for _ in range(n):
res = -a
return res
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertEqual(res, -3)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_UNARY_NEGATIVE", uops)
self.assertIn("_POP_TOP_NOP", uops)
self.assertLessEqual(count_ops(ex, "_POP_TOP"), 2)
def test_unary_invert(self):
def testfunc(n):
a = 3
for _ in range(n):
res = ~a
return res
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertEqual(res, -4)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_UNARY_INVERT", uops)
self.assertIn("_POP_TOP_NOP", uops)
self.assertLessEqual(count_ops(ex, "_POP_TOP"), 2)
def test_143026(self):
# https://github.com/python/cpython/issues/143026

View file

@ -434,14 +434,19 @@ dummy_func(
PyStackRef_CLOSE(receiver);
}
inst(UNARY_NEGATIVE, (value -- res)) {
macro(UNARY_NEGATIVE) = _UNARY_NEGATIVE + POP_TOP;
op(_UNARY_NEGATIVE, (value -- res, v)) {
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
ERROR_IF(res_o == NULL);
if (res_o == NULL) {
ERROR_NO_POP();
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
DEAD(value);
}
pure inst(UNARY_NOT, (value -- res)) {
inst(UNARY_NOT, (value -- res)) {
assert(PyStackRef_BoolCheck(value));
res = PyStackRef_IsFalse(value)
? PyStackRef_True : PyStackRef_False;
@ -570,11 +575,16 @@ dummy_func(
_REPLACE_WITH_TRUE +
POP_TOP;
inst(UNARY_INVERT, (value -- res)) {
macro(UNARY_INVERT) = _UNARY_INVERT + POP_TOP;
op(_UNARY_INVERT, (value -- res, v)) {
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
ERROR_IF(res_o == NULL);
if (res_o == NULL) {
ERROR_NO_POP();
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
DEAD(value);
}
family(BINARY_OP, INLINE_CACHE_ENTRIES_BINARY_OP) = {

View file

@ -2631,11 +2631,12 @@
break;
}
case _UNARY_NEGATIVE_r11: {
case _UNARY_NEGATIVE_r12: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef value;
_PyStackRef res;
_PyStackRef v;
_PyStackRef _stack_item_0 = _tos_cache0;
value = _stack_item_0;
stack_pointer[0] = value;
@ -2644,20 +2645,18 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_ERROR();
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
_tos_cache1 = v;
_tos_cache0 = res;
_tos_cache1 = PyStackRef_ZERO_BITS;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(2);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
@ -3667,11 +3666,12 @@
break;
}
case _UNARY_INVERT_r11: {
case _UNARY_INVERT_r12: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef value;
_PyStackRef res;
_PyStackRef v;
_PyStackRef _stack_item_0 = _tos_cache0;
value = _stack_item_0;
stack_pointer[0] = value;
@ -3680,20 +3680,18 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_ERROR();
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
_tos_cache1 = v;
_tos_cache0 = res;
_tos_cache1 = PyStackRef_ZERO_BITS;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(2);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}

View file

@ -11860,22 +11860,27 @@
INSTRUCTION_STATS(UNARY_INVERT);
_PyStackRef value;
_PyStackRef res;
value = stack_pointer[-1];
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
JUMP_TO_LABEL(error);
_PyStackRef v;
// _UNARY_INVERT
{
value = stack_pointer[-1];
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
JUMP_TO_LABEL(error);
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
}
// _POP_TOP
{
value = v;
stack_pointer[-1] = res;
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_XCLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
}
res = PyStackRef_FromPyObjectSteal(res_o);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
DISPATCH();
}
@ -11889,22 +11894,27 @@
INSTRUCTION_STATS(UNARY_NEGATIVE);
_PyStackRef value;
_PyStackRef res;
value = stack_pointer[-1];
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
JUMP_TO_LABEL(error);
_PyStackRef v;
// _UNARY_NEGATIVE
{
value = stack_pointer[-1];
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
JUMP_TO_LABEL(error);
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
}
// _POP_TOP
{
value = v;
stack_pointer[-1] = res;
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_XCLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
}
res = PyStackRef_FromPyObjectSteal(res_o);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
DISPATCH();
}

View file

@ -449,7 +449,8 @@ dummy_func(void) {
res = sym_new_truthiness(ctx, value, false);
}
op(_UNARY_NEGATIVE, (value -- res)) {
op(_UNARY_NEGATIVE, (value -- res, v)) {
v = value;
REPLACE_OPCODE_IF_EVALUATES_PURE(value, res);
if (sym_is_compact_int(value)) {
res = sym_new_compact_int(ctx);
@ -465,7 +466,8 @@ dummy_func(void) {
}
}
op(_UNARY_INVERT, (value -- res)) {
op(_UNARY_INVERT, (value -- res, v)) {
v = value;
// Required to avoid a warning due to the deprecation of bitwise inversion of bools
if (!sym_matches_type(value, &PyBool_Type)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(value, res);

View file

@ -221,30 +221,38 @@
case _UNARY_NEGATIVE: {
JitOptRef value;
JitOptRef res;
JitOptRef v;
value = stack_pointer[-1];
v = value;
if (
sym_is_safe_const(ctx, value)
) {
JitOptRef value_sym = value;
_PyStackRef value = sym_get_const_as_stackref(ctx, value_sym);
_PyStackRef res_stackref;
_PyStackRef v_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
if (res_o == NULL) {
goto error;
JUMP_TO_LABEL(error);
}
res_stackref = PyStackRef_FromPyObjectSteal(res_o);
v_stackref = value;
/* End of uop copied from bytecodes for constant evaluation */
(void)v_stackref;
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
if (sym_is_const(ctx, res)) {
PyObject *result = sym_get_const(ctx, res);
if (_Py_IsImmortal(result)) {
// Replace with _POP_TOP_LOAD_CONST_INLINE_BORROW since we have one input and an immortal result
REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
// Replace with _INSERT_1_LOAD_CONST_INLINE_BORROW since we have one input and an immortal result
REPLACE_OP(this_instr, _INSERT_1_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = res;
stack_pointer[0] = v;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
if (sym_is_compact_int(value)) {
@ -259,7 +267,11 @@
res = sym_new_not_null(ctx);
}
}
CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = res;
stack_pointer[0] = v;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
@ -444,7 +456,9 @@
case _UNARY_INVERT: {
JitOptRef value;
JitOptRef res;
JitOptRef v;
value = stack_pointer[-1];
v = value;
if (!sym_matches_type(value, &PyBool_Type)) {
if (
sym_is_safe_const(ctx, value)
@ -452,23 +466,29 @@
JitOptRef value_sym = value;
_PyStackRef value = sym_get_const_as_stackref(ctx, value_sym);
_PyStackRef res_stackref;
_PyStackRef v_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
if (res_o == NULL) {
goto error;
JUMP_TO_LABEL(error);
}
res_stackref = PyStackRef_FromPyObjectSteal(res_o);
v_stackref = value;
/* End of uop copied from bytecodes for constant evaluation */
(void)v_stackref;
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
if (sym_is_const(ctx, res)) {
PyObject *result = sym_get_const(ctx, res);
if (_Py_IsImmortal(result)) {
// Replace with _POP_TOP_LOAD_CONST_INLINE_BORROW since we have one input and an immortal result
REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
// Replace with _INSERT_1_LOAD_CONST_INLINE_BORROW since we have one input and an immortal result
REPLACE_OP(this_instr, _INSERT_1_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = res;
stack_pointer[0] = v;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
}
@ -478,7 +498,11 @@
else {
res = sym_new_not_null(ctx);
}
CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = res;
stack_pointer[0] = v;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}

View file

@ -242,7 +242,7 @@ def replace_opcode_if_evaluates_pure(
0: "_POP_TOP_LOAD_CONST_INLINE_BORROW",
# (left -- res, left)
# usually for unary ops with passthrough references
2: "_INSERT_1_LOAD_CONST_INLINE_BORROW",
1: "_INSERT_1_LOAD_CONST_INLINE_BORROW",
},
2: {
# (a. b -- res), usually for binary ops