Description
Right now, the github.com/gopherjs/gopherjs/js
package is officially only implemented for js
architecture. That's where using it is meaningful, as:
Package js provides functions for interacting with native JavaScript APIs. Calls to these functions are treated specially by GopherJS and translated directly to their corresponding JavaScript syntax.
However, in reality, it is also currently implemented for all other architectures. The implementation panics for most things with unfriendly messages, such as "invalid memory address or nil pointer dereference".
This means someone who tries to run Go code that (directly or indirectly) uses js
package under an unsupported architecture will likely see an unfriendly panic, such as:
todomvc $ GOARCH=amd64 go run -compiler=gc example.go
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x744f2]
goroutine 1 [running]:
panic(0xcaa20, 0xc42000a090)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
github.com/gopherjs/gopherjs/js.(*Object).Get(0x0, 0xe66bf, 0xc, 0xf3788)
/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/js/js.go:32 +0x22
main.attachLocalStorage()
/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/vecty/examples/todomvc/example.go:39 +0x7c
main.main()
/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/vecty/examples/todomvc/example.go:17 +0x26
exit status 2
I propose we change implementation of github.com/gopherjs/gopherjs/js
for unsupported architectures (everything other than js
) such that it panics with friendly error messages. For example:
todomvc $ GOARCH=amd64 go run -compiler=gc example.go
panic: js.Object.Get is only implemented on js architecture, it's not implemented on amd64 architecture
goroutine 1 [running]:
panic(0xc9340, 0xc42000a350)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
github.com/gopherjs/gopherjs/js.(*Object).Get(0x0, 0xe6764, 0xc, 0xf38a8)
/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/js/unimplemented.go:13 +0xe4
main.attachLocalStorage()
/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/vecty/examples/todomvc/example.go:39 +0x7c
main.main()
/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/vecty/examples/todomvc/example.go:17 +0x26
exit status 2
I think that's a good thing to do, and it should help people less familiar with GopherJS understand what's going on.
This idea is inspired by previous experiences and, most recently, by hexops/vecty#61. /cc @campoy
Implementation Discussion
In my prototype, I simply added // +build js
constraint to js.go
file, and created a second file unimplemented.go
that looks like this:
// +build !js
package js
import (
"fmt"
"runtime"
)
type Object struct{ object *Object }
func (o *Object) Get(key string) *Object {
panic(fmt.Errorf("js.Object.Get is only implemented on js architecture, it's not implemented on %s architecture", runtime.GOARCH))
}
// ...
However, the challenging part of the implementation is dealing with godoc
. When doing the above, it causes godoc of github.com/gopherjs/gopherjs/js
package to show up without any documentation, because the amd64
architecture has higher priority over js
.
I can think of a couple alternative solutions, but so far I'm not sure what's the best one.
Before I spend more time thinking about this, I wanted to make the proposal to see what the GopherJS team thinks. /cc @neelance