diff --git a/src/examples/wasm/Makefile b/src/examples/wasm/Makefile index 9b02bf67..02624779 100644 --- a/src/examples/wasm/Makefile +++ b/src/examples/wasm/Makefile @@ -1,3 +1,8 @@ +invoke: clean wasm_exec + tinygo build -o ./html/wasm.wasm -target wasm -no-debug ./invoke/wasm.go + cp ./invoke/wasm.js ./html/ + cp ./invoke/index.html ./html/ + export: clean wasm_exec tinygo build -o ./html/wasm.wasm -target wasm -no-debug ./export/wasm.go cp ./export/wasm.js ./html/ diff --git a/src/examples/wasm/invoke/index.html b/src/examples/wasm/invoke/index.html new file mode 100644 index 00000000..24df3499 --- /dev/null +++ b/src/examples/wasm/invoke/index.html @@ -0,0 +1,19 @@ + + + + + + + Go WebAssembly + + + + + + +

WebAssembly

+

Edit on either side to mimic values, using WebAssembly:

+ == + + + diff --git a/src/examples/wasm/invoke/wasm.go b/src/examples/wasm/invoke/wasm.go new file mode 100644 index 00000000..5d430976 --- /dev/null +++ b/src/examples/wasm/invoke/wasm.go @@ -0,0 +1,15 @@ +package main + +import ( + "syscall/js" +) + +func runner(this js.Value, args []js.Value) interface{} { + return args[0].Invoke(args[1]).String() +} + +func main() { + wait := make(chan struct{}, 0) + js.Global().Set("runner", js.FuncOf(runner)) + <-wait +} diff --git a/src/examples/wasm/invoke/wasm.js b/src/examples/wasm/invoke/wasm.js new file mode 100644 index 00000000..8ba43932 --- /dev/null +++ b/src/examples/wasm/invoke/wasm.js @@ -0,0 +1,43 @@ +'use strict'; + +const WASM_URL = 'wasm.wasm'; + +var wasm; + +function updateRight() { + const value = document.getElementById("a").value; + window.runner(function (value) { + document.getElementById("b").value = value; + }, value); +} + +function updateLeft() { + const value = document.getElementById("b").value; + window.runner(function (value) { + document.getElementById("a").value = value; + }, value); +} + +function init() { + document.querySelector('#a').oninput = updateRight; + document.querySelector('#b').oninput = updateLeft; + + const go = new Go(); + if ('instantiateStreaming' in WebAssembly) { + WebAssembly.instantiateStreaming(fetch(WASM_URL), go.importObject).then(function (obj) { + wasm = obj.instance; + go.run(wasm); + }) + } else { + fetch(WASM_URL).then(resp => + resp.arrayBuffer() + ).then(bytes => + WebAssembly.instantiate(bytes, go.importObject).then(function (obj) { + wasm = obj.instance; + go.run(wasm); + }) + ) + } +} + +init(); diff --git a/targets/wasm_exec.js b/targets/wasm_exec.js index 3f2a6b5a..665ac795 100644 --- a/targets/wasm_exec.js +++ b/targets/wasm_exec.js @@ -265,17 +265,17 @@ }, // func valueInvoke(v ref, args []ref) (ref, bool) - //"syscall/js.valueInvoke": (sp) => { - // try { - // const v = loadValue(sp + 8); - // const args = loadSliceOfValues(sp + 16); - // storeValue(sp + 40, Reflect.apply(v, undefined, args)); - // mem().setUint8(sp + 48, 1); - // } catch (err) { - // storeValue(sp + 40, err); - // mem().setUint8(sp + 48, 0); - // } - //}, + "syscall/js.valueInvoke": (ret_addr, v_addr, args_ptr, args_len, args_cap) => { + try { + const v = loadValue(v_addr); + const args = loadSliceOfValues(args_ptr, args_len, args_cap); + storeValue(ret_addr, Reflect.apply(v, undefined, args)); + mem().setUint8(ret_addr + 8, 1); + } catch (err) { + storeValue(ret_addr, err); + mem().setUint8(ret_addr + 8, 0); + } + }, // func valueNew(v ref, args []ref) (ref, bool) "syscall/js.valueNew": (ret_addr, v_addr, args_ptr, args_len, args_cap) => {