Skip to content

wasm callback loop handling: TypeError: "target argument of Reflect.get must be an object, got (void 0)" #28448

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
iivvoo opened this issue Oct 28, 2018 · 2 comments

Comments

@iivvoo
Copy link

iivvoo commented Oct 28, 2018

What version of Go are you using (go version)?

go version go1.11.1 linux/amd64

Does this issue reproduce with the latest release?

This is the latest (right?)

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ivo/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/ivo/m3r/projects/WASMBug"
GOPROXY=""
GORACE=""
GOROOT="/opt/go1.11.1"
GOTMPDIR=""
GOTOOLDIR="/opt/go1.11.1/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build637835953=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Play with wasm. Specifically, with registering callbacks. The most simple setup already results in a panic after the first callback.

main.go:

package main

import "syscall/js"


func bla(i []js.Value) {
	println("Hello World")
}

func registerCallbacks() {
	js.Global().Set("bla", js.NewCallback(bla))
}

func main() {
	println("WASM Go Initialized")
	registerCallbacks()
	js.Global().Get("document").Call("getElementById", "blaButton").Call("click")
	select {}
}

index.html

<html>

<head>
	<meta charset="utf-8">
	<title>Go wasm</title>
</head>

<body>

	<script src="wasm_exec.js"></script>

	<script>
		if (!WebAssembly.instantiateStreaming) { // polyfill
			WebAssembly.instantiateStreaming = async (resp, importObject) => {
				const source = await (await resp).arrayBuffer();
				return await WebAssembly.instantiate(source, importObject);
			};
		}

		const go = new Go();
		let mod, inst;
		WebAssembly.instantiateStreaming(fetch("lib.wasm"), go.importObject).then(async (result) => {
			mod = result.module;
			inst = result.instance;
			await go.run(inst)
		});

	</script>

	<button onClick="bla();" id="blaButton">Bla</button>

</body>

</html>

What did you expect to see?

Hello World on the console (which is shown) without a crash.

What did you see instead?

On firefox (but similar stacktraces on chromium)

call to closed callback wasm_exec.js:293:28
  syscall/js.valueCall http://localhost:8080/wasm_exec.js:293:28
  syscall_js.valueCall http://localhost:8080/lib.wasm:712567:2147484590
  syscall_js.Value.Call http://localhost:8080/lib.wasm:703432:2147484575
  syscall_js.callbackLoop http://localhost:8080/lib.wasm:693712:2147484563
  _rt0_wasm_js http://localhost:8080/lib.wasm:658064:2147484445
  run http://localhost:8080/wasm_exec.js:414:5

<-- this is debugging statements inserted by me. It appears to reflect.Get(undefined, "id")

obj undefined wasm_exec.js:260:5
key id wasm_exec.js:261:5

TypeError: "`target` argument of Reflect.get must be an object, got (void 0)"
	valueGet http://localhost:8080/wasm_exec.js:264:19
	valueGet http://localhost:8080/lib.wasm:wasm-function[938]:0xadeeb
	Get http://localhost:8080/lib.wasm:wasm-function[921]:0xab447
	callbackLoop http://localhost:8080/lib.wasm:wasm-function[915]:0xa932b
	_rt0_wasm_js http://localhost:8080/lib.wasm:wasm-function[797]:0xa0a90
	run http://localhost:8080/wasm_exec.js:414:5
wasm_exec.js:268:7 

panic: syscall/js: call of Value.Int on object wasm_exec.js:47:6


goroutine 4 [running]: wasm_exec.js:47:6
syscall/js.Value.float(0x7ff800000000001c, 0x194ab, 0x9, 0x7ff800000000001c) wasm_exec.js:47:6
	/opt/go1.11.1/src/syscall/js/js.go:326 +0x35 wasm_exec.js:47:6
syscall/js.Value.Int(0x7ff800000000001c, 0x190ac) wasm_exec.js:47:6
	/opt/go1.11.1/src/syscall/js/js.go:338 +0x2 wasm_exec.js:47:6
syscall/js.callbackLoop() wasm_exec.js:47:6
	/opt/go1.11.1/src/syscall/js/callback.go:102 +0xc wasm_exec.js:47:6
created by syscall/js.NewCallback.func1 wasm_exec.js:47:6
	/opt/go1.11.1/src/syscall/js/callback.go:40 +0x2

I've attempted to debug this myself. It seems that in go/src/syscall/js/callback.js,

cb := pendingCallbacks.Call("shift")

returns a (ref) Value 0 (not Undefined()) if the array is empty. If I add multiple similar shifts, I keep getting a 0 value:

Global().Get("console").Call("info", "cb is " + strconv.FormatUint(uint64(cb.ref ), 10))

It almost feels asif Call("shift") on an empty array gives some 0 value in stead of undefined like it does in js.

The id := uint32(cb.Get("id").Int()) a few lines later is what's eventually resulting in the panic "call of Value.Int on object wasm_exec.js:47:6"

I can't imagine such a trivial example not working so I must be doing something wrong but I'm unable to find it.

@agnivade
Copy link
Contributor

You most probably have an incorrect wasm_exec.js. Your wasm_exec must match with the Go compiler version. I just tried with the wasm_exec from 1.11 and it worked.

@iivvoo
Copy link
Author

iivvoo commented Oct 28, 2018

That was it. The tutorial wrongly suggests to download wasm_exec.js (I thinks I've seen it elsewhere as well), and the only other google hit I found on this issue (based on the chrome error "TypeError: Reflect.get called on non-object") suggested to download the latest version.

Perhaps wasm_exec should somehow check the go version it's running against?

I'll notify the tutorial author

@iivvoo iivvoo closed this as completed Oct 28, 2018
@golang golang locked and limited conversation to collaborators Oct 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants