Skip to content

Commit 4e9f423

Browse files
authored
Go 1.10 support (version bump to GopherJS 1.10-1). (gopherjs#755)
Merge pull request gopherjs#755 from branch go1.10.
2 parents 3926a9f + 4ebbd33 commit 4e9f423

25 files changed

+378
-208
lines changed

build/build.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ func importWithSrcDir(path string, srcDir string, mode build.ImportMode, install
115115
pkg.GoFiles = exclude(pkg.GoFiles, "fd_poll_runtime.go")
116116
case "crypto/rand":
117117
pkg.GoFiles = []string{"rand.go", "util.go"}
118+
pkg.TestGoFiles = exclude(pkg.TestGoFiles, "rand_linux_test.go") // Don't want linux-specific tests (since linux-specific package files are excluded too).
118119
}
119120

120121
if len(pkg.CgoFiles) > 0 {

circle.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ machine:
66

77
dependencies:
88
pre:
9-
- cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz | sudo tar -xz && sudo chmod a+w go/src/path/filepath
9+
- cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.10.linux-amd64.tar.gz | sudo tar -xz && sudo chmod a+w go/src/path/filepath
1010
post:
1111
- mv ./gopherjs $HOME/bin
1212
- npm install --global node-gyp

compiler/compiler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717

1818
var sizes32 = &types.StdSizes{WordSize: 4, MaxAlign: 8}
1919
var reservedKeywords = make(map[string]bool)
20-
var _ = ___GOPHERJS_REQUIRES_GO_VERSION_1_9___ // Compile error on other Go versions, because they're not supported.
20+
var _ = ___GOPHERJS_REQUIRES_GO_VERSION_1_10___ // Compile error on other Go versions, because they're not supported.
2121

2222
func init() {
2323
for _, keyword := range []string{"abstract", "arguments", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "eval", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "undefined", "var", "void", "volatile", "while", "with", "yield"} {

compiler/natives/fs_vfsdata.go

Lines changed: 147 additions & 132 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/natives/src/bytes/bytes_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"testing"
77
)
88

9-
func TestEqualNearPageBoundary(t *testing.T) {
10-
t.Skip()
9+
func dangerousSlice(t *testing.T) []byte {
10+
t.Skip("dangerousSlice relies on syscall.Getpagesize, which GopherJS doesn't implement")
11+
12+
panic("unreachable")
1113
}

compiler/natives/src/encoding/gob/gob_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,9 @@ func TestEndToEnd(t *testing.T) {
9898
t.Errorf("nil map received")
9999
}
100100
}
101+
102+
func TestTypeRace(t *testing.T) {
103+
// encoding/gob currently uses nosync. This test uses sync.WaitGroup and
104+
// cannot succeed when nosync is used.
105+
t.Skip("using nosync")
106+
}

compiler/natives/src/internal/poll/fd_poll_js.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,34 @@ func (*FD) SetWriteDeadline(t time.Time) error { return nil }
5555
func PollDescriptor() uintptr {
5656
return ^uintptr(0)
5757
}
58+
59+
// Copy of sync.runtime_Semacquire.
60+
func runtime_Semacquire(s *uint32) {
61+
if *s == 0 {
62+
ch := make(chan bool)
63+
semWaiters[s] = append(semWaiters[s], ch)
64+
<-ch
65+
}
66+
*s--
67+
}
68+
69+
// Copy of sync.runtime_Semrelease.
70+
func runtime_Semrelease(s *uint32) {
71+
*s++
72+
73+
w := semWaiters[s]
74+
if len(w) == 0 {
75+
return
76+
}
77+
78+
ch := w[0]
79+
w = w[1:]
80+
semWaiters[s] = w
81+
if len(w) == 0 {
82+
delete(semWaiters, s)
83+
}
84+
85+
ch <- true
86+
}
87+
88+
var semWaiters = make(map[*uint32][]chan bool)

compiler/natives/src/io/io_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ func TestMultiWriter_WriteStringSingleAlloc(t *testing.T) {
1111
}
1212

1313
func TestMultiReaderFlatten(t *testing.T) {
14-
t.Skip()
14+
t.Skip("test relies on runtime.Callers and runtime.CallersFrames, which GopherJS doesn't support")
15+
}
16+
17+
func TestMultiWriterSingleChainFlatten(t *testing.T) {
18+
t.Skip("test relies on runtime.Callers and runtime.CallersFrames, which GopherJS doesn't support")
1519
}
1620

1721
func TestMultiReaderFreesExhaustedReaders(t *testing.T) {

compiler/natives/src/math/math.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ func Cosh(x float64) float64 {
6363
return math.Call("cosh", x).Float()
6464
}
6565

66-
func Dim(x, y float64) float64 {
67-
return dim(x, y)
68-
}
69-
7066
func Erf(x float64) float64 {
7167
return erf(x)
7268
}

compiler/natives/src/reflect/reflect.go

Lines changed: 69 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func reflectType(typ *js.Object) *rtype {
4242
rt := &rtype{
4343
size: uintptr(typ.Get("size").Int()),
4444
kind: uint8(typ.Get("kind").Int()),
45-
str: newNameOff(newName(internalStr(typ.Get("string")), "", "", typ.Get("exported").Bool())),
45+
str: newNameOff(newName(internalStr(typ.Get("string")), "", typ.Get("exported").Bool())),
4646
}
4747
js.InternalObject(rt).Set("jsType", typ)
4848
typ.Set("reflectType", js.InternalObject(rt))
@@ -57,12 +57,12 @@ func reflectType(typ *js.Object) *rtype {
5757
for i := range reflectMethods {
5858
m := methodSet.Index(i)
5959
reflectMethods[i] = method{
60-
name: newNameOff(newName(internalStr(m.Get("name")), "", "", internalStr(m.Get("pkg")) == "")),
60+
name: newNameOff(newName(internalStr(m.Get("name")), "", internalStr(m.Get("pkg")) == "")),
6161
mtyp: newTypeOff(reflectType(m.Get("typ"))),
6262
}
6363
}
6464
ut := &uncommonType{
65-
pkgPath: newNameOff(newName(internalStr(typ.Get("pkg")), "", "", false)),
65+
pkgPath: newNameOff(newName(internalStr(typ.Get("pkg")), "", false)),
6666
mcount: uint16(methodSet.Length()),
6767
_methods: reflectMethods,
6868
}
@@ -116,13 +116,13 @@ func reflectType(typ *js.Object) *rtype {
116116
for i := range imethods {
117117
m := methods.Index(i)
118118
imethods[i] = imethod{
119-
name: newNameOff(newName(internalStr(m.Get("name")), "", "", internalStr(m.Get("pkg")) == "")),
119+
name: newNameOff(newName(internalStr(m.Get("name")), "", internalStr(m.Get("pkg")) == "")),
120120
typ: newTypeOff(reflectType(m.Get("typ"))),
121121
}
122122
}
123123
setKindType(rt, &interfaceType{
124124
rtype: *rt,
125-
pkgPath: newName(internalStr(typ.Get("pkg")), "", "", false),
125+
pkgPath: newName(internalStr(typ.Get("pkg")), "", false),
126126
methods: imethods,
127127
})
128128
case Map:
@@ -148,14 +148,14 @@ func reflectType(typ *js.Object) *rtype {
148148
offsetAnon |= 1
149149
}
150150
reflectFields[i] = structField{
151-
name: newName(internalStr(f.Get("name")), internalStr(f.Get("tag")), "", f.Get("exported").Bool()),
151+
name: newName(internalStr(f.Get("name")), internalStr(f.Get("tag")), f.Get("exported").Bool()),
152152
typ: reflectType(f.Get("typ")),
153153
offsetAnon: offsetAnon,
154154
}
155155
}
156156
setKindType(rt, &structType{
157157
rtype: *rt,
158-
pkgPath: newName(internalStr(typ.Get("pkgPath")), "", "", false),
158+
pkgPath: newName(internalStr(typ.Get("pkgPath")), "", false),
159159
fields: reflectFields,
160160
})
161161
}
@@ -213,34 +213,21 @@ type name struct {
213213
type nameData struct {
214214
name string
215215
tag string
216-
pkgPath string
217216
exported bool
218217
}
219218

220219
var nameMap = make(map[*byte]*nameData)
221220

222-
func (n name) name() (s string) {
223-
return nameMap[n.bytes].name
224-
}
225-
226-
func (n name) tag() (s string) {
227-
return nameMap[n.bytes].tag
228-
}
221+
func (n name) name() (s string) { return nameMap[n.bytes].name }
222+
func (n name) tag() (s string) { return nameMap[n.bytes].tag }
223+
func (n name) pkgPath() string { return "" }
224+
func (n name) isExported() bool { return nameMap[n.bytes].exported }
229225

230-
func (n name) pkgPath() string {
231-
return nameMap[n.bytes].pkgPath
232-
}
233-
234-
func (n name) isExported() bool {
235-
return nameMap[n.bytes].exported
236-
}
237-
238-
func newName(n, tag, pkgPath string, exported bool) name {
226+
func newName(n, tag string, exported bool) name {
239227
b := new(byte)
240228
nameMap[b] = &nameData{
241229
name: n,
242230
tag: tag,
243-
pkgPath: pkgPath,
244231
exported: exported,
245232
}
246233
return name{
@@ -491,7 +478,7 @@ func loadScalar(p unsafe.Pointer, n uintptr) uintptr {
491478
return js.InternalObject(p).Call("$get").Unsafe()
492479
}
493480

494-
func makechan(typ *rtype, size uint64) (ch unsafe.Pointer) {
481+
func makechan(typ *rtype, size int) (ch unsafe.Pointer) {
495482
ctyp := (*chanType)(unsafe.Pointer(typ))
496483
return unsafe.Pointer(js.Global.Get("$Chan").New(jsType(ctyp.elem), size).Unsafe())
497484
}
@@ -597,7 +584,7 @@ func cvtDirect(v Value, typ Type) Value {
597584
default:
598585
panic(&ValueError{"reflect.Convert", k})
599586
}
600-
return Value{typ.common(), unsafe.Pointer(val.Unsafe()), v.flag&(flagRO|flagIndir) | flag(typ.Kind())}
587+
return Value{typ.common(), unsafe.Pointer(val.Unsafe()), v.flag.ro() | v.flag&flagIndir | flag(typ.Kind())}
601588
}
602589

603590
func Copy(dst, src Value) int {
@@ -611,12 +598,18 @@ func Copy(dst, src Value) int {
611598
dst.mustBeExported()
612599

613600
sk := src.kind()
601+
var stringCopy bool
614602
if sk != Array && sk != Slice {
615-
panic(&ValueError{"reflect.Copy", sk})
603+
stringCopy = sk == String && dst.typ.Elem().Kind() == Uint8
604+
if !stringCopy {
605+
panic(&ValueError{"reflect.Copy", sk})
606+
}
616607
}
617608
src.mustBeExported()
618609

619-
typesMustMatch("reflect.Copy", dst.typ.Elem(), src.typ.Elem())
610+
if !stringCopy {
611+
typesMustMatch("reflect.Copy", dst.typ.Elem(), src.typ.Elem())
612+
}
620613

621614
dstVal := dst.object()
622615
if dk == Array {
@@ -628,6 +621,9 @@ func Copy(dst, src Value) int {
628621
srcVal = jsType(SliceOf(src.typ.Elem())).New(srcVal)
629622
}
630623

624+
if stringCopy {
625+
return js.Global.Call("$copyString", dstVal, srcVal).Int()
626+
}
631627
return js.Global.Call("$copySlice", dstVal, srcVal).Int()
632628
}
633629

@@ -645,11 +641,11 @@ func methodReceiver(op string, v Value, i int) (_, t *rtype, fn unsafe.Pointer)
645641
t = tt.typeOff(m.typ)
646642
prop = tt.nameOff(m.name).name()
647643
} else {
648-
ut := v.typ.uncommon()
649-
if ut == nil || uint(i) >= uint(ut.mcount) {
644+
ms := v.typ.exportedMethods()
645+
if uint(i) >= uint(len(ms)) {
650646
panic("reflect: internal error: invalid method index")
651647
}
652-
m := ut.methods()[i]
648+
m := ms[i]
653649
if !v.typ.nameOff(m.name).isExported() {
654650
panic("reflect: " + op + " of unexported method")
655651
}
@@ -702,7 +698,7 @@ func makeMethodValue(op string, v Value) Value {
702698
fv := js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} {
703699
return js.InternalObject(fn).Call("apply", rcvr, arguments)
704700
})
705-
return Value{v.Type().common(), unsafe.Pointer(fv.Unsafe()), v.flag&flagRO | flag(Func)}
701+
return Value{v.Type().common(), unsafe.Pointer(fv.Unsafe()), v.flag.ro() | flag(Func)}
706702
}
707703

708704
func (t *rtype) pointers() bool {
@@ -796,6 +792,39 @@ func (v Value) object() *js.Object {
796792
return js.InternalObject(v.ptr)
797793
}
798794

795+
func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
796+
if v.flag&flagMethod != 0 {
797+
v = makeMethodValue(context, v)
798+
}
799+
800+
switch {
801+
case directlyAssignable(dst, v.typ):
802+
// Overwrite type so that they match.
803+
// Same memory layout, so no harm done.
804+
fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
805+
fl |= flag(dst.Kind())
806+
return Value{dst, v.ptr, fl}
807+
808+
case implements(dst, v.typ):
809+
if target == nil {
810+
target = unsafe_New(dst)
811+
}
812+
// GopherJS: Skip the v.Kind() == Interface && v.IsNil() if statement
813+
// from upstream. ifaceE2I below does not panic, and it needs
814+
// to run, given its custom implementation.
815+
x := valueInterface(v, false)
816+
if dst.NumMethod() == 0 {
817+
*(*interface{})(target) = x
818+
} else {
819+
ifaceE2I(dst, x, target)
820+
}
821+
return Value{dst, target, flagIndir | flag(Interface)}
822+
}
823+
824+
// Failed.
825+
panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
826+
}
827+
799828
var callHelper = js.Global.Get("$call").Interface().(func(...interface{}) *js.Object)
800829

801830
func (v Value) call(op string, in []Value) []Value {
@@ -932,7 +961,7 @@ func (v Value) Elem() Value {
932961
return Value{}
933962
}
934963
typ := reflectType(val.Get("constructor"))
935-
return makeValue(typ, val.Get("$val"), v.flag&flagRO)
964+
return makeValue(typ, val.Get("$val"), v.flag.ro())
936965

937966
case Ptr:
938967
if v.IsNil() {
@@ -1053,8 +1082,7 @@ func (v Value) Index(i int) Value {
10531082
panic("reflect: array index out of range")
10541083
}
10551084
typ := tt.elem
1056-
fl := v.flag & (flagRO | flagIndir | flagAddr)
1057-
fl |= flag(typ.Kind())
1085+
fl := v.flag&(flagIndir|flagAddr) | v.flag.ro() | flag(typ.Kind())
10581086

10591087
a := js.InternalObject(v.ptr)
10601088
if fl&flagIndir != 0 && typ.Kind() != Array && typ.Kind() != Struct {
@@ -1072,8 +1100,7 @@ func (v Value) Index(i int) Value {
10721100
}
10731101
tt := (*sliceType)(unsafe.Pointer(v.typ))
10741102
typ := tt.elem
1075-
fl := flagAddr | flagIndir | v.flag&flagRO
1076-
fl |= flag(typ.Kind())
1103+
fl := flagAddr | flagIndir | v.flag.ro() | flag(typ.Kind())
10771104

10781105
i += s.Get("$offset").Int()
10791106
a := s.Get("$array")
@@ -1090,9 +1117,9 @@ func (v Value) Index(i int) Value {
10901117
if i < 0 || i >= len(str) {
10911118
panic("reflect: string index out of range")
10921119
}
1093-
fl := v.flag&flagRO | flag(Uint8)
1120+
fl := v.flag.ro() | flag(Uint8) | flagIndir
10941121
c := str[i]
1095-
return Value{uint8Type, unsafe.Pointer(&c), fl | flagIndir}
1122+
return Value{uint8Type, unsafe.Pointer(&c), fl}
10961123

10971124
default:
10981125
panic(&ValueError{"reflect.Value.Index", k})
@@ -1258,7 +1285,7 @@ func (v Value) Slice(i, j int) Value {
12581285
panic("reflect.Value.Slice: slice index out of bounds")
12591286
}
12601287

1261-
return makeValue(typ, js.Global.Call("$subslice", s, i, j), v.flag&flagRO)
1288+
return makeValue(typ, js.Global.Call("$subslice", s, i, j), v.flag.ro())
12621289
}
12631290

12641291
func (v Value) Slice3(i, j, k int) Value {
@@ -1290,7 +1317,7 @@ func (v Value) Slice3(i, j, k int) Value {
12901317
panic("reflect.Value.Slice3: slice index out of bounds")
12911318
}
12921319

1293-
return makeValue(typ, js.Global.Call("$subslice", s, i, j, k), v.flag&flagRO)
1320+
return makeValue(typ, js.Global.Call("$subslice", s, i, j, k), v.flag.ro())
12941321
}
12951322

12961323
func (v Value) Close() {

0 commit comments

Comments
 (0)