internal/lib/reflect: call variadic check
This commit is contained in:
@@ -1125,14 +1125,11 @@ func (t *rtype) Implements(u Type) bool {
|
||||
}
|
||||
|
||||
func (t *rtype) AssignableTo(u Type) bool {
|
||||
/*
|
||||
if u == nil {
|
||||
panic("reflect: nil type passed to Type.AssignableTo")
|
||||
}
|
||||
uu := u.common()
|
||||
return directlyAssignable(uu, t.common()) || implements(uu, t.common())
|
||||
*/
|
||||
panic("todo: reflect.rtype.AssignableTo")
|
||||
if u == nil {
|
||||
panic("reflect: nil type passed to Type.AssignableTo")
|
||||
}
|
||||
uu := u.common()
|
||||
return directlyAssignable(uu, t.common()) || implements(uu, t.common())
|
||||
}
|
||||
|
||||
func (t *rtype) ConvertibleTo(u Type) bool {
|
||||
@@ -1150,92 +1147,9 @@ func (t *rtype) Comparable() bool {
|
||||
}
|
||||
|
||||
// implements reports whether the type V implements the interface type T.
|
||||
func implements(T, V *abi.Type) bool {
|
||||
if T.Kind() != abi.Interface {
|
||||
return false
|
||||
}
|
||||
t := (*interfaceType)(unsafe.Pointer(T))
|
||||
if len(t.Methods) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
// The same algorithm applies in both cases, but the
|
||||
// method tables for an interface type and a concrete type
|
||||
// are different, so the code is duplicated.
|
||||
// In both cases the algorithm is a linear scan over the two
|
||||
// lists - T's methods and V's methods - simultaneously.
|
||||
// Since method tables are stored in a unique sorted order
|
||||
// (alphabetical, with no duplicate method names), the scan
|
||||
// through V's methods must hit a match for each of T's
|
||||
// methods along the way, or else V does not implement T.
|
||||
// This lets us run the scan in overall linear time instead of
|
||||
// the quadratic time a naive search would require.
|
||||
// See also ../runtime/iface.go.
|
||||
if V.Kind() == abi.Interface {
|
||||
v := (*interfaceType)(unsafe.Pointer(V))
|
||||
i := 0
|
||||
for j := 0; j < len(v.Methods); j++ {
|
||||
tm := &t.Methods[i]
|
||||
tmName := t.nameOff(tm.Name)
|
||||
vm := &v.Methods[j]
|
||||
vmName := nameOffFor(V, vm.Name)
|
||||
if vmName.Name() == tmName.Name() && typeOffFor(V, vm.Typ) == t.typeOff(tm.Typ) {
|
||||
if !tmName.IsExported() {
|
||||
tmPkgPath := pkgPath(tmName)
|
||||
if tmPkgPath == "" {
|
||||
tmPkgPath = t.PkgPath.Name()
|
||||
}
|
||||
vmPkgPath := pkgPath(vmName)
|
||||
if vmPkgPath == "" {
|
||||
vmPkgPath = v.PkgPath.Name()
|
||||
}
|
||||
if tmPkgPath != vmPkgPath {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if i++; i >= len(t.Methods) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
v := V.Uncommon()
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
i := 0
|
||||
vmethods := v.Methods()
|
||||
for j := 0; j < int(v.Mcount); j++ {
|
||||
tm := &t.Methods[i]
|
||||
tmName := t.nameOff(tm.Name)
|
||||
vm := vmethods[j]
|
||||
vmName := nameOffFor(V, vm.Name)
|
||||
if vmName.Name() == tmName.Name() && typeOffFor(V, vm.Mtyp) == t.typeOff(tm.Typ) {
|
||||
if !tmName.IsExported() {
|
||||
tmPkgPath := pkgPath(tmName)
|
||||
if tmPkgPath == "" {
|
||||
tmPkgPath = t.PkgPath.Name()
|
||||
}
|
||||
vmPkgPath := pkgPath(vmName)
|
||||
if vmPkgPath == "" {
|
||||
vmPkgPath = nameOffFor(V, v.PkgPath).Name()
|
||||
}
|
||||
if tmPkgPath != vmPkgPath {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if i++; i >= len(t.Methods) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
*/
|
||||
panic("todo: reflect.implements")
|
||||
}
|
||||
//
|
||||
//go:linkname implements github.com/goplus/llgo/internal/runtime.Implements
|
||||
func implements(T, V *abi.Type) bool
|
||||
|
||||
// specialChannelAssignability reports whether a value x of channel type V
|
||||
// can be directly assigned (using memmove) to another channel type T.
|
||||
|
||||
@@ -1843,7 +1843,6 @@ func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Va
|
||||
// Avoid the panic by returning a nil dst (e.g., Reader) explicitly.
|
||||
return Value{dst, nil, flag(Interface)}
|
||||
}
|
||||
/* TODO(xsw):
|
||||
x := valueInterface(v, false)
|
||||
if target == nil {
|
||||
target = unsafe_New(dst)
|
||||
@@ -1854,13 +1853,10 @@ func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Va
|
||||
ifaceE2I(dst, x, target)
|
||||
}
|
||||
return Value{dst, target, flagIndir | flag(Interface)}
|
||||
*/
|
||||
}
|
||||
|
||||
// Failed.
|
||||
// TODO(xsw):
|
||||
// panic(context + ": value of type " + stringFor(v.typ()) + " is not assignable to type " + stringFor(dst))
|
||||
panic("todo: reflect.Value.assignTo")
|
||||
panic(context + ": value of type " + stringFor(v.typ()) + " is not assignable to type " + stringFor(dst))
|
||||
}
|
||||
|
||||
// memmove copies size bytes to dst from src. No write barriers are used.
|
||||
@@ -2219,23 +2215,21 @@ func (v Value) call(op string, in []Value) (out []Value) {
|
||||
panic("reflect: " + op + " using zero Value argument")
|
||||
}
|
||||
}
|
||||
// TODO AssignableTo
|
||||
// for i := 0; i < n; i++ {
|
||||
// if xt, targ := in[i].Type(), ft.In(i); !xt.AssignableTo(toRType(targ)) {
|
||||
// panic("reflect: " + op + " using " + xt.String() + " as type " + stringFor(targ))
|
||||
// }
|
||||
// }
|
||||
for i := 0; i < n; i++ {
|
||||
if xt, targ := in[i].Type(), ft.In[i]; !xt.AssignableTo(toRType(targ)) {
|
||||
panic("reflect: " + op + " using " + xt.String() + " as type " + stringFor(targ))
|
||||
}
|
||||
}
|
||||
if !isSlice && isVariadic {
|
||||
// prepare slice for remaining values
|
||||
m := len(in) - n
|
||||
slice := MakeSlice(toRType(ft.In[n]), m, m)
|
||||
// elem := toRType(ft.In[n]).Elem() // FIXME cast to slice type and Elem()
|
||||
elem := toRType(ft.In[n].Elem()) // FIXME cast to slice type and Elem()
|
||||
for i := 0; i < m; i++ {
|
||||
x := in[n+i]
|
||||
// TODO AssignableTo
|
||||
// if xt := x.Type(); !xt.AssignableTo(elem) {
|
||||
// panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
|
||||
// }
|
||||
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
|
||||
@@ -2637,3 +2631,7 @@ func MakeSlice(typ Type, len, cap int) Value {
|
||||
s := unsafeheaderSlice{Data: unsafe_NewArray(&(typ.Elem().(*rtype).t), cap), Len: len, Cap: cap}
|
||||
return Value{&typ.(*rtype).t, unsafe.Pointer(&s), flagIndir | flag(Slice)}
|
||||
}
|
||||
|
||||
func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer) {
|
||||
panic("todo: reflect.ifaceE2I")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user