Initial syscall/js support was implemented in #53. I know everything doesn't work yet, but I did expect this simple demo to work without problems:
// +build js,wasm
package main
import "syscall/js"
var document js.Value
func init() {
document = js.Global().Get("document")
}
func main() {
div := document.Call("getElementById", "target")
node := document.Call("createElement", "div")
node.Set("innerText", "Hello World")
div.Call("appendChild", node)
}
This, when compiled and executed in the browser prints the following to the console:
Firefox 67.0b11:
panic: (21:0x00010618) wasm_exec.js:199:18
RuntimeError: unreachable executed test.wasm:457:1
Chromium 73.0.3683.103
panic: (21:0x00010618)
wasm-a2b042a6-7:9 Uncaught (in promise) RuntimeError: unreachable
at runtime._panic (wasm-function[7]:31)
at (syscall/js.Value).Call (wasm-function[16]:301)
at cwa_main (wasm-function[15]:297)
at global.Go.run (http://localhost:8080/wasm_exec.js:347:24)
at run (http://localhost:8080/:41:13)
at HTMLButtonElement.onclick (http://localhost:8080/:46:51)
runtime._panic @ wasm-a2b042a6-7:9
(syscall/js.Value).Call @ wasm-a2b042a6-16:127
cwa_main @ wasm-a2b042a6-15:101
run @ wasm_exec.js:347
run @ (index):41
onclick @ (index):46
async function (async)
run @ (index):41
onclick @ (index):46
The example works as expected when compiled with gc. This was tested with tinygo 0.5.0.
This can be reproduced by cloning my wasm-experiments repo and running make tinygo target=js.
This PR makes it clearer what is going on here: https://github.com/tinygo-org/tinygo/pull/300
OK I've recompiled with #300 merged:
panic: syscall/js: call of Value.Call on null wasm_exec.js:199:18
RuntimeError: unreachable executed test.wasm:542:1
Chromium:
panic: syscall/js: call of Value.Call on null
wasm_exec.js:347 Uncaught (in promise) RuntimeError: unreachable
at runtime._panic (wasm-function[9]:31)
at (syscall/js.Value).Call (wasm-function[18]:301)
at cwa_main (wasm-function[17]:297)
at global.Go.run (http://localhost:8080/wasm_exec.js:347:24)
at run (http://localhost:8080/:41:13)
at HTMLButtonElement.onclick (http://localhost:8080/:46:51)
Can you try compiling with -opt=1? That disables inlining and leads to a better stack trace.
With -opt=1:
Firefox:
panic: syscall/js: call of Value.Call on null wasm_exec.js:199:18
RuntimeError: unreachable executed test.wasm:914:1
Chromium:
wasm_exec.js:199 panic: syscall/js: call of Value.Call on null
wasm-d35d3dde-13:2 Uncaught (in promise) RuntimeError: unreachable
at runtime.abort (wasm-function[13]:1)
at runtime._panic (wasm-function[9]:31)
at (syscall/js.Value).Call (wasm-function[43]:237)
at ./js/main.go.main (wasm-function[20]:254)
at cwa_main (wasm-function[19]:7)
at global.Go.run (http://localhost:8080/wasm_exec.js:347:24)
at run (http://localhost:8080/:41:13)
at HTMLButtonElement.onclick (http://localhost:8080/:46:51)
runtime.abort @ wasm-d35d3dde-13:2
runtime._panic @ wasm-d35d3dde-9:9
(syscall/js.Value).Call @ wasm-d35d3dde-43:93
./js/main.go.main @ wasm-d35d3dde-20:86
cwa_main @ wasm-d35d3dde-19:3
run @ wasm_exec.js:347
run @ (index):41
onclick @ (index):46
async function (async)
run @ (index):41
onclick @ (index):46
After some discussion I added some more debugging to my example and it seems like the following line is assigning nil to div:
div := document.Call("getElementById", "target")
Wait sec, I think this is user error. That div is not in the HTML I'm using!
...
Yep, I updated my HTML and this example is working fine again. _hides_.
Most helpful comment
Wait sec, I think this is user error. That
divis not in the HTML I'm using!...
Yep, I updated my HTML and this example is working fine again. _hides_.