WebAssembly ABI mismatch between clang and rust
When I compile this C code to wasm32-wasi:
typedef struct Vector { int a; int b; } Vector; extern int extract_a(Vector v) { return v.a; }
And this Rust code to wasm32-wasi:
#[repr(C)] struct Vector { a: i32, b: i32, } extern "C" { fn extract_a(v: Vector) -> i32; } fn main() { unsafe { extract_a(Vector { a: 5, b: 4 }); } }
And try link them together, I'm getting linking errors:
= note: lld: error: function signature mismatch: extract_a
>>> defined as (i32, i32) -> i32 in /home/pierre/Projets/wasm-abi-test/target/wasm32-wasi/debug/deps/wasm_abi_test.67xpw7l331r9o5x.rcgu.o
>>> defined as (i32) -> i32 in /home/pierre/Projets/wasm-abi-test/target/wasm32-wasi/debug/build/wasm-abi-test-9c49ce7f6c5ca031/out/libfoo.a(test.o)
It seems that, according to clang, passing a struct by value should inline the fields, while for Rust it should be passed by pointer.
I uploaded an example project here: https://github.com/tomaka/wasm-abi-test
It can be built with something like:
AR_wasm32_wasi=/path/to/wasi-sdk-10.0/bin/ar CC_wasm32_wasi=/path/to/wasi-sdk-10.0/bin/clang cargo run --target=wasm32-wasi
Rust version: rustc 1.44.0-nightly (38114ff 2020-03-21)