satoshinm / NetCraft

Web-based fork of fogleman/Craft ⛺
https://satoshinm.github.io/NetCraft/
MIT License
56 stars 13 forks source link

wasm: Division by zero (evaluating 'Module["asm"]["dynCall_v"].apply(null,arguments)') #168

Closed satoshinm closed 7 years ago

satoshinm commented 7 years ago

When using wasm-build to connect to an online server (passed #localhost in URL), it divides by zero and fails to load:

[Error] exception thrown: Error: Division by zero (evaluating 'Module["asm"]["dynCall_v"].apply(null,arguments)'),wasm function: 263@[wasm code]
wasm function: 537@[wasm code]
wasm function@[wasm code]
dynCall_v@[native code]
http://localhost:8000/craftw.js:1:263481
browserIterationFunc@http://localhost:8000/craftw.js:1:53178
runIter@http://localhost:8000/craftw.js:1:56255
Browser_mainLoop_runner@http://localhost:8000/craftw.js:1:54720
    printErr (craftw.html:1245)
    runIter (craftw.js:1:56358)
    Browser_mainLoop_runner (craftw.js:1:54721)
[Error] Error: Division by zero (evaluating 'Module["asm"]["dynCall_v"].apply(null,arguments)')
    runIter (craftw.js:1:56400)
    Browser_mainLoop_runner (craftw.js:1:54721)
satoshinm commented 7 years ago

https://github.com/kripken/emscripten/blob/master/src/settings.js#L670-L672

var BINARYEN_IMPRECISE = 0; // Whether to apply imprecise/unsafe binaryen optimizations. If enabled,
                            // code will run faster, but some types of undefined behavior might
                            // trap in wasm.

hmm, CMakeLists.txt:

    if (WASM)
        add_definitions(-DBUILD_WASM)
        set_property(TARGET craft APPEND_STRING PROPERTY LINK_FLAGS " -s WASM=1")
        set_property(TARGET craft APPEND_STRING PROPERTY LINK_FLAGS " -s BINARYEN_IMPRECISE=1")
        set_target_properties(craft PROPERTIES OUTPUT_NAME "craftw")
    endif ()

fail with emscripten 1.37.12:

[  4%] Linking C executable craftw.html
WARNING:root:Assigning a non-existent settings attribute "BINARYEN_IMPRECISE"
WARNING:root: - did you mean one of BINARYEN_PASSES, BINARYEN_METHOD, BINARYEN_MEM_MAX?
WARNING:root: - perhaps a typo in emcc's  -s X=Y  notation?
WARNING:root: - (see src/settings.js for valid values)
[100%] Built target craft

The option has been renamed in incoming: https://github.com/kripken/emscripten/blob/2edfe1b2c0af7e832e0076938f089f7115804985/src/settings.js#L704-L711

var BINARYEN_TRAP_MODE = "allow"; // How we handle wasm operations that may trap, which includes integer
                                  // div/rem of 0 and float-to-int of values too large to fit in an int.
                                  //   js: do exactly what js does. this can be slower.
                                  //   clamp: avoid traps by clamping to a reasonable value. this can be
                                  //          faster than "js".
                                  //   allow: allow creating operations that can trap. this is the most
                                  //          compact, as we just emit a single wasm operation, with no
                                  //          guards to trapping values, and also often the fastest.
satoshinm commented 7 years ago

Setting BINARYEN_TRAP_MODE to clamp (see long discussion in https://github.com/kripken/emscripten/issues/4625 what this means) works for now, but really should identify and fix this division by zero. According to Douglas Crockford there was a Cray machine in which 0/0 returned 2. In JavaScript it returns NaN but in WebAssembly it traps!