Berry crash when comparing for equality float literals on ESP32 (#24610)

This commit is contained in:
s-hadinger
2026-04-04 09:47:12 +02:00
committed by GitHub
parent fcef1b63b0
commit e4c286dac3
2 changed files with 67 additions and 33 deletions
+1
View File
@@ -25,6 +25,7 @@ All notable changes to this project will be documented in this file.
- ESP8266 heap drain and exception 29 when DHCP provides NTP server (#24515, #24566)
- NeoPool possible IntegerDivideByZero (#24578)
- Shelly Dimmer 2 serial timeout regression from v15.2.0.1 (#24560)
- Berry crash when comparing for equality float literals on ESP32
### Removed
+66 -33
View File
@@ -81,36 +81,41 @@
#define opcase(opcode) case OP_##opcode
#define dispatch() goto loop
#define equal_rule(op, iseq) \
bbool res; \
be_assert(!var_isstatic(a)); \
be_assert(!var_isstatic(b)); \
if (var_isint(a) && var_isint(b)) { \
res = ibinop(op, a, b); \
} else if (var_isnumber(a) && var_isnumber(b)) { \
res = var2real(a) op var2real(b); \
} else if (var_isinstance(a) && !var_isnil(b)) { \
res = object_eqop(vm, #op, iseq, a, b); \
} else if (var_primetype(a) == var_primetype(b)) { /* same types */ \
if (var_isnil(a)) { /* nil op nil */ \
res = 1 op 1; \
} else if (var_isbool(a)) { /* bool op bool */ \
res = var_tobool(a) op var_tobool(b); \
} else if (var_isstr(a)) { /* string op string */ \
res = 1 op be_eqstr(a->v.s, b->v.s); \
} else if (var_isclass(a) || var_isfunction(a) || var_iscomptr(a)) { \
res = var_toobj(a) op var_toobj(b); \
} else { \
binop_error(vm, #op, a, b); \
res = bfalse; /* will not be executed */ \
#if CONFIG_IDF_TARGET_ESP32 /* when running on ESP32 in IRAM, there is a bug in early chip revision */
#define equal_rule(op, iseq) \
bbool res; \
be_assert(!var_isstatic(a)); \
be_assert(!var_isstatic(b)); \
if (var_isint(a) && var_isint(b)) { \
res = ibinop(op, a, b); \
} else if (var_isnumber(a) && var_isnumber(b)) { \
union bvaldata x, y; \
x.i = a->v.i; \
if (var_isint(a)) { x.r = (breal) x.i; } \
y.i = b->v.i; \
if (var_isint(b)) { y.r = (breal) y.i; } \
res = x.r op y.r; \
} else if (var_isinstance(a) && !var_isnil(b)) { \
res = object_eqop(vm, #op, iseq, a, b); \
} else if (var_primetype(a) == var_primetype(b)) { /* same types */ \
if (var_isnil(a)) { /* nil op nil */ \
res = 1 op 1; \
} else if (var_isbool(a)) { /* bool op bool */ \
res = var_tobool(a) op var_tobool(b); \
} else if (var_isstr(a)) { /* string op string */ \
res = 1 op be_eqstr(a->v.s, b->v.s); \
} else if (var_isclass(a) || var_isfunction(a) || var_iscomptr(a)) { \
res = var_toobj(a) op var_toobj(b); \
} else { \
binop_error(vm, #op, a, b); \
res = bfalse; /* will not be executed */ \
} \
} else { /* different types */ \
res = 1 op 0; \
} \
} else { /* different types */ \
res = 1 op 0; \
} \
return res
return res
/* when running on ESP32 in IRAM, there is a bug in early chip revision */
#ifdef ESP32
#define relop_rule(op) \
bbool res; \
if (var_isint(a) && var_isint(b)) { \
@@ -136,7 +141,35 @@
res = bfalse; /* will not be executed */ \
} \
return res
#else // ESP32
#else // CONFIG_IDF_TARGET_ESP32
#define equal_rule(op, iseq) \
bbool res; \
be_assert(!var_isstatic(a)); \
be_assert(!var_isstatic(b)); \
if (var_isint(a) && var_isint(b)) { \
res = ibinop(op, a, b); \
} else if (var_isnumber(a) && var_isnumber(b)) { \
res = var2real(a) op var2real(b); \
} else if (var_isinstance(a) && !var_isnil(b)) { \
res = object_eqop(vm, #op, iseq, a, b); \
} else if (var_primetype(a) == var_primetype(b)) { /* same types */ \
if (var_isnil(a)) { /* nil op nil */ \
res = 1 op 1; \
} else if (var_isbool(a)) { /* bool op bool */ \
res = var_tobool(a) op var_tobool(b); \
} else if (var_isstr(a)) { /* string op string */ \
res = 1 op be_eqstr(a->v.s, b->v.s); \
} else if (var_isclass(a) || var_isfunction(a) || var_iscomptr(a)) { \
res = var_toobj(a) op var_toobj(b); \
} else { \
binop_error(vm, #op, a, b); \
res = bfalse; /* will not be executed */ \
} \
} else { /* different types */ \
res = 1 op 0; \
} \
return res
#define relop_rule(op) \
bbool res; \
if (var_isint(a) && var_isint(b)) { \
@@ -156,7 +189,7 @@
res = bfalse; /* will not be executed */ \
} \
return res
#endif // ESP32
#endif // CONFIG_IDF_TARGET_ESP32
#define bitwise_block(op) \
bvalue *dst = RA(), *a = RKB(), *b = RKC(); \
@@ -662,17 +695,17 @@ newframe: /* a new call frame */
if (var_isint(a) && var_isint(b)) {
var_setint(dst, ibinop(+, a, b));
} else if (var_isnumber(a) && var_isnumber(b)) {
#ifdef ESP32 /* when running on ESP32 in IRAM, there is a bug in early chip revision */
#if CONFIG_IDF_TARGET_ESP32 /* when running on ESP32 in IRAM, there is a bug in early chip revision */
union bvaldata x, y; // TASMOTA workaround for ESP32 rev0 bug
x.i = a->v.i;
if (var_isint(a)) { x.r = (breal) x.i; }
y.i = b->v.i;
if (var_isint(b)) { y.r = (breal) y.i; }
var_setreal(dst, x.r + y.r);
#else // ESP32
#else // CONFIG_IDF_TARGET_ESP32
breal x = var2real(a), y = var2real(b);
var_setreal(dst, x + y);
#endif // ESP32
#endif // CONFIG_IDF_TARGET_ESP32
} else if (var_isstr(a) && var_isstr(b)) { /* strcat */
bstring *s = be_strcat(vm, var_tostr(a), var_tostr(b));
reg = vm->reg;