Skip to content

Commit 5ebc4cf

Browse files
committed
Fix floats on Wasm
On wasm32, terms are aligned by 4 bytes. `memory_heap_allocation` returns a pointer for `n` terms. We used float_term_t to create an union between a term and float. However, floats are aligned to 8 bytes which made casting between union and term pointers unsafe. We replaced union usage to `memcpy` which allows unaligned memory access. The true solution would be to return correctly aligned memory from memory_heap_alloc but fix for that would need a lot more testing. Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
1 parent 33736a0 commit 5ebc4cf

1 file changed

Lines changed: 7 additions & 5 deletions

File tree

src/libAtomVM/term.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,16 +2331,18 @@ static inline term term_from_float(avm_float_t f, Heap *heap)
23312331
term *boxed_value = memory_heap_alloc(heap, FLOAT_SIZE);
23322332
boxed_value[0] = ((FLOAT_SIZE - 1) << 6) | TERM_BOXED_FLOAT;
23332333

2334-
float_term_t *boxed_float = (float_term_t *) (boxed_value + 1);
2335-
boxed_float->f = f;
2336-
2334+
// For wasm32, alignof(avm_float_t) = 8 and alignof(term) = 4
2335+
// `memory_heap_alloc` returns memory aligned to term size.
2336+
memcpy(boxed_value + 1, &f, sizeof(avm_float_t));
23372337
return ((term) boxed_value) | TERM_PRIMARY_BOXED;
23382338
}
23392339

23402340
static inline avm_float_t term_to_float(term t)
23412341
{
2342-
const float_term_t *boxed_float = (float_term_t *) (term_to_const_term_ptr(t) + 1);
2343-
return boxed_float->f;
2342+
avm_float_t result;
2343+
// see `term_from_float`
2344+
memcpy(&result, term_to_const_term_ptr(t) + 1, sizeof(avm_float_t));
2345+
return result;
23442346
}
23452347

23462348
static inline bool term_is_number(term t)

0 commit comments

Comments
 (0)