]> Cypherpunks repositories - gostls13.git/commitdiff
internal/reflectlite: common up types, remove code
authorDavid Chase <drchase@google.com>
Wed, 26 Apr 2023 19:30:04 +0000 (15:30 -0400)
committerDavid Chase <drchase@google.com>
Thu, 11 May 2023 13:45:58 +0000 (13:45 +0000)
Change-Id: I4d3ef025b935e52c47896f69814ba2f1a504d749
Reviewed-on: https://go-review.googlesource.com/c/go/+/489375
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: David Chase <drchase@google.com>

src/internal/reflectlite/export_test.go
src/internal/reflectlite/swapper.go
src/internal/reflectlite/type.go
src/internal/reflectlite/value.go

index 2532065cadebf0659a89aee951f2d1a0f2b2b6a6..88be6e27230ddf1c184fb998afdad424f487bdc0 100644 (file)
@@ -15,17 +15,17 @@ func Field(v Value, i int) Value {
                panic(&ValueError{"reflect.Value.Field", v.kind()})
        }
        tt := (*structType)(unsafe.Pointer(v.typ))
-       if uint(i) >= uint(len(tt.fields)) {
+       if uint(i) >= uint(len(tt.Fields)) {
                panic("reflect: Field index out of range")
        }
-       field := &tt.fields[i]
-       typ := field.typ
+       field := &tt.Fields[i]
+       typ := field.Typ
 
        // Inherit permission bits from v, but clear flagEmbedRO.
        fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
        // Using an unexported field forces flagRO.
-       if !field.name.isExported() {
-               if field.embedded() {
+       if !field.Name.IsExported() {
+               if field.Embedded() {
                        fl |= flagEmbedRO
                } else {
                        fl |= flagStickyRO
@@ -36,27 +36,27 @@ func Field(v Value, i int) Value {
        // In the former case, we want v.ptr + offset.
        // In the latter case, we must have field.offset = 0,
        // so v.ptr + field.offset is still the correct address.
-       ptr := add(v.ptr, field.offset, "same as non-reflect &v.field")
+       ptr := add(v.ptr, field.Offset, "same as non-reflect &v.field")
        return Value{typ, ptr, fl}
 }
 
 func TField(typ Type, i int) Type {
-       t := typ.(*rtype)
+       t := typ.(rtype)
        if t.Kind() != Struct {
                panic("reflect: Field of non-struct type")
        }
-       tt := (*structType)(unsafe.Pointer(t))
+       tt := (*structType)(unsafe.Pointer(t.Type))
 
        return StructFieldType(tt, i)
 }
 
 // Field returns the i'th struct field.
 func StructFieldType(t *structType, i int) Type {
-       if i < 0 || i >= len(t.fields) {
+       if i < 0 || i >= len(t.Fields) {
                panic("reflect: Field index out of bounds")
        }
-       p := &t.fields[i]
-       return toType(p.typ)
+       p := &t.Fields[i]
+       return toType(p.Typ)
 }
 
 // Zero returns a Value representing the zero value for the specified type.
@@ -68,7 +68,7 @@ func Zero(typ Type) Value {
        if typ == nil {
                panic("reflect: Zero(nil)")
        }
-       t := typ.(*rtype)
+       t := typ.common()
        fl := flag(t.Kind())
        if ifaceIndir(t) {
                return Value{t, unsafe_New(t), fl | flagIndir}
@@ -105,11 +105,11 @@ func FirstMethodNameBytes(t Type) *byte {
                panic("type has no methods")
        }
        m := ut.Methods()[0]
-       mname := t.(*rtype).nameOff(m.Name)
-       if *mname.data(0, "name flag field")&(1<<2) == 0 {
+       mname := t.(rtype).nameOff(m.Name)
+       if *mname.DataChecked(0, "name flag field")&(1<<2) == 0 {
                panic("method name does not have pkgPath *string")
        }
-       return mname.bytes
+       return mname.Bytes
 }
 
 type Buffer struct {
index 1bc1bae87bf36788c8b0e13fcc4fd4b28eb6b29c..ac17d9bbc4658bc3526497dbd731b7b517223e2b 100644 (file)
@@ -31,7 +31,7 @@ func Swapper(slice any) func(i, j int) {
                }
        }
 
-       typ := v.Type().Elem().(*rtype)
+       typ := v.Type().Elem().common()
        size := typ.Size()
        hasPtr := typ.PtrBytes != 0
 
index cbc82c0ffc0c4667c507ee05b0dbebbe4107c11f..f13ce8fc6222c6849570fb645db54baec944772a 100644 (file)
@@ -63,7 +63,7 @@ type Type interface {
        // It panics if the type's Kind is not Ptr.
        Elem() Type
 
-       common() *rtype
+       common() *abi.Type
        uncommon() *uncommonType
 }
 
@@ -92,7 +92,7 @@ type typeOff = abi.TypeOff
 type textOff = abi.TextOff
 
 type rtype struct {
-       abi.Type
+       *abi.Type
 }
 
 // uncommonType is present only for defined types or types with methods
@@ -101,88 +101,38 @@ type rtype struct {
 // to describe a non-defined type with no methods.
 type uncommonType = abi.UncommonType
 
-// chanDir represents a channel type's direction.
-type chanDir int
-
-const (
-       recvDir chanDir             = 1 << iota // <-chan
-       sendDir                                 // chan<-
-       bothDir = recvDir | sendDir             // chan
-)
-
 // arrayType represents a fixed array type.
 type arrayType = abi.ArrayType
 
 // chanType represents a channel type.
 type chanType = abi.ChanType
 
-// funcType represents a function type.
-//
-// A *rtype for each in and out parameter is stored in an array that
-// directly follows the funcType (and possibly its uncommonType). So
-// a function type with one method, one input, and one output is:
-//
-//     struct {
-//             funcType
-//             uncommonType
-//             [2]*rtype    // [0] is in, [1] is out
-//     }
-type funcType struct {
-       rtype
-       inCount  uint16
-       outCount uint16 // top bit is set if last input parameter is ...
-}
+type funcType = abi.FuncType
 
-// interfaceType represents an interface type.
-type interfaceType struct {
-       rtype
-       pkgPath name          // import path
-       methods []abi.Imethod // sorted by hash
-}
+type interfaceType = abi.InterfaceType
 
 // mapType represents a map type.
 type mapType struct {
        rtype
-       key    *rtype // map key type
-       elem   *rtype // map element (value) type
-       bucket *rtype // internal bucket structure
+       Key    *abi.Type // map key type
+       Elem   *abi.Type // map element (value) type
+       Bucket *abi.Type // internal bucket structure
        // function for hashing keys (ptr to key, seed) -> hash
-       hasher     func(unsafe.Pointer, uintptr) uintptr
-       keysize    uint8  // size of key slot
-       valuesize  uint8  // size of value slot
-       bucketsize uint16 // size of bucket
-       flags      uint32
+       Hasher     func(unsafe.Pointer, uintptr) uintptr
+       KeySize    uint8  // size of key slot
+       ValueSize  uint8  // size of value slot
+       BucketSize uint16 // size of bucket
+       Flags      uint32
 }
 
 // ptrType represents a pointer type.
-type ptrType struct {
-       rtype
-       elem *rtype // pointer element (pointed at) type
-}
+type ptrType = abi.PtrType
 
 // sliceType represents a slice type.
-type sliceType struct {
-       rtype
-       elem *rtype // slice element type
-}
-
-// Struct field
-type structField struct {
-       name   name    // name is always non-empty
-       typ    *rtype  // type of field
-       offset uintptr // byte offset of field
-}
-
-func (f *structField) embedded() bool {
-       return f.name.embedded()
-}
+type sliceType = abi.SliceType
 
 // structType represents a struct type.
-type structType struct {
-       rtype
-       pkgPath name
-       fields  []structField // sorted by offset
-}
+type structType = abi.StructType
 
 // name is an encoded type name with optional extra data.
 //
@@ -257,21 +207,21 @@ func (n name) tag() string {
        return unsafe.String(n.data(1+i+l+i2, "non-empty string"), l2)
 }
 
-func (n name) pkgPath() string {
-       if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
+func pkgPath(n abi.Name) string {
+       if n.Bytes == nil || *n.DataChecked(0, "name flag field")&(1<<2) == 0 {
                return ""
        }
-       i, l := n.readVarint(1)
+       i, l := n.ReadVarint(1)
        off := 1 + i + l
-       if n.hasTag() {
-               i2, l2 := n.readVarint(off)
+       if n.HasTag() {
+               i2, l2 := n.ReadVarint(off)
                off += i2 + l2
        }
        var nameOff int32
        // Note that this field may not be aligned in memory,
        // so we cannot use a direct int32 assignment here.
-       copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:])
-       pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))}
+       copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.DataChecked(off, "name offset field")))[:])
+       pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.Bytes), nameOff))}
        return pkgPathName.name()
 }
 
@@ -290,31 +240,29 @@ func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
 // Implemented in the runtime package.
 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
 
-func (t *rtype) nameOff(off nameOff) name {
-       return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
+func (t rtype) nameOff(off nameOff) abi.Name {
+       return abi.Name{Bytes: (*byte)(resolveNameOff(unsafe.Pointer(t.Type), int32(off)))}
 }
 
-func (t *rtype) typeOff(off typeOff) *rtype {
-       return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
+func (t rtype) typeOff(off typeOff) *abi.Type {
+       return (*abi.Type)(resolveTypeOff(unsafe.Pointer(t.Type), int32(off)))
 }
 
-func (t *rtype) uncommon() *uncommonType {
+func (t rtype) uncommon() *uncommonType {
        return t.Uncommon()
 }
 
-func (t *rtype) String() string {
-       s := t.nameOff(t.Str).name()
+func (t rtype) String() string {
+       s := t.nameOff(t.Str).Name()
        if t.TFlag&abi.TFlagExtraStar != 0 {
                return s[1:]
        }
        return s
 }
 
-func (t *rtype) pointers() bool { return t.PtrBytes != 0 }
-
-func (t *rtype) common() *rtype { return t }
+func (t rtype) common() *abi.Type { return t.Type }
 
-func (t *rtype) exportedMethods() []abi.Method {
+func (t rtype) exportedMethods() []abi.Method {
        ut := t.uncommon()
        if ut == nil {
                return nil
@@ -322,15 +270,15 @@ func (t *rtype) exportedMethods() []abi.Method {
        return ut.ExportedMethods()
 }
 
-func (t *rtype) NumMethod() int {
-       if t.Kind() == Interface {
-               tt := (*interfaceType)(unsafe.Pointer(t))
+func (t rtype) NumMethod() int {
+       tt := t.Type.InterfaceType()
+       if tt != nil {
                return tt.NumMethod()
        }
        return len(t.exportedMethods())
 }
 
-func (t *rtype) PkgPath() string {
+func (t rtype) PkgPath() string {
        if t.TFlag&abi.TFlagNamed == 0 {
                return ""
        }
@@ -338,15 +286,11 @@ func (t *rtype) PkgPath() string {
        if ut == nil {
                return ""
        }
-       return t.nameOff(ut.PkgPath).name()
+       return t.nameOff(ut.PkgPath).Name()
 }
 
-func (t *rtype) hasName() bool {
-       return t.TFlag&abi.TFlagNamed != 0
-}
-
-func (t *rtype) Name() string {
-       if !t.hasName() {
+func (t rtype) Name() string {
+       if !t.HasName() {
                return ""
        }
        s := t.String()
@@ -364,116 +308,76 @@ func (t *rtype) Name() string {
        return s[i+1:]
 }
 
-func (t *rtype) chanDir() chanDir {
-       if t.Kind() != abi.Chan {
-               panic("reflect: chanDir of non-chan type")
-       }
-       tt := (*chanType)(unsafe.Pointer(t))
-       return chanDir(tt.Dir)
+func toRType(t *abi.Type) rtype {
+       return rtype{t}
 }
 
-func toRType(t *abi.Type) *rtype {
-       return (*rtype)(unsafe.Pointer(t))
+func elem(t *abi.Type) *abi.Type {
+       et := t.Elem()
+       if et != nil {
+               return et
+       }
+       panic("reflect: Elem of invalid type " + toRType(t).String())
 }
 
-func (t *rtype) Elem() Type {
-       switch t.Kind() {
-       case abi.Array:
-               tt := (*arrayType)(unsafe.Pointer(t))
-               return toType(toRType(tt.Elem))
-       case abi.Chan:
-               tt := (*chanType)(unsafe.Pointer(t))
-               return toType(toRType(tt.Elem))
-       case abi.Map:
-               tt := (*mapType)(unsafe.Pointer(t))
-               return toType(tt.elem)
-       case abi.Pointer:
-               tt := (*ptrType)(unsafe.Pointer(t))
-               return toType(tt.elem)
-       case abi.Slice:
-               tt := (*sliceType)(unsafe.Pointer(t))
-               return toType(tt.elem)
-       }
-       panic("reflect: Elem of invalid type")
+func (t rtype) Elem() Type {
+       return toType(elem(t.common()))
 }
 
-func (t *rtype) In(i int) Type {
-       if t.Kind() != abi.Func {
+func (t rtype) In(i int) Type {
+       tt := t.Type.FuncType()
+       if tt == nil {
                panic("reflect: In of non-func type")
        }
-       tt := (*funcType)(unsafe.Pointer(t))
-       return toType(tt.in()[i])
+       return toType(tt.InSlice()[i])
 }
 
-func (t *rtype) Key() Type {
-       if t.Kind() != abi.Map {
+func (t rtype) Key() Type {
+       tt := t.Type.MapType()
+       if tt == nil {
                panic("reflect: Key of non-map type")
        }
-       tt := (*mapType)(unsafe.Pointer(t))
-       return toType(tt.key)
+       return toType(tt.Key)
 }
 
-func (t *rtype) Len() int {
-       if t.Kind() != abi.Array {
+func (t rtype) Len() int {
+       tt := t.Type.ArrayType()
+       if tt == nil {
                panic("reflect: Len of non-array type")
        }
-       tt := (*arrayType)(unsafe.Pointer(t))
        return int(tt.Len)
 }
 
-func (t *rtype) NumField() int {
-       if t.Kind() != abi.Struct {
+func (t rtype) NumField() int {
+       tt := t.Type.StructType()
+       if tt == nil {
                panic("reflect: NumField of non-struct type")
        }
-       tt := (*structType)(unsafe.Pointer(t))
-       return len(tt.fields)
+       return len(tt.Fields)
 }
 
-func (t *rtype) NumIn() int {
-       if t.Kind() != abi.Func {
+func (t rtype) NumIn() int {
+       tt := t.Type.FuncType()
+       if tt == nil {
                panic("reflect: NumIn of non-func type")
        }
-       tt := (*funcType)(unsafe.Pointer(t))
-       return int(tt.inCount)
+       return int(tt.InCount)
 }
 
-func (t *rtype) NumOut() int {
-       if t.Kind() != abi.Func {
+func (t rtype) NumOut() int {
+       tt := t.Type.FuncType()
+       if tt == nil {
                panic("reflect: NumOut of non-func type")
        }
-       tt := (*funcType)(unsafe.Pointer(t))
-       return len(tt.out())
+       return tt.NumOut()
 }
 
-func (t *rtype) Out(i int) Type {
-       if t.Kind() != abi.Func {
+func (t rtype) Out(i int) Type {
+       tt := t.Type.FuncType()
+       if tt == nil {
                panic("reflect: Out of non-func type")
        }
-       tt := (*funcType)(unsafe.Pointer(t))
-       return toType(tt.out()[i])
-}
-
-func (t *funcType) in() []*rtype {
-       uadd := unsafe.Sizeof(*t)
-       if t.TFlag&abi.TFlagUncommon != 0 {
-               uadd += unsafe.Sizeof(uncommonType{})
-       }
-       if t.inCount == 0 {
-               return nil
-       }
-       return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount]
-}
-
-func (t *funcType) out() []*rtype {
-       uadd := unsafe.Sizeof(*t)
-       if t.TFlag&abi.TFlagUncommon != 0 {
-               uadd += unsafe.Sizeof(uncommonType{})
-       }
-       outCount := t.outCount & (1<<15 - 1)
-       if outCount == 0 {
-               return nil
-       }
-       return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount]
+       return toType(tt.OutSlice()[i])
 }
 
 // add returns p+x.
@@ -487,9 +391,6 @@ func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
        return unsafe.Pointer(uintptr(p) + x)
 }
 
-// NumMethod returns the number of interface methods in the type's method set.
-func (t *interfaceType) NumMethod() int { return len(t.methods) }
-
 // TypeOf returns the reflection Type that represents the dynamic type of i.
 // If i is a nil interface value, TypeOf returns nil.
 func TypeOf(i any) Type {
@@ -497,37 +398,40 @@ func TypeOf(i any) Type {
        return toType(eface.typ)
 }
 
-func (t *rtype) Implements(u Type) bool {
+func (t rtype) Implements(u Type) bool {
        if u == nil {
                panic("reflect: nil type passed to Type.Implements")
        }
        if u.Kind() != Interface {
                panic("reflect: non-interface type passed to Type.Implements")
        }
-       return implements(u.(*rtype), t)
+       return implements(u.common(), t.common())
 }
 
-func (t *rtype) AssignableTo(u Type) bool {
+func (t rtype) AssignableTo(u Type) bool {
        if u == nil {
                panic("reflect: nil type passed to Type.AssignableTo")
        }
-       uu := u.(*rtype)
-       return directlyAssignable(uu, t) || implements(uu, t)
+       uu := u.common()
+       tt := t.common()
+       return directlyAssignable(uu, tt) || implements(uu, tt)
 }
 
-func (t *rtype) Comparable() bool {
+func (t rtype) Comparable() bool {
        return t.Equal != nil
 }
 
 // implements reports whether the type V implements the interface type T.
-func implements(T, V *rtype) bool {
-       if T.Kind() != Interface {
+func implements(T, V *abi.Type) bool {
+       t := T.InterfaceType()
+       if t == nil {
                return false
        }
-       t := (*interfaceType)(unsafe.Pointer(T))
-       if len(t.methods) == 0 {
+       if len(t.Methods) == 0 {
                return true
        }
+       rT := toRType(T)
+       rV := toRType(V)
 
        // The same algorithm applies in both cases, but the
        // method tables for an interface type and a concrete type
@@ -544,26 +448,26 @@ func implements(T, V *rtype) bool {
        if V.Kind() == 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 := V.nameOff(vm.Name)
-                       if vmName.name() == tmName.name() && V.typeOff(vm.Typ) == t.typeOff(tm.Typ) {
-                               if !tmName.isExported() {
-                                       tmPkgPath := tmName.pkgPath()
+               for j := 0; j < len(v.Methods); j++ {
+                       tm := &t.Methods[i]
+                       tmName := rT.nameOff(tm.Name)
+                       vm := &v.Methods[j]
+                       vmName := rV.nameOff(vm.Name)
+                       if vmName.Name() == tmName.Name() && rV.typeOff(vm.Typ) == rT.typeOff(tm.Typ) {
+                               if !tmName.IsExported() {
+                                       tmPkgPath := pkgPath(tmName)
                                        if tmPkgPath == "" {
-                                               tmPkgPath = t.pkgPath.name()
+                                               tmPkgPath = t.PkgPath.Name()
                                        }
-                                       vmPkgPath := vmName.pkgPath()
+                                       vmPkgPath := pkgPath(vmName)
                                        if vmPkgPath == "" {
-                                               vmPkgPath = v.pkgPath.name()
+                                               vmPkgPath = v.PkgPath.Name()
                                        }
                                        if tmPkgPath != vmPkgPath {
                                                continue
                                        }
                                }
-                               if i++; i >= len(t.methods) {
+                               if i++; i >= len(t.Methods) {
                                        return true
                                }
                        }
@@ -571,32 +475,32 @@ func implements(T, V *rtype) bool {
                return false
        }
 
-       v := V.uncommon()
+       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)
+               tm := &t.Methods[i]
+               tmName := rT.nameOff(tm.Name)
                vm := vmethods[j]
-               vmName := V.nameOff(vm.Name)
-               if vmName.name() == tmName.name() && V.typeOff(vm.Mtyp) == t.typeOff(tm.Typ) {
-                       if !tmName.isExported() {
-                               tmPkgPath := tmName.pkgPath()
+               vmName := rV.nameOff(vm.Name)
+               if vmName.Name() == tmName.Name() && rV.typeOff(vm.Mtyp) == rT.typeOff(tm.Typ) {
+                       if !tmName.IsExported() {
+                               tmPkgPath := pkgPath(tmName)
                                if tmPkgPath == "" {
-                                       tmPkgPath = t.pkgPath.name()
+                                       tmPkgPath = t.PkgPath.Name()
                                }
-                               vmPkgPath := vmName.pkgPath()
+                               vmPkgPath := pkgPath(vmName)
                                if vmPkgPath == "" {
-                                       vmPkgPath = V.nameOff(v.PkgPath).name()
+                                       vmPkgPath = rV.nameOff(v.PkgPath).Name()
                                }
                                if tmPkgPath != vmPkgPath {
                                        continue
                                }
                        }
-                       if i++; i >= len(t.methods) {
+                       if i++; i >= len(t.Methods) {
                                return true
                        }
                }
@@ -609,7 +513,7 @@ func implements(T, V *rtype) bool {
 // https://golang.org/doc/go_spec.html#Assignability
 // Ignoring the interface rules (implemented elsewhere)
 // and the ideal constant rules (no ideal constants at run time).
-func directlyAssignable(T, V *rtype) bool {
+func directlyAssignable(T, V *abi.Type) bool {
        // x's type V is identical to T?
        if T == V {
                return true
@@ -617,7 +521,7 @@ func directlyAssignable(T, V *rtype) bool {
 
        // Otherwise at least one of T and V must not be defined
        // and they must have the same kind.
-       if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
+       if T.HasName() && V.HasName() || T.Kind() != V.Kind() {
                return false
        }
 
@@ -625,19 +529,19 @@ func directlyAssignable(T, V *rtype) bool {
        return haveIdenticalUnderlyingType(T, V, true)
 }
 
-func haveIdenticalType(T, V Type, cmpTags bool) bool {
+func haveIdenticalType(T, V *abi.Type, cmpTags bool) bool {
        if cmpTags {
                return T == V
        }
 
-       if T.Name() != V.Name() || T.Kind() != V.Kind() {
+       if toRType(T).Name() != toRType(V).Name() || T.Kind() != V.Kind() {
                return false
        }
 
-       return haveIdenticalUnderlyingType(T.common(), V.common(), false)
+       return haveIdenticalUnderlyingType(T, V, false)
 }
 
-func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
+func haveIdenticalUnderlyingType(T, V *abi.Type, cmpTags bool) bool {
        if T == V {
                return true
        }
@@ -662,17 +566,17 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
                // Special case:
                // x is a bidirectional channel value, T is a channel type,
                // and x's type V and T have identical element types.
-               if V.chanDir() == bothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) {
+               if V.ChanDir() == abi.BothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) {
                        return true
                }
 
                // Otherwise continue test for identical underlying type.
-               return V.chanDir() == T.chanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
+               return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
 
        case abi.Func:
                t := (*funcType)(unsafe.Pointer(T))
                v := (*funcType)(unsafe.Pointer(V))
-               if t.outCount != v.outCount || t.inCount != v.inCount {
+               if t.OutCount != v.OutCount || t.InCount != v.InCount {
                        return false
                }
                for i := 0; i < t.NumIn(); i++ {
@@ -690,7 +594,7 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
        case Interface:
                t := (*interfaceType)(unsafe.Pointer(T))
                v := (*interfaceType)(unsafe.Pointer(V))
-               if len(t.methods) == 0 && len(v.methods) == 0 {
+               if len(t.Methods) == 0 && len(v.Methods) == 0 {
                        return true
                }
                // Might have the same methods but still
@@ -706,28 +610,28 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
        case abi.Struct:
                t := (*structType)(unsafe.Pointer(T))
                v := (*structType)(unsafe.Pointer(V))
-               if len(t.fields) != len(v.fields) {
+               if len(t.Fields) != len(v.Fields) {
                        return false
                }
-               if t.pkgPath.name() != v.pkgPath.name() {
+               if t.PkgPath.Name() != v.PkgPath.Name() {
                        return false
                }
-               for i := range t.fields {
-                       tf := &t.fields[i]
-                       vf := &v.fields[i]
-                       if tf.name.name() != vf.name.name() {
+               for i := range t.Fields {
+                       tf := &t.Fields[i]
+                       vf := &v.Fields[i]
+                       if tf.Name.Name() != vf.Name.Name() {
                                return false
                        }
-                       if !haveIdenticalType(tf.typ, vf.typ, cmpTags) {
+                       if !haveIdenticalType(tf.Typ, vf.Typ, cmpTags) {
                                return false
                        }
-                       if cmpTags && tf.name.tag() != vf.name.tag() {
+                       if cmpTags && tf.Name.Tag() != vf.Name.Tag() {
                                return false
                        }
-                       if tf.offset != vf.offset {
+                       if tf.Offset != vf.Offset {
                                return false
                        }
-                       if tf.embedded() != vf.embedded() {
+                       if tf.Embedded() != vf.Embedded() {
                                return false
                        }
                }
@@ -737,24 +641,19 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
        return false
 }
 
-type structTypeUncommon struct {
-       structType
-       u uncommonType
-}
-
 // toType converts from a *rtype to a Type that can be returned
 // to the client of package reflect. In gc, the only concern is that
 // a nil *rtype must be replaced by a nil Type, but in gccgo this
 // function takes care of ensuring that multiple *rtype for the same
 // type are coalesced into a single Type.
-func toType(t *rtype) Type {
+func toType(t *abi.Type) Type {
        if t == nil {
                return nil
        }
-       return t
+       return toRType(t)
 }
 
 // ifaceIndir reports whether t is stored indirectly in an interface value.
-func ifaceIndir(t *rtype) bool {
+func ifaceIndir(t *abi.Type) bool {
        return t.Kind_&abi.KindDirectIface == 0
 }
index c14ed7c102d7392a7a3a5ef579841f2a6313ce76..eb798948420321b85f65bdae4d2cf5ec1091c1f0 100644 (file)
@@ -35,7 +35,7 @@ import (
 // they represent.
 type Value struct {
        // typ holds the type of the value represented by a Value.
-       typ *rtype
+       typ *abi.Type
 
        // Pointer-valued data or, if flagIndir is set, pointer to data.
        // Valid when either flagIndir is set or typ.pointers() is true.
@@ -90,7 +90,7 @@ func (f flag) ro() flag {
 // pointer returns the underlying pointer represented by v.
 // v.Kind() must be Pointer, Map, Chan, Func, or UnsafePointer
 func (v Value) pointer() unsafe.Pointer {
-       if v.typ.Size() != goarch.PtrSize || !v.typ.pointers() {
+       if v.typ.Size() != goarch.PtrSize || !v.typ.Pointers() {
                panic("can't call pointer on a non-pointer Value")
        }
        if v.flag&flagIndir != 0 {
@@ -179,7 +179,7 @@ func methodName() string {
 
 // emptyInterface is the header for an interface{} value.
 type emptyInterface struct {
-       typ  *rtype
+       typ  *abi.Type
        word unsafe.Pointer
 }
 
@@ -250,7 +250,7 @@ func (v Value) Elem() Value {
                        return Value{}
                }
                tt := (*ptrType)(unsafe.Pointer(v.typ))
-               typ := tt.elem
+               typ := tt.Elem
                fl := v.flag&flagRO | flagIndir | flagAddr
                fl |= flag(typ.Kind())
                return Value{typ, ptr, fl}
@@ -380,7 +380,7 @@ func (v Value) Type() Type {
                panic(&ValueError{"reflectlite.Value.Type", abi.Invalid})
        }
        // Method values not supported.
-       return v.typ
+       return toRType(v.typ)
 }
 
 /*
@@ -388,7 +388,7 @@ func (v Value) Type() Type {
  */
 
 // implemented in package runtime
-func unsafe_New(*rtype) unsafe.Pointer
+func unsafe_New(*abi.Type) unsafe.Pointer
 
 // ValueOf returns a new Value initialized to the concrete value
 // stored in the interface i. ValueOf(nil) returns the zero Value.
@@ -409,7 +409,7 @@ func ValueOf(i any) Value {
 // assignTo returns a value v that can be assigned directly to typ.
 // It panics if v is not assignable to typ.
 // For a conversion to an interface type, target is a suggested scratch space to use.
-func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
+func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Value {
        // if v.flag&flagMethod != 0 {
        //      v = makeMethodValue(context, v)
        // }
@@ -442,7 +442,7 @@ func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value
        }
 
        // Failed.
-       panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
+       panic(context + ": value of type " + toRType(v.typ).String() + " is not assignable to type " + toRType(dst).String())
 }
 
 // arrayAt returns the i-th element of p,
@@ -456,12 +456,12 @@ func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Po
        return add(p, uintptr(i)*eltSize, "i < len")
 }
 
-func ifaceE2I(t *rtype, src any, dst unsafe.Pointer)
+func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer)
 
 // typedmemmove copies a value of type t to dst from src.
 //
 //go:noescape
-func typedmemmove(t *rtype, dst, src unsafe.Pointer)
+func typedmemmove(t *abi.Type, dst, src unsafe.Pointer)
 
 // Dummy annotation marking that the value x escapes,
 // for use in cases where the reflect code is so clever that