From e4c286dac3584e41153c9921c6afdfc4d612934a Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Sat, 4 Apr 2026 09:47:12 +0200 Subject: [PATCH] Berry crash when comparing for equality float literals on ESP32 (#24610) --- CHANGELOG.md | 1 + lib/libesp32/berry/src/be_vm.c | 99 ++++++++++++++++++++++------------ 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 205f4f9a0..cdc431c39 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/lib/libesp32/berry/src/be_vm.c b/lib/libesp32/berry/src/be_vm.c index 4b2a98ebe..e4ccc5f79 100644 --- a/lib/libesp32/berry/src/be_vm.c +++ b/lib/libesp32/berry/src/be_vm.c @@ -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;