diff options
Diffstat (limited to 'libgo/go/reflect/value.go')
-rw-r--r-- | libgo/go/reflect/value.go | 43 |
1 files changed, 13 insertions, 30 deletions
diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go index 216ee3f1ca2..fc7dfae23d2 100644 --- a/libgo/go/reflect/value.go +++ b/libgo/go/reflect/value.go @@ -98,6 +98,7 @@ const ( flagIndir flagAddr flagMethod + flagMethodFn // gccgo: first fn parameter is always pointer flagKindShift = iota flagKindWidth = 5 // there are 27 kinds flagKindMask flag = 1<<flagKindWidth - 1 @@ -433,7 +434,7 @@ func (v Value) call(op string, in []Value) []Value { if v.flag&flagMethod != 0 { nin++ } - firstPointer := len(in) > 0 && t.In(0).Kind() != Ptr && v.flag&flagMethod == 0 && isMethod(v.typ) + firstPointer := len(in) > 0 && t.In(0).Kind() != Ptr && v.flag&flagMethodFn != 0 params := make([]unsafe.Pointer, nin) off := 0 if v.flag&flagMethod != 0 { @@ -484,33 +485,6 @@ func (v Value) call(op string, in []Value) []Value { return ret } -// gccgo specific test to see if typ is a method. We can tell by -// looking at the string to see if there is a receiver. We need this -// because for gccgo all methods take pointer receivers. -func isMethod(t *rtype) bool { - if Kind(t.kind) != Func { - return false - } - s := *t.string - parens := 0 - params := 0 - sawRet := false - for i, c := range s { - if c == '(' { - if parens == 0 { - params++ - } - parens++ - } else if c == ')' { - parens-- - } else if parens == 0 && c == ' ' && s[i+1] != '(' && !sawRet { - params++ - sawRet = true - } - } - return params > 2 -} - // methodReceiver returns information about the receiver // described by v. The Value v may or may not have the // flagMethod bit set, so the kind cached in v.flag should @@ -873,6 +847,16 @@ func valueInterface(v Value, safe bool) interface{} { v = makeMethodValue("Interface", v) } + if v.flag&flagMethodFn != 0 { + if v.typ.Kind() != Func { + panic("reflect: MethodFn of non-Func") + } + ft := (*funcType)(unsafe.Pointer(v.typ)) + if ft.in[0].Kind() != Ptr { + v = makeValueMethod(v) + } + } + k := v.kind() if k == Interface { // Special case: return the element inside the interface. @@ -1187,8 +1171,7 @@ func (v Value) Pointer() uintptr { // created via reflect have the same underlying code pointer, // so their Pointers are equal. The function used here must // match the one used in makeMethodValue. - // This is not properly implemented for gccgo. - f := Zero + f := makeFuncStub return **(**uintptr)(unsafe.Pointer(&f)) } p := v.val |