Skip to content

Go 1.11.1 support (version bump to GopherJS 1.11-2). #865

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 2 commits into from
Oct 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,14 @@ func parseAndAugment(bctx *build.Context, pkg *build.Package, isTest bool, fileS
return natives.FS.Open(name)
},
}

// reflect needs to tell Go 1.11 apart from Go 1.11.1 for https://github.com/gopherjs/gopherjs/issues/862,
// so provide it with the custom go1.11.1 build tag whenever we're on Go 1.11.1 or later.
// TODO: Remove this ad hoc special behavior in GopherJS 1.12.
if runtime.Version() != "go1.11" {
nativesContext.ReleaseTags = append(nativesContext.ReleaseTags, "go1.11.1")
}

if nativesPkg, err := nativesContext.Import(importPath, "", 0); err == nil {
names := nativesPkg.GoFiles
if isTest {
Expand Down
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ machine:

dependencies:
pre:
- cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.11.linux-amd64.tar.gz | sudo tar -xz && sudo chmod a+w go/src/path/filepath
- cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.11.1.linux-amd64.tar.gz | sudo tar -xz && sudo chmod a+w go/src/path/filepath
post:
- mv ./gopherjs $HOME/bin
- npm install --global node-gyp
Expand Down
76 changes: 46 additions & 30 deletions compiler/natives/fs_vfsdata.go

Large diffs are not rendered by default.

132 changes: 0 additions & 132 deletions compiler/natives/src/reflect/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,39 +647,6 @@ func Copy(dst, src Value) int {
return js.Global.Call("$copySlice", dstVal, srcVal).Int()
}

func methodReceiver(op string, v Value, i int) (_, t *rtype, fn unsafe.Pointer) {
var prop string
if v.typ.Kind() == Interface {
tt := (*interfaceType)(unsafe.Pointer(v.typ))
if i < 0 || i >= len(tt.methods) {
panic("reflect: internal error: invalid method index")
}
m := &tt.methods[i]
if !tt.nameOff(m.name).isExported() {
panic("reflect: " + op + " of unexported method")
}
t = tt.typeOff(m.typ)
prop = tt.nameOff(m.name).name()
} else {
ms := v.typ.exportedMethods()
if uint(i) >= uint(len(ms)) {
panic("reflect: internal error: invalid method index")
}
m := ms[i]
if !v.typ.nameOff(m.name).isExported() {
panic("reflect: " + op + " of unexported method")
}
t = v.typ.typeOff(m.mtyp)
prop = js.Global.Call("$methodSet", jsType(v.typ)).Index(i).Get("prop").String()
}
rcvr := v.object()
if isWrapped(v.typ) {
rcvr = jsType(v.typ).New(rcvr)
}
fn = unsafe.Pointer(rcvr.Get(prop).Unsafe())
return
}

func valueInterface(v Value, safe bool) interface{} {
if v.flag == 0 {
panic(&ValueError{"reflect.Value.Interface", 0})
Expand Down Expand Up @@ -847,105 +814,6 @@ func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value

var callHelper = js.Global.Get("$call").Interface().(func(...interface{}) *js.Object)

func (v Value) call(op string, in []Value) []Value {
var (
t *rtype
fn unsafe.Pointer
rcvr *js.Object
)
if v.flag&flagMethod != 0 {
_, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
rcvr = v.object()
if isWrapped(v.typ) {
rcvr = jsType(v.typ).New(rcvr)
}
} else {
t = v.typ
fn = unsafe.Pointer(v.object().Unsafe())
rcvr = js.Undefined
}

if fn == nil {
panic("reflect.Value.Call: call of nil function")
}

isSlice := op == "CallSlice"
n := t.NumIn()
if isSlice {
if !t.IsVariadic() {
panic("reflect: CallSlice of non-variadic function")
}
if len(in) < n {
panic("reflect: CallSlice with too few input arguments")
}
if len(in) > n {
panic("reflect: CallSlice with too many input arguments")
}
} else {
if t.IsVariadic() {
n--
}
if len(in) < n {
panic("reflect: Call with too few input arguments")
}
if !t.IsVariadic() && len(in) > n {
panic("reflect: Call with too many input arguments")
}
}
for _, x := range in {
if x.Kind() == Invalid {
panic("reflect: " + op + " using zero Value argument")
}
}
for i := 0; i < n; i++ {
if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
}
}
if !isSlice && t.IsVariadic() {
// prepare slice for remaining values
m := len(in) - n
slice := MakeSlice(t.In(n), m, m)
elem := t.In(n).Elem()
for i := 0; i < m; i++ {
x := in[n+i]
if xt := x.Type(); !xt.AssignableTo(elem) {
panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
}
slice.Index(i).Set(x)
}
origIn := in
in = make([]Value, n+1)
copy(in[:n], origIn)
in[n] = slice
}

nin := len(in)
if nin != t.NumIn() {
panic("reflect.Value.Call: wrong argument count")
}
nout := t.NumOut()

argsArray := js.Global.Get("Array").New(t.NumIn())
for i, arg := range in {
argsArray.SetIndex(i, unwrapJsObject(t.In(i), arg.assignTo("reflect.Value.Call", t.In(i).common(), nil).object()))
}
results := callHelper(js.InternalObject(fn), rcvr, argsArray)

switch nout {
case 0:
return nil
case 1:
return []Value{makeValue(t.Out(0), wrapJsObject(t.Out(0), results), 0)}
default:
ret := make([]Value, nout)
for i := range ret {
ret[i] = makeValue(t.Out(i), wrapJsObject(t.Out(i), results.Index(i)), 0)
}
return ret
}
}

func (v Value) Cap() int {
k := v.kind()
switch k {
Expand Down
142 changes: 142 additions & 0 deletions compiler/natives/src/reflect/reflect_go111.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// +build js
// +build !go1.11.1

package reflect

import (
"unsafe"

"github.com/gopherjs/gopherjs/js"
)

func methodReceiver(op string, v Value, i int) (_, t *rtype, fn unsafe.Pointer) {
var prop string
if v.typ.Kind() == Interface {
tt := (*interfaceType)(unsafe.Pointer(v.typ))
if i < 0 || i >= len(tt.methods) {
panic("reflect: internal error: invalid method index")
}
m := &tt.methods[i]
if !tt.nameOff(m.name).isExported() {
panic("reflect: " + op + " of unexported method")
}
t = tt.typeOff(m.typ)
prop = tt.nameOff(m.name).name()
} else {
ms := v.typ.exportedMethods()
if uint(i) >= uint(len(ms)) {
panic("reflect: internal error: invalid method index")
}
m := ms[i]
if !v.typ.nameOff(m.name).isExported() {
panic("reflect: " + op + " of unexported method")
}
t = v.typ.typeOff(m.mtyp)
prop = js.Global.Call("$methodSet", jsType(v.typ)).Index(i).Get("prop").String()
}
rcvr := v.object()
if isWrapped(v.typ) {
rcvr = jsType(v.typ).New(rcvr)
}
fn = unsafe.Pointer(rcvr.Get(prop).Unsafe())
return
}

func (v Value) call(op string, in []Value) []Value {
var (
t *rtype
fn unsafe.Pointer
rcvr *js.Object
)
if v.flag&flagMethod != 0 {
_, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
rcvr = v.object()
if isWrapped(v.typ) {
rcvr = jsType(v.typ).New(rcvr)
}
} else {
t = v.typ
fn = unsafe.Pointer(v.object().Unsafe())
rcvr = js.Undefined
}

if fn == nil {
panic("reflect.Value.Call: call of nil function")
}

isSlice := op == "CallSlice"
n := t.NumIn()
if isSlice {
if !t.IsVariadic() {
panic("reflect: CallSlice of non-variadic function")
}
if len(in) < n {
panic("reflect: CallSlice with too few input arguments")
}
if len(in) > n {
panic("reflect: CallSlice with too many input arguments")
}
} else {
if t.IsVariadic() {
n--
}
if len(in) < n {
panic("reflect: Call with too few input arguments")
}
if !t.IsVariadic() && len(in) > n {
panic("reflect: Call with too many input arguments")
}
}
for _, x := range in {
if x.Kind() == Invalid {
panic("reflect: " + op + " using zero Value argument")
}
}
for i := 0; i < n; i++ {
if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
}
}
if !isSlice && t.IsVariadic() {
// prepare slice for remaining values
m := len(in) - n
slice := MakeSlice(t.In(n), m, m)
elem := t.In(n).Elem()
for i := 0; i < m; i++ {
x := in[n+i]
if xt := x.Type(); !xt.AssignableTo(elem) {
panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
}
slice.Index(i).Set(x)
}
origIn := in
in = make([]Value, n+1)
copy(in[:n], origIn)
in[n] = slice
}

nin := len(in)
if nin != t.NumIn() {
panic("reflect.Value.Call: wrong argument count")
}
nout := t.NumOut()

argsArray := js.Global.Get("Array").New(t.NumIn())
for i, arg := range in {
argsArray.SetIndex(i, unwrapJsObject(t.In(i), arg.assignTo("reflect.Value.Call", t.In(i).common(), nil).object()))
}
results := callHelper(js.InternalObject(fn), rcvr, argsArray)

switch nout {
case 0:
return nil
case 1:
return []Value{makeValue(t.Out(0), wrapJsObject(t.Out(0), results), 0)}
default:
ret := make([]Value, nout)
for i := range ret {
ret[i] = makeValue(t.Out(i), wrapJsObject(t.Out(i), results.Index(i)), 0)
}
return ret
}
}
Loading