1
0
mirror of https://github.com/golang/go synced 2024-09-29 00:34:30 -06:00

internal/reflectlite: common up types, remove code

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>
This commit is contained in:
David Chase 2023-04-26 15:30:04 -04:00
parent 2e93fe0a9f
commit 3ee12d5702
4 changed files with 161 additions and 262 deletions

View 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 {

View 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

View 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() *abi.Type { return t.Type }
func (t *rtype) common() *rtype { return t }
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")
func toRType(t *abi.Type) rtype {
return rtype{t}
}
func elem(t *abi.Type) *abi.Type {
et := t.Elem()
if et != nil {
return et
}
tt := (*chanType)(unsafe.Pointer(t))
return chanDir(tt.Dir)
panic("reflect: Elem of invalid type " + toRType(t).String())
}
func toRType(t *abi.Type) *rtype {
return (*rtype)(unsafe.Pointer(t))
func (t rtype) Elem() Type {
return toType(elem(t.common()))
}
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) 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
}

View 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