Skip to content

Commit 8c691c2

Browse files
committed
Add new term_initialize_bigint function
Use `term_initialize_bigint` instead of `term_intn_data` + `intn_copy` Signed-off-by: Davide Bettio <davide@uninstall.it>
1 parent 823ea72 commit 8c691c2

File tree

6 files changed

+38
-13
lines changed

6 files changed

+38
-13
lines changed

src/libAtomVM/bif.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -819,8 +819,7 @@ static term make_bigint(Context *ctx, uint32_t fail_label, uint32_t live,
819819

820820
term bigres_term = term_create_uninitialized_intn(
821821
intn_data_size, (term_integer_sign_t) sign, &ctx->heap);
822-
intn_digit_t *dest_buf = (void *) term_intn_data(bigres_term);
823-
intn_copy(bigres, count, dest_buf, rounded_res_len);
822+
term_initialize_bigint(bigres_term, bigres, count, rounded_res_len);
824823

825824
return bigres_term;
826825
} else {

src/libAtomVM/externalterm.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,7 @@ static term parse_external_terms(const uint8_t *external_term_buf, size_t *eterm
597597
intn_integer_sign_t sign = is_negative ? IntNNegativeInteger : IntNPositiveInteger;
598598
term bigint_term
599599
= term_create_uninitialized_intn(intn_data_size, (term_integer_sign_t) sign, heap);
600-
intn_digit_t *dest_buf = (void *) term_intn_data(bigint_term);
601-
intn_copy(bigint, count, dest_buf, rounded_res_len);
600+
term_initialize_bigint(bigint_term, bigint, count, rounded_res_len);
602601

603602
return bigint_term;
604603
}

src/libAtomVM/jit.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,9 @@ static term jit_alloc_big_integer_fragment(
637637

638638
term bigint_term
639639
= term_create_uninitialized_intn(intn_data_size, (term_integer_sign_t) sign, &heap);
640-
void *digits_mem = term_intn_data(bigint_term);
640+
// Assumption: here we assume that bigints have standard boxed term layout
641+
// This code might need to be updated when changing bigint memory layout
642+
void *digits_mem = (void *) (term_to_const_term_ptr(bigint_term) + 1);
641643
// TODO: optimize: just initialize space that will not be used
642644
memset(digits_mem, 0, intn_data_size * sizeof(term));
643645

src/libAtomVM/nifs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,8 +2065,7 @@ static term make_bigint(Context *ctx, const intn_digit_t bigres[], size_t bigres
20652065

20662066
term bigres_term
20672067
= term_create_uninitialized_intn(intn_data_size, (term_integer_sign_t) sign, &ctx->heap);
2068-
intn_digit_t *dest_buf = (void *) term_intn_data(bigres_term);
2069-
intn_copy(bigres, bigres_len, dest_buf, rounded_res_len);
2068+
term_initialize_bigint(bigres_term, bigres, bigres_len, rounded_res_len);
20702069

20712070
return bigres_term;
20722071
}

src/libAtomVM/opcodesswitch.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,8 +1853,7 @@ static bool maybe_call_native(Context *ctx, atom_index_t module_name, atom_index
18531853

18541854
term bigint_term
18551855
= term_create_uninitialized_intn(intn_data_size, (term_integer_sign_t) sign, &heap);
1856-
intn_digit_t *dest_buf = (void *) term_intn_data(bigint_term);
1857-
intn_copy(bigint, count, dest_buf, rounded_res_len);
1856+
term_initialize_bigint(bigint_term, bigint, count, rounded_res_len);
18581857

18591858
memory_heap_append_heap(&ctx->heap, &heap);
18601859

src/libAtomVM/term.h

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,10 +1309,37 @@ static inline term term_create_uninitialized_intn(size_t n, term_integer_sign_t
13091309
return ((term) boxed_int) | TERM_PRIMARY_BOXED;
13101310
}
13111311

1312-
static inline void *term_intn_data(term t)
1312+
/**
1313+
* @brief Initialize multi-precision integer data in a pre-allocated term
1314+
*
1315+
* Copies multi-precision integer digits into an already allocated boxed term,
1316+
* zero-extending to fill the entire allocated space. This function is used
1317+
* after creating an uninitialized bigint term to populate it with actual data.
1318+
*
1319+
* @param t Uninitialized bigint term (created with \c term_create_uninitialized_intn())
1320+
* @param bigint Source digit array to copy
1321+
* @param bigint_len Number of digits in source array
1322+
* @param uninitialized_size Total size of destination buffer in digits
1323+
*
1324+
* @pre t must be a valid uninitialized bigint term
1325+
* @pre bigint != NULL
1326+
* @pre uninitialized_size must match the size allocated for the term
1327+
*
1328+
* @post Copies bigint_len digits from source to term
1329+
* @post Zero-fills remaining space from bigint_len to uninitialized_size
1330+
*
1331+
* @note This function does not set the sign - that should be done when creating the term
1332+
* @note The destination buffer size (uninitialized_size) is typically rounded up for alignment
1333+
*
1334+
* @see term_create_uninitialized_intn() to allocate the term before initialization
1335+
* @see intn_copy() which performs the actual copy and zero-extension
1336+
*/
1337+
static inline void term_initialize_bigint(
1338+
term t, const intn_digit_t *bigint, size_t bigint_len, size_t uninitialized_size)
13131339
{
13141340
const term *boxed_value = term_to_const_term_ptr(t);
1315-
return (void *) (boxed_value + 1);
1341+
intn_digit_t *dest_buf = (intn_digit_t *) (boxed_value + 1);
1342+
intn_copy(bigint, bigint_len, dest_buf, uninitialized_size);
13161343
}
13171344

13181345
static inline void term_intn_to_term_size(size_t n, size_t *intn_data_size, size_t *rounded_num_len)
@@ -1404,9 +1431,9 @@ _Static_assert(
14041431
static inline void term_to_bigint(
14051432
term t, const intn_digit_t *bigint[], size_t *bigint_len, intn_integer_sign_t *bigint_sign)
14061433
{
1407-
*bigint = (const intn_digit_t *) term_intn_data(t);
1408-
14091434
const term *boxed_value = term_to_const_term_ptr(t);
1435+
*bigint = (const intn_digit_t *) (boxed_value + 1);
1436+
14101437
size_t boxed_size = term_get_size_from_boxed_header(boxed_value[0]);
14111438
*bigint_len = boxed_size * (sizeof(term) / sizeof(intn_digit_t));
14121439

0 commit comments

Comments
 (0)