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

Emscripten support broken: missing function: emscripten_set_mousemove_callback / assertion failed: validate_hidpi_factor(dpi_factor) #760

Closed
iceiix opened this issue Jan 14, 2019 · 7 comments
Labels
B - bug Dang, that shouldn't have happened C - in progress Implementation is proceeding smoothly

Comments

@iceiix
Copy link

iceiix commented Jan 14, 2019

Is winit compatible with emscripten sdk 1.38.22? When running the examples I'm getting this error, interested if anyone else is seeing it, or if it is a misconfiguration on my end:

window.js:7196 missing function: emscripten_set_mousemove_callback

window.js:7196 missing function: emscripten_set_mousemove_callback
_emscripten_set_mousemove_callback @ window.js:7196
__ZN5winit8platform8platform6Window3new17h036fa7310bcbf823E @ grisu.rs:491
dynCall_viii @ grisu.rs:491
Module.dynCall_viii @ window.js:7835
invoke_viii @ window.js:7510
__ZN5winit6window38__LT_impl_u20_winit__WindowBuilder_GT_5build17h500b3e62957b8a6fE @ grisu.rs:491
dynCall_viii @ grisu.rs:491
Module.dynCall_viii @ window.js:7835
invoke_viii @ window.js:7510
__ZN6window4main17h6c9df911c3ebf060E @ grisu.rs:491
__ZN3std2rt10lang_start28__u7b__u7b_closure_u7d__u7d_17hc3810b9cbdf76d05E @ grisu.rs:491
__ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h45d765e0ad7e854fE @ grisu.rs:491
__ZN3std9panicking3try7do_call17he4712eb84191fb3bE_llvm_369D5A5A @ grisu.rs:491
dynCall_vi @ grisu.rs:491
Module.dynCall_vi @ window.js:7823
invoke_vi @ window.js:7477
___rust_maybe_catch_panic @ grisu.rs:491
__ZN3std2rt19lang_start_internal17h76f990c2b2c74932E @ grisu.rs:491
__ZN3std2rt10lang_start17h018a6e635825245eE @ grisu.rs:491
_main @ grisu.rs:491
Module._main @ window.js:7739
callMain @ window.js:7973
doRun @ window.js:8031
run @ window.js:8045
runCaller @ window.js:7950
removeRunDependency @ window.js:1462
receiveInstance @ window.js:1624
receiveInstantiatedSource @ window.js:1649
Promise.then (async)
doNativeWasm @ window.js:1665
Module.asm @ window.js:1751
(anonymous) @ window.js:7556
window.js:8131 -1
window.js:8132 -1
abort @ window.js:8132
_emscripten_set_mousemove_callback @ window.js:7196
__ZN5winit8platform8platform6Window3new17h036fa7310bcbf823E @ grisu.rs:491
dynCall_viii @ grisu.rs:491
Module.dynCall_viii @ window.js:7835
invoke_viii @ window.js:7510
__ZN5winit6window38__LT_impl_u20_winit__WindowBuilder_GT_5build17h500b3e62957b8a6fE @ grisu.rs:491
dynCall_viii @ grisu.rs:491
Module.dynCall_viii @ window.js:7835
invoke_viii @ window.js:7510
__ZN6window4main17h6c9df911c3ebf060E @ grisu.rs:491
__ZN3std2rt10lang_start28__u7b__u7b_closure_u7d__u7d_17hc3810b9cbdf76d05E @ grisu.rs:491
__ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h45d765e0ad7e854fE @ grisu.rs:491
__ZN3std9panicking3try7do_call17he4712eb84191fb3bE_llvm_369D5A5A @ grisu.rs:491
dynCall_vi @ grisu.rs:491
Module.dynCall_vi @ window.js:7823
invoke_vi @ window.js:7477
___rust_maybe_catch_panic @ grisu.rs:491
__ZN3std2rt19lang_start_internal17h76f990c2b2c74932E @ grisu.rs:491
__ZN3std2rt10lang_start17h018a6e635825245eE @ grisu.rs:491
_main @ grisu.rs:491
Module._main @ window.js:7739
callMain @ window.js:7973
doRun @ window.js:8031
run @ window.js:8045
runCaller @ window.js:7950
removeRunDependency @ window.js:1462
receiveInstance @ window.js:1624
receiveInstantiatedSource @ window.js:1649
Promise.then (async)
doNativeWasm @ window.js:1665
Module.asm @ window.js:1751
(anonymous) @ window.js:7556
window.js:311 warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling
warnOnce @ window.js:311
demangle @ window.js:1051
(anonymous) @ window.js:1060
demangleAll @ window.js:1058
stackTrace @ window.js:1085
abort @ window.js:8142
_emscripten_set_mousemove_callback @ window.js:7196
__ZN5winit8platform8platform6Window3new17h036fa7310bcbf823E @ grisu.rs:491
dynCall_viii @ grisu.rs:491
Module.dynCall_viii @ window.js:7835
invoke_viii @ window.js:7510
__ZN5winit6window38__LT_impl_u20_winit__WindowBuilder_GT_5build17h500b3e62957b8a6fE @ grisu.rs:491
dynCall_viii @ grisu.rs:491
Module.dynCall_viii @ window.js:7835
invoke_viii @ window.js:7510
__ZN6window4main17h6c9df911c3ebf060E @ grisu.rs:491
__ZN3std2rt10lang_start28__u7b__u7b_closure_u7d__u7d_17hc3810b9cbdf76d05E @ grisu.rs:491
__ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h45d765e0ad7e854fE @ grisu.rs:491
__ZN3std9panicking3try7do_call17he4712eb84191fb3bE_llvm_369D5A5A @ grisu.rs:491
dynCall_vi @ grisu.rs:491
Module.dynCall_vi @ window.js:7823
invoke_vi @ window.js:7477
___rust_maybe_catch_panic @ grisu.rs:491
__ZN3std2rt19lang_start_internal17h76f990c2b2c74932E @ grisu.rs:491
__ZN3std2rt10lang_start17h018a6e635825245eE @ grisu.rs:491
_main @ grisu.rs:491
Module._main @ window.js:7739
callMain @ window.js:7973
doRun @ window.js:8031
run @ window.js:8045
runCaller @ window.js:7950
removeRunDependency @ window.js:1462
receiveInstance @ window.js:1624
receiveInstantiatedSource @ window.js:1649
Promise.then (async)
doNativeWasm @ window.js:1665
Module.asm @ window.js:1751
(anonymous) @ window.js:7556
window.js:7993 exception thrown: abort(-1) at Error
at jsStackTrace (http://localhost:1235/window.js:1066:13)
at stackTrace (http://localhost:1235/window.js:1083:12)
at abort (http://localhost:1235/window.js:8142:44)
at _emscripten_set_mousemove_callback (http://localhost:1235/window.js:7196:63)
at __ZN5winit8platform8platform6Window3new17h036fa7310bcbf823E (wasm-function[431]:1924)
at dynCall_viii (wasm-function[1281]:17)
at Object.Module.dynCall_viii (http://localhost:1235/window.js:7835:40)
at invoke_viii (http://localhost:1235/window.js:7510:27)
at __ZN5winit6window38__LT_impl_u20_winit__WindowBuilder_GT_5build17h500b3e62957b8a6fE (wasm-function[182]:510)
at dynCall_viii (wasm-function[1281]:17)

To build:

rustup target install wasm32-unknown-emscripten
cargo build --example window --target wasm32-unknown-emscripten

This creates window.js and .wasm in target/wasm32-unknown-emscripten/debug/examples/, to load I added this file test.html in that directory, following the requirements outlined in https://github.com/tomaka/winit#emscripten-and-webassembly:

<!DOCTYPE html>
<head>
<title></title>
</head>
<body>
<canvas id="my_id"></canvas>
<script>
window.Module = { canvas: document.getElementById('my_id') };
</script>
<script src="window.js"></script>
</body>
</html>

then served the files through a simple Python web server:

import SimpleHTTPServer
import SocketServer
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map['.wasm'] = 'application/wasm'
httpd = SocketServer.TCPServer(("", 1234), Handler)
httpd.serve_forever()

visited http://localhost:1234/test.html in Chrome, then I received the window.js:7196 missing function: emscripten_set_mousemove_callback error in the JavaScript debugger.

Searching for this error message finds only one issue: emscripten-core/emscripten#7525 Emscripten 1.38.17+ incompatible with upstream SDL 2.0.8, slightly different situation, that user was able to resolve their problem by rebuilding. However I reinstalled the SDK, cargo clean, cleared out ~/.emscripten_cache, so I'm not sure what else I would need to rebuild?


Next I tried to build on a completely different system (Ubuntu Linux in a VM, first system was macOS 10.14.2) to isolate whether there was a stale misconfiguration with emscripten or something, but with the same emsdk 1.38.22, it failed even earlier, on cargo build --example window --target wasm32-unknown-emscripten compilation:

ubuntu@ubuntu-virtual-machine:~/winit$ cargo build --example window --target wasm32-unknown-emscripten
   Compiling libc v0.2.46                                                                                                                                                       
   Compiling cfg-if v0.1.6                                                                                                                                                      
   Compiling lazy_static v1.2.0                                                                                                                                                 
   Compiling log v0.4.6                                                                                                                                                         
   Compiling winit v0.18.1 (/home/ubuntu/winit)                                                                                                                                 
warning: unused `#[macro_use]` import                                                                                                                                           
  --> src/lib.rs:91:1                                                                                                                                                           
   |                                                                                                                                                                            
91 | #[macro_use]                                                                                                                                                               
   | ^^^^^^^^^^^^                                                                                                                                                               
   |                                                                                                                                                                            
   = note: #[warn(unused_imports)] on by default                                                                                                                                
                                                                                                                                                                                
warning: method is never used: `interrupt`                                                                                                                                      
   --> src/platform/emscripten/mod.rs:106:5                                                                                                                                     
    |                                                                                                                                                                           
106 |     pub fn interrupt(&self) {                                                                                                                                             
    |     ^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                               
    |                                                                                                                                                                           
    = note: #[warn(dead_code)] on by default                                                                                                                                    
                                                                                                                                                                                
warning: unused `std::result::Result` that must be used                                                                                                                         
   --> src/platform/emscripten/mod.rs:637:13                                                                                                                                    
    |                                                                                                                                                                           
637 |             self.grab_cursor(false);                                                                                                                                      
    |             ^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                      
    |                                                                                                                                                                           
    = note: #[warn(unused_must_use)] on by default                                                                                                                              
    = note: this `Result` may be an `Err` variant, which should be handled                                                                                                      
                                                                                                                                                                                
error: linking with `emcc` failed: exit code: 1                                                                                                                                 
  |                                                                                                                                                                             
  = note: "emcc" "-s" "DISABLE_EXCEPTION_CATCHING=0" "-L" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.10dxdxrs7zw90t7w.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.112p8kxaw8li07xn.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.1byri58jj3kgrm6p.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.1otiygkv9sqgwlm.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.1qy7jefab5zoyqvw.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.2avkabs4kucwq8k0.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.2j8jzbnkne1fufnk.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.2kb6lcwdsalzswye.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.2mjt5tg33laii3w.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.2ps4sb69egjig53x.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.2ubgkfkdaiumtfvk.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.30zhzew84tqsckiv.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.31nqc83gnwuihsum.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.39gv1tdykhc6zxid.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.3bmxtu9pai4w7bal.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.3hj86efhaywkvxay.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.3l6zmxcgxksruc1h.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.3r73wok95hzuewtd.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.3zftok7e4xm0bfxm.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.43soldk7xly8mcll.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.4e7msdguj4dsq5ee.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.4glgxh4cj2rzjd7c.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.4m8tsdp3ceytssgi.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.4urr3ciozaveezj9.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.59jdz47l3yg11pz6.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.5br8susbkrf0ip7k.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.5fmj62rl3b0862ux.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.6ey0ajfh30a5f4n.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.i0cbfotjaof81bs.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.ktsc5g5kc71n4v4.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.sdh2iyltljzkjto.rcgu.o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.ygq3gmy8sgtwtcq.rcgu.o" "-o" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.js" "-s" "EXPORTED_FUNCTIONS=[\"_main\",\"_rust_eh_personality\"]" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/examples/window-ad7c4d1114999516.y05gmiveyef4hib.rcgu.o" "-O0" "--memory-init-file" "0" "-g4" "-s" "DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[]" "-L" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/deps" "-L" "/home/ubuntu/winit/target/debug/deps" "-L" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/deps/libwinit-fb1da3298d337e9f.rlib" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/deps/liblog-2cde884c8ec75d89.rlib" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/deps/libcfg_if-47ae4f4904545192.rlib" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/deps/liblibc-66d20d13397431c1.rlib" "/home/ubuntu/winit/target/wasm32-unknown-emscripten/debug/deps/liblazy_static-2f3507fe8c59b581.rlib" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib/libstd-d3c8530a2103c66a.rlib" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib/libpanic_unwind-020f881579077ed2.rlib" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib/libunwind-9d7cbb3306207ed0.rlib" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib/liballoc_system-8883cbfabc444af4.rlib" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib/liblibc-1340b367e717a7b5.rlib" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib/liballoc-18e00c9c4b7e8101.rlib" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib/libcore-41e8ad90a408e7c3.rlib" "/home/ubuntu/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-emscripten/lib/libcompiler_builtins-354cd92321f64700.rlib" "-l" "c" "-s" "BINARYEN=1" "-s" "ERROR_ON_UNDEFINED_SYMBOLS=1"
  = note: Traceback (most recent call last):                                                                                                                                    
            File "/home/ubuntu/emsdk/emscripten/1.38.22/emcc.py", line 3088, in <module>                                                                                        
              sys.exit(run())                                                                                                                                                   
            File "/home/ubuntu/emsdk/emscripten/1.38.22/emcc.py", line 1642, in run                                                                                             
              extra_files_to_link += system_libs.calculate([f for _, f in sorted(temp_files)] + extra_files_to_link, in_temp, stdout_=None, stderr_=None, forced=forced_stdlibs)
            File "/home/ubuntu/emsdk/emscripten/1.38.22/tools/system_libs.py", line 550, in calculate                                                                           
              symbolses = shared.Building.parallel_llvm_nm([os.path.abspath(t) for t in temp_files])                                                                            
            File "/home/ubuntu/emsdk/emscripten/1.38.22/tools/shared.py", line 1801, in parallel_llvm_nm                                                                        
              object_contents = pool.map(g_llvm_nm_uncached, files)                                                                                                             
            File "/usr/lib/python2.7/multiprocessing/pool.py", line 253, in map                                                                                                 
              return self.map_async(func, iterable, chunksize).get()                                                                                                            
            File "/usr/lib/python2.7/multiprocessing/pool.py", line 572, in get                                                                                                 
              raise self._value                                                                                                                                                 
          OSError: [Errno 8] Exec format error                                                                                                                                  
                                                                                                                                                                                
                                                                                                                                                                                
error: aborting due to previous error                                                                                                                                           
                                                                                                                                                                                
error: Could not compile `winit`.                                                                                                                                               

To learn more, run the command again with --verbose.

With an earlier emscripten 1.37.12 installation on macOS 10.14.2, I could build but running would fail with yet a different error:

thread 'main' panicked at 'assertion failed: validate_hidpi_factor(dpi_factor)', .cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/winit-0.18.0/src/dpi.rs:236:9

https://github.com/tomaka/winit/blob/master/src/dpi.rs#L236

    #[inline]
    pub fn to_physical(&self, dpi_factor: f64) -> PhysicalSize {
        assert!(validate_hidpi_factor(dpi_factor));
        let width = self.width * dpi_factor;
        let height = self.height * dpi_factor;
        PhysicalSize::new(width, height)
    }

assuming this was an incompatibility fixed in newer emsdk, I updated to 1.38.22, but then hit the error described above. I see #548 "DPI for everyone" changed this code last, but the author couldn't get anything to run in the browser.

Is there a known-working compatible version of emsdk I should use? Any help appreciated

@francesca64
Copy link
Member

Can you find out the value of dpi_factor? I assume it's probably 0.0. If you just hardcode get_hidpi_factor to return 1.0, you'll be able to get further into execution to see if anything else explodes.

As for the other stuff, um...

@Osspial are you still interested in doing work on Emscripten?

@Osspial
Copy link
Contributor

Osspial commented Jan 17, 2019

I could if I had to, but I've already got a whole bunch of non-web stuff I'd like to work on and I'd rather avoid adding anything else to the pile if I can.

There seems to be plenty of people that are interested in having Emscripten work, though. It's probably worth putting out requests for help on the Reddit and the user forums to see if any of those people would be interested in working on it.

@iceiix
Copy link
Author

iceiix commented Jan 19, 2019

I might be willing to help maintain the Emscripten support, if I can get it working first...

@francesca64

Can you find out the value of dpi_factor? I assume it's probably 0.0. If you just hardcode get_hidpi_factor to return 1.0, you'll be able to get further into execution to see if anything else explodes.

Agreed this could be a promising direction of investigation.

I'll look into it, but another confounding factor seems to be the Rust compiler version. emsdk 1.37.12 + rustc 1.31.0 hits this assertion failed: validate_hidpi_factor(dpi_factor) error.

Upgrading rustc to 1.32.0 fails compilation with error: Invalid value (Producer: 'LLVM6.0.1' Reader: 'LLVM 4.0.0'). Only a very precise set of versions might be compatible, I'll try more permutations. For the record, this is where I'm starting (to investigate the validate_hidpi_factor assertion):

rustup default 1.31.0
rustup target install wasm32-unknown-emscripten
emsdk install sdk-1.38.16-64bit
emsdk activate sdk-1.38.16-64bit
source ~/emsdk/emsdk_env.sh
EMCC_DEBUG=1 cargo build --example window --target wasm32-unknown-emscripten

@iceiix
Copy link
Author

iceiix commented Jan 19, 2019

Adding logging in validate_hidpi_factor() shows that dpi_factor is 2, but is failing because dpi_factor.is_normal() is false.

--- a/src/dpi.rs
+++ b/src/dpi.rs
@@ -83,6 +83,7 @@
 /// otherwise, you risk panics.
 #[inline]
 pub fn validate_hidpi_factor(dpi_factor: f64) -> bool {
+    panic!("dpi_factor = {}, is_sign_positive={}, is_normal={}", dpi_factor, dpi_factor.is_sign_positive(), dpi_factor.is_normal());
     dpi_factor.is_sign_positive() && dpi_factor.is_normal()
 }

thread 'main' panicked at 'dpi_factor = 2, is_sign_positive=true, is_normal=false', src/dpi.rs:86:5

https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.is_normal documents is_normal as follows:

Returns true if the number is neither zero, infinite, subnormal, or NaN.

dpi_factor.classify() confirms this number is FpCategory::Subnormal. Why would "2" be subnormal?

https://stackoverflow.com/questions/8341395/what-is-a-subnormal-floating-point-number explains the bit representation of subnormals. dpi_factor.to_bits() returns 0x4000000000000000, exp bits are zero. dpi_factor==2.0 is true. Bug in the Rust standard library and/or the wasm32-unknown-emscripten target? is_normal() uses classify() which uses to_bits(), which only does unsafe { mem::transmute(self) }, maybe not as expected for emscripten's 64-bit floating point? From https://users.rust-lang.org/t/what-is-a-known-working-setup-for-using-rust-with-emscripten-wasm32-unknown-emscripten/24312/2:

Emscripten does not support native-int64, but will emulate this via floating-point (provided by environment) rust-wasm32-unknown-unknown does support native int64.

&ing with EXP_MASK should return non-zero:

  0x4000000000000000
& 0x7ff0000000000000
--------------------
  0x4000000000000000

minimal test case:

fn main() {
    let x = 2.0f64;
    panic!("x={}, is_sign_positive={}, is_normal={}, classify={:?}, to_bits=0x{:x}, ==2.0={}",
        x, x.is_sign_positive(), x.is_normal(), x.classify(),
        x.to_bits(),
        x == 2.0);
}

rustc 1.32.0 + emscripten sdk-1.38.22-64bit:
thread 'main' panicked at 'x=2, is_sign_positive=true, is_normal=true, classify=Normal, to_bits=0x4000000000000000, ==2.0=true', normaltest.rs:3:5

rustc 1.31.0 + emscripten sdk-1.37.12-64bit:
thread 'main' panicked at 'x=2, is_sign_positive=true, is_normal=false, classify=Subnormal, to_bits=0x4000000000000000, ==2.0=true', normaltest.rs:3:5

so, assertion failed: validate_hidpi_factor(dpi_factor) in winit is caused by f64 is_normal() misclassifying 2.0 as subnormal, apparently a bug fixed in latest rustc/emsdk, but, then we're back to the missing function: emscripten_set_mousemove_callback problem.

@iceiix iceiix changed the title missing function: emscripten_set_mousemove_callback Emscripten support broken: missing function: emscripten_set_mousemove_callback / assertion failed: validate_hidpi_factor(dpi_factor) Jan 19, 2019
@iceiix
Copy link
Author

iceiix commented Jan 19, 2019

If I remove the is_normal check:

--- a/src/dpi.rs
+++ b/src/dpi.rs
@@ -83,7 +83,7 @@
 /// otherwise, you risk panics.
 #[inline]
 pub fn validate_hidpi_factor(dpi_factor: f64) -> bool {
-    dpi_factor.is_sign_positive() && dpi_factor.is_normal()
+    dpi_factor.is_sign_positive()
 }
 
 /// A position represented in logical pixels.

then the window example can load on rustc 1.31.0 + emscripten sdk-1.37.12-64bit without error, and moving the mouse logs WindowEvents/DeviceEvents as expected. So far, so good!

Would still be a good idea to find out what is going on with winit on latest versions, rustc 1.32.0 + emscripten sdk-1.38.22-64bit causing missing function: emscripten_set_mousemove_callback, but at least the example works with older versions, going to try to continue porting my app on 1.31.0 + 1.37.12.

iceiix added a commit to iceiix/winit that referenced this issue Jan 19, 2019
rustc 1.32.0 + emscripten sdk-1.38.22-64bit:
thread 'main' panicked at 'x=2, is_sign_positive=true, is_normal=true, classify=Normal, to_bits=0x4000000000000000, ==2.0=true', normaltest.rs:3:5

rustc 1.31.0 + emscripten sdk-1.37.12-64bit:
thread 'main' panicked at 'x=2, is_sign_positive=true, is_normal=false, classify=Subnormal, to_bits=0x4000000000000000, ==2.0=true', normaltest.rs:3:5

rust-windowing#760 (comment)
rust-windowing#760 (comment)
@iceiix
Copy link
Author

iceiix commented Jan 20, 2019

I believe the missing function incompatibility is caused by the use of #defines in Emscripten to maintain source compatibility, which hides emscripten_set_mousemove_callback from winit's ffi in https://github.com/tomaka/winit/blob/master/src/platform/emscripten/ffi.rs#L261, since extern "C" can't access C macros.

To fix this, winit could switch to the _on_thread replacement functions they are defined to, as juj points out: https://github.com/emscripten-core/emscripten/blob/443447b14d34a3d710d33f229dea64e5c78a78ce/system/include/emscripten/html5.h#L483-L494

Was about to file a bug to rust-lang/rust before realizing this, I'll save the text here since it may be useful for the small repro case: https://gist.github.com/iceiix/94083aa0025471f37557466e836a4e8d

@ryanisaacg
Copy link
Contributor

Because emscripten support has been replaced with wasm32-unknown-unknown, I'm going to close this for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B - bug Dang, that shouldn't have happened C - in progress Implementation is proceeding smoothly
Development

No branches or pull requests

4 participants