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

cmd/link: don't resolve WebAssembly imports at link-time #29108

Open
PiotrSikora opened this issue Dec 5, 2018 · 5 comments
Open

cmd/link: don't resolve WebAssembly imports at link-time #29108

PiotrSikora opened this issue Dec 5, 2018 · 5 comments
Labels
arch-wasm WebAssembly issues compiler/runtime Issues related to the Go compiler and/or runtime. NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@PiotrSikora
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.11.2 linux/amd64

But also tested with devel:

$ go version
go version devel +be09bdf589 Tue Dec 4 23:01:00 2018 +0000 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/user/go"
GOPROXY=""
GORACE=""
GOROOT="/home/user/Google/go"
GOTMPDIR=""
GOTOOLDIR="/home/user/Google/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="clang-8"
CXX="clang++-8"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build949670883=/tmp/go-build -gno-record-gcc-switches"

What did you do?

$ cat wasm_log.go
package main

import (
        _ "unsafe" // for go:linkname
)

//go:linkname wasm_log wasm_log
func wasm_log(s string)

func main() {
        wasm_log("Hello, world!")
}

Note: the wasm_log function is provided by the host environment and is expected to be resolved at runtime, when the WASM module is instantiated.

What did you expect to see?

Compiled WASM module that communicates with the host environment.

For the comparison, it builds successfully with TinyGo, and the resulting WASM module works as expected:

$ tinygo build -target=wasm -no-debug -o wasm_log.wasm wasm_log.go
$ wavm-disas wasm_log.wasm wasm_log.wat
$ cat wasm_log.wat
(module
  (type $0 (func (result i32)))
  (type $1 (func (param i32 i32)))
  (type $2 (func))
  (import "env" "io_get_stdout" (func $io_get_stdout (result i32)))
  (import "env" "wasm_log" (func $wasm_log (param i32 i32)))
  (export "memory" (memory $4))
  (export "__heap_base" (global $6))
  (export "__data_end" (global $7))
  (export "_start" (func $_start))
  (export "cwa_main" (func $cwa_main))
  (memory $4  2)
  (table $3  1 1 anyfunc)
  (global $5  (mut i32) (i32.const 66576))
  (global $6  i32 (i32.const 66576))
  (global $7  i32 (i32.const 1037))
  (data $4 (i32.const 1024)
    "Hello, world!")

  (func $__wasm_call_ctors (type $2)
    )

  (func $_start (type $2)
    call $io_get_stdout
    drop
    )

  (func $cwa_main (type $2)
    call $io_get_stdout
    drop
    i32.const 1024
    i32.const 13
    call $wasm_log
    ))

What did you see instead?

With go1.11.2:

$ GOOS=js GOARCH=wasm go build -o wasm_log.wasm wasm_log.go
# command-line-arguments
./wasm_log.go:8:6: missing function body

With devel (thanks to https://golang.org/cl/151318):

$ GOOS=js GOARCH=wasm go build -o wasm_log.wasm wasm_log.go
# command-line-arguments
main.main: relocation target wasm_log not defined
@agnivade
Copy link
Contributor

agnivade commented Dec 5, 2018

IIUC, you are proposing //go:linkname to be treated differently in a wasm environment.

Will leave to @neelance @bradfitz to take a call.

@agnivade agnivade added NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. arch-wasm WebAssembly issues labels Dec 5, 2018
@neelance
Copy link
Member

neelance commented Dec 5, 2018

Currently the CallImport instruction is used to call imported functions, see https://github.com/golang/go/blob/master/src/syscall/js/js_js.s. This is not public API though.

@cherrymui
Copy link
Member

Supporting generating Wasm modules is probably a good idea.

I think this would be a different build mode, like c-archive or c-shared on other platforms, that generates a library instead of an executable. The library can be "loaded"/"linked" at later time. Maybe we just reuse one of them, although it is not really "c".

@cherrymui
Copy link
Member

IIUC, you are proposing //go:linkname to be treated differently in a wasm environment.

I don't think this needs anything with //go:linkname .

@PiotrSikora
Copy link
Author

Right now //go:linkname is needed to work-around the "missing function body" issue, and in case of TinyGo, it's used to change the function name in import in the WASM output, but yeah, if the linker had first-class support for WASM, then this shouldn't be necessary.

I could see a value in adding //go:wasm_import function_name [module_name] to make the dynamic import explicit, and to avoid any name clashes with resolved imports. Basically, a WASM-equivalent of //go:cgo_import_dynamic (which I couldn't figure out how to abuse to make it work for WASM).

Note that imports in WASM have both: module name and function name, so it would be great if one could specify both, with "env" being the default if no module name was provided.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 13, 2022
@seankhliao seankhliao added this to the Unplanned milestone Aug 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-wasm WebAssembly issues compiler/runtime Issues related to the Go compiler and/or runtime. NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
Status: Triage Backlog
Development

No branches or pull requests

6 participants