bytecodealliance/cargo-wasi

Invalid WASM module generated when using some libraries

Closed this issue · 4 comments

When using the dot method from the ndarray crate, a library compiled with cargo-wasi fails to import into wasmtime for .NET with the exception:

Unhandled exception. Wasmtime.WasmtimeException: WebAssembly module 'module.wasm' is not valid.

Testing the generated wasm file with the wasm-validate tool from https://github.com/WebAssembly/wabt results in the following output:

0000034: error: result count must be 0 or 1

Using wasm-objdump to investigate the header at 000034 gives the following output:

Contents of section Type:
000000e: 1460 0000 6000 017f 6001 7f00 6001 7f01  .`..`...`...`...
000001e: 7f60 017f 017e 6002 7f7f 0060 027f 7f01  .`...~`....`....
000002e: 7f60 027f 7f02 7f7f 6003 7f7f 7f00 6003  .`......`.....`.
000003e: 7f7f 7f01 7f60 047f 7f7f 7f00 6004 7f7f  .....`......`...
000004e: 7f7f 017f 6005 7f7f 7f7f 7f00 6005 7f7f  ....`.......`...
000005e: 7f7f 7f01 7f60 067f 7f7f 7f7f 7f01 7f60  .....`.........`
000006e: 077f 7f7f 7f7f 7f7f 017f 6009 7f7f 7f7f  ..........`.....
000007e: 7f7f 7f7f 7f01 7f60 037f 7c7c 0060 037e  .......`..||.`.~
000008e: 7f7f 017f 6007 7c7c 7f7f 7c7c 7f00       ....`.||..||..

When commenting out the call to the dot method, the Type section changes to:

Contents of section Type:
000000e: 1260 0000 6000 017f 6001 7f00 6001 7f01  .`..`...`...`...
000001e: 7f60 017f 017e 6002 7f7f 0060 027f 7f01  .`...~`....`....
000002e: 7f60 027f 7f02 7f7f 6003 7f7f 7f00 6003  .`......`.....`.
000003e: 7f7f 7f01 7f60 047f 7f7f 7f00 6004 7f7f  .....`......`...
000004e: 7f7f 017f 6005 7f7f 7f7f 7f00 6005 7f7f  ....`.......`...
000005e: 7f7f 7f01 7f60 067f 7f7f 7f7f 7f01 7f60  .....`.........`
000006e: 077f 7f7f 7f7f 7f7f 017f 6009 7f7f 7f7f  ..........`.....
000007e: 7f7f 7f7f 7f01 7f60 037e 7f7f 017f       .......`.~....

This is likely to the use of the multi-value. You can enable support for multi-value in wabt by passing the --enable-multi-value flag.

Thanks for the report! In addition to needing to explicitly enable multi-value it looks like you also might be using wasm-bindgen and interface-types, but unfortunately those features aren't working with the current wasmtime implementation. There's some more information on this here, but otherwise for now I'd recommend not using wasm-bindgen with wasmtime while we sort out the implementation

Thanks for the help, @sunfishcode and @alexcrichton! I had followed the demos at https://github.com/bytecodealliance/wasmtime-demos/blob/master/markdown/src/lib.rs without realizing the current incompatibility between wasm-bindgen and wasmtime, so I really appreciate the pointer. As someone new to working with wasm, may I ask if there's a recommended alternative to wasm-bindgen for use with wasmtime? Thanks!

Currently you'll need to manually set up how to transfer strings across the boundary with linear memory, there's no alternative like wasm-bindgen that's automatic right now (or at least not that I know of)