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 // Package reflect implements run-time reflection, allowing a program to
6 // manipulate objects with arbitrary types. The typical use is to take a value
7 // with static type interface{} and extract its dynamic type information by
8 // calling TypeOf, which returns a Type.
10 // A call to ValueOf returns a Value representing the run-time data.
11 // Zero takes a Type and returns a Value representing a zero value
14 // See "The Laws of Reflection" for an introduction to reflection in Go:
15 // http://golang.org/doc/articles/laws_of_reflection.html
25 // Type is the representation of a Go type.
27 // Not all methods apply to all kinds of types. Restrictions,
28 // if any, are noted in the documentation for each method.
29 // Use the Kind method to find out the kind of type before
30 // calling kind-specific methods. Calling a method
31 // inappropriate to the kind of type causes a run-time panic.
33 // Methods applicable to all types.
35 // Align returns the alignment in bytes of a value of
36 // this type when allocated in memory.
39 // FieldAlign returns the alignment in bytes of a value of
40 // this type when used as a field in a struct.
43 // Method returns the i'th method in the type's method set.
44 // It panics if i is not in the range [0, NumMethod()).
46 // For a non-interface type T or *T, the returned Method's Type and Func
47 // fields describe a function whose first argument is the receiver.
49 // For an interface type, the returned Method's Type field gives the
50 // method signature, without a receiver, and the Func field is nil.
53 // MethodByName returns the method with that name in the type's
54 // method set and a boolean indicating if the method was found.
56 // For a non-interface type T or *T, the returned Method's Type and Func
57 // fields describe a function whose first argument is the receiver.
59 // For an interface type, the returned Method's Type field gives the
60 // method signature, without a receiver, and the Func field is nil.
61 MethodByName(string) (Method
, bool)
63 // NumMethod returns the number of methods in the type's method set.
66 // Name returns the type's name within its package.
67 // It returns an empty string for unnamed types.
70 // PkgPath returns a named type's package path, that is, the import path
71 // that uniquely identifies the package, such as "encoding/base64".
72 // If the type was predeclared (string, error) or unnamed (*T, struct{}, []int),
73 // the package path will be the empty string.
76 // Size returns the number of bytes needed to store
77 // a value of the given type; it is analogous to unsafe.Sizeof.
80 // String returns a string representation of the type.
81 // The string representation may use shortened package names
82 // (e.g., base64 instead of "encoding/base64") and is not
83 // guaranteed to be unique among types. To test for equality,
84 // compare the Types directly.
87 // Used internally by gccgo--the string retaining quoting.
90 // Kind returns the specific kind of this type.
93 // Implements returns true if the type implements the interface type u.
94 Implements(u Type
) bool
96 // AssignableTo returns true if a value of the type is assignable to type u.
97 AssignableTo(u Type
) bool
99 // ConvertibleTo returns true if a value of the type is convertible to type u.
100 ConvertibleTo(u Type
) bool
102 // Comparable returns true if values of this type are comparable.
105 // Methods applicable only to some types, depending on Kind.
106 // The methods allowed for each kind are:
108 // Int*, Uint*, Float*, Complex*: Bits
110 // Chan: ChanDir, Elem
111 // Func: In, NumIn, Out, NumOut, IsVariadic.
115 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
117 // Bits returns the size of the type in bits.
118 // It panics if the type's Kind is not one of the
119 // sized or unsized Int, Uint, Float, or Complex kinds.
122 // ChanDir returns a channel type's direction.
123 // It panics if the type's Kind is not Chan.
126 // IsVariadic returns true if a function type's final input parameter
127 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's
128 // implicit actual type []T.
130 // For concreteness, if t represents func(x int, y ... float64), then
133 // t.In(0) is the reflect.Type for "int"
134 // t.In(1) is the reflect.Type for "[]float64"
135 // t.IsVariadic() == true
137 // IsVariadic panics if the type's Kind is not Func.
140 // Elem returns a type's element type.
141 // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
144 // Field returns a struct type's i'th field.
145 // It panics if the type's Kind is not Struct.
146 // It panics if i is not in the range [0, NumField()).
147 Field(i
int) StructField
149 // FieldByIndex returns the nested field corresponding
150 // to the index sequence. It is equivalent to calling Field
151 // successively for each index i.
152 // It panics if the type's Kind is not Struct.
153 FieldByIndex(index
[]int) StructField
155 // FieldByName returns the struct field with the given name
156 // and a boolean indicating if the field was found.
157 FieldByName(name
string) (StructField
, bool)
159 // FieldByNameFunc returns the first struct field with a name
160 // that satisfies the match function and a boolean indicating if
161 // the field was found.
162 FieldByNameFunc(match
func(string) bool) (StructField
, bool)
164 // In returns the type of a function type's i'th input parameter.
165 // It panics if the type's Kind is not Func.
166 // It panics if i is not in the range [0, NumIn()).
169 // Key returns a map type's key type.
170 // It panics if the type's Kind is not Map.
173 // Len returns an array type's length.
174 // It panics if the type's Kind is not Array.
177 // NumField returns a struct type's field count.
178 // It panics if the type's Kind is not Struct.
181 // NumIn returns a function type's input parameter count.
182 // It panics if the type's Kind is not Func.
185 // NumOut returns a function type's output parameter count.
186 // It panics if the type's Kind is not Func.
189 // Out returns the type of a function type's i'th output parameter.
190 // It panics if the type's Kind is not Func.
191 // It panics if i is not in the range [0, NumOut()).
195 uncommon() *uncommonType
198 // BUG(rsc): FieldByName and related functions consider struct field names to be equal
199 // if the names are equal, even if they are unexported names originating
200 // in different packages. The practical effect of this is that the result of
201 // t.FieldByName("x") is not well defined if the struct type t contains
202 // multiple fields named x (embedded from different packages).
203 // FieldByName may return one of the fields named x or may report that there are none.
204 // See golang.org/issue/4876 for more details.
207 * These data structures are known to the compiler (../../cmd/gc/reflect.c).
208 * A few are known to ../runtime/type.go to convey to debuggers.
209 * They are also known to ../runtime/type.h.
212 // A Kind represents the specific kind of type that a Type represents.
213 // The zero Kind is not a valid kind.
246 // rtype is the common implementation of most values.
247 // It is embedded in other, public struct types, but always
248 // with a unique tag like `reflect:"array"` or `reflect:"ptr"`
249 // so that code cannot convert from, say, *arrayType to *ptrType.
251 kind
uint8 // enumeration for C
252 align
int8 // alignment of variable with this type
253 fieldAlign
uint8 // alignment of struct field with this type
254 _
uint8 // unused/padding
256 hash
uint32 // hash of type; avoids computation in hash tables
258 hashfn
uintptr // hash function code
259 equalfn
uintptr // equality function code
261 gc unsafe
.Pointer
// garbage collection data
262 string *string // string form; unnecessary but undeniably useful
263 *uncommonType
// (relatively) uncommon fields
264 ptrToThis
*rtype
// type for pointer to this type, if used in binary or has methods
265 zero unsafe
.Pointer
// pointer to zero value
268 // Method on non-interface type
270 name
*string // name of method
271 pkgPath
*string // nil for exported Names; otherwise import path
272 mtyp
*rtype
// method type (without receiver)
273 typ
*rtype
// .(*FuncType) underneath (with receiver)
274 tfn unsafe
.Pointer
// fn used for normal method call
277 // uncommonType is present only for types with names or methods
278 // (if T is a named type, the uncommonTypes for T and *T have methods).
279 // Using a pointer to this struct reduces the overall size required
280 // to describe an unnamed type with no methods.
281 type uncommonType
struct {
282 name
*string // name of type
283 pkgPath
*string // import path; nil for built-in types like int, string
284 methods
[]method
// methods associated with type
287 // ChanDir represents a channel type's direction.
291 RecvDir ChanDir
= 1 << iota // <-chan
293 BothDir
= RecvDir | SendDir
// chan
296 // arrayType represents a fixed array type.
297 type arrayType
struct {
298 rtype
`reflect:"array"`
299 elem
*rtype
// array element type
300 slice
*rtype
// slice type
304 // chanType represents a channel type.
305 type chanType
struct {
306 rtype
`reflect:"chan"`
307 elem
*rtype
// channel element type
308 dir
uintptr // channel direction (ChanDir)
311 // funcType represents a function type.
312 type funcType
struct {
313 rtype
`reflect:"func"`
314 dotdotdot
bool // last input parameter is ...
315 in
[]*rtype
// input parameter types
316 out
[]*rtype
// output parameter types
319 // imethod represents a method on an interface type
320 type imethod
struct {
321 name
*string // name of method
322 pkgPath
*string // nil for exported Names; otherwise import path
323 typ
*rtype
// .(*FuncType) underneath
326 // interfaceType represents an interface type.
327 type interfaceType
struct {
328 rtype
`reflect:"interface"`
329 methods
[]imethod
// sorted by hash
332 // mapType represents a map type.
333 type mapType
struct {
334 rtype
`reflect:"map"`
335 key
*rtype
// map key type
336 elem
*rtype
// map element (value) type
339 // ptrType represents a pointer type.
340 type ptrType
struct {
341 rtype
`reflect:"ptr"`
342 elem
*rtype
// pointer element (pointed at) type
345 // sliceType represents a slice type.
346 type sliceType
struct {
347 rtype
`reflect:"slice"`
348 elem
*rtype
// slice element type
352 type structField
struct {
353 name
*string // nil for embedded fields
354 pkgPath
*string // nil for exported Names; otherwise import path
355 typ
*rtype
// type of field
356 tag
*string // nil if no tag
357 offset
uintptr // byte offset of field within struct
360 // structType represents a struct type.
361 type structType
struct {
362 rtype
`reflect:"struct"`
363 fields
[]structField
// sorted by offset
366 // NOTE: These are copied from ../runtime/mgc0.h.
367 // They must be kept in sync.
385 * The compiler knows the exact layout of all the data structures above.
386 * The compiler does not know about the data structures and methods below.
389 // Method represents a single method.
391 // Name is the method name.
392 // PkgPath is the package path that qualifies a lower case (unexported)
393 // method name. It is empty for upper case (exported) method names.
394 // The combination of PkgPath and Name uniquely identifies a method
396 // See http://golang.org/ref/spec#Uniqueness_of_identifiers
400 Type Type
// method type
401 Func Value
// func with receiver as first argument
402 Index
int // index for Type.Method
406 kindDirectIface
= 1 << 5
407 kindGCProg
= 1 << 6 // Type.gc points to GC program
408 kindNoPointers
= 1 << 7
409 kindMask
= (1 << 5) - 1
412 func (k Kind
) String() string {
413 if int(k
) < len(kindNames
) {
416 return "kind" + strconv
.Itoa(int(k
))
419 var kindNames
= []string{
435 Complex64
: "complex64",
436 Complex128
: "complex128",
440 Interface
: "interface",
446 UnsafePointer
: "unsafe.Pointer",
449 func (t
*uncommonType
) uncommon() *uncommonType
{
453 func (t
*uncommonType
) PkgPath() string {
454 if t
== nil || t
.pkgPath
== nil {
460 func (t
*uncommonType
) Name() string {
461 if t
== nil || t
.name
== nil {
467 func (t
*rtype
) rawString() string { return *t
.string }
469 func (t
*rtype
) String() string {
470 // For gccgo, strip out quoted strings.
473 r
:= make([]byte, len(s
))
475 for i
:= 0; i
< len(s
); i
++ {
486 func (t
*rtype
) Size() uintptr { return t
.size
}
488 func (t
*rtype
) Bits() int {
490 panic("reflect: Bits of nil Type")
493 if k
< Int || k
> Complex128
{
494 panic("reflect: Bits of non-arithmetic Type " + t
.String())
496 return int(t
.size
) * 8
499 func (t
*rtype
) Align() int { return int(t
.align
) }
501 func (t
*rtype
) FieldAlign() int { return int(t
.fieldAlign
) }
503 func (t
*rtype
) Kind() Kind
{ return Kind(t
.kind
& kindMask
) }
505 func (t
*rtype
) pointers() bool { return t
.kind
&kindNoPointers
== 0 }
507 func (t
*rtype
) common() *rtype
{ return t
}
509 func (t
*uncommonType
) Method(i
int) (m Method
) {
510 if t
== nil || i
< 0 || i
>= len(t
.methods
) {
511 panic("reflect: Method index out of range")
518 if p
.pkgPath
!= nil {
519 m
.PkgPath
= *p
.pkgPath
524 x
:= new(unsafe
.Pointer
)
525 *x
= unsafe
.Pointer(&p
.tfn
)
526 m
.Func
= Value
{mt
, unsafe
.Pointer(x
), fl | flagIndir | flagMethodFn
}
531 func (t
*uncommonType
) NumMethod() int {
535 return len(t
.methods
)
538 func (t
*uncommonType
) MethodByName(name
string) (m Method
, ok
bool) {
543 for i
:= range t
.methods
{
545 if p
.name
!= nil && *p
.name
== name
{
546 return t
.Method(i
), true
552 // TODO(rsc): 6g supplies these, but they are not
553 // as efficient as they could be: they have commonType
554 // as the receiver instead of *rtype.
555 func (t
*rtype
) NumMethod() int {
556 if t
.Kind() == Interface
{
557 tt
:= (*interfaceType
)(unsafe
.Pointer(t
))
558 return tt
.NumMethod()
560 return t
.uncommonType
.NumMethod()
563 func (t
*rtype
) Method(i
int) (m Method
) {
564 if t
.Kind() == Interface
{
565 tt
:= (*interfaceType
)(unsafe
.Pointer(t
))
568 return t
.uncommonType
.Method(i
)
571 func (t
*rtype
) MethodByName(name
string) (m Method
, ok
bool) {
572 if t
.Kind() == Interface
{
573 tt
:= (*interfaceType
)(unsafe
.Pointer(t
))
574 return tt
.MethodByName(name
)
576 return t
.uncommonType
.MethodByName(name
)
579 func (t
*rtype
) PkgPath() string {
580 return t
.uncommonType
.PkgPath()
583 func (t
*rtype
) Name() string {
584 return t
.uncommonType
.Name()
587 func (t
*rtype
) ChanDir() ChanDir
{
588 if t
.Kind() != Chan
{
589 panic("reflect: ChanDir of non-chan type")
591 tt
:= (*chanType
)(unsafe
.Pointer(t
))
592 return ChanDir(tt
.dir
)
595 func (t
*rtype
) IsVariadic() bool {
596 if t
.Kind() != Func
{
597 panic("reflect: IsVariadic of non-func type")
599 tt
:= (*funcType
)(unsafe
.Pointer(t
))
603 func (t
*rtype
) Elem() Type
{
606 tt
:= (*arrayType
)(unsafe
.Pointer(t
))
607 return toType(tt
.elem
)
609 tt
:= (*chanType
)(unsafe
.Pointer(t
))
610 return toType(tt
.elem
)
612 tt
:= (*mapType
)(unsafe
.Pointer(t
))
613 return toType(tt
.elem
)
615 tt
:= (*ptrType
)(unsafe
.Pointer(t
))
616 return toType(tt
.elem
)
618 tt
:= (*sliceType
)(unsafe
.Pointer(t
))
619 return toType(tt
.elem
)
621 panic("reflect: Elem of invalid type")
624 func (t
*rtype
) Field(i
int) StructField
{
625 if t
.Kind() != Struct
{
626 panic("reflect: Field of non-struct type")
628 tt
:= (*structType
)(unsafe
.Pointer(t
))
632 func (t
*rtype
) FieldByIndex(index
[]int) StructField
{
633 if t
.Kind() != Struct
{
634 panic("reflect: FieldByIndex of non-struct type")
636 tt
:= (*structType
)(unsafe
.Pointer(t
))
637 return tt
.FieldByIndex(index
)
640 func (t
*rtype
) FieldByName(name
string) (StructField
, bool) {
641 if t
.Kind() != Struct
{
642 panic("reflect: FieldByName of non-struct type")
644 tt
:= (*structType
)(unsafe
.Pointer(t
))
645 return tt
.FieldByName(name
)
648 func (t
*rtype
) FieldByNameFunc(match
func(string) bool) (StructField
, bool) {
649 if t
.Kind() != Struct
{
650 panic("reflect: FieldByNameFunc of non-struct type")
652 tt
:= (*structType
)(unsafe
.Pointer(t
))
653 return tt
.FieldByNameFunc(match
)
656 func (t
*rtype
) In(i
int) Type
{
657 if t
.Kind() != Func
{
658 panic("reflect: In of non-func type")
660 tt
:= (*funcType
)(unsafe
.Pointer(t
))
661 return toType(tt
.in
[i
])
664 func (t
*rtype
) Key() Type
{
666 panic("reflect: Key of non-map type")
668 tt
:= (*mapType
)(unsafe
.Pointer(t
))
669 return toType(tt
.key
)
672 func (t
*rtype
) Len() int {
673 if t
.Kind() != Array
{
674 panic("reflect: Len of non-array type")
676 tt
:= (*arrayType
)(unsafe
.Pointer(t
))
680 func (t
*rtype
) NumField() int {
681 if t
.Kind() != Struct
{
682 panic("reflect: NumField of non-struct type")
684 tt
:= (*structType
)(unsafe
.Pointer(t
))
685 return len(tt
.fields
)
688 func (t
*rtype
) NumIn() int {
689 if t
.Kind() != Func
{
690 panic("reflect: NumIn of non-func type")
692 tt
:= (*funcType
)(unsafe
.Pointer(t
))
696 func (t
*rtype
) NumOut() int {
697 if t
.Kind() != Func
{
698 panic("reflect: NumOut of non-func type")
700 tt
:= (*funcType
)(unsafe
.Pointer(t
))
704 func (t
*rtype
) Out(i
int) Type
{
705 if t
.Kind() != Func
{
706 panic("reflect: Out of non-func type")
708 tt
:= (*funcType
)(unsafe
.Pointer(t
))
709 return toType(tt
.out
[i
])
712 func (d ChanDir
) String() string {
721 return "ChanDir" + strconv
.Itoa(int(d
))
724 // Method returns the i'th method in the type's method set.
725 func (t
*interfaceType
) Method(i
int) (m Method
) {
726 if i
< 0 || i
>= len(t
.methods
) {
731 if p
.pkgPath
!= nil {
732 m
.PkgPath
= *p
.pkgPath
734 m
.Type
= toType(p
.typ
)
739 // NumMethod returns the number of interface methods in the type's method set.
740 func (t
*interfaceType
) NumMethod() int { return len(t
.methods
) }
742 // MethodByName method with the given name in the type's method set.
743 func (t
*interfaceType
) MethodByName(name
string) (m Method
, ok
bool) {
748 for i
:= range t
.methods
{
751 return t
.Method(i
), true
757 // A StructField describes a single field in a struct.
758 type StructField
struct {
759 // Name is the field name.
760 // PkgPath is the package path that qualifies a lower case (unexported)
761 // field name. It is empty for upper case (exported) field names.
762 // See http://golang.org/ref/spec#Uniqueness_of_identifiers
766 Type Type
// field type
767 Tag StructTag
// field tag string
768 Offset
uintptr // offset within struct, in bytes
769 Index
[]int // index sequence for Type.FieldByIndex
770 Anonymous
bool // is an embedded field
773 // A StructTag is the tag string in a struct field.
775 // By convention, tag strings are a concatenation of
776 // optionally space-separated key:"value" pairs.
777 // Each key is a non-empty string consisting of non-control
778 // characters other than space (U+0020 ' '), quote (U+0022 '"'),
779 // and colon (U+003A ':'). Each value is quoted using U+0022 '"'
780 // characters and Go string literal syntax.
781 type StructTag
string
783 // Get returns the value associated with key in the tag string.
784 // If there is no such key in the tag, Get returns the empty string.
785 // If the tag does not have the conventional format, the value
786 // returned by Get is unspecified.
787 func (tag StructTag
) Get(key
string) string {
789 // skip leading space
791 for i
< len(tag
) && tag
[i
] == ' ' {
800 // a space or a quote is a syntax error
802 for i
< len(tag
) && tag
[i
] != ' ' && tag
[i
] != ':' && tag
[i
] != '"' {
805 if i
+1 >= len(tag
) || tag
[i
] != ':' || tag
[i
+1] != '"' {
808 name
:= string(tag
[:i
])
811 // scan quoted string to find value
813 for i
< len(tag
) && tag
[i
] != '"' {
822 qvalue
:= string(tag
[:i
+1])
826 value
, _
:= strconv
.Unquote(qvalue
)
833 // Field returns the i'th struct field.
834 func (t
*structType
) Field(i
int) (f StructField
) {
835 if i
< 0 || i
>= len(t
.fields
) {
839 f
.Type
= toType(p
.typ
)
850 if p
.pkgPath
!= nil {
851 f
.PkgPath
= *p
.pkgPath
854 f
.Tag
= StructTag(*p
.tag
)
858 // NOTE(rsc): This is the only allocation in the interface
859 // presented by a reflect.Type. It would be nice to avoid,
860 // at least in the common cases, but we need to make sure
861 // that misbehaving clients of reflect cannot affect other
862 // uses of reflect. One possibility is CL 5371098, but we
863 // postponed that ugliness until there is a demonstrated
864 // need for the performance. This is issue 2320.
869 // TODO(gri): Should there be an error/bool indicator if the index
870 // is wrong for FieldByIndex?
872 // FieldByIndex returns the nested field corresponding to index.
873 func (t
*structType
) FieldByIndex(index
[]int) (f StructField
) {
874 f
.Type
= toType(&t
.rtype
)
875 for i
, x
:= range index
{
878 if ft
.Kind() == Ptr
&& ft
.Elem().Kind() == Struct
{
888 // A fieldScan represents an item on the fieldByNameFunc scan work list.
889 type fieldScan
struct {
894 // FieldByNameFunc returns the struct field with a name that satisfies the
895 // match function and a boolean to indicate if the field was found.
896 func (t
*structType
) FieldByNameFunc(match
func(string) bool) (result StructField
, ok
bool) {
897 // This uses the same condition that the Go language does: there must be a unique instance
898 // of the match at a given depth level. If there are multiple instances of a match at the
899 // same depth, they annihilate each other and inhibit any possible match at a lower level.
900 // The algorithm is breadth first search, one depth level at a time.
902 // The current and next slices are work queues:
903 // current lists the fields to visit on this depth level,
904 // and next lists the fields on the next lower level.
905 current
:= []fieldScan
{}
906 next
:= []fieldScan
{{typ
: t
}}
908 // nextCount records the number of times an embedded type has been
909 // encountered and considered for queueing in the 'next' slice.
910 // We only queue the first one, but we increment the count on each.
911 // If a struct type T can be reached more than once at a given depth level,
912 // then it annihilates itself and need not be considered at all when we
913 // process that next depth level.
914 var nextCount
map[*structType
]int
916 // visited records the structs that have been considered already.
917 // Embedded pointer fields can create cycles in the graph of
918 // reachable embedded types; visited avoids following those cycles.
919 // It also avoids duplicated effort: if we didn't find the field in an
920 // embedded type T at level 2, we won't find it in one at level 4 either.
921 visited
:= map[*structType
]bool{}
924 current
, next
= next
, current
[:0]
928 // Process all the fields at this depth, now listed in 'current'.
929 // The loop queues embedded fields found in 'next', for processing during the next
930 // iteration. The multiplicity of the 'current' field counts is recorded
931 // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
932 for _
, scan
:= range current
{
935 // We've looked through this type before, at a higher level.
936 // That higher level would shadow the lower level we're now at,
937 // so this one can't be useful to us. Ignore it.
941 for i
:= range t
.fields
{
943 // Find name and type for field f.
949 // Anonymous field of type T or *T.
950 // Name taken from type.
952 if ntyp
.Kind() == Ptr
{
953 ntyp
= ntyp
.Elem().common()
961 if count
[t
] > 1 || ok
{
962 // Name appeared multiple times at this level: annihilate.
963 return StructField
{}, false
967 result
.Index
= append(result
.Index
, scan
.index
...)
968 result
.Index
= append(result
.Index
, i
)
973 // Queue embedded struct fields for processing with next level,
974 // but only if we haven't seen a match yet at this level and only
975 // if the embedded types haven't already been queued.
976 if ok || ntyp
== nil || ntyp
.Kind() != Struct
{
979 ntyp
= toType(ntyp
).common()
980 styp
:= (*structType
)(unsafe
.Pointer(ntyp
))
981 if nextCount
[styp
] > 0 {
982 nextCount
[styp
] = 2 // exact multiple doesn't matter
985 if nextCount
== nil {
986 nextCount
= map[*structType
]int{}
990 nextCount
[styp
] = 2 // exact multiple doesn't matter
993 index
= append(index
, scan
.index
...)
994 index
= append(index
, i
)
995 next
= append(next
, fieldScan
{styp
, index
})
1005 // FieldByName returns the struct field with the given name
1006 // and a boolean to indicate if the field was found.
1007 func (t
*structType
) FieldByName(name
string) (f StructField
, present
bool) {
1008 // Quick check for top-level name, or struct without anonymous fields.
1011 for i
:= range t
.fields
{
1017 if *tf
.name
== name
{
1018 return t
.Field(i
), true
1025 return t
.FieldByNameFunc(func(s
string) bool { return s
== name
})
1028 // TypeOf returns the reflection Type of the value in the interface{}.
1029 // TypeOf(nil) returns nil.
1030 func TypeOf(i
interface{}) Type
{
1031 eface
:= *(*emptyInterface
)(unsafe
.Pointer(&i
))
1032 return toType(eface
.typ
)
1035 // ptrMap is the cache for PtrTo.
1038 m
map[*rtype
]*ptrType
1041 // garbage collection bytecode program for pointer to memory without pointers.
1042 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1043 type ptrDataGC
struct {
1044 width
uintptr // sizeof(ptr)
1045 op
uintptr // _GC_APTR
1047 end
uintptr // _GC_END
1050 var ptrDataGCProg
= ptrDataGC
{
1051 width
: unsafe
.Sizeof((*byte)(nil)),
1057 // garbage collection bytecode program for pointer to memory with pointers.
1058 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1060 width
uintptr // sizeof(ptr)
1061 op
uintptr // _GC_PTR
1063 elemgc unsafe
.Pointer
// element gc type
1064 end
uintptr // _GC_END
1067 // PtrTo returns the pointer type with element t.
1068 // For example, if t represents type Foo, PtrTo(t) represents *Foo.
1069 func PtrTo(t Type
) Type
{
1070 return t
.(*rtype
).ptrTo()
1073 func (t
*rtype
) ptrTo() *rtype
{
1074 if p
:= t
.ptrToThis
; p
!= nil {
1078 // Otherwise, synthesize one.
1079 // This only happens for pointers with no methods.
1080 // We keep the mapping in a map on the side, because
1081 // this operation is rare and a separate map lets us keep
1082 // the type structures in read-only memory.
1084 if m
:= ptrMap
.m
; m
!= nil {
1085 if p
:= m
[t
]; p
!= nil {
1092 if ptrMap
.m
== nil {
1093 ptrMap
.m
= make(map[*rtype
]*ptrType
)
1097 // some other goroutine won the race and created it
1102 s
:= "*" + *t
.string
1104 canonicalTypeLock
.RLock()
1105 r
, ok
:= canonicalType
[s
]
1106 canonicalTypeLock
.RUnlock()
1108 ptrMap
.m
[t
] = (*ptrType
)(unsafe
.Pointer(r
.(*rtype
)))
1113 // initialize p using *byte's ptrType as a prototype.
1115 var iptr
interface{} = (*unsafe
.Pointer
)(nil)
1116 prototype
:= *(**ptrType
)(unsafe
.Pointer(&iptr
))
1121 // For the type structures linked into the binary, the
1122 // compiler provides a good hash of the string.
1123 // Create a good hash for the new string by using
1124 // the FNV-1 hash's mixing function to combine the
1125 // old hash and the new "*".
1126 // p.hash = fnv1(t.hash, '*')
1127 // This is the gccgo version.
1128 p
.hash
= (t
.hash
<< 4) + 9
1130 p
.uncommonType
= nil
1132 p
.zero
= unsafe
.Pointer(&make([]byte, p
.size
)[0])
1135 if t
.kind
&kindNoPointers
!= 0 {
1136 p
.gc
= unsafe
.Pointer(&ptrDataGCProg
)
1138 p
.gc
= unsafe
.Pointer(&ptrGC
{
1147 q
:= canonicalize(&p
.rtype
)
1148 p
= (*ptrType
)(unsafe
.Pointer(q
.(*rtype
)))
1154 // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
1155 func fnv1(x
uint32, list
...byte) uint32 {
1156 for _
, b
:= range list
{
1157 x
= x
*16777619 ^ uint32(b
)
1162 func (t
*rtype
) Implements(u Type
) bool {
1164 panic("reflect: nil type passed to Type.Implements")
1166 if u
.Kind() != Interface
{
1167 panic("reflect: non-interface type passed to Type.Implements")
1169 return implements(u
.(*rtype
), t
)
1172 func (t
*rtype
) AssignableTo(u Type
) bool {
1174 panic("reflect: nil type passed to Type.AssignableTo")
1177 return directlyAssignable(uu
, t
) ||
implements(uu
, t
)
1180 func (t
*rtype
) ConvertibleTo(u Type
) bool {
1182 panic("reflect: nil type passed to Type.ConvertibleTo")
1185 return convertOp(uu
, t
) != nil
1188 func (t
*rtype
) Comparable() bool {
1190 case Bool
, Int
, Int8
, Int16
, Int32
, Int64
,
1191 Uint
, Uint8
, Uint16
, Uint32
, Uint64
, Uintptr
,
1192 Float32
, Float64
, Complex64
, Complex128
,
1193 Chan
, Interface
, Ptr
, String
, UnsafePointer
:
1196 case Func
, Map
, Slice
:
1200 return (*arrayType
)(unsafe
.Pointer(t
)).elem
.Comparable()
1203 tt
:= (*structType
)(unsafe
.Pointer(t
))
1204 for i
:= range tt
.fields
{
1205 if !tt
.fields
[i
].typ
.Comparable() {
1212 panic("reflect: impossible")
1216 // implements returns true if the type V implements the interface type T.
1217 func implements(T
, V
*rtype
) bool {
1218 if T
.Kind() != Interface
{
1221 t
:= (*interfaceType
)(unsafe
.Pointer(T
))
1222 if len(t
.methods
) == 0 {
1226 // The same algorithm applies in both cases, but the
1227 // method tables for an interface type and a concrete type
1228 // are different, so the code is duplicated.
1229 // In both cases the algorithm is a linear scan over the two
1230 // lists - T's methods and V's methods - simultaneously.
1231 // Since method tables are stored in a unique sorted order
1232 // (alphabetical, with no duplicate method names), the scan
1233 // through V's methods must hit a match for each of T's
1234 // methods along the way, or else V does not implement T.
1235 // This lets us run the scan in overall linear time instead of
1236 // the quadratic time a naive search would require.
1237 // See also ../runtime/iface.c.
1238 if V
.Kind() == Interface
{
1239 v
:= (*interfaceType
)(unsafe
.Pointer(V
))
1241 for j
:= 0; j
< len(v
.methods
); j
++ {
1244 if *vm
.name
== *tm
.name
&& (vm
.pkgPath
== tm
.pkgPath ||
(vm
.pkgPath
!= nil && tm
.pkgPath
!= nil && *vm
.pkgPath
== *tm
.pkgPath
)) && toType(vm
.typ
).common() == toType(tm
.typ
).common() {
1245 if i
++; i
>= len(t
.methods
) {
1258 for j
:= 0; j
< len(v
.methods
); j
++ {
1261 if *vm
.name
== *tm
.name
&& (vm
.pkgPath
== tm
.pkgPath ||
(vm
.pkgPath
!= nil && tm
.pkgPath
!= nil && *vm
.pkgPath
== *tm
.pkgPath
)) && toType(vm
.mtyp
).common() == toType(tm
.typ
).common() {
1262 if i
++; i
>= len(t
.methods
) {
1270 // directlyAssignable returns true if a value x of type V can be directly
1271 // assigned (using memmove) to a value of type T.
1272 // http://golang.org/doc/go_spec.html#Assignability
1273 // Ignoring the interface rules (implemented elsewhere)
1274 // and the ideal constant rules (no ideal constants at run time).
1275 func directlyAssignable(T
, V
*rtype
) bool {
1276 // x's type V is identical to T?
1281 // Otherwise at least one of T and V must be unnamed
1282 // and they must have the same kind.
1283 if T
.Name() != "" && V
.Name() != "" || T
.Kind() != V
.Kind() {
1287 // x's type T and V must have identical underlying types.
1288 return haveIdenticalUnderlyingType(T
, V
)
1291 func haveIdenticalUnderlyingType(T
, V
*rtype
) bool {
1297 if kind
!= V
.Kind() {
1301 // Non-composite types of equal kind have same underlying type
1302 // (the predefined instance of the type).
1303 if Bool
<= kind
&& kind
<= Complex128 || kind
== String || kind
== UnsafePointer
{
1310 return T
.Elem() == V
.Elem() && T
.Len() == V
.Len()
1314 // x is a bidirectional channel value, T is a channel type,
1315 // and x's type V and T have identical element types.
1316 if V
.ChanDir() == BothDir
&& T
.Elem() == V
.Elem() {
1320 // Otherwise continue test for identical underlying type.
1321 return V
.ChanDir() == T
.ChanDir() && T
.Elem() == V
.Elem()
1324 t
:= (*funcType
)(unsafe
.Pointer(T
))
1325 v
:= (*funcType
)(unsafe
.Pointer(V
))
1326 if t
.dotdotdot
!= v
.dotdotdot ||
len(t
.in
) != len(v
.in
) ||
len(t
.out
) != len(v
.out
) {
1329 for i
, typ
:= range t
.in
{
1334 for i
, typ
:= range t
.out
{
1335 if typ
!= v
.out
[i
] {
1342 t
:= (*interfaceType
)(unsafe
.Pointer(T
))
1343 v
:= (*interfaceType
)(unsafe
.Pointer(V
))
1344 if len(t
.methods
) == 0 && len(v
.methods
) == 0 {
1347 // Might have the same methods but still
1348 // need a run time conversion.
1352 return T
.Key() == V
.Key() && T
.Elem() == V
.Elem()
1355 return T
.Elem() == V
.Elem()
1358 t
:= (*structType
)(unsafe
.Pointer(T
))
1359 v
:= (*structType
)(unsafe
.Pointer(V
))
1360 if len(t
.fields
) != len(v
.fields
) {
1363 for i
:= range t
.fields
{
1366 if tf
.name
!= vf
.name
&& (tf
.name
== nil || vf
.name
== nil ||
*tf
.name
!= *vf
.name
) {
1369 if tf
.pkgPath
!= vf
.pkgPath
&& (tf
.pkgPath
== nil || vf
.pkgPath
== nil ||
*tf
.pkgPath
!= *vf
.pkgPath
) {
1372 if tf
.typ
!= vf
.typ
{
1375 if tf
.tag
!= vf
.tag
&& (tf
.tag
== nil || vf
.tag
== nil ||
*tf
.tag
!= *vf
.tag
) {
1378 if tf
.offset
!= vf
.offset
{
1388 // The lookupCache caches ChanOf, MapOf, and SliceOf lookups.
1389 var lookupCache
struct {
1391 m
map[cacheKey
]*rtype
1394 // A cacheKey is the key for use in the lookupCache.
1395 // Four values describe any of the types we are looking for:
1396 // type kind, one or two subtypes, and an extra integer.
1397 type cacheKey
struct {
1404 // cacheGet looks for a type under the key k in the lookupCache.
1405 // If it finds one, it returns that type.
1406 // If not, it returns nil with the cache locked.
1407 // The caller is expected to use cachePut to unlock the cache.
1408 func cacheGet(k cacheKey
) Type
{
1410 t
:= lookupCache
.m
[k
]
1411 lookupCache
.RUnlock()
1417 t
= lookupCache
.m
[k
]
1419 lookupCache
.Unlock()
1423 if lookupCache
.m
== nil {
1424 lookupCache
.m
= make(map[cacheKey
]*rtype
)
1430 // cachePut stores the given type in the cache, unlocks the cache,
1431 // and returns the type. It is expected that the cache is locked
1432 // because cacheGet returned nil.
1433 func cachePut(k cacheKey
, t
*rtype
) Type
{
1434 t
= toType(t
).common()
1435 lookupCache
.m
[k
] = t
1436 lookupCache
.Unlock()
1440 // garbage collection bytecode program for chan.
1441 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1442 type chanGC
struct {
1443 width
uintptr // sizeof(map)
1444 op
uintptr // _GC_CHAN_PTR
1446 typ
*rtype
// map type
1447 end
uintptr // _GC_END
1450 // ChanOf returns the channel type with the given direction and element type.
1451 // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
1453 // The gc runtime imposes a limit of 64 kB on channel element types.
1454 // If t's size is equal to or exceeds this limit, ChanOf panics.
1455 func ChanOf(dir ChanDir
, t Type
) Type
{
1459 ckey
:= cacheKey
{Chan
, typ
, nil, uintptr(dir
)}
1460 if ch
:= cacheGet(ckey
); ch
!= nil {
1464 // This restriction is imposed by the gc compiler and the runtime.
1465 if typ
.size
>= 1<<16 {
1466 lookupCache
.Unlock()
1467 panic("reflect.ChanOf: element size too large")
1470 // Look in known types.
1471 // TODO: Precedence when constructing string.
1475 lookupCache
.Unlock()
1476 panic("reflect.ChanOf: invalid dir")
1478 s
= "chan<- " + *typ
.string
1480 s
= "<-chan " + *typ
.string
1482 s
= "chan " + *typ
.string
1485 // Make a channel type.
1486 var ichan
interface{} = (chan unsafe
.Pointer
)(nil)
1487 prototype
:= *(**chanType
)(unsafe
.Pointer(&ichan
))
1492 // gccgo uses a different hash.
1493 // ch.hash = fnv1(typ.hash, 'c', byte(dir))
1495 if dir
&SendDir
!= 0 {
1498 if dir
&RecvDir
!= 0 {
1501 ch
.hash
+= typ
.hash
<< 2
1506 ch
.uncommonType
= nil
1508 ch
.zero
= unsafe
.Pointer(&make([]byte, ch
.size
)[0])
1510 ch
.gc
= unsafe
.Pointer(&chanGC
{
1518 // INCORRECT. Uncomment to check that TestChanOfGC fails when ch.gc is wrong.
1519 // ch.gc = unsafe.Pointer(&badGC{width: ch.size, end: _GC_END})
1521 return cachePut(ckey
, &ch
.rtype
)
1524 func ismapkey(*rtype
) bool // implemented in runtime
1526 // MapOf returns the map type with the given key and element types.
1527 // For example, if k represents int and e represents string,
1528 // MapOf(k, e) represents map[int]string.
1530 // If the key type is not a valid map key type (that is, if it does
1531 // not implement Go's == operator), MapOf panics.
1532 func MapOf(key
, elem Type
) Type
{
1533 ktyp
:= key
.(*rtype
)
1534 etyp
:= elem
.(*rtype
)
1536 if !ismapkey(ktyp
) {
1537 panic("reflect.MapOf: invalid key type " + ktyp
.String())
1541 ckey
:= cacheKey
{Map
, ktyp
, etyp
, 0}
1542 if mt
:= cacheGet(ckey
); mt
!= nil {
1546 // Look in known types.
1547 s
:= "map[" + *ktyp
.string + "]" + *etyp
.string
1550 var imap
interface{} = (map[unsafe
.Pointer
]unsafe
.Pointer
)(nil)
1551 prototype
:= *(**mapType
)(unsafe
.Pointer(&imap
))
1556 // gccgo uses a different hash
1557 // mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
1558 mt
.hash
= ktyp
.hash
+ etyp
.hash
+ 2 + 14
1562 mt
.uncommonType
= nil
1564 mt
.zero
= unsafe
.Pointer(&make([]byte, mt
.size
)[0])
1565 // mt.gc = unsafe.Pointer(&ptrGC{
1566 // width: unsafe.Sizeof(uintptr(0)),
1573 // TODO(cmang): Generate GC data for Map elements.
1574 mt
.gc
= unsafe
.Pointer(&ptrDataGCProg
)
1576 // INCORRECT. Uncomment to check that TestMapOfGC and TestMapOfGCValues
1577 // fail when mt.gc is wrong.
1578 //mt.gc = unsafe.Pointer(&badGC{width: mt.size, end: _GC_END})
1580 return cachePut(ckey
, &mt
.rtype
)
1583 // gcProg is a helper type for generatation of GC pointer info.
1584 type gcProg
struct {
1586 size
uintptr // size of type in bytes
1590 func (gc
*gcProg
) append(v
byte) {
1591 gc
.align(unsafe
.Sizeof(uintptr(0)))
1595 // Appends t's type info to the current program.
1596 func (gc
*gcProg
) appendProg(t
*rtype
) {
1597 gc
.align(uintptr(t
.align
))
1604 panic("reflect: non-pointer type marked as having pointers")
1605 case Ptr
, UnsafePointer
, Chan
, Func
, Map
:
1606 gc
.appendWord(bitsPointer
)
1608 gc
.appendWord(bitsPointer
)
1609 gc
.appendWord(bitsScalar
)
1610 gc
.appendWord(bitsScalar
)
1612 gc
.appendWord(bitsPointer
)
1613 gc
.appendWord(bitsScalar
)
1616 e
:= t
.Elem().common()
1617 for i
:= 0; i
< c
; i
++ {
1621 gc
.appendWord(bitsMultiWord
)
1622 if t
.NumMethod() == 0 {
1623 gc
.appendWord(bitsEface
)
1625 gc
.appendWord(bitsIface
)
1629 for i
:= 0; i
< c
; i
++ {
1630 gc
.appendProg(t
.Field(i
).Type
.common())
1632 gc
.align(uintptr(t
.align
))
1636 func (gc
*gcProg
) appendWord(v
byte) {
1637 ptrsize
:= unsafe
.Sizeof(uintptr(0))
1638 if gc
.size%ptrsize
!= 0 {
1639 panic("reflect: unaligned GC program")
1641 nptr
:= gc
.size
/ ptrsize
1642 for uintptr(len(gc
.gc
)) < nptr
/2+1 {
1643 gc
.gc
= append(gc
.gc
, 0x44) // BitsScalar
1645 gc
.gc
[nptr
/2] &= ^(3 << ((nptr%2
)*4 + 2))
1646 gc
.gc
[nptr
/2] |
= v
<< ((nptr%2
)*4 + 2)
1648 if v
== bitsPointer
{
1653 func (gc
*gcProg
) finalize() (unsafe
.Pointer
, bool) {
1657 ptrsize
:= unsafe
.Sizeof(uintptr(0))
1659 nptr
:= gc
.size
/ ptrsize
1660 for uintptr(len(gc
.gc
)) < nptr
/2+1 {
1661 gc
.gc
= append(gc
.gc
, 0x44) // BitsScalar
1663 // If number of words is odd, repeat the mask twice.
1664 // Compiler does the same.
1666 for i
:= uintptr(0); i
< nptr
; i
++ {
1667 gc
.appendWord(extractGCWord(gc
.gc
, i
))
1670 return unsafe
.Pointer(&gc
.gc
[0]), gc
.hasPtr
1673 func extractGCWord(gc
[]byte, i
uintptr) byte {
1674 return (gc
[i
/2] >> ((i%2
)*4 + 2)) & 3
1677 func (gc
*gcProg
) align(a
uintptr) {
1678 gc
.size
= align(gc
.size
, a
)
1681 // These constants must stay in sync with ../runtime/mgc0.h.
1691 // Make sure these routines stay in sync with ../../runtime/hashmap.go!
1692 // These types exist only for GC, so we only fill out GC relevant info.
1693 // Currently, that's just size and the GC program. We also fill in string
1694 // for possible debugging use.
1701 func bucketOf(ktyp
, etyp
*rtype
) *rtype
{
1702 if ktyp
.size
> maxKeySize
{
1703 ktyp
= PtrTo(ktyp
).(*rtype
)
1705 if etyp
.size
> maxValSize
{
1706 etyp
= PtrTo(etyp
).(*rtype
)
1708 ptrsize
:= unsafe
.Sizeof(uintptr(0))
1712 for i
:= 0; i
< int(bucketSize
*unsafe
.Sizeof(uint8(0))/ptrsize
); i
++ {
1713 gc
.append(bitsScalar
)
1716 for i
:= 0; i
< bucketSize
; i
++ {
1720 for i
:= 0; i
< bucketSize
; i
++ {
1724 gc
.append(bitsPointer
)
1725 if runtime
.GOARCH
== "amd64p32" {
1726 gc
.append(bitsScalar
)
1731 // b.gc[0], _ = gc.finalize()
1732 b
.kind |
= kindGCProg
1733 s
:= "bucket(" + *ktyp
.string + "," + *etyp
.string + ")"
1738 // Take the GC program for "t" and append it to the GC program "gc".
1739 func appendGCProgram(gc
[]uintptr, t
*rtype
) []uintptr {
1741 p
= unsafe
.Pointer(uintptr(p
) + unsafe
.Sizeof(uintptr(0))) // skip size
1745 switch *(*uintptr)(p
) {
1747 // Note: _GC_END not included in append
1749 case _GC_ARRAY_NEXT
:
1751 case _GC_APTR
, _GC_STRING
, _GC_EFACE
, _GC_IFACE
:
1753 case _GC_PTR
, _GC_CALL
, _GC_CHAN_PTR
, _GC_SLICE
:
1755 case _GC_ARRAY_START
, _GC_REGION
:
1758 panic("unknown GC program op for " + *t
.string + ": " + strconv
.FormatUint(*(*uint64)(p
), 10))
1760 for i
:= 0; i
< argcnt
+1; i
++ {
1761 gc
= append(gc
, *(*uintptr)(p
))
1762 p
= unsafe
.Pointer(uintptr(p
) + unsafe
.Sizeof(uintptr(0)))
1767 func hMapOf(bucket
*rtype
) *rtype
{
1768 ptrsize
:= unsafe
.Sizeof(uintptr(0))
1770 // make gc program & compute hmap size
1771 gc
:= make([]uintptr, 1) // first entry is size, filled in at the end
1772 offset
:= unsafe
.Sizeof(uint(0)) // count
1773 offset
+= unsafe
.Sizeof(uint32(0)) // flags
1774 offset
+= unsafe
.Sizeof(uint32(0)) // hash0
1775 offset
+= unsafe
.Sizeof(uint8(0)) // B
1776 offset
+= unsafe
.Sizeof(uint8(0)) // keysize
1777 offset
+= unsafe
.Sizeof(uint8(0)) // valuesize
1778 offset
= (offset
+ 1) / 2 * 2
1779 offset
+= unsafe
.Sizeof(uint16(0)) // bucketsize
1780 offset
= (offset
+ ptrsize
- 1) / ptrsize
* ptrsize
1781 // gc = append(gc, _GC_PTR, offset, uintptr(bucket.gc)) // buckets
1783 // gc = append(gc, _GC_PTR, offset, uintptr(bucket.gc)) // oldbuckets
1785 offset
+= ptrsize
// nevacuate
1786 gc
= append(gc
, _GC_END
)
1791 // h.gc = unsafe.Pointer(&gc[0])
1792 s
:= "hmap(" + *bucket
.string + ")"
1797 // garbage collection bytecode program for slice of non-zero-length values.
1798 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1799 type sliceGC
struct {
1800 width
uintptr // sizeof(slice)
1801 op
uintptr // _GC_SLICE
1803 elemgc unsafe
.Pointer
// element gc program
1804 end
uintptr // _GC_END
1807 // garbage collection bytecode program for slice of zero-length values.
1808 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1809 type sliceEmptyGC
struct {
1810 width
uintptr // sizeof(slice)
1811 op
uintptr // _GC_APTR
1813 end
uintptr // _GC_END
1816 var sliceEmptyGCProg
= sliceEmptyGC
{
1817 width
: unsafe
.Sizeof([]byte(nil)),
1823 // SliceOf returns the slice type with element type t.
1824 // For example, if t represents int, SliceOf(t) represents []int.
1825 func SliceOf(t Type
) Type
{
1829 ckey
:= cacheKey
{Slice
, typ
, nil, 0}
1830 if slice
:= cacheGet(ckey
); slice
!= nil {
1834 // Look in known types.
1835 s
:= "[]" + *typ
.string
1837 // Make a slice type.
1838 var islice
interface{} = ([]unsafe
.Pointer
)(nil)
1839 prototype
:= *(**sliceType
)(unsafe
.Pointer(&islice
))
1840 slice
:= new(sliceType
)
1844 // gccgo uses a different hash.
1845 // slice.hash = fnv1(typ.hash, '[')
1846 slice
.hash
= typ
.hash
+ 1 + 13
1849 slice
.uncommonType
= nil
1850 slice
.ptrToThis
= nil
1851 slice
.zero
= unsafe
.Pointer(&make([]byte, slice
.size
)[0])
1854 slice
.gc
= unsafe
.Pointer(&sliceEmptyGCProg
)
1856 slice
.gc
= unsafe
.Pointer(&sliceGC
{
1865 // INCORRECT. Uncomment to check that TestSliceOfOfGC fails when slice.gc is wrong.
1866 // slice.gc = unsafe.Pointer(&badGC{width: slice.size, end: _GC_END})
1868 return cachePut(ckey
, &slice
.rtype
)
1871 // ArrayOf returns the array type with the given count and element type.
1872 // For example, if t represents int, ArrayOf(5, t) represents [5]int.
1874 // If the resulting type would be larger than the available address space,
1877 // TODO(rsc): Unexported for now. Export once the alg field is set correctly
1878 // for the type. This may require significant work.
1880 // TODO(rsc): TestArrayOf is also disabled. Re-enable.
1881 func arrayOf(count
int, elem Type
) Type
{
1882 typ
:= elem
.(*rtype
)
1883 slice
:= SliceOf(elem
)
1886 ckey
:= cacheKey
{Array
, typ
, nil, uintptr(count
)}
1887 if slice
:= cacheGet(ckey
); slice
!= nil {
1891 // Look in known types.
1892 s
:= "[" + strconv
.Itoa(count
) + "]" + *typ
.string
1894 // Make an array type.
1895 var iarray
interface{} = [1]unsafe
.Pointer
{}
1896 prototype
:= *(**arrayType
)(unsafe
.Pointer(&iarray
))
1897 array
:= new(arrayType
)
1899 // TODO: Set extra kind bits correctly.
1902 // gccgo uses a different hash.
1903 // array.hash = fnv1(typ.hash, '[')
1904 // for n := uint32(count); n > 0; n >>= 8 {
1905 // array.hash = fnv1(array.hash, byte(n))
1907 // array.hash = fnv1(array.hash, ']')
1908 array
.hash
= typ
.hash
+ 1 + 13
1911 max
:= ^uintptr(0) / typ
.size
1912 if uintptr(count
) > max
{
1913 panic("reflect.ArrayOf: array size would exceed virtual address space")
1915 array
.size
= typ
.size
* uintptr(count
)
1916 array
.align
= typ
.align
1917 array
.fieldAlign
= typ
.fieldAlign
1921 array
.uncommonType
= nil
1922 array
.ptrToThis
= nil
1923 array
.zero
= unsafe
.Pointer(&make([]byte, array
.size
)[0])
1924 array
.len = uintptr(count
)
1925 array
.slice
= slice
.(*rtype
)
1927 return cachePut(ckey
, &array
.rtype
)
1930 // toType converts from a *rtype to a Type that can be returned
1931 // to the client of package reflect. In gc, the only concern is that
1932 // a nil *rtype must be replaced by a nil Type, but in gccgo this
1933 // function takes care of ensuring that multiple *rtype for the same
1934 // type are coalesced into a single Type.
1935 var canonicalType
= make(map[string]Type
)
1937 var canonicalTypeLock sync
.RWMutex
1939 func canonicalize(t Type
) Type
{
1944 canonicalTypeLock
.RLock()
1945 if r
, ok
:= canonicalType
[s
]; ok
{
1946 canonicalTypeLock
.RUnlock()
1949 canonicalTypeLock
.RUnlock()
1950 canonicalTypeLock
.Lock()
1951 if r
, ok
:= canonicalType
[s
]; ok
{
1952 canonicalTypeLock
.Unlock()
1955 canonicalType
[s
] = t
1956 canonicalTypeLock
.Unlock()
1960 func toType(p
*rtype
) Type
{
1964 return canonicalize(p
)
1967 // ifaceIndir reports whether t is stored indirectly in an interface value.
1968 func ifaceIndir(t
*rtype
) bool {
1969 return t
.kind
&kindDirectIface
== 0
1972 // Layout matches runtime.BitVector (well enough).
1973 type bitVector
struct {
1974 n
uint32 // number of bits
1978 // append a bit pair to the bitmap.
1979 func (bv
*bitVector
) append2(bits
uint8) {
1980 // assume bv.n is a multiple of 2, since append2 is the only operation.
1982 bv
.data
= append(bv
.data
, 0)
1984 bv
.data
[bv
.n
/8] |
= bits
<< (bv
.n
% 8)
1988 func addTypeBits(bv
*bitVector
, offset
*uintptr, t
*rtype
) {
1989 *offset
= align(*offset
, uintptr(t
.align
))
1990 if t
.kind
&kindNoPointers
!= 0 {
1995 switch Kind(t
.kind
& kindMask
) {
1996 case Chan
, Func
, Map
, Ptr
, Slice
, String
, UnsafePointer
:
1997 // 1 pointer at start of representation
1998 for bv
.n
< 2*uint32(*offset
/uintptr(ptrSize
)) {
1999 bv
.append2(bitsScalar
)
2001 bv
.append2(bitsPointer
)
2005 for bv
.n
< 2*uint32(*offset
/uintptr(ptrSize
)) {
2006 bv
.append2(bitsScalar
)
2008 bv
.append2(bitsPointer
)
2009 bv
.append2(bitsPointer
)
2012 // repeat inner type
2013 tt
:= (*arrayType
)(unsafe
.Pointer(t
))
2014 for i
:= 0; i
< int(tt
.len); i
++ {
2015 addTypeBits(bv
, offset
, tt
.elem
)
2020 tt
:= (*structType
)(unsafe
.Pointer(t
))
2022 for i
:= range tt
.fields
{
2024 off
:= start
+ f
.offset
2025 addTypeBits(bv
, &off
, f
.typ
)