aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2023-04-21 13:40:58 -0400
committerDavid Chase <drchase@google.com>2023-05-11 01:43:28 +0000
commit1d92e0e3fa6bb79d0679f3dbb47877f4a693deb9 (patch)
tree3f9d4dc59173cc1920e8c881427c9ab625044f5b
parent6cf7602b716ef94f8edc0b21cf2f73d2aa82281c (diff)
downloadgo-1d92e0e3fa6bb79d0679f3dbb47877f4a693deb9.tar.xz
reflect: change rtype so that it (not *rtype) implements Type
The abi.Type field was changed to *abi.Type, thus the bitwise representation is the same, many casts are now avoided and replace by either rtype{afoo} or rfoo.Type. Change-Id: Ie7643edc714a0e56027c2875498a4dfe989cf7dd Reviewed-on: https://go-review.googlesource.com/c/go/+/487558 Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
-rw-r--r--src/reflect/all_test.go6
-rw-r--r--src/reflect/benchmark_test.go5
-rw-r--r--src/reflect/export_test.go12
-rw-r--r--src/reflect/makefunc.go2
-rw-r--r--src/reflect/type.go233
-rw-r--r--src/reflect/value.go24
6 files changed, 145 insertions, 137 deletions
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index 31f6416ed9..4898189b24 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -7215,11 +7215,11 @@ func join(b ...[]byte) []byte { return bytes.Join(b, nil) }
func lit(x ...byte) []byte { return x }
func TestTypeOfTypeOf(t *testing.T) {
- // Check that all the type constructors return concrete *rtype implementations.
+ // Check that all the type constructors return concrete rtype implementations.
// It's difficult to test directly because the reflect package is only at arm's length.
- // The easiest thing to do is just call a function that crashes if it doesn't get an *rtype.
+ // The easiest thing to do is just call a function that crashes if it doesn't get an rtype.
check := func(name string, typ Type) {
- if underlying := TypeOf(typ).String(); underlying != "*reflect.rtype" {
+ if underlying := TypeOf(typ).String(); underlying != "reflect.rtype" {
t.Errorf("%v returned %v, not *reflect.rtype", name, underlying)
}
}
diff --git a/src/reflect/benchmark_test.go b/src/reflect/benchmark_test.go
index 9241c2c3d3..aa816ce032 100644
--- a/src/reflect/benchmark_test.go
+++ b/src/reflect/benchmark_test.go
@@ -247,10 +247,9 @@ func BenchmarkPtrTo(b *testing.B) {
// Construct a type with a zero ptrToThis.
type T struct{ int }
t := SliceOf(TypeOf(T{}))
- ptrToThis := ValueOf(t).Elem().FieldByName("PtrToThis")
+ ptrToThis := ValueOf(t).Field(0).Elem().FieldByName("PtrToThis")
if !ptrToThis.IsValid() {
- b.Skipf("%v has no ptrToThis field; was it removed from rtype?", t) // TODO fix this at top of refactoring
- // b.Fatalf("%v has no ptrToThis field; was it removed from rtype?", t)
+ b.Fatalf("%v has no ptrToThis field; was it removed from rtype?", t)
}
if ptrToThis.Int() != 0 {
b.Fatalf("%v.ptrToThis unexpectedly nonzero", t)
diff --git a/src/reflect/export_test.go b/src/reflect/export_test.go
index 2496c8dcd9..a9587fdef1 100644
--- a/src/reflect/export_test.go
+++ b/src/reflect/export_test.go
@@ -35,7 +35,7 @@ func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr,
if rcvr != nil {
ft, _, abid = funcLayout((*funcType)(unsafe.Pointer(t.common())), rcvr.common())
} else {
- ft, _, abid = funcLayout((*funcType)(unsafe.Pointer(t.(*rtype))), nil)
+ ft, _, abid = funcLayout((*funcType)(unsafe.Pointer(t.common())), nil)
}
// Extract size information.
argSize = abid.stackCallArgsSize
@@ -80,7 +80,7 @@ func TypeLinks() []string {
for i, offs := range offset {
rodata := sections[i]
for _, off := range offs {
- typ := (*rtype)(resolveTypeOff(unsafe.Pointer(rodata), off))
+ typ := toRType((*abi.Type)(resolveTypeOff(unsafe.Pointer(rodata), off)))
r = append(r, typ.String())
}
}
@@ -96,11 +96,11 @@ func MapBucketOf(x, y Type) Type {
}
func CachedBucketOf(m Type) Type {
- t := m.(*rtype)
+ t := m.(rtype)
if Kind(t.t.Kind_&kindMask) != Map {
panic("not map")
}
- tt := (*mapType)(unsafe.Pointer(t))
+ tt := (*mapType)(unsafe.Pointer(t.t))
return toType(tt.Bucket)
}
@@ -122,7 +122,7 @@ func FirstMethodNameBytes(t Type) *byte {
panic("type has no methods")
}
m := ut.Methods()[0]
- mname := t.(*rtype).nameOff(m.Name)
+ mname := t.(rtype).nameOff(m.Name)
if *mname.DataChecked(0, "name flag field")&(1<<2) == 0 {
panic("method name does not have pkgPath *string")
}
@@ -135,7 +135,7 @@ type OtherPkgFields struct {
}
func IsExported(t Type) bool {
- typ := t.(*rtype)
+ typ := t.(rtype)
n := typ.nameOff(typ.t.Str)
return n.IsExported()
}
diff --git a/src/reflect/makefunc.go b/src/reflect/makefunc.go
index 6f9be08917..f4f17549e2 100644
--- a/src/reflect/makefunc.go
+++ b/src/reflect/makefunc.go
@@ -104,7 +104,7 @@ func makeMethodValue(op string, v Value) Value {
rcvr := Value{v.typ, v.ptr, fl}
// v.Type returns the actual type of the method value.
- ftyp := (*funcType)(unsafe.Pointer(v.Type().(*rtype)))
+ ftyp := (*funcType)(unsafe.Pointer(v.Type().common()))
code := methodValueCallCodePtr()
diff --git a/src/reflect/type.go b/src/reflect/type.go
index b027077aff..d2fde0b3ae 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -279,22 +279,17 @@ const Ptr = Pointer
// to describe a non-defined type with no methods.
type uncommonType = abi.UncommonType
-// Embed this type to get common/uncommon
-type common struct {
- abi.Type
-}
-
// rtype is the common implementation of most values.
// It is embedded in other struct types.
type rtype struct {
- t abi.Type
+ t *abi.Type
}
-func (t *rtype) common() *abi.Type {
- return &t.t
+func (t rtype) common() *abi.Type {
+ return t.t
}
-func (t *rtype) uncommon() *abi.UncommonType {
+func (t rtype) uncommon() *abi.UncommonType {
return t.t.Uncommon()
}
@@ -318,16 +313,6 @@ type arrayType = abi.ArrayType
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 = abi.FuncType
// interfaceType represents an interface type.
@@ -476,17 +461,17 @@ var kindNames = []string{
}
// resolveNameOff resolves a name offset from a base pointer.
-// The (*rtype).nameOff method is a convenience wrapper for this function.
+// The (rtype).nameOff method is a convenience wrapper for this function.
// Implemented in the runtime package.
func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
-// resolveTypeOff resolves an *rtype offset from a base type.
-// The (*rtype).typeOff method is a convenience wrapper for this function.
+// resolveTypeOff resolves an rtype offset from a base type.
+// The (rtype).typeOff method is a convenience wrapper for this function.
// Implemented in the runtime package.
func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
// resolveTextOff resolves a function pointer offset from a base type.
-// The (*rtype).textOff method is a convenience wrapper for this function.
+// The (rtype).textOff method is a convenience wrapper for this function.
// Implemented in the runtime package.
func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
@@ -501,7 +486,7 @@ func resolveReflectName(n abi.Name) aNameOff {
return aNameOff(addReflectOff(unsafe.Pointer(n.Bytes)))
}
-// resolveReflectType adds a *rtype to the reflection lookup map in the runtime.
+// resolveReflectType adds a type to the reflection lookup map in the runtime.
// It returns a new typeOff that can be used to refer to the pointer.
func resolveReflectType(t *abi.Type) aTypeOff {
return aTypeOff(addReflectOff(unsafe.Pointer(t)))
@@ -514,23 +499,23 @@ func resolveReflectText(ptr unsafe.Pointer) aTextOff {
return aTextOff(addReflectOff(ptr))
}
-func (t *rtype) nameOff(off aNameOff) abi.Name {
- return abi.Name{Bytes: (*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
+func (t rtype) nameOff(off aNameOff) abi.Name {
+ return abi.Name{Bytes: (*byte)(resolveNameOff(unsafe.Pointer(t.t), int32(off)))}
}
-func (t *rtype) typeOff(off aTypeOff) *abi.Type {
- return (*abi.Type)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
+func (t rtype) typeOff(off aTypeOff) *abi.Type {
+ return (*abi.Type)(resolveTypeOff(unsafe.Pointer(t.t), int32(off)))
}
-func (t *rtype) textOff(off aTextOff) unsafe.Pointer {
- return resolveTextOff(unsafe.Pointer(t), int32(off))
+func (t rtype) textOff(off aTextOff) unsafe.Pointer {
+ return resolveTextOff(unsafe.Pointer(t.t), int32(off))
}
func textOffFor(t *abi.Type, off aTextOff) unsafe.Pointer {
return toRType(t).textOff(off)
}
-func (t *rtype) String() string {
+func (t rtype) String() string {
s := t.nameOff(t.t.Str).Name()
if t.t.TFlag&abi.TFlagExtraStar != 0 {
return s[1:]
@@ -538,10 +523,10 @@ func (t *rtype) String() string {
return s
}
-func (t *rtype) Size() uintptr { return t.t.Size() }
+func (t rtype) Size() uintptr { return t.t.Size() }
-func (t *rtype) Bits() int {
- if t == nil {
+func (t rtype) Bits() int {
+ if t.t == nil {
panic("reflect: Bits of nil Type")
}
k := t.Kind()
@@ -551,13 +536,13 @@ func (t *rtype) Bits() int {
return int(t.t.Size_) * 8
}
-func (t *rtype) Align() int { return t.t.Align() }
+func (t rtype) Align() int { return t.t.Align() }
-func (t *rtype) FieldAlign() int { return t.t.FieldAlign() }
+func (t rtype) FieldAlign() int { return t.t.FieldAlign() }
-func (t *rtype) Kind() Kind { return Kind(t.t.Kind()) }
+func (t rtype) Kind() Kind { return Kind(t.t.Kind()) }
-func (t *rtype) exportedMethods() []abi.Method {
+func (t rtype) exportedMethods() []abi.Method {
ut := t.uncommon()
if ut == nil {
return nil
@@ -565,17 +550,17 @@ func (t *rtype) exportedMethods() []abi.Method {
return ut.ExportedMethods()
}
-func (t *rtype) NumMethod() int {
+func (t rtype) NumMethod() int {
if t.Kind() == Interface {
- tt := (*interfaceType)(unsafe.Pointer(t))
+ tt := (*interfaceType)(unsafe.Pointer(t.t))
return tt.NumMethod()
}
return len(t.exportedMethods())
}
-func (t *rtype) Method(i int) (m Method) {
+func (t rtype) Method(i int) (m Method) {
if t.Kind() == Interface {
- tt := (*interfaceType)(unsafe.Pointer(t))
+ tt := (*interfaceType)(unsafe.Pointer(t.t))
return tt.Method(i)
}
methods := t.exportedMethods()
@@ -601,15 +586,15 @@ func (t *rtype) Method(i int) (m Method) {
m.Type = mt
tfn := t.textOff(p.Tfn)
fn := unsafe.Pointer(&tfn)
- m.Func = Value{&mt.(*rtype).t, fn, fl}
+ m.Func = Value{mt.common(), fn, fl}
m.Index = i
return m
}
-func (t *rtype) MethodByName(name string) (m Method, ok bool) {
+func (t rtype) MethodByName(name string) (m Method, ok bool) {
if t.Kind() == Interface {
- tt := (*interfaceType)(unsafe.Pointer(t))
+ tt := (*interfaceType)(unsafe.Pointer(t.t))
return tt.MethodByName(name)
}
ut := t.uncommon()
@@ -639,7 +624,7 @@ func (t *rtype) MethodByName(name string) (m Method, ok bool) {
return Method{}, false
}
-func (t *rtype) PkgPath() string {
+func (t rtype) PkgPath() string {
if t.t.TFlag&abi.TFlagNamed == 0 {
return ""
}
@@ -654,7 +639,7 @@ func pkgPathFor(t *abi.Type) string {
return toRType(t).PkgPath()
}
-func (t *rtype) Name() string {
+func (t rtype) Name() string {
if !t.t.HasName() {
return ""
}
@@ -677,16 +662,16 @@ func nameFor(t *abi.Type) string {
return toRType(t).Name()
}
-func (t *rtype) ChanDir() ChanDir {
+func (t rtype) ChanDir() ChanDir {
if t.Kind() != Chan {
panic("reflect: ChanDir of non-chan type " + t.String())
}
- tt := (*abi.ChanType)(unsafe.Pointer(t))
+ tt := (*abi.ChanType)(unsafe.Pointer(t.t))
return ChanDir(tt.Dir)
}
-func toRType(t *abi.Type) *rtype {
- return (*rtype)(unsafe.Pointer(t))
+func toRType(t *abi.Type) rtype {
+ return rtype{t}
}
func elem(t *abi.Type) *abi.Type {
@@ -697,103 +682,131 @@ func elem(t *abi.Type) *abi.Type {
panic("reflect: Elem of invalid type " + stringFor(t))
}
-func (t *rtype) Elem() Type {
+func (t rtype) Elem() Type {
return toType(elem(t.common()))
}
-func (t *rtype) Field(i int) StructField {
+func (t rtype) structType() *structType {
if t.Kind() != Struct {
+ return nil
+ }
+ return (*structType)(unsafe.Pointer(t.t))
+}
+
+func (t rtype) mapType() *mapType {
+ if t.Kind() != Map {
+ return nil
+ }
+ return (*mapType)(unsafe.Pointer(t.t))
+}
+
+func (t rtype) arrayType() *arrayType {
+ if t.Kind() != Array {
+ return nil
+ }
+ return (*arrayType)(unsafe.Pointer(t.t))
+}
+
+func (t rtype) funcType() *funcType {
+ if t.Kind() != Func {
+ return nil
+ }
+ return (*funcType)(unsafe.Pointer(t.t))
+}
+
+func (t rtype) Field(i int) StructField {
+ tt := t.structType()
+ if tt == nil {
panic("reflect: Field of non-struct type " + t.String())
}
- tt := (*structType)(unsafe.Pointer(t))
return tt.Field(i)
}
-func (t *rtype) FieldByIndex(index []int) StructField {
- if t.Kind() != Struct {
+func (t rtype) FieldByIndex(index []int) StructField {
+ tt := t.structType()
+ if tt == nil {
panic("reflect: FieldByIndex of non-struct type " + t.String())
}
- tt := (*structType)(unsafe.Pointer(t))
return tt.FieldByIndex(index)
}
-func (t *rtype) FieldByName(name string) (StructField, bool) {
- if t.Kind() != Struct {
+func (t rtype) FieldByName(name string) (StructField, bool) {
+ tt := t.structType()
+ if tt == nil {
panic("reflect: FieldByName of non-struct type " + t.String())
}
- tt := (*structType)(unsafe.Pointer(t))
return tt.FieldByName(name)
}
-func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
- if t.Kind() != Struct {
+func (t rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
+ tt := t.structType()
+ if tt == nil {
panic("reflect: FieldByNameFunc of non-struct type " + t.String())
}
- tt := (*structType)(unsafe.Pointer(t))
return tt.FieldByNameFunc(match)
}
-func (t *rtype) Key() Type {
- if t.Kind() != Map {
+func (t rtype) Key() Type {
+ tt := t.mapType()
+ if tt == nil {
panic("reflect: Key of non-map type " + t.String())
}
- tt := (*mapType)(unsafe.Pointer(t))
return toType(tt.Key)
}
-func (t *rtype) Len() int {
- if t.Kind() != Array {
+func (t rtype) Len() int {
+ tt := t.arrayType()
+ if tt == nil {
panic("reflect: Len of non-array type " + t.String())
}
- tt := (*arrayType)(unsafe.Pointer(t))
return int(tt.Len)
}
-func (t *rtype) NumField() int {
- if t.Kind() != Struct {
+func (t rtype) NumField() int {
+ tt := t.structType()
+ if tt == nil {
panic("reflect: NumField of non-struct type " + t.String())
}
- tt := (*structType)(unsafe.Pointer(t))
return len(tt.Fields)
}
-func (t *rtype) In(i int) Type {
- if t.Kind() != Func {
+func (t rtype) In(i int) Type {
+ tt := t.funcType()
+ if tt == nil {
panic("reflect: In of non-func type " + t.String())
}
- tt := (*abi.FuncType)(unsafe.Pointer(t))
return toType(tt.InSlice()[i])
}
-func (t *rtype) NumIn() int {
- if t.Kind() != Func {
+func (t rtype) NumIn() int {
+ tt := t.funcType()
+ if tt == nil {
panic("reflect: NumIn of non-func type " + t.String())
}
- tt := (*abi.FuncType)(unsafe.Pointer(t))
return tt.NumIn()
}
-func (t *rtype) NumOut() int {
- if t.Kind() != Func {
+func (t rtype) NumOut() int {
+ tt := t.funcType()
+ if tt == nil {
panic("reflect: NumOut of non-func type " + t.String())
}
- tt := (*abi.FuncType)(unsafe.Pointer(t))
return tt.NumOut()
}
-func (t *rtype) Out(i int) Type {
- if t.Kind() != Func {
+func (t rtype) Out(i int) Type {
+ tt := t.funcType()
+ if tt == nil {
panic("reflect: Out of non-func type " + t.String())
}
- tt := (*abi.FuncType)(unsafe.Pointer(t))
return toType(tt.OutSlice()[i])
}
-func (t *rtype) IsVariadic() bool {
- if t.Kind() != Func {
+func (t rtype) IsVariadic() bool {
+ tt := t.funcType()
+ if tt == nil {
panic("reflect: IsVariadic of non-func type " + t.String())
}
- tt := (*abi.FuncType)(unsafe.Pointer(t))
return tt.IsVariadic()
}
@@ -1147,7 +1160,7 @@ func TypeOf(i any) Type {
return toType(eface.typ)
}
-// rtypeOf directly extracts the *rtype of the provided value.
+// rtypeOf directly extracts the type of the provided value.
func rtypeOf(i any) *abi.Type {
eface := *(*emptyInterface)(unsafe.Pointer(&i))
return eface.typ
@@ -1166,11 +1179,11 @@ func PtrTo(t Type) Type { return PointerTo(t) }
// PointerTo returns the pointer type with element t.
// For example, if t represents type Foo, PointerTo(t) represents *Foo.
func PointerTo(t Type) Type {
- return toRType(t.(*rtype).ptrTo())
+ return toRType(t.(rtype).ptrTo())
}
-func (t *rtype) ptrTo() *abi.Type {
- at := &t.t
+func (t rtype) ptrTo() *abi.Type {
+ at := t.t
if at.PtrToThis != 0 {
return t.typeOff(at.PtrToThis)
}
@@ -1184,7 +1197,7 @@ func (t *rtype) ptrTo() *abi.Type {
s := "*" + t.String()
for _, tt := range typesByString(s) {
p := (*ptrType)(unsafe.Pointer(tt))
- if p.Elem != &t.t {
+ if p.Elem != t.t {
continue
}
pi, _ := ptrMap.LoadOrStore(t, p)
@@ -1225,7 +1238,7 @@ func fnv1(x uint32, list ...byte) uint32 {
return x
}
-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")
}
@@ -1235,7 +1248,7 @@ func (t *rtype) Implements(u Type) bool {
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")
}
@@ -1243,14 +1256,14 @@ func (t *rtype) AssignableTo(u Type) bool {
return directlyAssignable(uu, t.common()) || implements(uu, t.common())
}
-func (t *rtype) ConvertibleTo(u Type) bool {
+func (t rtype) ConvertibleTo(u Type) bool {
if u == nil {
panic("reflect: nil type passed to Type.ConvertibleTo")
}
return convertOp(u.common(), t.common()) != nil
}
-func (t *rtype) Comparable() bool {
+func (t rtype) Comparable() bool {
return t.t.Equal != nil
}
@@ -1482,14 +1495,14 @@ func haveIdenticalUnderlyingType(T, V *abi.Type, cmpTags bool) bool {
// typelinks is implemented in package runtime.
// It returns a slice of the sections in each module,
-// and a slice of *rtype offsets in each module.
+// and a slice of *abi.Type offsets in each module.
//
// The types in each module are sorted by string. That is, the first
// two linked types of the first module are:
//
// d0 := sections[0]
-// t1 := (*rtype)(add(d0, offset[0][0]))
-// t2 := (*rtype)(add(d0, offset[0][1]))
+// t1 := (*abi.Type)(add(d0, offset[0][0]))
+// t2 := (*abi.Type)(add(d0, offset[0][1]))
//
// and
//
@@ -1545,7 +1558,7 @@ func typesByString(s string) []*abi.Type {
}
// The lookupCache caches ArrayOf, ChanOf, MapOf and SliceOf lookups.
-var lookupCache sync.Map // map[cacheKey]*rtype
+var lookupCache sync.Map // map[cacheKey]rtype
// A cacheKey is the key for use in the lookupCache.
// Four values describe any of the types we are looking for:
@@ -1563,7 +1576,7 @@ type cacheKey struct {
var funcLookupCache struct {
sync.Mutex // Guards stores (but not loads) on m.
- // m is a map[uint32][]*rtype keyed by the hash calculated in FuncOf.
+ // m is a map[uint32][]rtype keyed by the hash calculated in FuncOf.
// Elements of m are append-only and thus safe for concurrent reading.
m sync.Map
}
@@ -1579,7 +1592,7 @@ func ChanOf(dir ChanDir, t Type) Type {
// Look in cache.
ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
if ch, ok := lookupCache.Load(ckey); ok {
- return ch.(*rtype)
+ return ch.(rtype)
}
// This restriction is imposed by the gc compiler and the runtime.
@@ -1754,13 +1767,13 @@ func FuncOf(in, out []Type, variadic bool) Type {
o := New(initFuncTypes(n)).Elem()
ft := (*funcType)(unsafe.Pointer(o.Field(0).Addr().Pointer()))
- args := unsafe.Slice((**rtype)(unsafe.Pointer(o.Field(1).Addr().Pointer())), n)[0:0:n]
+ args := unsafe.Slice((*rtype)(unsafe.Pointer(o.Field(1).Addr().Pointer())), n)[0:0:n]
*ft = *prototype
// Build a hash and minimally populate ft.
var hash uint32
for _, in := range in {
- t := in.(*rtype)
+ t := in.(rtype)
args = append(args, t)
hash = fnv1(hash, byte(t.t.Hash>>24), byte(t.t.Hash>>16), byte(t.t.Hash>>8), byte(t.t.Hash))
}
@@ -1769,7 +1782,7 @@ func FuncOf(in, out []Type, variadic bool) Type {
}
hash = fnv1(hash, '.')
for _, out := range out {
- t := out.(*rtype)
+ t := out.(rtype)
args = append(args, t)
hash = fnv1(hash, byte(t.t.Hash>>24), byte(t.t.Hash>>16), byte(t.t.Hash>>8), byte(t.t.Hash))
}
@@ -2008,10 +2021,6 @@ func bucketOf(ktyp, etyp *abi.Type) *abi.Type {
return b
}
-func (t *rtype) gcSlice(begin, end uintptr) []byte {
- return (*[1 << 30]byte)(unsafe.Pointer(t.t.GCData))[begin:end:end]
-}
-
// emitGCMask writes the GC mask for [n]typ into out, starting at bit
// offset base.
func emitGCMask(out []byte, base uintptr, typ *abi.Type, n uintptr) {
@@ -2660,7 +2669,7 @@ func ArrayOf(length int, elem Type) Type {
array.Align_ = typ.Align_
array.FieldAlign_ = typ.FieldAlign_
array.Len = uintptr(length)
- array.Slice = &(SliceOf(elem).(*rtype).t)
+ array.Slice = SliceOf(elem).common()
switch {
case typ.PtrBytes == 0 || array.Size_ == 0:
@@ -2754,9 +2763,9 @@ func appendVarint(x []byte, v uintptr) []byte {
return x
}
-// toType converts from a *rtype to a Type that can be returned
+// toType converts from a *abi.Type 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
+// a nil *abi.Type 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 *abi.Type) Type {
diff --git a/src/reflect/value.go b/src/reflect/value.go
index f079b8228b..849e00fa44 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -517,11 +517,11 @@ func (v Value) call(op string, in []Value) []Value {
// Handle arguments.
for i, v := range in {
v.mustBeExported()
- targ := toRType(t.In(i))
+ targ := t.In(i)
// TODO(mknyszek): Figure out if it's possible to get some
// scratch space for this assignment check. Previously, it
// was possible to use space in the argument frame.
- v = v.assignTo("reflect.Value.Call", &targ.t, nil)
+ v = v.assignTo("reflect.Value.Call", targ, nil)
stepsLoop:
for _, st := range abid.call.stepsForValue(i + inStart) {
switch st.kind {
@@ -529,7 +529,7 @@ func (v Value) call(op string, in []Value) []Value {
// Copy values to the "stack."
addr := add(stackArgs, st.stkOff, "precomputed stack arg offset")
if v.flag&flagIndir != 0 {
- typedmemmove(&targ.t, addr, v.ptr)
+ typedmemmove(targ, addr, v.ptr)
} else {
*(*unsafe.Pointer)(addr) = v.ptr
}
@@ -2600,7 +2600,7 @@ func (v Value) TrySend(x Value) bool {
// Type returns v's type.
func (v Value) Type() Type {
if v.flag != 0 && v.flag&flagMethod == 0 {
- return (*rtype)(unsafe.Pointer(v.typ)) // inline of toRType(v.typ), for own inlining in inline test
+ return rtype{v.typ} // inline of toRType(v.typ), for own inlining in inline test
}
return v.typeSlow()
}
@@ -2929,7 +2929,7 @@ func Copy(dst, src Value) int {
// This must match ../runtime/select.go:/runtimeSelect
type runtimeSelect struct {
dir SelectDir // SelectSend, SelectRecv or SelectDefault
- typ *rtype // channel type
+ typ *abi.Type // channel type
ch unsafe.Pointer // channel
val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
}
@@ -3032,7 +3032,7 @@ func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
panic("reflect.Select: SendDir case using recv-only channel")
}
rc.ch = ch.pointer()
- rc.typ = toRType(&tt.Type)
+ rc.typ = &tt.Type
v := c.Send
if !v.IsValid() {
panic("reflect.Select: SendDir case missing Send value")
@@ -3060,7 +3060,7 @@ func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
panic("reflect.Select: RecvDir case using send-only channel")
}
rc.ch = ch.pointer()
- rc.typ = toRType(&tt.Type)
+ rc.typ = &tt.Type
rc.val = unsafe_New(tt.Elem)
}
}
@@ -3104,8 +3104,8 @@ func MakeSlice(typ Type, len, cap int) Value {
panic("reflect.MakeSlice: len > cap")
}
- s := unsafeheader.Slice{Data: unsafe_NewArray(&(typ.Elem().(*rtype).t), cap), Len: len, Cap: cap}
- return Value{&typ.(*rtype).t, unsafe.Pointer(&s), flagIndir | flag(Slice)}
+ s := unsafeheader.Slice{Data: unsafe_NewArray(typ.Elem().common(), cap), Len: len, Cap: cap}
+ return Value{typ.common(), unsafe.Pointer(&s), flagIndir | flag(Slice)}
}
// MakeChan creates a new channel with the specified type and buffer size.
@@ -3175,7 +3175,7 @@ func Zero(typ Type) Value {
if typ == nil {
panic("reflect: Zero(nil)")
}
- t := &typ.(*rtype).t
+ t := typ.common()
fl := flag(t.Kind())
if t.IfaceIndir() {
var p unsafe.Pointer
@@ -3201,7 +3201,7 @@ func New(typ Type) Value {
if typ == nil {
panic("reflect: New(nil)")
}
- t := &typ.(*rtype).t
+ t := typ.common()
pt := ptrTo(t)
if ifaceIndir(pt) {
// This is a pointer to a not-in-heap type.
@@ -3216,7 +3216,7 @@ func New(typ Type) Value {
// specified type, using p as that pointer.
func NewAt(typ Type, p unsafe.Pointer) Value {
fl := flag(Pointer)
- t := typ.(*rtype)
+ t := typ.(rtype)
return Value{t.ptrTo(), p, fl}
}