Skip to content

Commit a60a679

Browse files
committed
Merge pull request #1522 from bettio/bif-error-in-call_ext-opcodes
opcodesswitch: fix BIF error handling in `CALL_EXT` (and similar) Check return value for `term_invalid_term()` otherwise error will not be raised, and invalid terms will appear. These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents 2ac2041 + 7dfcc87 commit a60a679

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ integers
4040
- Fixed support for setting esp32 boot_path in NVS.
4141
- Fixed race conditions in network:start/stop.
4242
- Fixed crash calling network:sta_rssi(), when network not up.
43+
- Fix error handling when calling `min` and `max` with code compiled before OTP-26: there was a
44+
bug when handling errors from BIFs used as NIFs (when called with `CALL_EXT` and similar opcodes)`
4345

4446
## [0.6.5] - 2024-10-15
4547

src/libAtomVM/opcodesswitch.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,19 +1990,23 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
19901990
// Support compilers < OTP26 that generate CALL_EXT
19911991
// for min/2 and max/2
19921992
const struct Bif *bif = EXPORTED_FUNCTION_TO_BIF(func);
1993+
term return_value;
19931994
switch (arity) {
19941995
case 0:
1995-
x_regs[0] = bif->bif0_ptr(ctx);
1996+
return_value = bif->bif0_ptr(ctx);
19961997
break;
19971998
case 1:
1998-
x_regs[0] = bif->bif1_ptr(ctx, 0, x_regs[0]);
1999+
return_value = bif->bif1_ptr(ctx, 0, x_regs[0]);
19992000
break;
20002001
case 2:
2001-
x_regs[0] = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
2002+
return_value = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
20022003
break;
20032004
default:
20042005
fprintf(stderr, "Invalid arity %" PRIu32 " for bif\n", arity);
2006+
AVM_ABORT();
20052007
}
2008+
PROCESS_MAYBE_TRAP_RETURN_VALUE_RESTORE_PC(return_value, orig_pc);
2009+
x_regs[0] = return_value;
20062010

20072011
break;
20082012
}
@@ -2090,19 +2094,23 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
20902094
ctx->e += (n_words + 1);
20912095

20922096
const struct Bif *bif = EXPORTED_FUNCTION_TO_BIF(func);
2097+
term return_value;
20932098
switch (arity) {
20942099
case 0:
2095-
x_regs[0] = bif->bif0_ptr(ctx);
2100+
return_value = bif->bif0_ptr(ctx);
20962101
break;
20972102
case 1:
2098-
x_regs[0] = bif->bif1_ptr(ctx, 0, x_regs[0]);
2103+
return_value = bif->bif1_ptr(ctx, 0, x_regs[0]);
20992104
break;
21002105
case 2:
2101-
x_regs[0] = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
2106+
return_value = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
21022107
break;
21032108
default:
21042109
fprintf(stderr, "Invalid arity %" PRIu32 " for bif\n", arity);
2110+
AVM_ABORT();
21052111
}
2112+
PROCESS_MAYBE_TRAP_RETURN_VALUE_LAST(return_value);
2113+
x_regs[0] = return_value;
21062114

21072115
DO_RETURN();
21082116

@@ -3541,19 +3549,23 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
35413549
// Support compilers < OTP26 that generate CALL_EXT_ONLY
35423550
// for min/2 and max/2
35433551
const struct Bif *bif = EXPORTED_FUNCTION_TO_BIF(func);
3552+
term return_value;
35443553
switch (arity) {
35453554
case 0:
3546-
x_regs[0] = bif->bif0_ptr(ctx);
3555+
return_value = bif->bif0_ptr(ctx);
35473556
break;
35483557
case 1:
3549-
x_regs[0] = bif->bif1_ptr(ctx, 0, x_regs[0]);
3558+
return_value = bif->bif1_ptr(ctx, 0, x_regs[0]);
35503559
break;
35513560
case 2:
3552-
x_regs[0] = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
3561+
return_value = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
35533562
break;
35543563
default:
35553564
fprintf(stderr, "Invalid arity %" PRIu32 " for bif\n", arity);
3565+
AVM_ABORT();
35563566
}
3567+
PROCESS_MAYBE_TRAP_RETURN_VALUE_LAST(return_value);
3568+
x_regs[0] = return_value;
35573569

35583570
DO_RETURN();
35593571

0 commit comments

Comments
 (0)