Merge pull request #826 from visualfc/reflect_value
internal/lib/reflect: fix valueInterface
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -553,6 +553,22 @@ func (t *Type) InterfaceType() *InterfaceType {
|
|||||||
return (*InterfaceType)(unsafe.Pointer(t))
|
return (*InterfaceType)(unsafe.Pointer(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Type) ExportedMethods() []Method {
|
||||||
|
ut := t.Uncommon()
|
||||||
|
if ut == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ut.ExportedMethods()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Type) NumMethod() int {
|
||||||
|
if t.Kind() == Interface {
|
||||||
|
tt := (*InterfaceType)(unsafe.Pointer(t))
|
||||||
|
return tt.NumMethod()
|
||||||
|
}
|
||||||
|
return len(t.ExportedMethods())
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// addChecked returns p+x.
|
// addChecked returns p+x.
|
||||||
|
|||||||
@@ -759,7 +759,6 @@ func valueInterface(v Value, safe bool) any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if v.kind() == Interface {
|
if v.kind() == Interface {
|
||||||
/* TODO(xsw):
|
|
||||||
// Special case: return the element inside the interface.
|
// Special case: return the element inside the interface.
|
||||||
// Empty interface has one layout, all interfaces with
|
// Empty interface has one layout, all interfaces with
|
||||||
// methods have a second layout.
|
// methods have a second layout.
|
||||||
@@ -769,8 +768,6 @@ func valueInterface(v Value, safe bool) any {
|
|||||||
return *(*interface {
|
return *(*interface {
|
||||||
M()
|
M()
|
||||||
})(v.ptr)
|
})(v.ptr)
|
||||||
*/
|
|
||||||
panic("todo: reflect.valueInterface")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: pass safe to packEface so we don't need to copy if safe==true?
|
// TODO: pass safe to packEface so we don't need to copy if safe==true?
|
||||||
@@ -1528,7 +1525,6 @@ func (v Value) Type() Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) typeSlow() Type {
|
func (v Value) typeSlow() Type {
|
||||||
/* TODO(xsw):
|
|
||||||
if v.flag == 0 {
|
if v.flag == 0 {
|
||||||
panic(&ValueError{"reflect.Value.Type", Invalid})
|
panic(&ValueError{"reflect.Value.Type", Invalid})
|
||||||
}
|
}
|
||||||
@@ -1548,7 +1544,7 @@ func (v Value) typeSlow() Type {
|
|||||||
panic("reflect: internal error: invalid method index")
|
panic("reflect: internal error: invalid method index")
|
||||||
}
|
}
|
||||||
m := &tt.Methods[i]
|
m := &tt.Methods[i]
|
||||||
return toRType(typeOffFor(typ, m.Typ))
|
return toRType(&m.Typ_.Type)
|
||||||
}
|
}
|
||||||
// Method on concrete type.
|
// Method on concrete type.
|
||||||
ms := typ.ExportedMethods()
|
ms := typ.ExportedMethods()
|
||||||
@@ -1556,9 +1552,7 @@ func (v Value) typeSlow() Type {
|
|||||||
panic("reflect: internal error: invalid method index")
|
panic("reflect: internal error: invalid method index")
|
||||||
}
|
}
|
||||||
m := ms[i]
|
m := ms[i]
|
||||||
return toRType(typeOffFor(typ, m.Mtyp))
|
return toRType(&m.Mtyp_.Type)
|
||||||
*/
|
|
||||||
panic("todo: reflect.Value.Type")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanUint reports whether Uint can be used without panicking.
|
// CanUint reports whether Uint can be used without panicking.
|
||||||
@@ -1955,3 +1949,57 @@ func noescape(p unsafe.Pointer) unsafe.Pointer {
|
|||||||
x := uintptr(p)
|
x := uintptr(p)
|
||||||
return unsafe.Pointer(x ^ 0)
|
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)<<flagMethodShift | flagMethod
|
||||||
|
return Value{v.typ(), v.ptr, fl}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NumMethod returns the number of methods in the value's method set.
|
||||||
|
//
|
||||||
|
// For a non-interface type, it returns the number of exported methods.
|
||||||
|
//
|
||||||
|
// For an interface type, it returns the number of exported and unexported methods.
|
||||||
|
func (v Value) NumMethod() int {
|
||||||
|
if v.typ() == nil {
|
||||||
|
panic(&ValueError{"reflect.Value.NumMethod", Invalid})
|
||||||
|
}
|
||||||
|
if v.flag&flagMethod != 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return toRType(v.typ()).NumMethod()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MethodByName returns a function value corresponding to the method
|
||||||
|
// of v with the given name.
|
||||||
|
// The arguments to a Call on the returned function should not include
|
||||||
|
// a receiver; the returned function will always use v as the receiver.
|
||||||
|
// It returns the zero Value if no method was found.
|
||||||
|
func (v Value) MethodByName(name string) Value {
|
||||||
|
if v.typ() == nil {
|
||||||
|
panic(&ValueError{"reflect.Value.MethodByName", Invalid})
|
||||||
|
}
|
||||||
|
if v.flag&flagMethod != 0 {
|
||||||
|
return Value{}
|
||||||
|
}
|
||||||
|
m, ok := toRType(v.typ()).MethodByName(name)
|
||||||
|
if !ok {
|
||||||
|
return Value{}
|
||||||
|
}
|
||||||
|
return v.Method(m.Index)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user