Skip to content

Commit 5d59e2c

Browse files
committed
Rename term_create_uninitialized_intn and term_intn_to_term_size
`term_create_uninitialized_intn` -> `term_create_uninitialized_bigint` `term_intn_to_term_size` -> `term_bigint_size_requirements` Also add doxygen documentation. Signed-off-by: Davide Bettio <davide@uninstall.it>
1 parent 8c691c2 commit 5d59e2c

File tree

6 files changed

+79
-20
lines changed

6 files changed

+79
-20
lines changed

src/libAtomVM/bif.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -809,15 +809,15 @@ static term make_bigint(Context *ctx, uint32_t fail_label, uint32_t live,
809809
if (!intn_fits_int64(bigres, count, sign)) {
810810
size_t intn_data_size;
811811
size_t rounded_res_len;
812-
term_intn_to_term_size(count, &intn_data_size, &rounded_res_len);
812+
term_bigint_size_requirements(count, &intn_data_size, &rounded_res_len);
813813

814814
if (UNLIKELY(memory_ensure_free_with_roots(
815815
ctx, BOXED_INTN_SIZE(intn_data_size), live, ctx->x, MEMORY_CAN_SHRINK)
816816
!= MEMORY_GC_OK)) {
817817
RAISE_ERROR_BIF(fail_label, OUT_OF_MEMORY_ATOM);
818818
}
819819

820-
term bigres_term = term_create_uninitialized_intn(
820+
term bigres_term = term_create_uninitialized_bigint(
821821
intn_data_size, (term_integer_sign_t) sign, &ctx->heap);
822822
term_initialize_bigint(bigres_term, bigres, count, rounded_res_len);
823823

src/libAtomVM/externalterm.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -592,11 +592,11 @@ static term parse_external_terms(const uint8_t *external_term_buf, size_t *eterm
592592

593593
size_t intn_data_size;
594594
size_t rounded_res_len;
595-
term_intn_to_term_size(count, &intn_data_size, &rounded_res_len);
595+
term_bigint_size_requirements(count, &intn_data_size, &rounded_res_len);
596596

597597
intn_integer_sign_t sign = is_negative ? IntNNegativeInteger : IntNPositiveInteger;
598598
term bigint_term
599-
= term_create_uninitialized_intn(intn_data_size, (term_integer_sign_t) sign, heap);
599+
= term_create_uninitialized_bigint(intn_data_size, (term_integer_sign_t) sign, heap);
600600
term_initialize_bigint(bigint_term, bigint, count, rounded_res_len);
601601

602602
return bigint_term;
@@ -1011,7 +1011,7 @@ static int calculate_heap_usage(const uint8_t *external_term_buf, size_t remaini
10111011
size_t required_digits = intn_required_digits_for_unsigned_integer(num_bytes);
10121012
size_t data_size;
10131013
size_t unused_rounded_len;
1014-
term_intn_to_term_size(required_digits, &data_size, &unused_rounded_len);
1014+
term_bigint_size_requirements(required_digits, &data_size, &unused_rounded_len);
10151015
return BOXED_INTN_SIZE(data_size);
10161016
}
10171017

src/libAtomVM/jit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ static term jit_alloc_big_integer_fragment(
627627

628628
size_t intn_data_size;
629629
size_t rounded_res_len;
630-
term_intn_to_term_size(digits_len, &intn_data_size, &rounded_res_len);
630+
term_bigint_size_requirements(digits_len, &intn_data_size, &rounded_res_len);
631631

632632
if (UNLIKELY(memory_init_heap(&heap, BOXED_INTN_SIZE(intn_data_size)) != MEMORY_GC_OK)) {
633633
ctx->x[0] = ERROR_ATOM;
@@ -636,7 +636,7 @@ static term jit_alloc_big_integer_fragment(
636636
}
637637

638638
term bigint_term
639-
= term_create_uninitialized_intn(intn_data_size, (term_integer_sign_t) sign, &heap);
639+
= term_create_uninitialized_bigint(intn_data_size, (term_integer_sign_t) sign, &heap);
640640
// Assumption: here we assume that bigints have standard boxed term layout
641641
// This code might need to be updated when changing bigint memory layout
642642
void *digits_mem = (void *) (term_to_const_term_ptr(bigint_term) + 1);

src/libAtomVM/nifs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,14 +2057,14 @@ static term make_bigint(Context *ctx, const intn_digit_t bigres[], size_t bigres
20572057
{
20582058
size_t intn_data_size;
20592059
size_t rounded_res_len;
2060-
term_intn_to_term_size(bigres_len, &intn_data_size, &rounded_res_len);
2060+
term_bigint_size_requirements(bigres_len, &intn_data_size, &rounded_res_len);
20612061

20622062
if (UNLIKELY(memory_ensure_free(ctx, BOXED_INTN_SIZE(intn_data_size)) != MEMORY_GC_OK)) {
20632063
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
20642064
}
20652065

20662066
term bigres_term
2067-
= term_create_uninitialized_intn(intn_data_size, (term_integer_sign_t) sign, &ctx->heap);
2067+
= term_create_uninitialized_bigint(intn_data_size, (term_integer_sign_t) sign, &ctx->heap);
20682068
term_initialize_bigint(bigres_term, bigres, bigres_len, rounded_res_len);
20692069

20702070
return bigres_term;

src/libAtomVM/opcodesswitch.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,7 +1840,7 @@ static bool maybe_call_native(Context *ctx, atom_index_t module_name, atom_index
18401840

18411841
size_t intn_data_size;
18421842
size_t rounded_res_len;
1843-
term_intn_to_term_size(count, &intn_data_size, &rounded_res_len);
1843+
term_bigint_size_requirements(count, &intn_data_size, &rounded_res_len);
18441844

18451845
Heap heap;
18461846
if (UNLIKELY(
@@ -1852,7 +1852,7 @@ static bool maybe_call_native(Context *ctx, atom_index_t module_name, atom_index
18521852
}
18531853

18541854
term bigint_term
1855-
= term_create_uninitialized_intn(intn_data_size, (term_integer_sign_t) sign, &heap);
1855+
= term_create_uninitialized_bigint(intn_data_size, (term_integer_sign_t) sign, &heap);
18561856
term_initialize_bigint(bigint_term, bigint, count, rounded_res_len);
18571857

18581858
memory_heap_append_heap(&ctx->heap, &heap);

src/libAtomVM/term.h

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,7 +1301,32 @@ static inline size_t term_boxed_integer_size(avm_int64_t value)
13011301
}
13021302
}
13031303

1304-
static inline term term_create_uninitialized_intn(size_t n, term_integer_sign_t sign, Heap *heap)
1304+
/**
1305+
* @brief Create an uninitialized bigint term with allocated storage
1306+
*
1307+
* Allocates heap space for a multi-precision integer term and sets up the
1308+
* boxed header with size and sign information. The digit data area is left
1309+
* uninitialized and must be filled using \c term_initialize_bigint().
1310+
*
1311+
* @param n Size of data area in terms (not digits)
1312+
* @param sign Sign of the integer (\c TERM_INTEGER_POSITIVE or \c TERM_INTEGER_NEGATIVE)
1313+
* @param heap Heap to allocate from
1314+
* @return Newly created uninitialized bigint term
1315+
*
1316+
* @pre n must be > \c BOXED_TERMS_REQUIRED_FOR_INT64 to ensure bigint distinction
1317+
* @pre heap must have at least (1 + n) terms of free space
1318+
*
1319+
* @post Allocates 1 header term + n data terms on the heap
1320+
* @post Header contains size and sign information
1321+
* @post Data area is uninitialized and must be filled before use
1322+
*
1323+
* @note The size n is in terms, not \c intn_digit_t digits
1324+
* @note Use \c term_bigint_size_requirements() to calculate appropriate n value
1325+
*
1326+
* @see term_initialize_bigint() to fill the allocated data area
1327+
* @see term_bigint_size_requirements() to calculate required size
1328+
*/
1329+
static inline term term_create_uninitialized_bigint(size_t n, term_integer_sign_t sign, Heap *heap)
13051330
{
13061331
term *boxed_int = memory_heap_alloc(heap, 1 + n);
13071332
boxed_int[0] = (n << 6) | TERM_BOXED_POSITIVE_INTEGER | sign;
@@ -1316,7 +1341,7 @@ static inline term term_create_uninitialized_intn(size_t n, term_integer_sign_t
13161341
* zero-extending to fill the entire allocated space. This function is used
13171342
* after creating an uninitialized bigint term to populate it with actual data.
13181343
*
1319-
* @param t Uninitialized bigint term (created with \c term_create_uninitialized_intn())
1344+
* @param t Uninitialized bigint term (created with \c term_create_uninitialized_bigint())
13201345
* @param bigint Source digit array to copy
13211346
* @param bigint_len Number of digits in source array
13221347
* @param uninitialized_size Total size of destination buffer in digits
@@ -1331,7 +1356,7 @@ static inline term term_create_uninitialized_intn(size_t n, term_integer_sign_t
13311356
* @note This function does not set the sign - that should be done when creating the term
13321357
* @note The destination buffer size (uninitialized_size) is typically rounded up for alignment
13331358
*
1334-
* @see term_create_uninitialized_intn() to allocate the term before initialization
1359+
* @see term_create_uninitialized_bigint() to allocate the term before initialization
13351360
* @see intn_copy() which performs the actual copy and zero-extension
13361361
*/
13371362
static inline void term_initialize_bigint(
@@ -1342,18 +1367,52 @@ static inline void term_initialize_bigint(
13421367
intn_copy(bigint, bigint_len, dest_buf, uninitialized_size);
13431368
}
13441369

1345-
static inline void term_intn_to_term_size(size_t n, size_t *intn_data_size, size_t *rounded_num_len)
1370+
/**
1371+
* @brief Calculate term allocation size for multi-precision integer
1372+
*
1373+
* Converts the number of \c intn_digit_t digits needed for a bigint into the
1374+
* corresponding term allocation size and rounded digit count. Handles platform
1375+
* differences between 32-bit systems (where term = intn_digit_t) and 64-bit
1376+
* systems (where term = 2 × intn_digit_t), including alignment requirements.
1377+
*
1378+
* @param n Number of non-zero \c intn_digit_t digits in the integer
1379+
* @param[out] intn_data_size Number of terms needed for storage
1380+
* @param[out] rounded_num_len Rounded number of digits for zero-padding
1381+
*
1382+
* @pre n > 0
1383+
* @pre intn_data_size != NULL
1384+
* @pre rounded_num_len != NULL
1385+
*
1386+
* @post *intn_data_size > \c BOXED_TERMS_REQUIRED_FOR_INT64 (ensures bigint distinction)
1387+
* @post *rounded_num_len >= n (includes padding for alignment)
1388+
*
1389+
* @note Forces minimum size > \c BOXED_TERMS_REQUIRED_FOR_INT64 to distinguish
1390+
* bigints from regular boxed int64 values (which use two's complement)
1391+
* @note Rounds up to 8-byte boundaries for alignment
1392+
* @note On 64-bit systems, 2 digits fit per term; on 32-bit systems, 1 digit per term
1393+
*
1394+
* @code
1395+
* // Example usage:
1396+
* size_t count = intn_count_digits(bigint, bigint_len);
1397+
* size_t intn_data_size, rounded_res_len;
1398+
* term_bigint_size_requirements(count, &intn_data_size, &rounded_res_len);
1399+
* term t = term_create_uninitialized_bigint(intn_data_size, sign, heap);
1400+
* term_initialize_bigint(t, bigint, count, rounded_res_len);
1401+
* @endcode
1402+
*/
1403+
static inline void term_bigint_size_requirements(
1404+
size_t n, size_t *intn_data_size, size_t *rounded_num_len)
13461405
{
13471406
size_t bytes = n * sizeof(intn_digit_t);
13481407
size_t rounded = ((bytes + 7) >> 3) << 3;
13491408
*intn_data_size = rounded / sizeof(term);
13501409

13511410
if (*intn_data_size == BOXED_TERMS_REQUIRED_FOR_INT64) {
1352-
// we need to distinguish between "small" boxed integers, that are integers
1353-
// up to int64, and bigger integers.
1354-
// The real difference is that "small" boxed integers use 2-complement,
1355-
// real bigints not (and also endianess might differ).
1356-
// So we force real bigints to be > BOXED_TERMS_REQUIRED_FOR_INT64 terms
1411+
// We need to distinguish between "small" boxed integers (up to int64)
1412+
// and true bigints. Small boxed integers use two's complement
1413+
// representation, while bigints use sign-magnitude (and endianness
1414+
// might also differ). To ensure this distinction, we force bigints
1415+
// to use > BOXED_TERMS_REQUIRED_FOR_INT64 terms.
13571416
*intn_data_size = BOXED_TERMS_REQUIRED_FOR_INT64 + 1;
13581417
rounded = *intn_data_size * sizeof(term);
13591418
}

0 commit comments

Comments
 (0)