Skip to content

Instantly share code, notes, and snippets.

@bnjbvr
Last active January 9, 2017 16:24
Show Gist options
  • Save bnjbvr/326522674622f796e69c7968b23ac1eb to your computer and use it in GitHub Desktop.
Save bnjbvr/326522674622f796e69c7968b23ac1eb to your computer and use it in GitHub Desktop.
const wasmEvalText = (txt, maybeImports) => new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(txt)), maybeImports);
let module = new WebAssembly.Module(wasmTextToBinary(`
(module
(import "global" "func" (result i32))
(table (import "env" "table") 3 anyfunc)
(func (export "func_0") (result i32)
call 0 ;; calls the import, which is func #0
)
(memory (export "mem") 10)
)
`));
print("imports:")
for (let descriptor of WebAssembly.Module.imports(module)) {
print(JSON.stringify(descriptor));
}
print("\nexports:")
for (let descriptor of WebAssembly.Module.exports(module)) {
print(JSON.stringify(descriptor));
}
let imports = {
global: {
func: function() {
console.log('hello world');
return 1337;
}
},
env: {
table: new WebAssembly.Table({ element: 'anyfunc', initial: 3 })
}
};
let instance = new WebAssembly.Instance(module, imports);
let exported_func0 = instance.exports.func_0;
print(exported_func0());
let memory = instance.exports.mem;
// Example of dummy imports.
let anotherModule = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
(module
(func (export "leet") (result f32)
f32.const 13.37
)
)
`)));
let dummyImports = {
env: {
// Note that the initial size of the table must be compatible with the
// one declared in the module. If the module says:
// (table (import "env" "table") N anyfunc)
// where N is a number,
// then initial here must be >= N.
table: new WebAssembly.Table({ element: 'anyfunc', initial: 10 }),
// Note `initial` size is in number of 4K pages. The same rule
// described above applies for tables.
memory: new WebAssembly.Memory({ initial: 1 }),
some_func: function() { console.log('I can be a JS function!'); return 42; },
// Or an exported wasm function: note that the signature declared in
// the `anotherModule` must match the one we declare in the module that
// imports this function.
some_other_func: anotherModule.exports.leet,
numeric_value: 42
}
};
let newModule = new WebAssembly.Module(wasmTextToBinary(`
(module
;; (this is a wasm comment)
;; i32 means we'll apply JS::ToInt32 on the imported value; since
;; numeric_value is float(13.37), this global (called $g1) will contain 13.
;; The original imported JS value isn't changed.
;; Note: imported globals are immutable by default in the MVP.
(global $g1 (import "env" "numeric_value") i32)
;; same value imported, but in a second global with a f32 type, so it will
;; contain float(13.37) instead.
(global (import "env" "numeric_value") f32)
;; import the table: the declared initial size has to be >= the actual initial size.
(table (import "env" "table") 5 anyfunc)
;; import the memory: same rule applies
(memory (import "env" "memory") 1)
;; import a function with a given signature:
(func $some_i32 (import "env" "some_func") (result i32))
;; can be reimported with a different signature: no checks are done at instanciation, since
;; this is a JS function.
(func $some_f32 (import "env" "some_func") (result f32) (param i32))
;; import another function with a given signature: since we pass a wasm function at
;; instanciation, there'll be a signature check *at instanciation*, so the signature of this
;; function must be the same as the one in anotherModule
(func $some_other (import "env" "some_other_func") (result f32))
;; one can also re-export anything.
(export "some_func" $some_i32)
(export "some_other" $some_other)
)
`));
let i = new WebAssembly.Instance(newModule, dummyImports);
print("Calling into the new module.");
print(i.exports.some_func());
print(i.exports.some_other());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment