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
wasm: re-use //export mechanism for exporting identifiers within wasm modules #25612
Comments
I've hit the same rough patches after doing some "real" work with wasm in Go, and trying to integrate my module into a JS workflow. To me, the primary issue is how Go functions are provided to JS. Presently, it seems that polluting the global object ( func main() {
done := make(chan struct{})
js.Global().Set("protolock", make(map[string]interface{}))
module := js.Global().Get("protolock")
module.Set("initialize",
js.FuncOf(func(this js.Value, args []js.Value) interface{} {
if args == nil {
fmt.Println("initialize: not enough args")
return nil
}
return toJson(initialize(args[0].String()))
}),
)
module.Set("status",
js.FuncOf(func(this js.Value, args []js.Value) interface{} {
if args == nil || len(args) < 2 {
fmt.Println("status: not enough args")
return nil
}
return toJson(status(args[0].String(), args[1].String()))
}))
<-done
} While this works, it doesn't make for a very seamless integration with modern JS workflows. Ideally, we'd be able to generate at minimum a
This would make the interoperability between wasm modules in a JS environment much simpler, hiding the fact that a function is run in wasm. I'm not sure the Do we have a working doc/wiki anywhere to track this? I couldn't find anything in an admittedly rather shallow search. Happy to kick it off if one does not exist yet. |
After more digging and a quick browse through @neelance's wasm implementation as well as the disassembled .wat of a Go compiled .wasm binary, it's much more clear that the |
TinyGo exposes this functionality via a |
The meaning for each approach seems the same though: "This function should be included in the wasm exports list, and therefore callable from Javascript. Functions without it will not be". @johanbrandhorst When you say there's a way to do it in pure Go with |
|
I mean that you can also do js.Global().Set("myexport", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
//stuff
}) |
the point of my original request is exactly to not only target and support |
It'll be hard to say whether we'll have the same capability to set exports via |
the wasm can't be used in webworker also. |
Why can’t the wasm be used in a webworker? |
@pkieltyka because the exported function is mounted on window or global variable, but in webworker, we should add it on self |
Shouldn't standard Go exporting rules be used? |
I was coming from the taking a regular Go package (non- |
Note that exporting all Go symbols starting with an uppercase character may drastically increase file size, as the linker won't be able to do dead code elimination. I'm not sure whether this is happening right now, but it's something to keep in mind. |
Agree, i would love to experiment golang wasm target for extending a golang software through a plugin like mechanism, running it in wasm intepreters like https://github.com/go-interpreter/wagon, https://github.com/perlin-network/life or https://github.com/wasmerio/go-ext-wasm. Is this worth another issue? |
I would imagine only the Go symbols in the root/main package would need to be exported. |
Another possible option would be a compiler(or linker) argument with a list of functions that need to be exported. |
Please see #38248, which I believe solves the same issue in a different way. |
I have been adding exports to the global |
There are some really great thoughts on this issue, but I'm curious about the current momentum on this topic. After scanning the open issues, I've come to the following two conclusions for myself:
Summary: it is currently painful to turn Go code into useful and concise WASM. The lack of idiomatic use of modules appears to be at the heart of that pain. |
Right now, compiling the following piece of Go code:
like so:
will produce the following
foo.wasm
module:especially:
ie: the user can not control what is exported.
the recommended way to export something currently, is to use
js.NewCallback
.this is - mainly - because one needs to setup a few things for the Go and js runtimes to cooperate nicely together.
I would argue that, in the same spirit than when one compiles the same
main.go
file with-buildmode=c-shared
, it should be possible to achieve the same thing forGOOS=xyz GOARCH=wasm
, and only export what is//export
-ed.initialization of the runtime(s) would be performed via the wasm module's start function.
(this is a re-hash of neelance/go#22.)
The text was updated successfully, but these errors were encountered: