Skip to content
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

WebAssembly (wasm) target support, faster/smaller than asm.js #1

Closed
satoshinm opened this issue Apr 2, 2017 · 3 comments
Closed

WebAssembly (wasm) target support, faster/smaller than asm.js #1

satoshinm opened this issue Apr 2, 2017 · 3 comments
Labels
Milestone

Comments

@satoshinm
Copy link
Owner

Build for wasm in addition to asm.js, expected faster but less compatible (requires prerelease browsers at the time of this writing). Build for both and let the user choose, or fallback automatically.

Add -s WASM=1 to emcc, and BINARYEN_METHOD native-wasm and/or asmjs, refer to: https://github.com/kripken/emscripten/wiki/WebAssembly

@satoshinm satoshinm added the speed label Apr 2, 2017
@satoshinm
Copy link
Owner Author

Adding -s WASM to CMakeFiles.txt LINK_FLAGS, it builds but cannot test locally due to promise fetch API:

craft.js:1806 Fetch API cannot load file:////NetCraft/build/craft.wasm. URL scheme must be "http" or "https" for CORS request.
Uncaught (in promise) TypeError: Failed to fetch
at getBinaryPromise (craft.js:1806)
at doNativeWasm (craft.js:1877)
at Object.Module.asm (craft.js:2027)
at craft.js:9827

run from a local server:

python -m SimpleHTTPServer

then http://localhost:8000/craft.html - this works in Chrome 57.0.2987.133, and seems snappier. The wasm build output with emscripten is a lot smaller:

build $ ls -lh craft*
-rw-r--r--  1 admin  staff   100K Apr  4 22:24 craft.html
-rw-r--r--  1 admin  staff   1.1M Apr  4 22:24 craft.js
-rw-r--r--  1 admin  staff   2.6M Apr  4 22:24 craft.wasm

than the asm.js emscripten output:

build $ ls -lh craft*
-rw-r--r--  1 admin  staff   100K Apr  4 22:32 craft.html
-rw-r--r--  1 admin  staff    14M Apr  4 22:32 craft.js

1.1M + 2.6M = 3.7M for wasm vs 14M for asm.js. But the downside is less browser compatibility, just hangs in Safari Technical Preview. So the asm.js-based emscripten build would still be needed.

Question now is how to integrate this variant into the build system. Make it a cmake option (to add to the arguments of cmake -DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake ..)? Or maybe better, always build both asm.js and wasm (run build twice?), then load either with a fallback?

@satoshinm
Copy link
Owner Author

satoshinm commented Apr 11, 2017

Added for GH-45 and this a wasm build type:

mkdir wasm-build
cmake -DWASM=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake ..
make

However, wasm used to work, when I first tried it -- but now, get an out-of-memory access?!

craft.html:1251 exception thrown: RuntimeError: memory access out of bounds,RuntimeError: memory access out of bounds
at ([273]+70)
at ([279]+40)
at Object.Module._main (http://localhost:8000/craft.js:1:827350)
at Object.callMain (http://localhost:8000/craft.js:1:836819)
at doRun (http://localhost:8000/craft.js:1:837562)
at http://localhost:8000/craft.js:1:837712

screen shot 2017-04-10 at 11 24 25 pm

What changed? Need to regress to 4/4, isolate


cp CMakeLists.txt /tmp

git checkout CMakeLists.txt
git checkout X
cp /tmp/CMakeLists.txt .

cd wasm-build
rm craft* ; make ; ls -l craft.wasm && python -m SimpleHTTPServer

works:

fails to compile (missing conditional compilation for web):

  • aa99147 Add fullscreen/windowed toggle with F11 using glfwSetWindowMonitor()

broken (memory access out of bounds error):

so it's something from aa99147 or 999ac5e? Wouldn't have expected it...


Starting with aa99147 and commenting out native calls so it compiles:

--- a/src/main.c
+++ b/src/main.c
@@ -2430,13 +2430,13 @@ void get_fullscreen_monitor_dimensions() {
 }
 
 void fullscreen_exit() {
-    glfwSetWindowMonitor(g->window, NULL, g->window_xpos, g->window_ypos, g->window_width, g->window_height, GLFW_DONT_CARE);
+    //glfwSetWindowMonitor(g->window, NULL, g->window_xpos, g->window_ypos, g->window_width, g->window_height, GLFW_DONT_CARE);
 }
 
 void fullscreen_enter() {
     glfwGetWindowPos(g->window, &g->window_xpos, &g->window_ypos);
     glfwGetWindowSize(g->window, &g->window_width, &g->window_height);
-    glfwSetWindowMonitor(g->window, g->fullscreen_monitor, 0, 0, g->fullscreen_width, g->fullscreen_height, GLFW_DONT_CARE);
+    //glfwSetWindowMonitor(g->window, g->fullscreen_monitor, 0, 0, g->fullscreen_width, g->fullscreen_height, GLFW_DONT_CARE);
 }
 
 void create_window() {

wasm does crash with RuntimeError: memory access out of bounds,RuntimeError: memory access out of bounds, so, it is something added in this commit


Found it: get_fullscreen_monitor_dimensions(). This calls glfwGetPrimaryMonitor() and indexes the video modes array, certainly not needed for the web. The variables it sets weren't being used on the web (native only, where there are monitors) so execution was harmless except for the out-of-bounds memory accesses it caused.

@satoshinm
Copy link
Owner Author

screen shot 2017-04-11 at 12 01 15 am

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant