Skip to content

Instantly share code, notes, and snippets.

@anthumchris
Last active July 3, 2021 02:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anthumchris/c1b5f5526b966011dac39fbb17dacafe to your computer and use it in GitHub Desktop.
Save anthumchris/c1b5f5526b966011dac39fbb17dacafe to your computer and use it in GitHub Desktop.
Emscripten WebAssembly Module.ready Promise initialization similar to Module.onRuntimeInitialized
#!/bin/bash
emcc \
-O0 `# leave uncompressed for example` \
-s WASM=1 \
-s EXPORTED_FUNCTIONS="['_hello']" \
-s EXTRA_EXPORTED_RUNTIME_METHODS="['cwrap']" \
-o emscripten-module.js \
--post-js module-post.js \
hello.c
char *hello() {
return "Hello there. Welcome to WebAssembly.";
}
// Module.ready resolves when WASM instantiates. (ready is now a property and not function via @surma fork)
Module.ready = new Promise(function(resolve, reject) {
addOnPreMain(function() {
var api = {
sayHello: Module.cwrap('hello', 'string', [])
};
resolve(api);
});
// Propagate error to Module.ready.catch()
// WARNING: this is a hack based Emscripten's current abort() implementation
// and could break in the future.
// Rewrite existing abort(what) function to reject Promise before it executes.
var origAbort = this.abort;
this.abort = function(what) {
reject(Error(what));
origAbort.call(this, what);
}
});
<script>
const worker = new Worker('web-worker.js');
worker.onmessage = event => {
const error = event.data.error;
if (error) {
console.error('WASM failed to instantiate', error);
}
}
// post a few messages and view console
for (let i=0; i<10; i++) {
worker.postMessage(i);
}
</script>
<script src="emscripten-module.js"></script>
<script>
Module.ready
.then(api => console.log( api.sayHello() ))
.catch(e => console.error('💩', e))
</script>
self.importScripts('emscripten-module.js');
self.onmessage = event => {
Module.ready
.then(api => {
if (self.isClosed) return;
const data = event.data;
// Interact with Module...
console.log( data, api.sayHello() );
})
.catch(e => {
if (self.isClosed) return;
exitOnError(e);
console.error('Module failed to initialize', e);
});
}
// Terminate Worker and prevent Promise microtasks from completing
function exitOnError(e) {
// "throw e" won't be received by controller. Post as message instead
self.postMessage({error: e.message});
self.close();
self.isClosed = true;
}
@Alexufo
Copy link

Alexufo commented Jul 3, 2021

have you phread version?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment