Skip to content

Commit 0d64504

Browse files
committed
WIP BIF: refactor helpers
Signed-off-by: Davide Bettio <davide@uninstall.it>
1 parent ce3bf97 commit 0d64504

File tree

1 file changed

+50
-64
lines changed

1 file changed

+50
-64
lines changed

src/libAtomVM/bif.c

Lines changed: 50 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
RAISE_ERROR_BIF(fail_label, BADARG_ATOM); \
5858
}
5959

60+
#define MAX(a, b) ((a) > (b) ? (a) : (b))
61+
6062
const struct ExportedFunction *bif_registry_get_handler(AtomString module, AtomString function, int arity)
6163
{
6264
char bifname[MAX_BIF_NAME_LEN];
@@ -641,84 +643,68 @@ static term mul_overflow_helper(Context *ctx, uint32_t fail_label, uint32_t live
641643

642644
static term mul_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, term arg1, term arg2)
643645
{
644-
int use_float = 0;
645-
int size = 0;
646-
if (term_is_boxed_integer(arg1)) {
647-
size = term_boxed_size(arg1);
648-
} else if (term_is_float(arg1)) {
649-
use_float = 1;
650-
} else if (!term_is_integer(arg1)) {
651-
TRACE("error: arg1: 0x%lx, arg2: 0x%lx\n", arg1, arg2);
652-
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
653-
}
654-
655-
if (term_is_boxed_integer(arg2)) {
656-
size |= term_boxed_size(arg2);
657-
} else if (term_is_float(arg2)) {
658-
use_float = 1;
659-
} else if (!term_is_integer(arg2)) {
660-
TRACE("error: arg1: 0x%lx, arg2: 0x%lx\n", arg1, arg2);
646+
if (UNLIKELY(!term_is_number(arg1) || !term_is_number(arg2))) {
661647
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
662648
}
663649

664-
if (use_float) {
665-
avm_float_t farg1 = term_conv_to_float(arg1);
666-
avm_float_t farg2 = term_conv_to_float(arg2);
667-
avm_float_t fresult = farg1 * farg2;
668-
if (UNLIKELY(!isfinite(fresult))) {
669-
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
670-
}
671-
if (UNLIKELY(memory_ensure_free_with_roots(ctx, FLOAT_SIZE, live, ctx->x, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
672-
RAISE_ERROR_BIF(fail_label, OUT_OF_MEMORY_ATOM);
673-
}
674-
return term_from_float(fresult, &ctx->heap);
675-
}
650+
if (term_is_any_integer(arg1) && term_is_any_integer(arg2)) {
676651

677-
switch (size) {
678-
case 0: {
679-
//BUG
680-
AVM_ABORT();
681-
}
652+
size_t arg1_size = term_is_integer(arg1) ? 0 : term_boxed_size(arg1);
653+
size_t arg2_size = term_is_integer(arg2) ? 0 : term_boxed_size(arg2);
654+
switch (MAX(arg1_size, arg2_size)) {
655+
case 0:
656+
UNREACHABLE();
657+
case 1: {
658+
avm_int_t val1 = term_maybe_unbox_int(arg1);
659+
avm_int_t val2 = term_maybe_unbox_int(arg2);
660+
avm_int_t res;
682661

683-
case 1: {
684-
avm_int_t val1 = term_maybe_unbox_int(arg1);
685-
avm_int_t val2 = term_maybe_unbox_int(arg2);
686-
avm_int_t res;
662+
if (BUILTIN_MUL_OVERFLOW_INT(val1, val2, &res)) {
663+
#if BOXED_TERMS_REQUIRED_FOR_INT64 == 2
664+
avm_int64_t res64 = (avm_int64_t) val1 * (avm_int64_t) val2;
665+
return make_boxed_int64(ctx, fail_label, live, res64);
687666

688-
if (BUILTIN_MUL_OVERFLOW_INT(val1, val2, &res)) {
689-
#if BOXED_TERMS_REQUIRED_FOR_INT64 == 2
690-
avm_int64_t res64 = (avm_int64_t) val1 * (avm_int64_t) val2;
691-
return make_boxed_int64(ctx, fail_label, live, res64);
667+
#elif BOXED_TERMS_REQUIRED_FOR_INT64 == 1
668+
TRACE("overflow: arg1: " AVM_INT64_FMT ", arg2: " AVM_INT64_FMT "\n", arg1, arg2);
669+
RAISE_ERROR_BIF(fail_label, OVERFLOW_ATOM);
670+
#else
671+
#error "Unsupported configuration."
672+
#endif
673+
}
692674

693-
#elif BOXED_TERMS_REQUIRED_FOR_INT64 == 1
694-
TRACE("overflow: arg1: " AVM_INT64_FMT ", arg2: " AVM_INT64_FMT "\n", arg1, arg2);
695-
RAISE_ERROR_BIF(fail_label, OVERFLOW_ATOM);
696-
#else
697-
#error "Unsupported configuration."
698-
#endif
675+
return make_maybe_boxed_int(ctx, fail_label, live, res);
699676
}
700677

701-
return make_maybe_boxed_int(ctx, fail_label, live, res);
702-
}
678+
#if BOXED_TERMS_REQUIRED_FOR_INT64 == 2
679+
case 2: {
680+
avm_int64_t val1 = term_maybe_unbox_int64(arg1);
681+
avm_int64_t val2 = term_maybe_unbox_int64(arg2);
682+
avm_int64_t res;
703683

704-
#if BOXED_TERMS_REQUIRED_FOR_INT64 == 2
705-
case 2:
706-
case 3: {
707-
avm_int64_t val1 = term_maybe_unbox_int64(arg1);
708-
avm_int64_t val2 = term_maybe_unbox_int64(arg2);
709-
avm_int64_t res;
684+
if (BUILTIN_MUL_OVERFLOW_INT64(val1, val2, &res)) {
685+
TRACE("overflow: arg1: 0x%lx, arg2: 0x%lx\n", arg1, arg2);
686+
RAISE_ERROR_BIF(fail_label, OVERFLOW_ATOM);
687+
}
710688

711-
if (BUILTIN_MUL_OVERFLOW_INT64(val1, val2, &res)) {
712-
TRACE("overflow: arg1: 0x%lx, arg2: 0x%lx\n", arg1, arg2);
713-
RAISE_ERROR_BIF(fail_label, OVERFLOW_ATOM);
689+
return make_maybe_boxed_int64(ctx, fail_label, live, res);
714690
}
691+
#endif
715692

716-
return make_maybe_boxed_int64(ctx, fail_label, live, res);
693+
default:
694+
UNREACHABLE();
717695
}
718-
#endif
719-
720-
default:
721-
RAISE_ERROR_BIF(fail_label, OVERFLOW_ATOM);
696+
} else {
697+
avm_float_t farg1 = term_conv_to_float(arg1);
698+
avm_float_t farg2 = term_conv_to_float(arg2);
699+
avm_float_t fresult = farg1 * farg2;
700+
if (UNLIKELY(!isfinite(fresult))) {
701+
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
702+
}
703+
if (UNLIKELY(memory_ensure_free_with_roots(ctx, FLOAT_SIZE, live, ctx->x, MEMORY_CAN_SHRINK)
704+
!= MEMORY_GC_OK)) {
705+
RAISE_ERROR_BIF(fail_label, OUT_OF_MEMORY_ATOM);
706+
}
707+
return term_from_float(fresult, &ctx->heap);
722708
}
723709
}
724710

0 commit comments

Comments
 (0)