gh-134584: Remove custom float decref ops (GH-142576)

This commit is contained in:
Ken Jin 2025-12-16 03:38:58 +08:00 committed by GitHub
parent b3b644b6b8
commit 0ac4e6c6cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 2606 additions and 3131 deletions

View file

@ -678,53 +678,7 @@ dummy_func(
EXIT_IF(!PyFloat_CheckExact(value_o));
}
pure op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyFloat_CheckExact(left_o));
assert(PyFloat_CheckExact(right_o));
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left_o)->ob_fval *
((PyFloatObject *)right_o)->ob_fval;
res = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
INPUTS_DEAD();
ERROR_IF(PyStackRef_IsNull(res));
}
pure op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyFloat_CheckExact(left_o));
assert(PyFloat_CheckExact(right_o));
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left_o)->ob_fval +
((PyFloatObject *)right_o)->ob_fval;
res = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
INPUTS_DEAD();
ERROR_IF(PyStackRef_IsNull(res));
}
pure op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyFloat_CheckExact(left_o));
assert(PyFloat_CheckExact(right_o));
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left_o)->ob_fval -
((PyFloatObject *)right_o)->ob_fval;
res = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
INPUTS_DEAD();
ERROR_IF(PyStackRef_IsNull(res));
}
pure op(_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS, (left, right -- res)) {
pure op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res, l, r)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyFloat_CheckExact(left_o));
@ -735,11 +689,15 @@ dummy_func(
((PyFloatObject *)left_o)->ob_fval *
((PyFloatObject *)right_o)->ob_fval;
res = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
ERROR_NO_POP();
}
l = left;
r = right;
INPUTS_DEAD();
ERROR_IF(PyStackRef_IsNull(res));
}
pure op(_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS, (left, right -- res)) {
pure op(_BINARY_OP_ADD_FLOAT, (left, right -- res, l, r)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyFloat_CheckExact(left_o));
@ -750,11 +708,15 @@ dummy_func(
((PyFloatObject *)left_o)->ob_fval +
((PyFloatObject *)right_o)->ob_fval;
res = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
ERROR_NO_POP();
}
l = left;
r = right;
INPUTS_DEAD();
ERROR_IF(PyStackRef_IsNull(res));
}
pure op(_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS, (left, right -- res)) {
pure op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res, l, r)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyFloat_CheckExact(left_o));
@ -765,16 +727,20 @@ dummy_func(
((PyFloatObject *)left_o)->ob_fval -
((PyFloatObject *)right_o)->ob_fval;
res = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
ERROR_NO_POP();
}
l = left;
r = right;
INPUTS_DEAD();
ERROR_IF(PyStackRef_IsNull(res));
}
macro(BINARY_OP_MULTIPLY_FLOAT) =
_GUARD_TOS_FLOAT + _GUARD_NOS_FLOAT + unused/5 + _BINARY_OP_MULTIPLY_FLOAT;
_GUARD_TOS_FLOAT + _GUARD_NOS_FLOAT + unused/5 + _BINARY_OP_MULTIPLY_FLOAT + _POP_TOP_FLOAT + _POP_TOP_FLOAT;
macro(BINARY_OP_ADD_FLOAT) =
_GUARD_TOS_FLOAT + _GUARD_NOS_FLOAT + unused/5 + _BINARY_OP_ADD_FLOAT;
_GUARD_TOS_FLOAT + _GUARD_NOS_FLOAT + unused/5 + _BINARY_OP_ADD_FLOAT + _POP_TOP_FLOAT + _POP_TOP_FLOAT;
macro(BINARY_OP_SUBTRACT_FLOAT) =
_GUARD_TOS_FLOAT + _GUARD_NOS_FLOAT + unused/5 + _BINARY_OP_SUBTRACT_FLOAT;
_GUARD_TOS_FLOAT + _GUARD_NOS_FLOAT + unused/5 + _BINARY_OP_SUBTRACT_FLOAT + _POP_TOP_FLOAT + _POP_TOP_FLOAT;
pure op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);

View file

@ -252,10 +252,11 @@ GETITEM(PyObject *v, Py_ssize_t i) {
(frame->owner == FRAME_OWNED_BY_INTERPRETER || (STACK_LEVEL() >= 0 && STACK_LEVEL() <= STACK_SIZE()))
#if defined(Py_DEBUG) && !defined(_Py_JIT)
#define WITHIN_STACK_BOUNDS_WITH_CACHE() \
(frame->owner == FRAME_OWNED_BY_INTERPRETER || (STACK_LEVEL() >= 0 && (STACK_LEVEL() + current_cached_values) <= STACK_SIZE()))
// This allows temporary stack "overflows", provided it's all in the cache at any point of time.
#define WITHIN_STACK_BOUNDS_IGNORING_CACHE() \
(frame->owner == FRAME_OWNED_BY_INTERPRETER || (STACK_LEVEL() >= 0 && (STACK_LEVEL()) <= STACK_SIZE()))
#else
#define WITHIN_STACK_BOUNDS_WITH_CACHE WITHIN_STACK_BOUNDS
#define WITHIN_STACK_BOUNDS_IGNORING_CACHE WITHIN_STACK_BOUNDS
#endif
/* Data access macros */

3229
Python/executor_cases.c.h generated

File diff suppressed because it is too large Load diff

View file

@ -96,6 +96,8 @@
_PyStackRef left;
_PyStackRef right;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
// _GUARD_TOS_FLOAT
{
value = stack_pointer[-1];
@ -128,10 +130,24 @@
double dres =
((PyFloatObject *)left_o)->ob_fval +
((PyFloatObject *)right_o)->ob_fval;
res = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
res = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
JUMP_TO_LABEL(pop_2_error);
JUMP_TO_LABEL(error);
}
l = left;
r = right;
}
// _POP_TOP_FLOAT
{
value = r;
assert(PyFloat_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyFloat_ExactDealloc);
}
// _POP_TOP_FLOAT
{
value = l;
assert(PyFloat_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyFloat_ExactDealloc);
}
stack_pointer[-2] = res;
stack_pointer += -1;
@ -421,6 +437,8 @@
_PyStackRef left;
_PyStackRef right;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
// _GUARD_TOS_FLOAT
{
value = stack_pointer[-1];
@ -453,10 +471,24 @@
double dres =
((PyFloatObject *)left_o)->ob_fval *
((PyFloatObject *)right_o)->ob_fval;
res = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
res = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
JUMP_TO_LABEL(pop_2_error);
JUMP_TO_LABEL(error);
}
l = left;
r = right;
}
// _POP_TOP_FLOAT
{
value = r;
assert(PyFloat_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyFloat_ExactDealloc);
}
// _POP_TOP_FLOAT
{
value = l;
assert(PyFloat_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyFloat_ExactDealloc);
}
stack_pointer[-2] = res;
stack_pointer += -1;
@ -1003,6 +1035,8 @@
_PyStackRef left;
_PyStackRef right;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
// _GUARD_TOS_FLOAT
{
value = stack_pointer[-1];
@ -1035,10 +1069,24 @@
double dres =
((PyFloatObject *)left_o)->ob_fval -
((PyFloatObject *)right_o)->ob_fval;
res = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
res = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
JUMP_TO_LABEL(pop_2_error);
JUMP_TO_LABEL(error);
}
l = left;
r = right;
}
// _POP_TOP_FLOAT
{
value = r;
assert(PyFloat_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyFloat_ExactDealloc);
}
// _POP_TOP_FLOAT
{
value = l;
assert(PyFloat_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyFloat_ExactDealloc);
}
stack_pointer[-2] = res;
stack_pointer += -1;

View file

@ -196,7 +196,7 @@ check_stack_bounds(JitOptContext *ctx, JitOptRef *stack_pointer, int offset, int
(opcode == _RETURN_VALUE) ||
(opcode == _RETURN_GENERATOR) ||
(opcode == _YIELD_VALUE);
if (should_check && (stack_level < 0 || stack_level > STACK_SIZE())) {
if (should_check && (stack_level < 0 || stack_level > STACK_SIZE() + MAX_CACHED_REGISTER)) {
ctx->contradiction = true;
ctx->done = true;
return 1;
@ -312,7 +312,7 @@ _Py_opt_assert_within_stack_bounds(
fflush(stdout);
abort();
}
int size = (int)(frame->stack_len);
int size = (int)(frame->stack_len) + MAX_CACHED_REGISTER;
if (level > size) {
printf("Stack overflow (depth = %d) at %s:%d\n", level, filename, lineno);
fflush(stdout);
@ -327,13 +327,6 @@ _Py_opt_assert_within_stack_bounds(
#define ASSERT_WITHIN_STACK_BOUNDS(F, L) (void)0
#endif
// TODO (gh-134584) generate most of this table automatically
const uint16_t op_without_decref_inputs[MAX_UOP_ID + 1] = {
[_BINARY_OP_MULTIPLY_FLOAT] = _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS,
[_BINARY_OP_ADD_FLOAT] = _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS,
[_BINARY_OP_SUBTRACT_FLOAT] = _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS,
};
/* >0 (length) for success, 0 for not ready, clears all possible errors. */
static int
optimize_uops(

View file

@ -261,31 +261,25 @@ dummy_func(void) {
res = sym_new_compact_int(ctx);
}
op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) {
op(_BINARY_OP_ADD_FLOAT, (left, right -- res, l, r)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
res = sym_new_type(ctx, &PyFloat_Type);
// TODO (gh-134584): Refactor this to use another uop
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0);
}
l = left;
r = right;
}
op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) {
op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res, l, r)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
res = sym_new_type(ctx, &PyFloat_Type);
// TODO (gh-134584): Refactor this to use another uop
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0);
}
l = left;
r = right;
}
op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) {
op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res, l, r)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
res = sym_new_type(ctx, &PyFloat_Type);
// TODO (gh-134584): Refactor this to use another uop
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0);
}
l = left;
r = right;
}
op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) {
@ -546,6 +540,12 @@ dummy_func(void) {
}
}
op(_POP_TOP_FLOAT, (value --)) {
if (PyJitRef_IsBorrowed(value)) {
REPLACE_OP(this_instr, _POP_TOP_NOP, 0, 0);
}
}
op(_COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) {
assert(oparg > 0);
top = bottom;

View file

@ -153,6 +153,11 @@
}
case _POP_TOP_FLOAT: {
JitOptRef value;
value = stack_pointer[-1];
if (PyJitRef_IsBorrowed(value)) {
REPLACE_OP(this_instr, _POP_TOP_NOP, 0, 0);
}
CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
@ -668,6 +673,8 @@
JitOptRef right;
JitOptRef left;
JitOptRef res;
JitOptRef l;
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
@ -679,6 +686,8 @@
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
_PyStackRef l_stackref;
_PyStackRef r_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
@ -688,32 +697,32 @@
double dres =
((PyFloatObject *)left_o)->ob_fval *
((PyFloatObject *)right_o)->ob_fval;
res_stackref = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
if (PyStackRef_IsNull(res_stackref )) {
goto error;
res_stackref = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
JUMP_TO_LABEL(error);
}
l_stackref = left;
r_stackref = right;
/* End of uop copied from bytecodes for constant evaluation */
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_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(-1);
l = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(l_stackref));
r = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(r_stackref));
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyFloat_Type);
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0);
}
CHECK_STACK_BOUNDS(-1);
l = left;
r = right;
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
@ -722,6 +731,8 @@
JitOptRef right;
JitOptRef left;
JitOptRef res;
JitOptRef l;
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
@ -733,6 +744,8 @@
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
_PyStackRef l_stackref;
_PyStackRef r_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
@ -742,32 +755,32 @@
double dres =
((PyFloatObject *)left_o)->ob_fval +
((PyFloatObject *)right_o)->ob_fval;
res_stackref = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
if (PyStackRef_IsNull(res_stackref )) {
goto error;
res_stackref = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
JUMP_TO_LABEL(error);
}
l_stackref = left;
r_stackref = right;
/* End of uop copied from bytecodes for constant evaluation */
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_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(-1);
l = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(l_stackref));
r = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(r_stackref));
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyFloat_Type);
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0);
}
CHECK_STACK_BOUNDS(-1);
l = left;
r = right;
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
@ -776,6 +789,8 @@
JitOptRef right;
JitOptRef left;
JitOptRef res;
JitOptRef l;
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
@ -787,6 +802,8 @@
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
_PyStackRef l_stackref;
_PyStackRef r_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
@ -796,62 +813,32 @@
double dres =
((PyFloatObject *)left_o)->ob_fval -
((PyFloatObject *)right_o)->ob_fval;
res_stackref = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
if (PyStackRef_IsNull(res_stackref )) {
goto error;
res_stackref = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
JUMP_TO_LABEL(error);
}
l_stackref = left;
r_stackref = right;
/* End of uop copied from bytecodes for constant evaluation */
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_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(-1);
l = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(l_stackref));
r = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(r_stackref));
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyFloat_Type);
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0);
}
CHECK_STACK_BOUNDS(-1);
l = left;
r = right;
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
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__);
break;
}
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__);
break;
}
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;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}