mirror of https://github.com/golang/go.git
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:
parent
a851511947
commit
639957eb66
|
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue