emcc
supports compiling.ll
and.bc
files- Based on LLVM's tests, we can have LLVM IR generate a
call_indirect
function (with several types of function signatures of parameters)
Last active
November 15, 2017 07:32
-
-
Save AmaanC/2731b753c50c177c2fbe583eae34fa43 to your computer and use it in GitHub Desktop.
Adding support for WebAssembly's call_indirect operator directly in your C code by compiling LLVM IR with your C code through emscripten
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
target datalayout = "e-p:32:32-i64:64-v128:32:128-n32-S128" | |
target triple = "asmjs-unknown-emscripten" | |
; https://github.com/llvm-mirror/llvm/blob/45ed11f7a623932117ee4a3deb540e3869c38fe4/test/CodeGen/WebAssembly/call.ll#L84-L92 | |
define void @call_indirect(void ()* %callee) { | |
call void %callee() | |
ret void | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src='loader.js'></script> | |
<h1>Check the console</h1> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let imports = { | |
env: { | |
memory: WebAssembly.Memory({ initial: 256 }), | |
memoryBase: 0, | |
table: WebAssembly.Table({ initial: 1, element: 'anyfunc' }), | |
tableBase: 0, | |
abort: () => { | |
debugger; | |
}, | |
_call_js: () => { | |
console.log('main.c called call_js'); | |
debugger; | |
} | |
} | |
}; | |
fetch('main.wasm').then((resp) => { | |
return resp.arrayBuffer(); | |
}).then((buffer) => { | |
return WebAssembly.instantiate( | |
buffer, | |
imports | |
); | |
}).then(({instance, module}) => { | |
imports.env.table.set(0, instance.exports._call_js_log); | |
instance.exports._main(); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void call_indirect(int index); | |
void call_js(); | |
// WebAssembly#Table's can only have Exported Function Exotic Objects | |
// https://github.com/WebAssembly/design/blob/master/JS.md#webassemblytable-objects | |
// We'll put call_js_log in the Table then, and call_indirect(0) should call it | |
void call_js_log() | |
{ | |
call_js(); | |
} | |
int main() | |
{ | |
// Assumes the environment sets the default Table up with an entry at 0 | |
call_indirect(0); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main.wasm: main.c call-indirect.ll | |
emcc $^ -o $@ \ | |
-O3 \ | |
-s LEGALIZE_JS_FFI=0 \ | |
-s WASM=1 -s SIDE_MODULE=1 \ | |
-g4 | |
.PHONY: serve | |
serve: main.wasm loader.js index.html | |
python3 -m http.server 8888 | |
echo "Visit http://localhost:8888/" | |
.PHONE: clean | |
clean: | |
rm main.wasm |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment