diff --git a/internal/lib/reflect/value.go b/internal/lib/reflect/value.go index 09ec02a8..a8f994a9 100644 --- a/internal/lib/reflect/value.go +++ b/internal/lib/reflect/value.go @@ -759,7 +759,6 @@ func valueInterface(v Value, safe bool) any { } if v.kind() == Interface { - /* TODO(xsw): // Special case: return the element inside the interface. // Empty interface has one layout, all interfaces with // methods have a second layout. @@ -769,8 +768,6 @@ func valueInterface(v Value, safe bool) any { return *(*interface { M() })(v.ptr) - */ - panic("todo: reflect.valueInterface") } // TODO: pass safe to packEface so we don't need to copy if safe==true? @@ -1955,3 +1952,57 @@ func noescape(p unsafe.Pointer) unsafe.Pointer { x := uintptr(p) return unsafe.Pointer(x ^ 0) } + +// Method returns a function value corresponding to v's i'th method. +// The arguments to a Call on the returned function should not include +// a receiver; the returned function will always use v as the receiver. +// Method panics if i is out of range or if v is a nil interface value. +func (v Value) Method(i int) Value { + if v.typ() == nil { + panic(&ValueError{"reflect.Value.Method", Invalid}) + } + if v.flag&flagMethod != 0 || uint(i) >= uint(toRType(v.typ()).NumMethod()) { + panic("reflect: Method index out of range") + } + if v.typ().Kind() == abi.Interface && v.IsNil() { + panic("reflect: Method on nil interface value") + } + fl := v.flag.ro() | (v.flag & flagIndir) + fl |= flag(Func) + fl |= flag(i)<