1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Runtime type representation.
11 "runtime/internal/atomic"
15 // tflag is documented in reflect/type.go.
17 // tflag values must be kept in sync with copies in:
20 // internal/reflectlite/type.go
24 tflagRegularMemory tflag
= 1 << 3 // equal and hash can treat values of this type as a single region of t.size bytes
27 // Needs to be in sync with
29 // ../reflect/type.go:/^type.rtype.
30 // ../internal/reflectlite/type.go:/^type.rtype.
39 // function for comparing objects of this type
40 // (ptr to object A, ptr to object B) -> ==?
41 equal
func(unsafe
.Pointer
, unsafe
.Pointer
) bool
42 // gcdata stores the GC type data for the garbage collector.
43 // If the KindGCProg bit is set in kind, gcdata is a GC program.
44 // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
51 func (t
*_type
) string() string {
52 // For gccgo, try to strip out quoted strings.
58 for i
:= 0; i
< len(s
); i
++ {
69 return s
[start
: end
+1]
72 // pkgpath returns the path of the package where t was defined, if
73 // available. This is not the same as the reflect package's PkgPath
74 // method, in that it returns the package path for struct and interface
75 // types, not just named types.
76 func (t
*_type
) pkgpath() string {
77 if u
:= t
.uncommontype
; u
!= nil {
94 type uncommontype
struct {
100 type imethod
struct {
106 type interfacetype
struct {
111 type maptype
struct {
115 bucket
*_type
// internal type representing a hash bucket
116 // function for hashing keys (ptr to key, seed) -> hash
117 hasher
func(unsafe
.Pointer
, uintptr) uintptr
118 keysize
uint8 // size of key slot
119 elemsize
uint8 // size of elem slot
120 bucketsize
uint16 // size of bucket
124 // Note: flag values must match those used in the TMAP case
125 // in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
126 func (mt
*maptype
) indirectkey() bool { // store ptr to key instead of key itself
127 return mt
.flags
&1 != 0
129 func (mt
*maptype
) indirectelem() bool { // store ptr to elem instead of elem itself
130 return mt
.flags
&2 != 0
132 func (mt
*maptype
) reflexivekey() bool { // true if k==k for all keys
133 return mt
.flags
&4 != 0
135 func (mt
*maptype
) needkeyupdate() bool { // true if we need to update key on an overwrite
136 return mt
.flags
&8 != 0
138 func (mt
*maptype
) hashMightPanic() bool { // true if hash function might panic
139 return mt
.flags
&16 != 0
142 type arraytype
struct {
149 type chantype
struct {
155 type slicetype
struct {
160 type functype
struct {
167 type ptrtype
struct {
172 type structfield
struct {
173 name
*string // nil for embedded fields
174 pkgPath
*string // nil for exported Names; otherwise import path
175 typ
*_type
// type of field
176 tag
*string // nil if no tag
177 offsetAnon
uintptr // byte offset of field<<1 | isAnonymous
180 func (f
*structfield
) offset() uintptr {
181 return f
.offsetAnon
>> 1
184 func (f
*structfield
) anon() bool {
185 return f
.offsetAnon
&1 != 0
188 type structtype
struct {
193 // typeDescriptorList holds a list of type descriptors generated
194 // by the compiler. This is used for the compiler to register
195 // type descriptors to the runtime.
196 // The layout is known to the compiler.
198 type typeDescriptorList
struct {
200 types
[1]uintptr // variable length
203 // typelist holds all type descriptors generated by the comiler.
204 // This is for the reflect package to deduplicate type descriptors
205 // when it creates a type that is also a compiler-generated type.
206 var typelist
struct {
208 lists
[]*typeDescriptorList
// one element per package
209 types
map[string]uintptr // map from a type's string to *_type, lazily populated
210 // TODO: use a sorted array instead?
212 var typelistLock mutex
214 // The compiler generates a call of this function in the main
215 // package's init function, to register compiler-generated
217 // p points to a list of *typeDescriptorList, n is the length
219 //go:linkname registerTypeDescriptors
220 func registerTypeDescriptors(n
int, p unsafe
.Pointer
) {
221 *(*slice
)(unsafe
.Pointer(&typelist
.lists
)) = slice
{p
, n
, n
}
224 // The reflect package uses this function to look up a compiler-
225 // generated type descriptor.
226 //go:linkname reflect_lookupType reflect.lookupType
227 func reflect_lookupType(s
string) *_type
{
228 // Lazy initialization. We don't need to do this if we never create
229 // types through reflection.
230 if atomic
.Load(&typelist
.initialized
) == 0 {
232 if atomic
.Load(&typelist
.initialized
) == 0 {
234 for _
, list
:= range typelist
.lists
{
237 typelist
.types
= make(map[string]uintptr, n
)
238 for _
, list
:= range typelist
.lists
{
239 for i
:= 0; i
< list
.count
; i
++ {
240 typ
:= *(**_type
)(add(unsafe
.Pointer(&list
.types
), uintptr(i
)*goarch
.PtrSize
))
241 typelist
.types
[typ
.string()] = uintptr(unsafe
.Pointer(typ
))
244 atomic
.Store(&typelist
.initialized
, 1)
246 unlock(&typelistLock
)
249 return (*_type
)(unsafe
.Pointer(typelist
.types
[s
]))