Skip to content

Instantly share code, notes, and snippets.

@anthumchris
Last active July 3, 2021 02:56
Show Gist options
  • Select an option

  • Save anthumchris/c1b5f5526b966011dac39fbb17dacafe to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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