internal/reflectlite, runtime: move more constants and types into internal/abi

Change-Id: If5da1057ead34eb3e4c7f42bbe6ad3d350b97725
Reviewed-on: https://go-review.googlesource.com/c/go/+/484856
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
David Chase 2023-04-14 14:09:12 -04:00
parent a851511947
commit 639957eb66
9 changed files with 90 additions and 259 deletions

View File

@ -7,6 +7,7 @@ package reflectlite_test
import ( import (
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"internal/abi"
. "internal/reflectlite" . "internal/reflectlite"
"math" "math"
"reflect" "reflect"
@ -240,37 +241,37 @@ func TestSetValue(t *testing.T) {
for i, tt := range valueTests { for i, tt := range valueTests {
v := ValueOf(tt.i).Elem() v := ValueOf(tt.i).Elem()
switch v.Kind() { switch v.Kind() {
case Int: case abi.Int:
v.Set(ValueOf(int(132))) v.Set(ValueOf(int(132)))
case Int8: case abi.Int8:
v.Set(ValueOf(int8(8))) v.Set(ValueOf(int8(8)))
case Int16: case abi.Int16:
v.Set(ValueOf(int16(16))) v.Set(ValueOf(int16(16)))
case Int32: case abi.Int32:
v.Set(ValueOf(int32(32))) v.Set(ValueOf(int32(32)))
case Int64: case abi.Int64:
v.Set(ValueOf(int64(64))) v.Set(ValueOf(int64(64)))
case Uint: case abi.Uint:
v.Set(ValueOf(uint(132))) v.Set(ValueOf(uint(132)))
case Uint8: case abi.Uint8:
v.Set(ValueOf(uint8(8))) v.Set(ValueOf(uint8(8)))
case Uint16: case abi.Uint16:
v.Set(ValueOf(uint16(16))) v.Set(ValueOf(uint16(16)))
case Uint32: case abi.Uint32:
v.Set(ValueOf(uint32(32))) v.Set(ValueOf(uint32(32)))
case Uint64: case abi.Uint64:
v.Set(ValueOf(uint64(64))) v.Set(ValueOf(uint64(64)))
case Float32: case abi.Float32:
v.Set(ValueOf(float32(256.25))) v.Set(ValueOf(float32(256.25)))
case Float64: case abi.Float64:
v.Set(ValueOf(512.125)) v.Set(ValueOf(512.125))
case Complex64: case abi.Complex64:
v.Set(ValueOf(complex64(532.125 + 10i))) v.Set(ValueOf(complex64(532.125 + 10i)))
case Complex128: case abi.Complex128:
v.Set(ValueOf(complex128(564.25 + 1i))) v.Set(ValueOf(complex128(564.25 + 1i)))
case String: case abi.String:
v.Set(ValueOf("stringy cheese")) v.Set(ValueOf("stringy cheese"))
case Bool: case abi.Bool:
v.Set(ValueOf(true)) v.Set(ValueOf(true))
} }
s := valueToString(v) s := valueToString(v)
@ -946,7 +947,7 @@ func TestInvalid(t *testing.T) {
t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind()) t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind())
} }
v = v.Elem() v = v.Elem()
if v.IsValid() != false || v.Kind() != Invalid { if v.IsValid() != false || v.Kind() != abi.Invalid {
t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind()) t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind())
} }
} }

View File

@ -19,7 +19,6 @@ import (
) )
var typeNames = []string{ var typeNames = []string{
"rtype",
"uncommonType", "uncommonType",
"arrayType", "arrayType",
"chanType", "chanType",
@ -115,7 +114,7 @@ func TestMirrorWithReflect(t *testing.T) {
wg.Wait() wg.Wait()
if len(rl.m) != len(r.m) { if len(rl.m) != len(r.m) {
t.Fatalf("number of types mismatch, reflect: %d, reflectlite: %d", len(r.m), len(rl.m)) t.Fatalf("number of types mismatch, reflect: %d, reflectlite: %d (%+v, %+v)", len(r.m), len(rl.m), r.m, rl.m)
} }
for typName := range r.m { for typName := range r.m {

View File

@ -75,45 +75,25 @@ type Type interface {
// A Kind represents the specific kind of type that a Type represents. // A Kind represents the specific kind of type that a Type represents.
// The zero Kind is not a valid kind. // The zero Kind is not a valid kind.
type Kind uint type Kind = abi.Kind
const Ptr = abi.Pointer
const ( const (
Invalid Kind = iota // Import-and-export these constants as necessary
Bool Interface = abi.Interface
Int Slice = abi.Slice
Int8 String = abi.String
Int16 Struct = abi.Struct
Int32
Int64
Uint
Uint8
Uint16
Uint32
Uint64
Uintptr
Float32
Float64
Complex64
Complex128
Array
Chan
Func
Interface
Map
Pointer
Slice
String
Struct
UnsafePointer
) )
const Ptr = Pointer
type nameOff = abi.NameOff type nameOff = abi.NameOff
type typeOff = abi.TypeOff type typeOff = abi.TypeOff
type textOff = abi.TextOff type textOff = abi.TextOff
type rtype abi.Type type rtype struct {
abi.Type
}
// uncommonType is present only for defined types or types with methods // uncommonType is present only for defined types or types with methods
// (if T is a defined type, the uncommonTypes for T and *T have methods). // (if T is a defined type, the uncommonTypes for T and *T have methods).
@ -304,50 +284,6 @@ func (n name) pkgPath() string {
* The compiler does not know about the data structures and methods below. * The compiler does not know about the data structures and methods below.
*/ */
const (
kindDirectIface = 1 << 5
kindGCProg = 1 << 6 // Type.gc points to GC program
kindMask = (1 << 5) - 1
)
// String returns the name of k.
func (k Kind) String() string {
if int(k) < len(kindNames) {
return kindNames[k]
}
return kindNames[0]
}
var kindNames = []string{
Invalid: "invalid",
Bool: "bool",
Int: "int",
Int8: "int8",
Int16: "int16",
Int32: "int32",
Int64: "int64",
Uint: "uint",
Uint8: "uint8",
Uint16: "uint16",
Uint32: "uint32",
Uint64: "uint64",
Uintptr: "uintptr",
Float32: "float32",
Float64: "float64",
Complex64: "complex64",
Complex128: "complex128",
Array: "array",
Chan: "chan",
Func: "func",
Interface: "interface",
Map: "map",
Ptr: "ptr",
Slice: "slice",
String: "string",
Struct: "struct",
UnsafePointer: "unsafe.Pointer",
}
// resolveNameOff resolves a name offset from a base pointer. // 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. // Implemented in the runtime package.
@ -367,61 +303,7 @@ func (t *rtype) typeOff(off typeOff) *rtype {
} }
func (t *rtype) uncommon() *uncommonType { func (t *rtype) uncommon() *uncommonType {
if t.TFlag&abi.TFlagUncommon == 0 { return t.Uncommon()
return nil
}
switch t.Kind() {
case Struct:
return &(*structTypeUncommon)(unsafe.Pointer(t)).u
case Ptr:
type u struct {
ptrType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Func:
type u struct {
funcType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Slice:
type u struct {
sliceType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Array:
type u struct {
arrayType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Chan:
type u struct {
chanType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Map:
type u struct {
mapType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
case Interface:
type u struct {
interfaceType
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
default:
type u struct {
rtype
u uncommonType
}
return &(*u)(unsafe.Pointer(t)).u
}
} }
func (t *rtype) String() string { func (t *rtype) String() string {
@ -432,10 +314,6 @@ func (t *rtype) String() string {
return s return s
} }
func (t *rtype) Size() uintptr { return t.Size_ }
func (t *rtype) Kind() Kind { return Kind(t.Kind_ & kindMask) }
func (t *rtype) pointers() bool { return t.PtrBytes != 0 } func (t *rtype) pointers() bool { return t.PtrBytes != 0 }
func (t *rtype) common() *rtype { return t } func (t *rtype) common() *rtype { return t }
@ -491,28 +369,32 @@ func (t *rtype) Name() string {
} }
func (t *rtype) chanDir() chanDir { func (t *rtype) chanDir() chanDir {
if t.Kind() != Chan { if t.Kind() != abi.Chan {
panic("reflect: chanDir of non-chan type") panic("reflect: chanDir of non-chan type")
} }
tt := (*chanType)(unsafe.Pointer(t)) tt := (*chanType)(unsafe.Pointer(t))
return chanDir(tt.dir) return chanDir(tt.dir)
} }
func toRType(t *abi.Type) *rtype {
return (*rtype)(unsafe.Pointer(t))
}
func (t *rtype) Elem() Type { func (t *rtype) Elem() Type {
switch t.Kind() { switch t.Kind() {
case Array: case abi.Array:
tt := (*arrayType)(unsafe.Pointer(t)) tt := (*arrayType)(unsafe.Pointer(t))
return toType((*rtype)(tt.Elem)) return toType(toRType(tt.Elem))
case Chan: case abi.Chan:
tt := (*chanType)(unsafe.Pointer(t)) tt := (*chanType)(unsafe.Pointer(t))
return toType(tt.elem) return toType(tt.elem)
case Map: case abi.Map:
tt := (*mapType)(unsafe.Pointer(t)) tt := (*mapType)(unsafe.Pointer(t))
return toType(tt.elem) return toType(tt.elem)
case Ptr: case abi.Pointer:
tt := (*ptrType)(unsafe.Pointer(t)) tt := (*ptrType)(unsafe.Pointer(t))
return toType(tt.elem) return toType(tt.elem)
case Slice: case abi.Slice:
tt := (*sliceType)(unsafe.Pointer(t)) tt := (*sliceType)(unsafe.Pointer(t))
return toType(tt.elem) return toType(tt.elem)
} }
@ -520,7 +402,7 @@ func (t *rtype) Elem() Type {
} }
func (t *rtype) In(i int) Type { func (t *rtype) In(i int) Type {
if t.Kind() != Func { if t.Kind() != abi.Func {
panic("reflect: In of non-func type") panic("reflect: In of non-func type")
} }
tt := (*funcType)(unsafe.Pointer(t)) tt := (*funcType)(unsafe.Pointer(t))
@ -528,7 +410,7 @@ func (t *rtype) In(i int) Type {
} }
func (t *rtype) Key() Type { func (t *rtype) Key() Type {
if t.Kind() != Map { if t.Kind() != abi.Map {
panic("reflect: Key of non-map type") panic("reflect: Key of non-map type")
} }
tt := (*mapType)(unsafe.Pointer(t)) tt := (*mapType)(unsafe.Pointer(t))
@ -536,7 +418,7 @@ func (t *rtype) Key() Type {
} }
func (t *rtype) Len() int { func (t *rtype) Len() int {
if t.Kind() != Array { if t.Kind() != abi.Array {
panic("reflect: Len of non-array type") panic("reflect: Len of non-array type")
} }
tt := (*arrayType)(unsafe.Pointer(t)) tt := (*arrayType)(unsafe.Pointer(t))
@ -544,7 +426,7 @@ func (t *rtype) Len() int {
} }
func (t *rtype) NumField() int { func (t *rtype) NumField() int {
if t.Kind() != Struct { if t.Kind() != abi.Struct {
panic("reflect: NumField of non-struct type") panic("reflect: NumField of non-struct type")
} }
tt := (*structType)(unsafe.Pointer(t)) tt := (*structType)(unsafe.Pointer(t))
@ -552,7 +434,7 @@ func (t *rtype) NumField() int {
} }
func (t *rtype) NumIn() int { func (t *rtype) NumIn() int {
if t.Kind() != Func { if t.Kind() != abi.Func {
panic("reflect: NumIn of non-func type") panic("reflect: NumIn of non-func type")
} }
tt := (*funcType)(unsafe.Pointer(t)) tt := (*funcType)(unsafe.Pointer(t))
@ -560,7 +442,7 @@ func (t *rtype) NumIn() int {
} }
func (t *rtype) NumOut() int { func (t *rtype) NumOut() int {
if t.Kind() != Func { if t.Kind() != abi.Func {
panic("reflect: NumOut of non-func type") panic("reflect: NumOut of non-func type")
} }
tt := (*funcType)(unsafe.Pointer(t)) tt := (*funcType)(unsafe.Pointer(t))
@ -568,7 +450,7 @@ func (t *rtype) NumOut() int {
} }
func (t *rtype) Out(i int) Type { func (t *rtype) Out(i int) Type {
if t.Kind() != Func { if t.Kind() != abi.Func {
panic("reflect: Out of non-func type") panic("reflect: Out of non-func type")
} }
tt := (*funcType)(unsafe.Pointer(t)) tt := (*funcType)(unsafe.Pointer(t))
@ -771,16 +653,16 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
// Non-composite types of equal kind have same underlying type // Non-composite types of equal kind have same underlying type
// (the predefined instance of the type). // (the predefined instance of the type).
if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer { if abi.Bool <= kind && kind <= abi.Complex128 || kind == abi.String || kind == abi.UnsafePointer {
return true return true
} }
// Composite types. // Composite types.
switch kind { switch kind {
case Array: case abi.Array:
return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
case Chan: case abi.Chan:
// Special case: // Special case:
// x is a bidirectional channel value, T is a channel type, // x is a bidirectional channel value, T is a channel type,
// and x's type V and T have identical element types. // and x's type V and T have identical element types.
@ -791,7 +673,7 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
// Otherwise continue test for identical underlying type. // 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 Func: case abi.Func:
t := (*funcType)(unsafe.Pointer(T)) t := (*funcType)(unsafe.Pointer(T))
v := (*funcType)(unsafe.Pointer(V)) v := (*funcType)(unsafe.Pointer(V))
if t.outCount != v.outCount || t.inCount != v.inCount { if t.outCount != v.outCount || t.inCount != v.inCount {
@ -819,13 +701,13 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
// need a run time conversion. // need a run time conversion.
return false return false
case Map: case abi.Map:
return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
case Ptr, Slice: case Ptr, abi.Slice:
return haveIdenticalType(T.Elem(), V.Elem(), cmpTags) return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
case Struct: case abi.Struct:
t := (*structType)(unsafe.Pointer(T)) t := (*structType)(unsafe.Pointer(T))
v := (*structType)(unsafe.Pointer(V)) v := (*structType)(unsafe.Pointer(V))
if len(t.fields) != len(v.fields) { if len(t.fields) != len(v.fields) {
@ -878,5 +760,5 @@ func toType(t *rtype) Type {
// ifaceIndir reports whether t is stored indirectly in an interface value. // ifaceIndir reports whether t is stored indirectly in an interface value.
func ifaceIndir(t *rtype) bool { func ifaceIndir(t *rtype) bool {
return t.Kind_&kindDirectIface == 0 return t.Kind_&abi.KindDirectIface == 0
} }

View File

@ -5,6 +5,7 @@
package reflectlite package reflectlite
import ( import (
"internal/abi"
"internal/goarch" "internal/goarch"
"internal/unsafeheader" "internal/unsafeheader"
"runtime" "runtime"
@ -89,7 +90,7 @@ func (f flag) ro() flag {
// pointer returns the underlying pointer represented by v. // pointer returns the underlying pointer represented by v.
// v.Kind() must be Pointer, Map, Chan, Func, or UnsafePointer // v.Kind() must be Pointer, Map, Chan, Func, or UnsafePointer
func (v Value) pointer() unsafe.Pointer { 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") panic("can't call pointer on a non-pointer Value")
} }
if v.flag&flagIndir != 0 { if v.flag&flagIndir != 0 {
@ -198,7 +199,7 @@ func (f flag) mustBeExported() {
// or it is not addressable. // or it is not addressable.
func (f flag) mustBeAssignable() { func (f flag) mustBeAssignable() {
if f == 0 { if f == 0 {
panic(&ValueError{methodName(), Invalid}) panic(&ValueError{methodName(), abi.Invalid})
} }
// Assignable if addressable and not read-only. // Assignable if addressable and not read-only.
if f&flagRO != 0 { if f&flagRO != 0 {
@ -225,7 +226,7 @@ func (v Value) CanSet() bool {
func (v Value) Elem() Value { func (v Value) Elem() Value {
k := v.kind() k := v.kind()
switch k { switch k {
case Interface: case abi.Interface:
var eface any var eface any
if v.typ.NumMethod() == 0 { if v.typ.NumMethod() == 0 {
eface = *(*any)(v.ptr) eface = *(*any)(v.ptr)
@ -239,7 +240,7 @@ func (v Value) Elem() Value {
x.flag |= v.flag.ro() x.flag |= v.flag.ro()
} }
return x return x
case Pointer: case abi.Pointer:
ptr := v.ptr ptr := v.ptr
if v.flag&flagIndir != 0 { if v.flag&flagIndir != 0 {
ptr = *(*unsafe.Pointer)(ptr) ptr = *(*unsafe.Pointer)(ptr)
@ -262,7 +263,7 @@ func valueInterface(v Value) any {
panic(&ValueError{"reflectlite.Value.Interface", 0}) panic(&ValueError{"reflectlite.Value.Interface", 0})
} }
if v.kind() == Interface { if v.kind() == abi.Interface {
// Special case: return the element inside the interface. // Special case: return the element inside the interface.
// Empty interface has one layout, all interfaces with // Empty interface has one layout, all interfaces with
// methods have a second layout. // methods have a second layout.
@ -288,7 +289,7 @@ func valueInterface(v Value) any {
func (v Value) IsNil() bool { func (v Value) IsNil() bool {
k := v.kind() k := v.kind()
switch k { switch k {
case Chan, Func, Map, Pointer, UnsafePointer: case abi.Chan, abi.Func, abi.Map, abi.Pointer, abi.UnsafePointer:
// if v.flag&flagMethod != 0 { // if v.flag&flagMethod != 0 {
// return false // return false
// } // }
@ -297,7 +298,7 @@ func (v Value) IsNil() bool {
ptr = *(*unsafe.Pointer)(ptr) ptr = *(*unsafe.Pointer)(ptr)
} }
return ptr == nil return ptr == nil
case Interface, Slice: case abi.Interface, abi.Slice:
// Both interface and slice are nil if first word is 0. // Both interface and slice are nil if first word is 0.
// Both are always bigger than a word; assume flagIndir. // Both are always bigger than a word; assume flagIndir.
return *(*unsafe.Pointer)(v.ptr) == nil return *(*unsafe.Pointer)(v.ptr) == nil
@ -329,17 +330,17 @@ func maplen(unsafe.Pointer) int
func (v Value) Len() int { func (v Value) Len() int {
k := v.kind() k := v.kind()
switch k { switch k {
case Array: case abi.Array:
tt := (*arrayType)(unsafe.Pointer(v.typ)) tt := (*arrayType)(unsafe.Pointer(v.typ))
return int(tt.Len) return int(tt.Len)
case Chan: case abi.Chan:
return chanlen(v.pointer()) return chanlen(v.pointer())
case Map: case abi.Map:
return maplen(v.pointer()) return maplen(v.pointer())
case Slice: case abi.Slice:
// Slice is bigger than a word; assume flagIndir. // Slice is bigger than a word; assume flagIndir.
return (*unsafeheader.Slice)(v.ptr).Len return (*unsafeheader.Slice)(v.ptr).Len
case String: case abi.String:
// String is bigger than a word; assume flagIndir. // String is bigger than a word; assume flagIndir.
return (*unsafeheader.String)(v.ptr).Len return (*unsafeheader.String)(v.ptr).Len
} }
@ -349,7 +350,7 @@ func (v Value) Len() int {
// NumMethod returns the number of exported methods in the value's method set. // NumMethod returns the number of exported methods in the value's method set.
func (v Value) numMethod() int { func (v Value) numMethod() int {
if v.typ == nil { if v.typ == nil {
panic(&ValueError{"reflectlite.Value.NumMethod", Invalid}) panic(&ValueError{"reflectlite.Value.NumMethod", abi.Invalid})
} }
return v.typ.NumMethod() return v.typ.NumMethod()
} }
@ -361,7 +362,7 @@ func (v Value) Set(x Value) {
v.mustBeAssignable() v.mustBeAssignable()
x.mustBeExported() // do not let unexported x leak x.mustBeExported() // do not let unexported x leak
var target unsafe.Pointer var target unsafe.Pointer
if v.kind() == Interface { if v.kind() == abi.Interface {
target = v.ptr target = v.ptr
} }
x = x.assignTo("reflectlite.Set", v.typ, target) x = x.assignTo("reflectlite.Set", v.typ, target)
@ -376,7 +377,7 @@ func (v Value) Set(x Value) {
func (v Value) Type() Type { func (v Value) Type() Type {
f := v.flag f := v.flag
if f == 0 { if f == 0 {
panic(&ValueError{"reflectlite.Value.Type", Invalid}) panic(&ValueError{"reflectlite.Value.Type", abi.Invalid})
} }
// Method values not supported. // Method values not supported.
return v.typ return v.typ
@ -425,11 +426,11 @@ func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value
if target == nil { if target == nil {
target = unsafe_New(dst) target = unsafe_New(dst)
} }
if v.Kind() == Interface && v.IsNil() { if v.Kind() == abi.Interface && v.IsNil() {
// A nil ReadWriter passed to nil Reader is OK, // A nil ReadWriter passed to nil Reader is OK,
// but using ifaceE2I below will panic. // but using ifaceE2I below will panic.
// Avoid the panic by returning a nil dst (e.g., Reader) explicitly. // Avoid the panic by returning a nil dst (e.g., Reader) explicitly.
return Value{dst, nil, flag(Interface)} return Value{dst, nil, flag(abi.Interface)}
} }
x := valueInterface(v) x := valueInterface(v)
if dst.NumMethod() == 0 { if dst.NumMethod() == 0 {
@ -437,7 +438,7 @@ func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value
} else { } else {
ifaceE2I(dst, x, target) ifaceE2I(dst, x, target)
} }
return Value{dst, target, flagIndir | flag(Interface)} return Value{dst, target, flagIndir | flag(abi.Interface)}
} }
// Failed. // Failed.

View File

@ -174,7 +174,7 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
case kindArray: case kindArray:
a := (*arraytype)(unsafe.Pointer(t)) a := (*arraytype)(unsafe.Pointer(t))
for i := uintptr(0); i < a.Len; i++ { for i := uintptr(0); i < a.Len; i++ {
h = typehash((*_type)(a.Elem), add(p, i*a.Elem.Size_), h) h = typehash(toType(a.Elem), add(p, i*a.Elem.Size_), h)
} }
return h return h
case kindStruct: case kindStruct:

View File

@ -466,11 +466,11 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
if at.Len != 1 { if at.Len != 1 {
throw("can't happen") throw("can't happen")
} }
cgoCheckArg((*_type)(at.Elem), p, at.Elem.Kind_&kindDirectIface == 0, top, msg) cgoCheckArg(toType(at.Elem), p, at.Elem.Kind_&kindDirectIface == 0, top, msg)
return return
} }
for i := uintptr(0); i < at.Len; i++ { for i := uintptr(0); i < at.Len; i++ {
cgoCheckArg((*_type)(at.Elem), p, true, top, msg) cgoCheckArg(toType(at.Elem), p, true, top, msg)
p = add(p, at.Elem.Size_) p = add(p, at.Elem.Size_)
} }
case kindChan, kindMap: case kindChan, kindMap:

View File

@ -249,7 +249,7 @@ func cgoCheckUsingType(typ *_type, src unsafe.Pointer, off, size uintptr) {
at := (*arraytype)(unsafe.Pointer(typ)) at := (*arraytype)(unsafe.Pointer(typ))
for i := uintptr(0); i < at.Len; i++ { for i := uintptr(0); i < at.Len; i++ {
if off < at.Elem.Size_ { if off < at.Elem.Size_ {
cgoCheckUsingType((*_type)(at.Elem), src, off, size) cgoCheckUsingType(toType(at.Elem), src, off, size)
} }
src = add(src, at.Elem.Size_) src = add(src, at.Elem.Size_)
skipped := off skipped := off

View File

@ -186,7 +186,7 @@ func (p *abiDesc) tryRegAssignArg(t *_type, offset uintptr) bool {
case kindArray: case kindArray:
at := (*arraytype)(unsafe.Pointer(t)) at := (*arraytype)(unsafe.Pointer(t))
if at.Len == 1 { if at.Len == 1 {
return p.tryRegAssignArg((*_type)(at.Elem), offset) return p.tryRegAssignArg((*_type)(unsafe.Pointer(at.Elem)), offset) // TODO fix when runtime is fully commoned up w/ abi.Type
} }
case kindStruct: case kindStruct:
st := (*structtype)(unsafe.Pointer(t)) st := (*structtype)(unsafe.Pointer(t))

View File

@ -19,7 +19,9 @@ type textOff = abi.TextOff
// ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and // ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and
// ../reflect/type.go:/^type.rtype. // ../reflect/type.go:/^type.rtype.
// ../internal/reflectlite/type.go:/^type.rtype. // ../internal/reflectlite/type.go:/^type.rtype.
type _type abi.Type type _type struct {
abi.Type
}
func (t *_type) string() string { func (t *_type) string() string {
s := t.nameOff(t.Str).name() s := t.nameOff(t.Str).name()
@ -30,65 +32,7 @@ func (t *_type) string() string {
} }
func (t *_type) uncommon() *uncommontype { func (t *_type) uncommon() *uncommontype {
if t.TFlag&abi.TFlagUncommon == 0 { return t.Uncommon()
return nil
}
switch t.Kind_ & kindMask {
case kindStruct:
type u struct {
structtype
u uncommontype
}
return &(*u)(unsafe.Pointer(t)).u
case kindPtr:
type u struct {
ptrtype
u uncommontype
}
return &(*u)(unsafe.Pointer(t)).u
case kindFunc:
type u struct {
functype
u uncommontype
}
return &(*u)(unsafe.Pointer(t)).u
case kindSlice:
type u struct {
slicetype
u uncommontype
}
return &(*u)(unsafe.Pointer(t)).u
case kindArray:
type u struct {
arraytype
u uncommontype
}
return &(*u)(unsafe.Pointer(t)).u
case kindChan:
type u struct {
chantype
u uncommontype
}
return &(*u)(unsafe.Pointer(t)).u
case kindMap:
type u struct {
maptype
u uncommontype
}
return &(*u)(unsafe.Pointer(t)).u
case kindInterface:
type u struct {
interfacetype
u uncommontype
}
return &(*u)(unsafe.Pointer(t)).u
default:
type u struct {
_type
u uncommontype
}
return &(*u)(unsafe.Pointer(t)).u
}
} }
func (t *_type) name() string { func (t *_type) name() string {
@ -500,6 +444,10 @@ type _typePair struct {
t2 *_type t2 *_type
} }
func toType(t *abi.Type) *_type {
return (*_type)(unsafe.Pointer(t))
}
// typesEqual reports whether two types are equal. // typesEqual reports whether two types are equal.
// //
// Everywhere in the runtime and reflect packages, it is assumed that // Everywhere in the runtime and reflect packages, it is assumed that
@ -554,7 +502,7 @@ func typesEqual(t, v *_type, seen map[_typePair]struct{}) bool {
case kindArray: case kindArray:
at := (*arraytype)(unsafe.Pointer(t)) at := (*arraytype)(unsafe.Pointer(t))
av := (*arraytype)(unsafe.Pointer(v)) av := (*arraytype)(unsafe.Pointer(v))
return typesEqual((*_type)(at.Elem), (*_type)(av.Elem), seen) && at.Len == av.Len return typesEqual(toType(at.Elem), toType(av.Elem), seen) && at.Len == av.Len
case kindChan: case kindChan:
ct := (*chantype)(unsafe.Pointer(t)) ct := (*chantype)(unsafe.Pointer(t))
cv := (*chantype)(unsafe.Pointer(v)) cv := (*chantype)(unsafe.Pointer(v))