Skip to content
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

Feature: Go Support (golang) #2903

Closed
tracker1 opened this issue Apr 8, 2019 · 3 comments
Closed

Feature: Go Support (golang) #2903

tracker1 opened this issue Apr 8, 2019 · 3 comments

Comments

@tracker1
Copy link
Contributor

tracker1 commented Apr 8, 2019

🙋 feature request

Similar to Rust support, it would be nice/interesting to see Go (golang) support.

🤔 Expected Behavior

import { foo } from 'file.go'

😯 Current Behavior

Currently unsupported

💁 Possible Solution

I'm not familiar enough with internals to know where to start, should build using Go model, but the injection points should be similar to Rusts's wasm file usage.

🔦 Context

It's not something that is directly impacting me currently. Given the communication models in Go, it may be a great fit.

💻 Examples

N/A

@lucacasonato
Copy link

lucacasonato commented Apr 19, 2019

I have actually tried to implement this before, but failed at importing the WASM modules as they are laid out differently than Rust (rather than exporting functions, it sets variables on the global object). Go also needs a JS loader file which is not currently supported AFAIK.

Some more details on this: Go treats a WASM as a whole program that gets executed rather than a collection of functions. (https://www.aaron-powell.com/posts/2019-02-05-golang-wasm-2-writing-go#conclusion). To start a Go WASM program you would actually do this:

<html>
    <head>
      <meta charset="utf-8">
      <script src="wasm_exec.js"></script>
      <script>
            async function init() {
                const go = new Go();
                let result = await WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject)
                go.run(result.instance);
            }
            init();
       </script>
    </head>
    <body></body>
</html>

The Go required to register a math add function would look something like this

package main

import "syscall/js"

func add(i []js.Value) {
    js.Global().Set("output", js.ValueOf(i[0].Int()+i[1].Int()))
    println(js.ValueOf(i[0].Int() + i[1].Int()).String())
}

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

func main() {
    c := make(chan struct{}, 0)

    println("WASM Go Initialized")
    // register functions
    registerCallbacks()
    <-c
}

The main issue is not the building of the WASM but actually running and exposing functions. We would have to do some magic to expose the functions individually the same way as we do for Rust.

The building is actually way easier to implement than Rust. If I should make a PR to implement building the WASM modules, please let me know.

EDIT: I have an open issue regarding go supporting instance.exports: golang/go#31574

@graingert
Copy link

looks like that ticket got closed, see golang/go#25612

@devongovett
Copy link
Member

Going to close this. I don't have the bandwidth to implement and maintain this. It would be great as a third party plugin if someone wants to build it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants
@devongovett @graingert @tracker1 @DeMoorJasper @mischnic @lucacasonato and others