-
Notifications
You must be signed in to change notification settings - Fork 135
Fix floats on Wasm #2041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix floats on Wasm #2041
Conversation
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>
| float_term_t *boxed_float = (float_term_t *) (boxed_value + 1); | ||
| boxed_float->f = f; | ||
|
|
||
| // For wasm32, alignof(avm_float_t) = 8 and alignof(term) = 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is somehow slightly misleading, this is not just an issue for wasm32.
It should be rephrased as:
// alignof(avm_float_t) might be != alignof(term)
|
|
||
| // For wasm32, alignof(avm_float_t) = 8 and alignof(term) = 4 | ||
| // `memory_heap_alloc` returns memory aligned to term size. | ||
| memcpy(boxed_value + 1, &f, sizeof(avm_float_t)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, but sadly there is a know ESP32 GCC bug that I opened 2 years ago: https://gcc.gnu.org/pipermail/gcc-bugs/2023-October/839353.html
Can you keep also the old code and use it with such a similar macro?
#if defined(__XTENSA__)
// See https://gcc.gnu.org/pipermail/gcc-bugs/2023-October/839353.html
[...]
#else
// your new code here
#endif
| return boxed_float->f; | ||
| avm_float_t result; | ||
| // see `term_from_float` | ||
| memcpy(&result, term_to_const_term_ptr(t) + 1, sizeof(avm_float_t)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as the previous comment.
On wasm32, terms are aligned by 4 bytes.
memory_heap_allocationreturns a pointer fornterms. 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
memcpywhich allows unaligned memory access. The true solution would be to return correctly aligned memory frommemory_heap_allocbut fix for that would need a lot more testing.These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).
SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later