Description
The u128
and i128
types on the wasm targets has alignment of 8. This is inconsistent with the alignment on all Tier-1 targets.
Compile this code:
#![crate_type = "cdylib"]
#[no_mangle]
pub extern "C" fn align_of_u128() -> usize {
std::mem::align_of::<u128>()
}
The body of this function on all Tier-1 targets is "return 16", while on wasm32-unknown-unknown
, wasm32-unknown-emscripten
, and wasm32-wasi
it compiles to "return 8".
This causes arrays that are aligned on wasm to no longer be aligned when pointers are passed through FFI to the host. For example, creating a Vec<u128>
in wasm and returning it as slice to the host causes misalignment.
I am not sure if this is a compiler bug or if this is for some reason intentional, but it is very annoying. A workaround is to declare your own this wrapper to force alignment and use it throughout:
#[repr(C, align(16))]
struct au128(u128);
however that doesn't play well with external libraries that use u128
.
Meta
This happens both on stable 1.83 (see the Godbolt link above) and my nightly from 2024-12-05
rustc --version --verbose
:
rustc 1.85.0-nightly (c94848c04 2024-12-05)
binary: rustc
commit-hash: c94848c046d29f9a80c09aae758e27e418a289f2
commit-date: 2024-12-05
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.5