-
Notifications
You must be signed in to change notification settings - Fork 20
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
Add support for emscripten (wasm) #7
Conversation
Okay, after a bit of testing with mlua I'm not sure anymore if supporting When running the mlua test suite, a huge amount of stack and heap memory is required in order to pass successfully. This must be set via the # without --release the memory size must be increased even more
$ CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER="node" RUSTFLAGS="-C link-args=-sERROR_ON_UNDEFINED_SYMBOLS=0 -C link-args=-sSTACK_SIZE=50MB -C link-args=-sTOTAL_MEMORY=100MB" cargo test --tests --features lua51 --target wasm32-unknown-emscripten --release Also the # the "guided_tour" example triggers this
$ CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER="node" RUSTFLAGS="-C link-args=-sERROR_ON_UNDEFINED_SYMBOLS=0" cargo run --features "lua51 async serialize macros" --target wasm32-unknown-emscripten --example guided_tour |
Thanks for the PR! I'll take a look to what required for this target too.
This possibly could be related to some tests that explicitly try to overflow Lua stack to check the behaviour.
Actually Lua can be compiled with custom |
I bumped into the same function signature mismatch errors in an application I'm working on, which I resolved in mlua-rs/mlua#337 using what turn out to be the same techniques ( |
I switched the emscripten build process to use the C++ compiler and now
Thanks for pointing this out, I actually tried to compiled it with C++ before I opened this PR too but ran into an issue where C++ exceptions could not be caught... turns out I had to set the |
Thanks! |
This adds support for wasm via the
wasm32-unknown-emscripten
toolchain.Behavioral changes
Given the following lua function:
The following implementation which just works fine on Tier 1 platforms (at least on those I've tested), will cause a linking error when compiling to
wasm32-unknown-emscripten
:If such a mismatch is the case, the linkage will always fails with a "function signature mismatch" error. The
extern "C" fn
must always return the same value as the original C function.This also applies for the
!
type, for example thelua_error
C function returns aint
although it never actually returns. In Rust, this function could be represented aspub extern "C" fn lua_error(lua_State *L) -> !
(which is how e.g. mlua does it), but the linker also forbids this.Other wasm targets
Because lua uses libc, other wasm targets cannot be targeted natively (atm):
wasm32-wasi
has a libc port which is built on top of WASI system calls (wasi-libc) but this port doesn't fully support all calls lua requires to work. The error I ran into was the missing setjmp call which lua uses to handle errors.wasm32-unknown-unknown
&wasm64-unknown-unknown
have no libc implementation/wrapper at all.Notes
When testing via
cargo test
, the compilation will fail with "undefined symbol: <some libc symbol>". The error can be ignored by declaring the env variableRUSTFLAGS="-C link-args=-sERROR_ON_UNDEFINED_SYMBOLS=0"
. With this set,testcrate
compiles without issues.cargo test
also tries to execute the generated test binary, which is actually just a.js
file that imports the compiled wasm binary, but this will result in an error. To prevent this, you can set the env variableCARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER="node"
to use nodejs to execute the js file.The
asmjs-unknown-emscription
toolchain is also supported because it uses the same tools aswasm32-unknown-emscripten
but as it is considered depreacted in favor of wasm I didn't add any tests for it.