Open Boscop opened 6 years ago
I did the following steps:
wasm2js frontend.wasm -o wasm.jsm
(The frontend.wasm file was generated by cargo web deploy
along with a frontend.js file.)
Since it is in ESM format, which IE doesn't support, I transpiled it with babel to UMD so that it works in IE11:
node --max-old-space-size=16384 node_modules\@babel\cli\bin\babel.js --plugins @babel/transform-modules-umd --presets @babel/preset-env wasm.jsm -o wasm.js -s true --module-id meow
Inspired by this.
Then I changed the generated frontend.js file to this:
Instead of fetching the wasm file, compiling and instantiating it, and then calling its main()
function, since I want to load the wasm.js file, I do that in index.html. But here I first assign all the imports to window
so that the wasm.js file can access them, and store instance.initialize
with window
so that I can call it after wasm.js was loaded:
for (var i in instance.imports) window[i] = instance.imports[i];
window.__initialize = instance.initialize;
The rest of that file stays the same.
Now in index.html I put <script src="wasm.js"></script>
in the <head>
and <script src="frontend-init.js"></script>
in the <body>
. This file contains the following:
window.__initialize({ exports: window.meow });
When I open index.html in the browser, it loads the frontend UI and also executes the code that connects via websocket to my backend etc. BUT then I get this error:
frontend.js:428 Uncaught TypeError: Cannot read property 'get' of undefined
at Object.Module.STDWEB_PRIVATE.dyncall (frontend.js:428)
at WebSocket.output (frontend.js:171)
Module.STDWEB_PRIVATE.dyncall @ frontend.js:428
output @ frontend.js:171
error (async)
(anonymous) @ frontend.js:527
__extjs_7c5535365a3df6a4cc1f59c4a957bfce1dbfb8ee @ frontend.js:527
_$LT$frontend__app__Model$u20$as$u20$yew__html__Component$GT$__update__hc3f28c3839ea6127 @ wasm.jsm:118591
_$LT$yew__html__ComponentEnvelope$LT$COMP$GT$$u20$as$u20$yew__scheduler__Runnable$GT$__run__hc2bdd83f84c2f23f @ wasm.jsm:112824
yew__scheduler__Scheduler__put_and_try_run__h74799cfeb6bb02bb @ wasm.jsm:29774
frontend__main__h4b6651b4f1b2a19d @ wasm.jsm:42438
std__rt__lang_start___$u7b$$u7b$closure$u7d$$u7d$__hc2ce99dbb9f784cb @ wasm.jsm:44454
std__sys_common__backtrace____rust_begin_short_backtrace__hc3417943071d4ca9 @ wasm.jsm:43623
std__rt__lang_start__h60080c07a5a697ad @ wasm.jsm:41592
main @ wasm.jsm:154530
initialize @ frontend.js:747
(anonymous) @ frontend-asm.js:1
frontend.js:428 Uncaught TypeError: Cannot read property 'get' of undefined
at Object.Module.STDWEB_PRIVATE.dyncall (frontend.js:428)
at WebSocket.output (frontend.js:171)
Line 428 of frontend.js is the middle line of these 3:
Module.STDWEB_PRIVATE.dyncall = function( signature, ptr, args ) {
return Module.web_table.get( ptr ).apply( null, args );
};
@yurydelendik helped me on IRC with this and he said that apparently wasm2js doesn't support web table..
What would it take to make this work? :)
Bonus question: I'd prefer to init the js module in the same frontend.js file, like it does it with the wasm file originally. How can I adapt the fetch code so that it fetches and evals the wasm.js
file, so that I can then call instance.initialize
on it and call its main()
function in the same setup js file? So that in my index.html file I only have to include one js file (like in the original wasm case).
Minimal test case:
(module
(table $t (export "table") 1 anyfunc)
(elem $t (i32.const 0) $f)
(func $f (nop))
)
generates:
function asmFunc(global, env, buffer) {
"use asm";
var HEAP8 = new global.Int8Array(buffer);
var HEAP16 = new global.Int16Array(buffer);
var HEAP32 = new global.Int32Array(buffer);
var HEAPU8 = new global.Uint8Array(buffer);
var HEAPU16 = new global.Uint16Array(buffer);
var HEAPU32 = new global.Uint32Array(buffer);
var HEAPF32 = new global.Float32Array(buffer);
var HEAPF64 = new global.Float64Array(buffer);
var Math_imul = global.Math.imul;
var Math_fround = global.Math.fround;
var Math_abs = global.Math.abs;
var Math_clz32 = global.Math.clz32;
var Math_min = global.Math.min;
var Math_max = global.Math.max;
var Math_floor = global.Math.floor;
var Math_ceil = global.Math.ceil;
var Math_sqrt = global.Math.sqrt;
var abort = env.abort;
var nan = global.NaN;
var infinity = global.Infinity;
var i64toi32_i32$HIGH_BITS = 0;
function $0() {
}
var FUNCTION_TABLE_v = [$0];
return {
};
}
const memasmFunc = new ArrayBuffer(65536);
const retasmFunc = asmFunc({Math,Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,NaN,Infinity}, {abort:function() { throw new Error('abort'); }},memasmFunc);
I'd like to use the yew frontend framework for the GUI of Windows programs in Rust, in combination with web-view which embeds a IE11 Window. IE11 doesn't support wasm, so I want to compile my frontend.wasm file to asm.js with wasm2js, but what's the right way to do it?
The reason why I don't want to build my frontend to asm.js via the emscripten target is because I don't want the huge emscripten runtime included in my app, and I don't want to depend on emscripten..