Skip to content

Go1.16 stdlib test fixes: sync/atomic, io, internal/unsafeheader, internal/fmtsort, and type assertion errors. #1004

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

Merged
merged 8 commits into from
Mar 22, 2021
2 changes: 1 addition & 1 deletion compiler/gopherjspkg/fs_vfsdata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 37 additions & 20 deletions compiler/natives/fs_vfsdata.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion compiler/natives/src/internal/fmtsort/fmtsort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
// needsSkip reports whether the kind doesn't work for sorting on GopherJS.
func needsSkip(k reflect.Kind) bool {
switch k {
case reflect.Ptr, reflect.Chan:
case reflect.Ptr, reflect.Chan, reflect.UnsafePointer:
return true
}
return false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//+build js

package unsafeheader_test

import "testing"

func TestWriteThroughHeader(t *testing.T) {
t.Skip("GopherJS uses different slice and string implementation than internal/unsafeheader.")
}
7 changes: 7 additions & 0 deletions compiler/natives/src/io/io_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,10 @@ func TestMultiWriterSingleChainFlatten(t *testing.T) {
func TestMultiReaderFreesExhaustedReaders(t *testing.T) {
t.Skip("test relies on runtime.SetFinalizer, which GopherJS does not implement")
}

func TestCopyLargeWriter(t *testing.T) {
// This test actually behaves more or less correctly, but it triggers a
// different code path that panics instead of returning an error due to a bug
// referenced below.
t.Skip("https://github.com/gopherjs/gopherjs/issues/1003")
}
2 changes: 1 addition & 1 deletion compiler/natives/src/reflect/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ func cvtDirect(v Value, typ Type) Value {
case Struct:
val = jsType(typ).Get("ptr").New()
copyStruct(val, srcVal, typ)
case Array, Bool, Chan, Func, Interface, Map, String:
case Array, Bool, Chan, Func, Interface, Map, String, UnsafePointer:
val = js.InternalObject(v.ptr)
default:
panic(&ValueError{"reflect.Convert", k})
Expand Down
57 changes: 51 additions & 6 deletions compiler/natives/src/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,48 @@ type Error interface {
RuntimeError()
}

// TODO(nevkontakte): In the upstream, this struct is meant to be compatible
// with reflect.rtype, but here we use a minimal stub that satisfies the API
// TypeAssertionError expects, which we dynamically instantiate in $assertType().
type _type struct{ str string }

func (t *_type) string() string { return t.str }
func (t *_type) pkgpath() string { return "" }

// A TypeAssertionError explains a failed type assertion.
type TypeAssertionError struct{}
type TypeAssertionError struct {
_interface *_type
concrete *_type
asserted *_type
missingMethod string // one method needed by Interface, missing from Concrete
}

func (*TypeAssertionError) RuntimeError() {}
func (*TypeAssertionError) Error() string {
panic("TypeAssertionError is not used in GopherJS.")

func (e *TypeAssertionError) Error() string {
inter := "interface"
if e._interface != nil {
inter = e._interface.string()
}
as := e.asserted.string()
if e.concrete == nil {
return "interface conversion: " + inter + " is nil, not " + as
}
cs := e.concrete.string()
if e.missingMethod == "" {
msg := "interface conversion: " + inter + " is " + cs + ", not " + as
if cs == as {
// provide slightly clearer error message
if e.concrete.pkgpath() != e.asserted.pkgpath() {
msg += " (types from different packages)"
} else {
msg += " (types from different scopes)"
}
}
return msg
}
return "interface conversion: " + cs + " is not " + as +
": missing method " + e.missingMethod
}

func init() {
Expand All @@ -47,10 +83,10 @@ func GOROOT() string {
if process == js.Undefined {
return "/"
}
if v := process.Get("env").Get("GOPHERJS_GOROOT"); v != js.Undefined {
if v := process.Get("env").Get("GOPHERJS_GOROOT"); v != js.Undefined && v.String() != "" {
// GopherJS-specific GOROOT value takes precedence.
return v.String()
} else if v := process.Get("env").Get("GOROOT"); v != js.Undefined {
} else if v := process.Get("env").Get("GOROOT"); v != js.Undefined && v.String() != "" {
return v.String()
}
// sys.DefaultGoroot is now gone, can't use it as fallback anymore.
Expand Down Expand Up @@ -283,6 +319,15 @@ func NumCgoCall() int64 {

func KeepAlive(interface{}) {}

// An errorString represents a runtime error described by a single string.
type errorString string

func (e errorString) RuntimeError() {}

func (e errorString) Error() string {
return "runtime error: " + string(e)
}

func throw(s string) {
panic("runtime error: " + s)
panic(errorString(s))
}
4 changes: 4 additions & 0 deletions compiler/natives/src/sync/atomic/atomic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ import "testing"
func TestHammerStoreLoad(t *testing.T) {
t.Skip("use of unsafe")
}

func TestUnaligned64(t *testing.T) {
t.Skip("GopherJS emulates atomics, which makes alignment irrelevant.")
}
2 changes: 1 addition & 1 deletion tests/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ func TestInterfaceConversionRuntimeError(t *testing.T) {
}
re, ok := r.(runtime.Error)
if !ok {
t.Fatalf("got %T, want runtime.Error", r)
t.Fatalf("got %T (%s), want runtime.Error", r, r)
}
if got, want := re.Error(), "interface conversion: int is not tests.I: missing method Get"; got != want {
t.Fatalf("got %q, want %q", got, want)
Expand Down