Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/src/programmers-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ The following Erlang type specification enumerates this type:
Erlang/OTP uses the Christian epoch to count time units from year 0 in the Gregorian calendar. The, for example, the value 0 in Gregorian seconds represents the date Jan 1, year 0, and midnight (UTC), or in Erlang terms, `{{0, 1, 1}, {0, 0, 0}}`.

```{attention}
AtomVM is currently limited to representing integers in at most 64 bits, with one bit representing the sign bit.
AtomVM is currently limited to representing time in at most 64 bits, with one bit representing the sign bit.
However, even with this limitation, AtomVM is able to resolve microsecond values in the Gregorian calendar for over
292,000 years, likely well past the likely lifetime of an AtomVM application (unless perhaps launched on a deep
space probe).
Expand Down
2 changes: 2 additions & 0 deletions src/libAtomVM/bif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,7 @@ term bif_erlang_fdiv_2(Context *ctx, uint32_t fail_label, int live, term arg1, t

static term div_maybe_bigint(Context *ctx, uint32_t fail_label, uint32_t live, term arg1, term arg2)
{
// 0 is always normalized to `term_from_int(0)`, so we can do this
if (UNLIKELY(arg2 == term_from_int(0))) {
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
}
Expand Down Expand Up @@ -1360,6 +1361,7 @@ term bif_erlang_abs_1(Context *ctx, uint32_t fail_label, int live, term arg1)

static term rem_maybe_bigint(Context *ctx, uint32_t fail_label, uint32_t live, term arg1, term arg2)
{
// 0 is always normalized to `term_from_int(0)`, so we can do this
if (UNLIKELY(arg2 == term_from_int(0))) {
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
}
Expand Down
2 changes: 2 additions & 0 deletions src/libAtomVM/nifs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2051,6 +2051,8 @@ static term nif_erlang_binary_to_atom_1(Context *ctx, int argc, term argv[])
return result;
}

// This make_bigint version doesn't do any overflow check and it doesn't normalize integers
// These contraints are ok for parse_integer, since it checks this before calling make_bigint
static term make_bigint(Context *ctx, const intn_digit_t bigres[], size_t bigres_len, intn_integer_sign_t sign)
{
size_t intn_data_size;
Expand Down
7 changes: 6 additions & 1 deletion src/libAtomVM/opcodesswitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,8 @@ static size_t decode_nbits_integer(Context *ctx, const uint8_t *encoded, term *o
static term large_integer_to_term(Context *ctx, int num_bytes, const uint8_t **encoded)
{
const uint8_t *compact_term = *encoded;
// num_bytes is decoded from a 3 bits value and incremented by 2,
// meaning that minimum value is 0 and maximum value is 7
switch (num_bytes) {
case 0:
case 1:
Expand Down Expand Up @@ -1815,8 +1817,11 @@ static bool maybe_call_native(Context *ctx, atom_index_t module_name, atom_index
static size_t decode_nbits_integer(Context *ctx, const uint8_t *encoded, term *out_term)
{
const uint8_t *new_encoded = encoded;
unsigned int len;
uint32_t len;
DECODE_LITERAL(len, new_encoded);
// TODO: check this: actually should be enough: len = *(new_encoded)++ >> 4;
// it seems that likely range is something like from 9 (9 + 0) to 24 (9 + 15)
// that is 192 bits integer

len += 9;

Expand Down
Loading