rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.62k stars 12.63k forks source link

Emscripten with -O2 and higher fails to generate correctly running JavaScript #38757

Closed LaylBongers closed 7 years ago

LaylBongers commented 7 years ago

Currently my code is compiled with the emscripten target with -O2 or higher, rather than printing the correct result (based on reading some javascript values), it will print the following:

0
0

-O1 works fine, but gives a very large resulting file.

LaylBongers commented 7 years ago

After further reading, I was using the API wrong. When calling functions directly in emscripten, they should be prefixed with Module.. So, instead of:

_foo();

You should be calling:

Module._foo();

The direct call will be optimized out.

LaylBongers commented 7 years ago

Seems I closed this too early, while the docs do recommend that, it has the same result for me currently.

LaylBongers commented 7 years ago

I've narrowed down the issue to happening on the first time it has to call outside the code itself, either println!() or some external call.

LaylBongers commented 7 years ago

After talking on the emscripten IRC, I've been informed of the problem. It was calling functions before emscripten was properly loaded, which was because it was looking for a .mem file and thus loading asynchronously. Here's my full (now working) build script for the interested

# Explanation of all arguments given to emscripten:
# EXPORTED_FUNCTIONS        These export the functions needed to call into Rust.
# NO_EXIT_RUNTIME=1         Prevents emscripten from unloading after main.
# DEMANGLE_SUPPORT=1        Allows rust to demangle when a panic happens, for
#                           debug info. (Can be disabled if needed)
# --memory-init-file 0      Disables the memory init file generation so
#                           emscripten can load synchronously. This is needed
#                           so it can be loaded inside the Screeps node
#                           environment.
# --pre-js/--post-js        Injects extra javascript, used to configure
#                           emscripten and export modules.
# --bind                    Adds embind javascript, allowing us to alter JS data.
# -O1/-O2/-O3               Optimization level, select as needed.
# -g2                       Disables minifying, allowing easier debugging of
#                           optimized code. (Currently disabled)
cargo rustc --release --target asmjs-unknown-emscripten -- -Clink-args="-s EXPORTED_FUNCTIONS=['_main','_load','_tick'] -s NO_EXIT_RUNTIME=1 -s DEMANGLE_SUPPORT=1 --memory-init-file 0 --pre-js pre.js --post-js post.js -s ASSERTIONS=1 --bind -O2"