-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
proposal: cmd/compile: ability to export functions as WASM exports #58584
Comments
CC @golang/runtime @golang/wasm |
@cherrymui unlike mentioned issues, my proposal provides a (vague) example of desired Go function call implementation from JS/host side. Also this issue mentions ability to access Go memory allocator on JS side for complex Go values allocation such as slices or strings. |
I'm not sure this is a good idea. This requires user code to understand the details of Go's stack-based calling convention and it is complex to write. If we do this, I'd think the functions on the JS/Wasm side to use Wasm calling convention, so they can be called more easily on the JS/Wasm side. We can generate adaptor functions as needed. Not really sure about complex data types. Maybe wrap in a JS Value somehow. |
@cherrymui I was thinking about low-level foundation to start with for two reasons:
As an example, I started writing a small handy library to read and write Go values from WASM memory which is used at the moment in custom WASM import functions. I would like to avoid Also I would mention that this mechanism is not a replacement for |
I will explain my current problem to illustrate a desired behaviour. I'm working on alternative Go playground with ability to run Go code offline right in a browser. Download dependencies are cached in Most of my logic is inside my Go program except an adapter on JS side which reads files from Right now there is a problem that most of browser operations are async and to pass a Go callback as a parameter, it's still necessary to wrap it using |
@cherrymui updated proposal with a second more convenient option |
This also seems a dupe of #42372. I would suggest making these suggestions in that thread. I think this will have the same problems as pointed out by Richard in #42372 (comment). |
I see the problem https://github.com/hack-pad/safejs Is a solution to avoid js calls. It api direct match and so can be used easily. There is a perf advantage with this too I found that varies be pending on the code use case.. please let me know if this helps. |
@johanbrandhorst I gave multiple examples of possible implementation in the issue description, unlike the mentioned issue. |
I don't think this proposal can get to the implementation planning stage until the basic questions outlined in the other proposal about the same functionality is answered. What happens if the exported function blocks? What happens if the exported function creates a goroutine? I still think this is a duplicate of the basic functionality of #42372. I would prefer to close this issue and resume this discussion there. Once we can find answers to basic questions like this we can start talking about implementation details. |
Closing as duplicate of #42372 |
This proposal is a duplicate of a previously discussed proposal, as noted above, |
Background
At the moment, Go programs compiled as
GOOS=js GOARCH=wasm
cannot directly export functions or other symbols directly as WASM exports.The only way to export a value is to wrap it and assign as a global JS namespace object (aka
window/globalThis
).By default, each WASM module produced by Go compiler exports a few functions used internally by
wasm_exec.js
bridge and list of those symbols are hardcoded into a linker, likewasm_export_resume
.Current State
Current FFI allows wrapping Go functions as callbacks and assign them to JS global namespace object.
Go callback can only accept and return
js.Value
values.This approach might be okay for simple tasks but might introduce some drawbacks for complex cases.
globalThis
to attach Go callbacks.js.Value
references can be passed.Proposal
I propose to add some kind of mechanism to mark Go function to be exported in WASM module. It can be a compiler directive like
//go:wasmexport
or a special instruction similar toCallImport
for exports.Exported function should appear in exported WebAssembly instance symbols alongside built-in exports.
Calling Exports
Option 1 - Manual stack preparation
This option is inspired by existing low-level import mechanism used internally by
wasm_exec.js
.Values should be manually prepared and pushed into Go stack before calling an export.
Access to Go's memory allocator or
arena
package functions might be required for complex values like strings or slices.Call to an exported Go function should resume WASM program execution and return back control to a caller on return.
Abstract example:
Option 2 - Pass args directly to a function
This option is similar to previous, but allows passing arguments to a function instead of manual stack manipulation.
Scalar types can be passed as-is but complex types should be manually allocated before passing.
It is inspired by wasm-bindgen's examples.
References
main
package by default. Don't require conversion for scalar types.malloc
for complex values allocation.The text was updated successfully, but these errors were encountered: