Tinygo: Wasm callback functions working with Go 1.12, but not working with Go 1.13

Created on 12 Nov 2019  路  12Comments  路  Source: tinygo-org/tinygo

Found an interesting regression (?). Callback creation code that works with TinyGo 0.9.0 + Go 1.12, doesn't work when used with Go 1.13.

For example, the canvas demo in @johanbrandhorst's wasm-experiments repo:

The error given on the browser console is:

panic: syscall/js: Value.Call: property _makeFuncWrapper is not a function, got undefined

Not sure what to err... make of this, as _makeFuncWrapper() is a function included in the TinyGo wasm_exec.js, and is a literal copy of the mainline Go one.

Anyone have ideas?

bug

Most helpful comment

I had luck with @jfreymuth's solution as well, although, I'm not sure what that breaks (if anything) haha

All 12 comments

Minimal repro:

package main

import (
    "syscall/js"
)

func main() {
    js.Global().Get("document").Call("onLoad", js.FuncOf(fn))
    select {}
}

func fn(this js.Value, args []js.Value) interface{} {
    return ""
}

Good thinking @OneOfOne.:smile:

Confirming. I'm using TinyGo (tag v0.11) with Go (v1.13.5) I get the same error. It doesn't seem to be exclusive to callbacks, but the use of any sort of javascript interaction in general:

package main

import "syscall/js"

func test(this js.Value, inputs []js.Value) interface{} {
    println("test")
    return nil
}

func main() {
    js.Global().Set("testfunc", js.FuncOf(test)) 
}

js.FuncOf essentially creates a callback, so yes it is still caused by callbacks.

1.14 is almost out, the issue is still there.

Line 335 in tinygo's wasm_exec.js doesn't exist in the mainline version. Removing that line makes the callback example work for me.

https://github.com/tinygo-org/tinygo/blob/1d913a62bc0ceef841953058c2c6fb1dd2a40f6a/targets/wasm_exec.js#L328-L337

That sounds hopeful. :smile:

I had luck with @jfreymuth's solution as well, although, I'm not sure what that breaks (if anything) haha

I'm rather certain this is the correct solution, the array in wasm_exec.js should match the definitions in the syscall/js package:
https://github.com/golang/go/blob/5bd145413a84be1afa74a82767384d9e224f7069/src/syscall/js/js.go#L101-L107
The change was made in commit https://github.com/golang/go/commit/c468ad04177c422534ad1ed4547295935f84743d (part of go 1.13).
Since syscall/js is not part of tinygo, changing our wasm_exec.js would break wasm for go 1.12 users. A possible solution would be for tinygo to ship it's own syscall/js package.

I think we have to try and stay compatible with the latest release of Go, so please submit a PR with the proposed changes and I'll review and merge it. @aykevl might have some further comments regarding go compatibility goals.

I've merged #911 to the dev branch, which means it will be part of the next release. Therefore I'll close the issue.

Thanks again @jfreymuth for discovering the issue and providing a fix.

I think we have to try and stay compatible with the latest release of Go.

It's kind of a hard call when it's one of those "either/or" situations. The bug this fixes is probably the only remaining thing (I can think of) which would be stopping people from using Go 1.13 with TinyGo anyway. So should be safe in this instance. :smile:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andrewrynhard picture andrewrynhard  路  7Comments

maheshjena1 picture maheshjena1  路  8Comments

justinclift picture justinclift  路  5Comments

sh0rez picture sh0rez  路  4Comments

marwan-at-work picture marwan-at-work  路  3Comments