Skip to content

Commit

Permalink
Merge branch 'master' into ci2
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitshur committed Oct 4, 2018
2 parents 15120d0 + 0fee806 commit b6889c3
Show file tree
Hide file tree
Showing 8 changed files with 349 additions and 165 deletions.
8 changes: 8 additions & 0 deletions build/build.go
Original file line number Original file line 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) 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 { if nativesPkg, err := nativesContext.Import(importPath, "", 0); err == nil {
names := nativesPkg.GoFiles names := nativesPkg.GoFiles
if isTest { if isTest {
Expand Down
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- checkout - checkout
- run: git clone https://github.com/creationix/nvm $HOME/.nvm && cd $HOME/.nvm && git checkout v0.33.9 && echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV && echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV - run: git clone https://github.com/creationix/nvm $HOME/.nvm && cd $HOME/.nvm && git checkout v0.33.9 && echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV && echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV
- run: nvm install 10.0.0 && nvm alias default 10.0.0 - run: nvm install 10.0.0 && nvm alias default 10.0.0
- run: cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.11.linux-amd64.tar.gz | sudo tar -xz - run: cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.11.1.linux-amd64.tar.gz | sudo tar -xz
- run: echo 'export PATH="$PATH:/usr/local/go/bin:$HOME/go/bin"' >> $BASH_ENV - run: echo 'export PATH="$PATH:/usr/local/go/bin:$HOME/go/bin"' >> $BASH_ENV
- run: go get -t -d -v ./... - run: go get -t -d -v ./...
- run: go install -v - run: go install -v
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 Original file line 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() 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{} { func valueInterface(v Value, safe bool) interface{} {
if v.flag == 0 { if v.flag == 0 {
panic(&ValueError{"reflect.Value.Interface", 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) 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 { func (v Value) Cap() int {
k := v.kind() k := v.kind()
switch k { switch k {
Expand Down
142 changes: 142 additions & 0 deletions compiler/natives/src/reflect/reflect_go111.go
Original file line number Original file line 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

0 comments on commit b6889c3

Please sign in to comment.