Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go WASM export functions

Tags:

go

webassembly

I want to create a .wasm file which still has the function names exported when compiled.

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Main")
}

func MyFunc() {
    fmt.Println("MyFunc")
}

I'm building with

GOOS=js GOARCH=wasm go build -o main.wasm

Which produces the wasm file (and awesome that Go targets wasm natively).

But using wabt and doing an object dump exposes these functions.

Export[4]:
 - func[958] <wasm_export_run> -> "run"
 - func[959] <wasm_export_resume> -> "resume"
 - func[961] <wasm_export_getsp> -> "getsp"
 - memory[0] -> "mem"

I'm expecting to see something like

func[137] <MyFunc> -> "MyFunc"

Does anyone know how to export functions in Go WASM?

In rust including #[no_mangle] and pub extern "C" keeps the function available in the output with wasm-pack. I'm looking for something similar with Go.

like image 875
Lex Avatar asked Nov 07 '22 01:11

Lex


1 Answers

If you plan to write a lot of WASM in Go, you might want to consider compiling with TinyGo, which is a Go compiler for embedded and WASM.

TinyGo supports a //export <name> or alias //go:export <name> comment directive that does what you're looking for.

I'm copy-pasting the very first example from TinyGo WASM docs:

package main

// This calls a JS function from Go.
func main() {
    println("adding two numbers:", add(2, 3)) // expecting 5
}

// ...omitted

// This function is exported to JavaScript, so can be called using
// exports.multiply() in JavaScript.
//export multiply
func multiply(x, y int) int {
    return x * y;
}

And you build it with: tinygo build -o wasm.wasm -target wasm ./main.go.


The standard Go compiler has an ongoing open discussion about replicating TinyGo feature. The tl;dr seems to be that you can achieve this by setting funcs to the JS global namespace, with the js.Global().Set(...)

like image 153
blackgreen Avatar answered Nov 11 '22 04:11

blackgreen