Skip to content

Instantly share code, notes, and snippets.

@surma
Forked from anthumchris/build.sh
Created March 29, 2018 17:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save surma/74b356795be6cb24b67059e095cf055e to your computer and use it in GitHub Desktop.
Save surma/74b356795be6cb24b67059e095cf055e to your computer and use it in GitHub Desktop.
Emscripten WebAssembly Module.ready() Promise initialization similar to Module.onRuntimeInitialized
#!/bin/bash
docker run --rm -v $(pwd):/src trzeci/emscripten 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.";
}
// Wrap in self-executing function to restrict exposure of Promise vars
(function() {
Module.ready = new Promise((resolve, reject) => {
addOnPreMain(() => {
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 = Module.abort;
Module.abort = function(what) {
reject(Error(what));
origAbort.call(this, what);
}
});
})();
self.importScripts('emscripten-module.js');
self.onmessage = event => {
Module.ready()
.then(api => {
if (self.isClosed) return;
// Interact with Module...
console.log( 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;
}
<script src="emscripten-module.js"></script>
<script>
Module.ready()
.then(api => console.log( api.sayHello() ))
.catch(e => console.error('💩', e))
</script>
@anthumchris
Copy link

@surma Great idea changing Module.ready() function to Module.ready property. Much cleaner.

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