From: David Chase Date: Wed, 26 Apr 2023 19:30:04 +0000 (-0400) Subject: internal/reflectlite: common up types, remove code X-Git-Tag: go1.21rc1~590 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=3ee12d5702be8e2e13e256d6dec28c6464e0a7e5;p=gostls13.git internal/reflectlite: common up types, remove code Change-Id: I4d3ef025b935e52c47896f69814ba2f1a504d749 Reviewed-on: https://go-review.googlesource.com/c/go/+/489375 Reviewed-by: Keith Randall Reviewed-by: Keith Randall TryBot-Result: Gopher Robot Run-TryBot: David Chase --- diff --git a/src/internal/reflectlite/export_test.go b/src/internal/reflectlite/export_test.go index 2532065cad..88be6e2723 100644 --- a/src/internal/reflectlite/export_test.go +++ b/src/internal/reflectlite/export_test.go @@ -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 { diff --git a/src/internal/reflectlite/swapper.go b/src/internal/reflectlite/swapper.go index 1bc1bae87b..ac17d9bbc4 100644 --- a/src/internal/reflectlite/swapper.go +++ b/src/internal/reflectlite/swapper.go @@ -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 diff --git a/src/internal/reflectlite/type.go b/src/internal/reflectlite/type.go index cbc82c0ffc..f13ce8fc62 100644 --- a/src/internal/reflectlite/type.go +++ b/src/internal/reflectlite/type.go @@ -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 } diff --git a/src/internal/reflectlite/value.go b/src/internal/reflectlite/value.go index c14ed7c102..eb79894842 100644 --- a/src/internal/reflectlite/value.go +++ b/src/internal/reflectlite/value.go @@ -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