hoppetosse: I reread the gist, the only big thing I've left out is what I thought it was... you have to 1) build llvm from http://prereleases.llvm.org/6.0.0/ adding the DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly to CMake
then build zig where -DCMAKE_PREFIX_PATH is set to the install directory of that llvm
off of the llvm6 branch
and from there I think the gist is accurate
so many hoops to jump through but it works
looks like this:
zig build-obj --release-fast --target-arch wasm32 --target-os freestanding thing.zig --output out.wasm
export fn doubler(x:i32) i32 {
return x * 2;
}
and I just hardcoded the environ, since I couldn't figure out why it wasn't accepting it...
diff --git a/src/target.cpp b/src/target.cpp
index 69b1d6a8..d95817f8 100644
--- a/src/target.cpp
+++ b/src/target.cpp
@@ -503,10 +503,12 @@ void get_target_triple(Buf *triple, const ZigTarget *target) {
get_arch_name(arch_name, &target->arch);
buf_resize(triple, 0);
- buf_appendf(triple, "%s-%s-%s-%s", arch_name,
+ buf_appendf(triple, "%s-%s-%s-wasm", arch_name,
ZigLLVMGetVendorTypeName(target->vendor),
- ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
- ZigLLVMGetEnvironmentTypeName(target->env_type));
+ ZigLLVMGetOSTypeName(get_llvm_os_type(target->os))
+ );
+
+ /* ZigLLVMGetEnvironmentTypeName(target->env_type)); */
}
static bool is_os_darwin(ZigTarget *target) {
That gives me a binary that I can use binaryen's wasm-dis on to see:
(module
(type $0 (func (param i32) (result i32)))
(import "env" "__linear_memory" (memory $0 0))
(import "env" "__indirect_function_table" (table 0 anyfunc))
(export "doubler" (func $doubler))
(func $doubler (; 0 ;) (type $0) (param $var$0 i32) (result i32)
(i32.shl
(get_local $var$0)
(i32.const 1)
)
)
;; custom section "linking", size 0
)
then the instantiation:
fetch('out.wasm').then blah blah res
WebAssembly.instantiateStreaming(res, {
env: {
__linear_memory: new WebAssembly.Memory({initial: 10}),
__indirect_function_table: new WebAssembly.Table({element:'anyfunc', initial: 10})
}
}).then(function (wasmModule) {
return wasmModule.instance.exports;
});
And
const {doubler} = require('./out.wasm');
console.log(doubler(4));
prints 8 in the browser.
There is a lot of work to do but I'm super jazzed.
This is now out of date,
If llvm is compiled with
DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly
, this should work out of the box with something along the lines ofzig build-obj --release-fast --target-arch wasm32 --target-os freestanding thing.zig --output out.wasm
the goal in the next half year would be to flesh out the std lib and polyfilling functionality b/t the js runtime (as "os") and the wasm code.