Fix bootstrap/PR63632
[official-gcc.git] / libgo / go / reflect / type.go
blob91697c4b56b608f671ed5e4cedb6fe39e3cf0c83
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.
9 //
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
12 // for that type.
14 // See "The Laws of Reflection" for an introduction to reflection in Go:
15 // http://golang.org/doc/articles/laws_of_reflection.html
16 package reflect
18 import (
19 "runtime"
20 "strconv"
21 "sync"
22 "unsafe"
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.
32 type Type interface {
33 // Methods applicable to all types.
35 // Align returns the alignment in bytes of a value of
36 // this type when allocated in memory.
37 Align() int
39 // FieldAlign returns the alignment in bytes of a value of
40 // this type when used as a field in a struct.
41 FieldAlign() int
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.
51 Method(int) Method
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.
64 NumMethod() int
66 // Name returns the type's name within its package.
67 // It returns an empty string for unnamed types.
68 Name() string
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.
74 PkgPath() string
76 // Size returns the number of bytes needed to store
77 // a value of the given type; it is analogous to unsafe.Sizeof.
78 Size() uintptr
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.
85 String() string
87 // Used internally by gccgo--the string retaining quoting.
88 rawString() string
90 // Kind returns the specific kind of this type.
91 Kind() Kind
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 // Methods applicable only to some types, depending on Kind.
103 // The methods allowed for each kind are:
105 // Int*, Uint*, Float*, Complex*: Bits
106 // Array: Elem, Len
107 // Chan: ChanDir, Elem
108 // Func: In, NumIn, Out, NumOut, IsVariadic.
109 // Map: Key, Elem
110 // Ptr: Elem
111 // Slice: Elem
112 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
114 // Bits returns the size of the type in bits.
115 // It panics if the type's Kind is not one of the
116 // sized or unsized Int, Uint, Float, or Complex kinds.
117 Bits() int
119 // ChanDir returns a channel type's direction.
120 // It panics if the type's Kind is not Chan.
121 ChanDir() ChanDir
123 // IsVariadic returns true if a function type's final input parameter
124 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's
125 // implicit actual type []T.
127 // For concreteness, if t represents func(x int, y ... float64), then
129 // t.NumIn() == 2
130 // t.In(0) is the reflect.Type for "int"
131 // t.In(1) is the reflect.Type for "[]float64"
132 // t.IsVariadic() == true
134 // IsVariadic panics if the type's Kind is not Func.
135 IsVariadic() bool
137 // Elem returns a type's element type.
138 // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
139 Elem() Type
141 // Field returns a struct type's i'th field.
142 // It panics if the type's Kind is not Struct.
143 // It panics if i is not in the range [0, NumField()).
144 Field(i int) StructField
146 // FieldByIndex returns the nested field corresponding
147 // to the index sequence. It is equivalent to calling Field
148 // successively for each index i.
149 // It panics if the type's Kind is not Struct.
150 FieldByIndex(index []int) StructField
152 // FieldByName returns the struct field with the given name
153 // and a boolean indicating if the field was found.
154 FieldByName(name string) (StructField, bool)
156 // FieldByNameFunc returns the first struct field with a name
157 // that satisfies the match function and a boolean indicating if
158 // the field was found.
159 FieldByNameFunc(match func(string) bool) (StructField, bool)
161 // In returns the type of a function type's i'th input parameter.
162 // It panics if the type's Kind is not Func.
163 // It panics if i is not in the range [0, NumIn()).
164 In(i int) Type
166 // Key returns a map type's key type.
167 // It panics if the type's Kind is not Map.
168 Key() Type
170 // Len returns an array type's length.
171 // It panics if the type's Kind is not Array.
172 Len() int
174 // NumField returns a struct type's field count.
175 // It panics if the type's Kind is not Struct.
176 NumField() int
178 // NumIn returns a function type's input parameter count.
179 // It panics if the type's Kind is not Func.
180 NumIn() int
182 // NumOut returns a function type's output parameter count.
183 // It panics if the type's Kind is not Func.
184 NumOut() int
186 // Out returns the type of a function type's i'th output parameter.
187 // It panics if the type's Kind is not Func.
188 // It panics if i is not in the range [0, NumOut()).
189 Out(i int) Type
191 common() *rtype
192 uncommon() *uncommonType
195 // BUG(rsc): FieldByName and related functions consider struct field names to be equal
196 // if the names are equal, even if they are unexported names originating
197 // in different packages. The practical effect of this is that the result of
198 // t.FieldByName("x") is not well defined if the struct type t contains
199 // multiple fields named x (embedded from different packages).
200 // FieldByName may return one of the fields named x or may report that there are none.
201 // See golang.org/issue/4876 for more details.
204 * These data structures are known to the compiler (../../cmd/gc/reflect.c).
205 * A few are known to ../runtime/type.go to convey to debuggers.
206 * They are also known to ../runtime/type.h.
209 // A Kind represents the specific kind of type that a Type represents.
210 // The zero Kind is not a valid kind.
211 type Kind uint
213 const (
214 Invalid Kind = iota
215 Bool
217 Int8
218 Int16
219 Int32
220 Int64
221 Uint
222 Uint8
223 Uint16
224 Uint32
225 Uint64
226 Uintptr
227 Float32
228 Float64
229 Complex64
230 Complex128
231 Array
232 Chan
233 Func
234 Interface
237 Slice
238 String
239 Struct
240 UnsafePointer
243 // rtype is the common implementation of most values.
244 // It is embedded in other, public struct types, but always
245 // with a unique tag like `reflect:"array"` or `reflect:"ptr"`
246 // so that code cannot convert from, say, *arrayType to *ptrType.
247 type rtype struct {
248 kind uint8 // enumeration for C
249 align int8 // alignment of variable with this type
250 fieldAlign uint8 // alignment of struct field with this type
251 _ uint8 // unused/padding
252 size uintptr // size in bytes
253 hash uint32 // hash of type; avoids computation in hash tables
255 hashfn uintptr // hash function code
256 equalfn uintptr // equality function code
258 gc unsafe.Pointer // garbage collection data
259 string *string // string form; unnecessary but undeniably useful
260 *uncommonType // (relatively) uncommon fields
261 ptrToThis *rtype // type for pointer to this type, if used in binary or has methods
262 zero unsafe.Pointer // pointer to zero value
265 // Method on non-interface type
266 type method struct {
267 name *string // name of method
268 pkgPath *string // nil for exported Names; otherwise import path
269 mtyp *rtype // method type (without receiver)
270 typ *rtype // .(*FuncType) underneath (with receiver)
271 tfn unsafe.Pointer // fn used for normal method call
274 // uncommonType is present only for types with names or methods
275 // (if T is a named type, the uncommonTypes for T and *T have methods).
276 // Using a pointer to this struct reduces the overall size required
277 // to describe an unnamed type with no methods.
278 type uncommonType struct {
279 name *string // name of type
280 pkgPath *string // import path; nil for built-in types like int, string
281 methods []method // methods associated with type
284 // ChanDir represents a channel type's direction.
285 type ChanDir int
287 const (
288 RecvDir ChanDir = 1 << iota // <-chan
289 SendDir // chan<-
290 BothDir = RecvDir | SendDir // chan
293 // arrayType represents a fixed array type.
294 type arrayType struct {
295 rtype `reflect:"array"`
296 elem *rtype // array element type
297 slice *rtype // slice type
298 len uintptr
301 // chanType represents a channel type.
302 type chanType struct {
303 rtype `reflect:"chan"`
304 elem *rtype // channel element type
305 dir uintptr // channel direction (ChanDir)
308 // funcType represents a function type.
309 type funcType struct {
310 rtype `reflect:"func"`
311 dotdotdot bool // last input parameter is ...
312 in []*rtype // input parameter types
313 out []*rtype // output parameter types
316 // imethod represents a method on an interface type
317 type imethod struct {
318 name *string // name of method
319 pkgPath *string // nil for exported Names; otherwise import path
320 typ *rtype // .(*FuncType) underneath
323 // interfaceType represents an interface type.
324 type interfaceType struct {
325 rtype `reflect:"interface"`
326 methods []imethod // sorted by hash
329 // mapType represents a map type.
330 type mapType struct {
331 rtype `reflect:"map"`
332 key *rtype // map key type
333 elem *rtype // map element (value) type
334 // bucket *rtype // internal bucket structure
335 // hmap *rtype // internal map header
338 // ptrType represents a pointer type.
339 type ptrType struct {
340 rtype `reflect:"ptr"`
341 elem *rtype // pointer element (pointed at) type
344 // sliceType represents a slice type.
345 type sliceType struct {
346 rtype `reflect:"slice"`
347 elem *rtype // slice element type
350 // Struct field
351 type structField struct {
352 name *string // nil for embedded fields
353 pkgPath *string // nil for exported Names; otherwise import path
354 typ *rtype // type of field
355 tag *string // nil if no tag
356 offset uintptr // byte offset of field within struct
359 // structType represents a struct type.
360 type structType struct {
361 rtype `reflect:"struct"`
362 fields []structField // sorted by offset
365 // NOTE: These are copied from ../runtime/mgc0.h.
366 // They must be kept in sync.
367 const (
368 _GC_END = iota
369 _GC_PTR
370 _GC_APTR
371 _GC_ARRAY_START
372 _GC_ARRAY_NEXT
373 _GC_CALL
374 _GC_CHAN_PTR
375 _GC_STRING
376 _GC_EFACE
377 _GC_IFACE
378 _GC_SLICE
379 _GC_REGION
380 _GC_NUM_INSTR
384 * The compiler knows the exact layout of all the data structures above.
385 * The compiler does not know about the data structures and methods below.
388 // Method represents a single method.
389 type Method struct {
390 // Name is the method name.
391 // PkgPath is the package path that qualifies a lower case (unexported)
392 // method name. It is empty for upper case (exported) method names.
393 // The combination of PkgPath and Name uniquely identifies a method
394 // in a method set.
395 // See http://golang.org/ref/spec#Uniqueness_of_identifiers
396 Name string
397 PkgPath string
399 Type Type // method type
400 Func Value // func with receiver as first argument
401 Index int // index for Type.Method
404 // High bit says whether type has
405 // embedded pointers,to help garbage collector.
406 const (
407 kindMask = 0x7f
408 kindNoPointers = 0x80
411 func (k Kind) String() string {
412 if int(k) < len(kindNames) {
413 return kindNames[k]
415 return "kind" + strconv.Itoa(int(k))
418 var kindNames = []string{
419 Invalid: "invalid",
420 Bool: "bool",
421 Int: "int",
422 Int8: "int8",
423 Int16: "int16",
424 Int32: "int32",
425 Int64: "int64",
426 Uint: "uint",
427 Uint8: "uint8",
428 Uint16: "uint16",
429 Uint32: "uint32",
430 Uint64: "uint64",
431 Uintptr: "uintptr",
432 Float32: "float32",
433 Float64: "float64",
434 Complex64: "complex64",
435 Complex128: "complex128",
436 Array: "array",
437 Chan: "chan",
438 Func: "func",
439 Interface: "interface",
440 Map: "map",
441 Ptr: "ptr",
442 Slice: "slice",
443 String: "string",
444 Struct: "struct",
445 UnsafePointer: "unsafe.Pointer",
448 func (t *uncommonType) uncommon() *uncommonType {
449 return t
452 func (t *uncommonType) PkgPath() string {
453 if t == nil || t.pkgPath == nil {
454 return ""
456 return *t.pkgPath
459 func (t *uncommonType) Name() string {
460 if t == nil || t.name == nil {
461 return ""
463 return *t.name
466 func (t *rtype) rawString() string { return *t.string }
468 func (t *rtype) String() string {
469 // For gccgo, strip out quoted strings.
470 s := *t.string
471 var q bool
472 r := make([]byte, len(s))
473 j := 0
474 for i := 0; i < len(s); i++ {
475 if s[i] == '\t' {
476 q = !q
477 } else if !q {
478 r[j] = s[i]
482 return string(r[:j])
485 func (t *rtype) Size() uintptr { return t.size }
487 func (t *rtype) Bits() int {
488 if t == nil {
489 panic("reflect: Bits of nil Type")
491 k := t.Kind()
492 if k < Int || k > Complex128 {
493 panic("reflect: Bits of non-arithmetic Type " + t.String())
495 return int(t.size) * 8
498 func (t *rtype) Align() int { return int(t.align) }
500 func (t *rtype) FieldAlign() int { return int(t.fieldAlign) }
502 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
504 func (t *rtype) pointers() bool { return t.kind&kindNoPointers == 0 }
506 func (t *rtype) common() *rtype { return t }
508 func (t *uncommonType) Method(i int) (m Method) {
509 if t == nil || i < 0 || i >= len(t.methods) {
510 panic("reflect: Method index out of range")
512 p := &t.methods[i]
513 if p.name != nil {
514 m.Name = *p.name
516 fl := flag(Func) << flagKindShift
517 if p.pkgPath != nil {
518 m.PkgPath = *p.pkgPath
519 fl |= flagRO
521 mt := p.typ
522 m.Type = toType(mt)
523 x := new(unsafe.Pointer)
524 *x = unsafe.Pointer(&p.tfn)
525 m.Func = Value{mt, unsafe.Pointer(x) /* 0, */, fl | flagIndir | flagMethodFn}
526 m.Index = i
527 return
530 func (t *uncommonType) NumMethod() int {
531 if t == nil {
532 return 0
534 return len(t.methods)
537 func (t *uncommonType) MethodByName(name string) (m Method, ok bool) {
538 if t == nil {
539 return
541 var p *method
542 for i := range t.methods {
543 p = &t.methods[i]
544 if p.name != nil && *p.name == name {
545 return t.Method(i), true
548 return
551 // TODO(rsc): 6g supplies these, but they are not
552 // as efficient as they could be: they have commonType
553 // as the receiver instead of *rtype.
554 func (t *rtype) NumMethod() int {
555 if t.Kind() == Interface {
556 tt := (*interfaceType)(unsafe.Pointer(t))
557 return tt.NumMethod()
559 return t.uncommonType.NumMethod()
562 func (t *rtype) Method(i int) (m Method) {
563 if t.Kind() == Interface {
564 tt := (*interfaceType)(unsafe.Pointer(t))
565 return tt.Method(i)
567 return t.uncommonType.Method(i)
570 func (t *rtype) MethodByName(name string) (m Method, ok bool) {
571 if t.Kind() == Interface {
572 tt := (*interfaceType)(unsafe.Pointer(t))
573 return tt.MethodByName(name)
575 return t.uncommonType.MethodByName(name)
578 func (t *rtype) PkgPath() string {
579 return t.uncommonType.PkgPath()
582 func (t *rtype) Name() string {
583 return t.uncommonType.Name()
586 func (t *rtype) ChanDir() ChanDir {
587 if t.Kind() != Chan {
588 panic("reflect: ChanDir of non-chan type")
590 tt := (*chanType)(unsafe.Pointer(t))
591 return ChanDir(tt.dir)
594 func (t *rtype) IsVariadic() bool {
595 if t.Kind() != Func {
596 panic("reflect: IsVariadic of non-func type")
598 tt := (*funcType)(unsafe.Pointer(t))
599 return tt.dotdotdot
602 func (t *rtype) Elem() Type {
603 switch t.Kind() {
604 case Array:
605 tt := (*arrayType)(unsafe.Pointer(t))
606 return toType(tt.elem)
607 case Chan:
608 tt := (*chanType)(unsafe.Pointer(t))
609 return toType(tt.elem)
610 case Map:
611 tt := (*mapType)(unsafe.Pointer(t))
612 return toType(tt.elem)
613 case Ptr:
614 tt := (*ptrType)(unsafe.Pointer(t))
615 return toType(tt.elem)
616 case Slice:
617 tt := (*sliceType)(unsafe.Pointer(t))
618 return toType(tt.elem)
620 panic("reflect: Elem of invalid type")
623 func (t *rtype) Field(i int) StructField {
624 if t.Kind() != Struct {
625 panic("reflect: Field of non-struct type")
627 tt := (*structType)(unsafe.Pointer(t))
628 return tt.Field(i)
631 func (t *rtype) FieldByIndex(index []int) StructField {
632 if t.Kind() != Struct {
633 panic("reflect: FieldByIndex of non-struct type")
635 tt := (*structType)(unsafe.Pointer(t))
636 return tt.FieldByIndex(index)
639 func (t *rtype) FieldByName(name string) (StructField, bool) {
640 if t.Kind() != Struct {
641 panic("reflect: FieldByName of non-struct type")
643 tt := (*structType)(unsafe.Pointer(t))
644 return tt.FieldByName(name)
647 func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
648 if t.Kind() != Struct {
649 panic("reflect: FieldByNameFunc of non-struct type")
651 tt := (*structType)(unsafe.Pointer(t))
652 return tt.FieldByNameFunc(match)
655 func (t *rtype) In(i int) Type {
656 if t.Kind() != Func {
657 panic("reflect: In of non-func type")
659 tt := (*funcType)(unsafe.Pointer(t))
660 return toType(tt.in[i])
663 func (t *rtype) Key() Type {
664 if t.Kind() != Map {
665 panic("reflect: Key of non-map type")
667 tt := (*mapType)(unsafe.Pointer(t))
668 return toType(tt.key)
671 func (t *rtype) Len() int {
672 if t.Kind() != Array {
673 panic("reflect: Len of non-array type")
675 tt := (*arrayType)(unsafe.Pointer(t))
676 return int(tt.len)
679 func (t *rtype) NumField() int {
680 if t.Kind() != Struct {
681 panic("reflect: NumField of non-struct type")
683 tt := (*structType)(unsafe.Pointer(t))
684 return len(tt.fields)
687 func (t *rtype) NumIn() int {
688 if t.Kind() != Func {
689 panic("reflect: NumIn of non-func type")
691 tt := (*funcType)(unsafe.Pointer(t))
692 return len(tt.in)
695 func (t *rtype) NumOut() int {
696 if t.Kind() != Func {
697 panic("reflect: NumOut of non-func type")
699 tt := (*funcType)(unsafe.Pointer(t))
700 return len(tt.out)
703 func (t *rtype) Out(i int) Type {
704 if t.Kind() != Func {
705 panic("reflect: Out of non-func type")
707 tt := (*funcType)(unsafe.Pointer(t))
708 return toType(tt.out[i])
711 func (d ChanDir) String() string {
712 switch d {
713 case SendDir:
714 return "chan<-"
715 case RecvDir:
716 return "<-chan"
717 case BothDir:
718 return "chan"
720 return "ChanDir" + strconv.Itoa(int(d))
723 // Method returns the i'th method in the type's method set.
724 func (t *interfaceType) Method(i int) (m Method) {
725 if i < 0 || i >= len(t.methods) {
726 return
728 p := &t.methods[i]
729 m.Name = *p.name
730 if p.pkgPath != nil {
731 m.PkgPath = *p.pkgPath
733 m.Type = toType(p.typ)
734 m.Index = i
735 return
738 // NumMethod returns the number of interface methods in the type's method set.
739 func (t *interfaceType) NumMethod() int { return len(t.methods) }
741 // MethodByName method with the given name in the type's method set.
742 func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
743 if t == nil {
744 return
746 var p *imethod
747 for i := range t.methods {
748 p = &t.methods[i]
749 if *p.name == name {
750 return t.Method(i), true
753 return
756 // A StructField describes a single field in a struct.
757 type StructField struct {
758 // Name is the field name.
759 // PkgPath is the package path that qualifies a lower case (unexported)
760 // field name. It is empty for upper case (exported) field names.
761 // See http://golang.org/ref/spec#Uniqueness_of_identifiers
762 Name string
763 PkgPath string
765 Type Type // field type
766 Tag StructTag // field tag string
767 Offset uintptr // offset within struct, in bytes
768 Index []int // index sequence for Type.FieldByIndex
769 Anonymous bool // is an embedded field
772 // A StructTag is the tag string in a struct field.
774 // By convention, tag strings are a concatenation of
775 // optionally space-separated key:"value" pairs.
776 // Each key is a non-empty string consisting of non-control
777 // characters other than space (U+0020 ' '), quote (U+0022 '"'),
778 // and colon (U+003A ':'). Each value is quoted using U+0022 '"'
779 // characters and Go string literal syntax.
780 type StructTag string
782 // Get returns the value associated with key in the tag string.
783 // If there is no such key in the tag, Get returns the empty string.
784 // If the tag does not have the conventional format, the value
785 // returned by Get is unspecified.
786 func (tag StructTag) Get(key string) string {
787 for tag != "" {
788 // skip leading space
789 i := 0
790 for i < len(tag) && tag[i] == ' ' {
793 tag = tag[i:]
794 if tag == "" {
795 break
798 // scan to colon.
799 // a space or a quote is a syntax error
800 i = 0
801 for i < len(tag) && tag[i] != ' ' && tag[i] != ':' && tag[i] != '"' {
804 if i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
805 break
807 name := string(tag[:i])
808 tag = tag[i+1:]
810 // scan quoted string to find value
811 i = 1
812 for i < len(tag) && tag[i] != '"' {
813 if tag[i] == '\\' {
818 if i >= len(tag) {
819 break
821 qvalue := string(tag[:i+1])
822 tag = tag[i+1:]
824 if key == name {
825 value, _ := strconv.Unquote(qvalue)
826 return value
829 return ""
832 // Field returns the i'th struct field.
833 func (t *structType) Field(i int) (f StructField) {
834 if i < 0 || i >= len(t.fields) {
835 return
837 p := &t.fields[i]
838 f.Type = toType(p.typ)
839 if p.name != nil {
840 f.Name = *p.name
841 } else {
842 t := f.Type
843 if t.Kind() == Ptr {
844 t = t.Elem()
846 f.Name = t.Name()
847 f.Anonymous = true
849 if p.pkgPath != nil {
850 f.PkgPath = *p.pkgPath
852 if p.tag != nil {
853 f.Tag = StructTag(*p.tag)
855 f.Offset = p.offset
857 // NOTE(rsc): This is the only allocation in the interface
858 // presented by a reflect.Type. It would be nice to avoid,
859 // at least in the common cases, but we need to make sure
860 // that misbehaving clients of reflect cannot affect other
861 // uses of reflect. One possibility is CL 5371098, but we
862 // postponed that ugliness until there is a demonstrated
863 // need for the performance. This is issue 2320.
864 f.Index = []int{i}
865 return
868 // TODO(gri): Should there be an error/bool indicator if the index
869 // is wrong for FieldByIndex?
871 // FieldByIndex returns the nested field corresponding to index.
872 func (t *structType) FieldByIndex(index []int) (f StructField) {
873 f.Type = toType(&t.rtype)
874 for i, x := range index {
875 if i > 0 {
876 ft := f.Type
877 if ft.Kind() == Ptr && ft.Elem().Kind() == Struct {
878 ft = ft.Elem()
880 f.Type = ft
882 f = f.Type.Field(x)
884 return
887 // A fieldScan represents an item on the fieldByNameFunc scan work list.
888 type fieldScan struct {
889 typ *structType
890 index []int
893 // FieldByNameFunc returns the struct field with a name that satisfies the
894 // match function and a boolean to indicate if the field was found.
895 func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) {
896 // This uses the same condition that the Go language does: there must be a unique instance
897 // of the match at a given depth level. If there are multiple instances of a match at the
898 // same depth, they annihilate each other and inhibit any possible match at a lower level.
899 // The algorithm is breadth first search, one depth level at a time.
901 // The current and next slices are work queues:
902 // current lists the fields to visit on this depth level,
903 // and next lists the fields on the next lower level.
904 current := []fieldScan{}
905 next := []fieldScan{{typ: t}}
907 // nextCount records the number of times an embedded type has been
908 // encountered and considered for queueing in the 'next' slice.
909 // We only queue the first one, but we increment the count on each.
910 // If a struct type T can be reached more than once at a given depth level,
911 // then it annihilates itself and need not be considered at all when we
912 // process that next depth level.
913 var nextCount map[*structType]int
915 // visited records the structs that have been considered already.
916 // Embedded pointer fields can create cycles in the graph of
917 // reachable embedded types; visited avoids following those cycles.
918 // It also avoids duplicated effort: if we didn't find the field in an
919 // embedded type T at level 2, we won't find it in one at level 4 either.
920 visited := map[*structType]bool{}
922 for len(next) > 0 {
923 current, next = next, current[:0]
924 count := nextCount
925 nextCount = nil
927 // Process all the fields at this depth, now listed in 'current'.
928 // The loop queues embedded fields found in 'next', for processing during the next
929 // iteration. The multiplicity of the 'current' field counts is recorded
930 // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
931 for _, scan := range current {
932 t := scan.typ
933 if visited[t] {
934 // We've looked through this type before, at a higher level.
935 // That higher level would shadow the lower level we're now at,
936 // so this one can't be useful to us. Ignore it.
937 continue
939 visited[t] = true
940 for i := range t.fields {
941 f := &t.fields[i]
942 // Find name and type for field f.
943 var fname string
944 var ntyp *rtype
945 if f.name != nil {
946 fname = *f.name
947 } else {
948 // Anonymous field of type T or *T.
949 // Name taken from type.
950 ntyp = f.typ
951 if ntyp.Kind() == Ptr {
952 ntyp = ntyp.Elem().common()
954 fname = ntyp.Name()
957 // Does it match?
958 if match(fname) {
959 // Potential match
960 if count[t] > 1 || ok {
961 // Name appeared multiple times at this level: annihilate.
962 return StructField{}, false
964 result = t.Field(i)
965 result.Index = nil
966 result.Index = append(result.Index, scan.index...)
967 result.Index = append(result.Index, i)
968 ok = true
969 continue
972 // Queue embedded struct fields for processing with next level,
973 // but only if we haven't seen a match yet at this level and only
974 // if the embedded types haven't already been queued.
975 if ok || ntyp == nil || ntyp.Kind() != Struct {
976 continue
978 ntyp = toType(ntyp).common()
979 styp := (*structType)(unsafe.Pointer(ntyp))
980 if nextCount[styp] > 0 {
981 nextCount[styp] = 2 // exact multiple doesn't matter
982 continue
984 if nextCount == nil {
985 nextCount = map[*structType]int{}
987 nextCount[styp] = 1
988 if count[t] > 1 {
989 nextCount[styp] = 2 // exact multiple doesn't matter
991 var index []int
992 index = append(index, scan.index...)
993 index = append(index, i)
994 next = append(next, fieldScan{styp, index})
997 if ok {
998 break
1001 return
1004 // FieldByName returns the struct field with the given name
1005 // and a boolean to indicate if the field was found.
1006 func (t *structType) FieldByName(name string) (f StructField, present bool) {
1007 // Quick check for top-level name, or struct without anonymous fields.
1008 hasAnon := false
1009 if name != "" {
1010 for i := range t.fields {
1011 tf := &t.fields[i]
1012 if tf.name == nil {
1013 hasAnon = true
1014 continue
1016 if *tf.name == name {
1017 return t.Field(i), true
1021 if !hasAnon {
1022 return
1024 return t.FieldByNameFunc(func(s string) bool { return s == name })
1027 // TypeOf returns the reflection Type of the value in the interface{}.
1028 // TypeOf(nil) returns nil.
1029 func TypeOf(i interface{}) Type {
1030 eface := *(*emptyInterface)(unsafe.Pointer(&i))
1031 return toType(eface.typ)
1034 // ptrMap is the cache for PtrTo.
1035 var ptrMap struct {
1036 sync.RWMutex
1037 m map[*rtype]*ptrType
1040 // garbage collection bytecode program for pointer to memory without pointers.
1041 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1042 type ptrDataGC struct {
1043 width uintptr // sizeof(ptr)
1044 op uintptr // _GC_APTR
1045 off uintptr // 0
1046 end uintptr // _GC_END
1049 var ptrDataGCProg = ptrDataGC{
1050 width: unsafe.Sizeof((*byte)(nil)),
1051 op: _GC_APTR,
1052 off: 0,
1053 end: _GC_END,
1056 // garbage collection bytecode program for pointer to memory with pointers.
1057 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1058 type ptrGC struct {
1059 width uintptr // sizeof(ptr)
1060 op uintptr // _GC_PTR
1061 off uintptr // 0
1062 elemgc unsafe.Pointer // element gc type
1063 end uintptr // _GC_END
1066 // PtrTo returns the pointer type with element t.
1067 // For example, if t represents type Foo, PtrTo(t) represents *Foo.
1068 func PtrTo(t Type) Type {
1069 return t.(*rtype).ptrTo()
1072 func (t *rtype) ptrTo() *rtype {
1073 if p := t.ptrToThis; p != nil {
1074 return p
1077 // Otherwise, synthesize one.
1078 // This only happens for pointers with no methods.
1079 // We keep the mapping in a map on the side, because
1080 // this operation is rare and a separate map lets us keep
1081 // the type structures in read-only memory.
1082 ptrMap.RLock()
1083 if m := ptrMap.m; m != nil {
1084 if p := m[t]; p != nil {
1085 ptrMap.RUnlock()
1086 return &p.rtype
1089 ptrMap.RUnlock()
1090 ptrMap.Lock()
1091 if ptrMap.m == nil {
1092 ptrMap.m = make(map[*rtype]*ptrType)
1094 p := ptrMap.m[t]
1095 if p != nil {
1096 // some other goroutine won the race and created it
1097 ptrMap.Unlock()
1098 return &p.rtype
1101 s := "*" + *t.string
1103 canonicalTypeLock.RLock()
1104 r, ok := canonicalType[s]
1105 canonicalTypeLock.RUnlock()
1106 if ok {
1107 ptrMap.m[t] = (*ptrType)(unsafe.Pointer(r.(*rtype)))
1108 ptrMap.Unlock()
1109 return r.(*rtype)
1112 // initialize p using *byte's ptrType as a prototype.
1113 p = new(ptrType)
1114 var iptr interface{} = (*unsafe.Pointer)(nil)
1115 prototype := *(**ptrType)(unsafe.Pointer(&iptr))
1116 *p = *prototype
1118 p.string = &s
1120 // For the type structures linked into the binary, the
1121 // compiler provides a good hash of the string.
1122 // Create a good hash for the new string by using
1123 // the FNV-1 hash's mixing function to combine the
1124 // old hash and the new "*".
1125 // p.hash = fnv1(t.hash, '*')
1126 // This is the gccgo version.
1127 p.hash = (t.hash << 4) + 9
1129 p.uncommonType = nil
1130 p.ptrToThis = nil
1131 p.zero = unsafe.Pointer(&make([]byte, p.size)[0])
1132 p.elem = t
1134 if t.kind&kindNoPointers != 0 {
1135 p.gc = unsafe.Pointer(&ptrDataGCProg)
1136 } else {
1137 p.gc = unsafe.Pointer(&ptrGC{
1138 width: p.size,
1139 op: _GC_PTR,
1140 off: 0,
1141 elemgc: t.gc,
1142 end: _GC_END,
1146 q := canonicalize(&p.rtype)
1147 p = (*ptrType)(unsafe.Pointer(q.(*rtype)))
1149 ptrMap.m[t] = p
1150 ptrMap.Unlock()
1151 return &p.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)
1159 return x
1162 func (t *rtype) Implements(u Type) bool {
1163 if u == nil {
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 {
1173 if u == nil {
1174 panic("reflect: nil type passed to Type.AssignableTo")
1176 uu := u.(*rtype)
1177 return directlyAssignable(uu, t) || implements(uu, t)
1180 func (t *rtype) ConvertibleTo(u Type) bool {
1181 if u == nil {
1182 panic("reflect: nil type passed to Type.ConvertibleTo")
1184 uu := u.(*rtype)
1185 return convertOp(uu, t) != nil
1188 // implements returns true if the type V implements the interface type T.
1189 func implements(T, V *rtype) bool {
1190 if T.Kind() != Interface {
1191 return false
1193 t := (*interfaceType)(unsafe.Pointer(T))
1194 if len(t.methods) == 0 {
1195 return true
1198 // The same algorithm applies in both cases, but the
1199 // method tables for an interface type and a concrete type
1200 // are different, so the code is duplicated.
1201 // In both cases the algorithm is a linear scan over the two
1202 // lists - T's methods and V's methods - simultaneously.
1203 // Since method tables are stored in a unique sorted order
1204 // (alphabetical, with no duplicate method names), the scan
1205 // through V's methods must hit a match for each of T's
1206 // methods along the way, or else V does not implement T.
1207 // This lets us run the scan in overall linear time instead of
1208 // the quadratic time a naive search would require.
1209 // See also ../runtime/iface.c.
1210 if V.Kind() == Interface {
1211 v := (*interfaceType)(unsafe.Pointer(V))
1212 i := 0
1213 for j := 0; j < len(v.methods); j++ {
1214 tm := &t.methods[i]
1215 vm := &v.methods[j]
1216 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() {
1217 if i++; i >= len(t.methods) {
1218 return true
1222 return false
1225 v := V.uncommon()
1226 if v == nil {
1227 return false
1229 i := 0
1230 for j := 0; j < len(v.methods); j++ {
1231 tm := &t.methods[i]
1232 vm := &v.methods[j]
1233 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() {
1234 if i++; i >= len(t.methods) {
1235 return true
1239 return false
1242 // directlyAssignable returns true if a value x of type V can be directly
1243 // assigned (using memmove) to a value of type T.
1244 // http://golang.org/doc/go_spec.html#Assignability
1245 // Ignoring the interface rules (implemented elsewhere)
1246 // and the ideal constant rules (no ideal constants at run time).
1247 func directlyAssignable(T, V *rtype) bool {
1248 // x's type V is identical to T?
1249 if T == V {
1250 return true
1253 // Otherwise at least one of T and V must be unnamed
1254 // and they must have the same kind.
1255 if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() {
1256 return false
1259 // x's type T and V must have identical underlying types.
1260 return haveIdenticalUnderlyingType(T, V)
1263 func haveIdenticalUnderlyingType(T, V *rtype) bool {
1264 if T == V {
1265 return true
1268 kind := T.Kind()
1269 if kind != V.Kind() {
1270 return false
1273 // Non-composite types of equal kind have same underlying type
1274 // (the predefined instance of the type).
1275 if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
1276 return true
1279 // Composite types.
1280 switch kind {
1281 case Array:
1282 return T.Elem() == V.Elem() && T.Len() == V.Len()
1284 case Chan:
1285 // Special case:
1286 // x is a bidirectional channel value, T is a channel type,
1287 // and x's type V and T have identical element types.
1288 if V.ChanDir() == BothDir && T.Elem() == V.Elem() {
1289 return true
1292 // Otherwise continue test for identical underlying type.
1293 return V.ChanDir() == T.ChanDir() && T.Elem() == V.Elem()
1295 case Func:
1296 t := (*funcType)(unsafe.Pointer(T))
1297 v := (*funcType)(unsafe.Pointer(V))
1298 if t.dotdotdot != v.dotdotdot || len(t.in) != len(v.in) || len(t.out) != len(v.out) {
1299 return false
1301 for i, typ := range t.in {
1302 if typ != v.in[i] {
1303 return false
1306 for i, typ := range t.out {
1307 if typ != v.out[i] {
1308 return false
1311 return true
1313 case Interface:
1314 t := (*interfaceType)(unsafe.Pointer(T))
1315 v := (*interfaceType)(unsafe.Pointer(V))
1316 if len(t.methods) == 0 && len(v.methods) == 0 {
1317 return true
1319 // Might have the same methods but still
1320 // need a run time conversion.
1321 return false
1323 case Map:
1324 return T.Key() == V.Key() && T.Elem() == V.Elem()
1326 case Ptr, Slice:
1327 return T.Elem() == V.Elem()
1329 case Struct:
1330 t := (*structType)(unsafe.Pointer(T))
1331 v := (*structType)(unsafe.Pointer(V))
1332 if len(t.fields) != len(v.fields) {
1333 return false
1335 for i := range t.fields {
1336 tf := &t.fields[i]
1337 vf := &v.fields[i]
1338 if tf.name != vf.name && (tf.name == nil || vf.name == nil || *tf.name != *vf.name) {
1339 return false
1341 if tf.pkgPath != vf.pkgPath && (tf.pkgPath == nil || vf.pkgPath == nil || *tf.pkgPath != *vf.pkgPath) {
1342 return false
1344 if tf.typ != vf.typ {
1345 return false
1347 if tf.tag != vf.tag && (tf.tag == nil || vf.tag == nil || *tf.tag != *vf.tag) {
1348 return false
1350 if tf.offset != vf.offset {
1351 return false
1354 return true
1357 return false
1360 // The lookupCache caches ChanOf, MapOf, and SliceOf lookups.
1361 var lookupCache struct {
1362 sync.RWMutex
1363 m map[cacheKey]*rtype
1366 // A cacheKey is the key for use in the lookupCache.
1367 // Four values describe any of the types we are looking for:
1368 // type kind, one or two subtypes, and an extra integer.
1369 type cacheKey struct {
1370 kind Kind
1371 t1 *rtype
1372 t2 *rtype
1373 extra uintptr
1376 // cacheGet looks for a type under the key k in the lookupCache.
1377 // If it finds one, it returns that type.
1378 // If not, it returns nil with the cache locked.
1379 // The caller is expected to use cachePut to unlock the cache.
1380 func cacheGet(k cacheKey) Type {
1381 lookupCache.RLock()
1382 t := lookupCache.m[k]
1383 lookupCache.RUnlock()
1384 if t != nil {
1385 return t
1388 lookupCache.Lock()
1389 t = lookupCache.m[k]
1390 if t != nil {
1391 lookupCache.Unlock()
1392 return t
1395 if lookupCache.m == nil {
1396 lookupCache.m = make(map[cacheKey]*rtype)
1399 return nil
1402 // cachePut stores the given type in the cache, unlocks the cache,
1403 // and returns the type. It is expected that the cache is locked
1404 // because cacheGet returned nil.
1405 func cachePut(k cacheKey, t *rtype) Type {
1406 t = toType(t).common()
1407 lookupCache.m[k] = t
1408 lookupCache.Unlock()
1409 return t
1412 // garbage collection bytecode program for chan.
1413 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1414 type chanGC struct {
1415 width uintptr // sizeof(map)
1416 op uintptr // _GC_CHAN_PTR
1417 off uintptr // 0
1418 typ *rtype // map type
1419 end uintptr // _GC_END
1422 type badGC struct {
1423 width uintptr
1424 end uintptr
1427 // ChanOf returns the channel type with the given direction and element type.
1428 // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
1430 // The gc runtime imposes a limit of 64 kB on channel element types.
1431 // If t's size is equal to or exceeds this limit, ChanOf panics.
1432 func ChanOf(dir ChanDir, t Type) Type {
1433 typ := t.(*rtype)
1435 // Look in cache.
1436 ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
1437 if ch := cacheGet(ckey); ch != nil {
1438 return ch
1441 // This restriction is imposed by the gc compiler and the runtime.
1442 if typ.size >= 1<<16 {
1443 lookupCache.Unlock()
1444 panic("reflect.ChanOf: element size too large")
1447 // Look in known types.
1448 // TODO: Precedence when constructing string.
1449 var s string
1450 switch dir {
1451 default:
1452 lookupCache.Unlock()
1453 panic("reflect.ChanOf: invalid dir")
1454 case SendDir:
1455 s = "chan<- " + *typ.string
1456 case RecvDir:
1457 s = "<-chan " + *typ.string
1458 case BothDir:
1459 s = "chan " + *typ.string
1462 // Make a channel type.
1463 var ichan interface{} = (chan unsafe.Pointer)(nil)
1464 prototype := *(**chanType)(unsafe.Pointer(&ichan))
1465 ch := new(chanType)
1466 *ch = *prototype
1467 ch.string = &s
1469 // gccgo uses a different hash.
1470 // ch.hash = fnv1(typ.hash, 'c', byte(dir))
1471 ch.hash = 0
1472 if dir&SendDir != 0 {
1473 ch.hash += 1
1475 if dir&RecvDir != 0 {
1476 ch.hash += 2
1478 ch.hash += typ.hash << 2
1479 ch.hash <<= 3
1480 ch.hash += 15
1482 ch.elem = typ
1483 ch.uncommonType = nil
1484 ch.ptrToThis = nil
1485 ch.zero = unsafe.Pointer(&make([]byte, ch.size)[0])
1487 ch.gc = unsafe.Pointer(&chanGC{
1488 width: ch.size,
1489 op: _GC_CHAN_PTR,
1490 off: 0,
1491 typ: &ch.rtype,
1492 end: _GC_END,
1495 // INCORRECT. Uncomment to check that TestChanOfGC fails when ch.gc is wrong.
1496 // ch.gc = unsafe.Pointer(&badGC{width: ch.size, end: _GC_END})
1498 return cachePut(ckey, &ch.rtype)
1501 func ismapkey(*rtype) bool // implemented in runtime
1503 // MapOf returns the map type with the given key and element types.
1504 // For example, if k represents int and e represents string,
1505 // MapOf(k, e) represents map[int]string.
1507 // If the key type is not a valid map key type (that is, if it does
1508 // not implement Go's == operator), MapOf panics.
1509 func MapOf(key, elem Type) Type {
1510 ktyp := key.(*rtype)
1511 etyp := elem.(*rtype)
1513 if !ismapkey(ktyp) {
1514 panic("reflect.MapOf: invalid key type " + ktyp.String())
1517 // Look in cache.
1518 ckey := cacheKey{Map, ktyp, etyp, 0}
1519 if mt := cacheGet(ckey); mt != nil {
1520 return mt
1523 // Look in known types.
1524 s := "map[" + *ktyp.string + "]" + *etyp.string
1526 // Make a map type.
1527 var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
1528 prototype := *(**mapType)(unsafe.Pointer(&imap))
1529 mt := new(mapType)
1530 *mt = *prototype
1531 mt.string = &s
1533 // gccgo uses a different hash
1534 // mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
1535 mt.hash = ktyp.hash + etyp.hash + 2 + 14
1537 mt.key = ktyp
1538 mt.elem = etyp
1539 // mt.bucket = bucketOf(ktyp, etyp)
1540 // mt.hmap = hMapOf(mt.bucket)
1541 mt.uncommonType = nil
1542 mt.ptrToThis = nil
1543 mt.zero = unsafe.Pointer(&make([]byte, mt.size)[0])
1544 // mt.gc = unsafe.Pointer(&ptrGC{
1545 // width: unsafe.Sizeof(uintptr(0)),
1546 // op: _GC_PTR,
1547 // off: 0,
1548 // elemgc: nil,
1549 // end: _GC_END,
1550 // })
1552 // TODO(cmang): Generate GC data for Map elements.
1553 mt.gc = unsafe.Pointer(&ptrDataGCProg)
1555 // INCORRECT. Uncomment to check that TestMapOfGC and TestMapOfGCValues
1556 // fail when mt.gc is wrong.
1557 //mt.gc = unsafe.Pointer(&badGC{width: mt.size, end: _GC_END})
1559 return cachePut(ckey, &mt.rtype)
1562 // Make sure these routines stay in sync with ../../pkg/runtime/hashmap.c!
1563 // These types exist only for GC, so we only fill out GC relevant info.
1564 // Currently, that's just size and the GC program. We also fill in string
1565 // for possible debugging use.
1566 const (
1567 _BUCKETSIZE = 8
1568 _MAXKEYSIZE = 128
1569 _MAXVALSIZE = 128
1572 func bucketOf(ktyp, etyp *rtype) *rtype {
1573 if ktyp.size > _MAXKEYSIZE {
1574 ktyp = PtrTo(ktyp).(*rtype)
1576 if etyp.size > _MAXVALSIZE {
1577 etyp = PtrTo(etyp).(*rtype)
1579 ptrsize := unsafe.Sizeof(uintptr(0))
1581 gc := make([]uintptr, 1) // first entry is size, filled in at the end
1582 offset := _BUCKETSIZE * unsafe.Sizeof(uint8(0)) // topbits
1583 gc = append(gc, _GC_PTR, offset, 0 /*self pointer set below*/) // overflow
1584 offset += ptrsize
1586 if runtime.GOARCH == "amd64p32" {
1587 offset += 4
1590 // keys
1591 if ktyp.kind&kindNoPointers == 0 {
1592 gc = append(gc, _GC_ARRAY_START, offset, _BUCKETSIZE, ktyp.size)
1593 gc = appendGCProgram(gc, ktyp)
1594 gc = append(gc, _GC_ARRAY_NEXT)
1596 offset += _BUCKETSIZE * ktyp.size
1598 // values
1599 if etyp.kind&kindNoPointers == 0 {
1600 gc = append(gc, _GC_ARRAY_START, offset, _BUCKETSIZE, etyp.size)
1601 gc = appendGCProgram(gc, etyp)
1602 gc = append(gc, _GC_ARRAY_NEXT)
1604 offset += _BUCKETSIZE * etyp.size
1606 gc = append(gc, _GC_END)
1607 gc[0] = offset
1608 gc[3] = uintptr(unsafe.Pointer(&gc[0])) // set self pointer
1610 b := new(rtype)
1611 b.size = offset
1612 // b.gc = unsafe.Pointer(&gc[0])
1613 s := "bucket(" + *ktyp.string + "," + *etyp.string + ")"
1614 b.string = &s
1615 return b
1618 // Take the GC program for "t" and append it to the GC program "gc".
1619 func appendGCProgram(gc []uintptr, t *rtype) []uintptr {
1620 p := t.gc
1621 p = unsafe.Pointer(uintptr(p) + unsafe.Sizeof(uintptr(0))) // skip size
1622 loop:
1623 for {
1624 var argcnt int
1625 switch *(*uintptr)(p) {
1626 case _GC_END:
1627 // Note: _GC_END not included in append
1628 break loop
1629 case _GC_ARRAY_NEXT:
1630 argcnt = 0
1631 case _GC_APTR, _GC_STRING, _GC_EFACE, _GC_IFACE:
1632 argcnt = 1
1633 case _GC_PTR, _GC_CALL, _GC_CHAN_PTR, _GC_SLICE:
1634 argcnt = 2
1635 case _GC_ARRAY_START, _GC_REGION:
1636 argcnt = 3
1637 default:
1638 panic("unknown GC program op for " + *t.string + ": " + strconv.FormatUint(*(*uint64)(p), 10))
1640 for i := 0; i < argcnt+1; i++ {
1641 gc = append(gc, *(*uintptr)(p))
1642 p = unsafe.Pointer(uintptr(p) + unsafe.Sizeof(uintptr(0)))
1645 return gc
1647 func hMapOf(bucket *rtype) *rtype {
1648 ptrsize := unsafe.Sizeof(uintptr(0))
1650 // make gc program & compute hmap size
1651 gc := make([]uintptr, 1) // first entry is size, filled in at the end
1652 offset := unsafe.Sizeof(uint(0)) // count
1653 offset += unsafe.Sizeof(uint32(0)) // flags
1654 offset += unsafe.Sizeof(uint32(0)) // hash0
1655 offset += unsafe.Sizeof(uint8(0)) // B
1656 offset += unsafe.Sizeof(uint8(0)) // keysize
1657 offset += unsafe.Sizeof(uint8(0)) // valuesize
1658 offset = (offset + 1) / 2 * 2
1659 offset += unsafe.Sizeof(uint16(0)) // bucketsize
1660 offset = (offset + ptrsize - 1) / ptrsize * ptrsize
1661 // gc = append(gc, _GC_PTR, offset, uintptr(bucket.gc)) // buckets
1662 offset += ptrsize
1663 // gc = append(gc, _GC_PTR, offset, uintptr(bucket.gc)) // oldbuckets
1664 offset += ptrsize
1665 offset += ptrsize // nevacuate
1666 gc = append(gc, _GC_END)
1667 gc[0] = offset
1669 h := new(rtype)
1670 h.size = offset
1671 // h.gc = unsafe.Pointer(&gc[0])
1672 s := "hmap(" + *bucket.string + ")"
1673 h.string = &s
1674 return h
1677 // garbage collection bytecode program for slice of non-zero-length values.
1678 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1679 type sliceGC struct {
1680 width uintptr // sizeof(slice)
1681 op uintptr // _GC_SLICE
1682 off uintptr // 0
1683 elemgc unsafe.Pointer // element gc program
1684 end uintptr // _GC_END
1687 // garbage collection bytecode program for slice of zero-length values.
1688 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1689 type sliceEmptyGC struct {
1690 width uintptr // sizeof(slice)
1691 op uintptr // _GC_APTR
1692 off uintptr // 0
1693 end uintptr // _GC_END
1696 var sliceEmptyGCProg = sliceEmptyGC{
1697 width: unsafe.Sizeof([]byte(nil)),
1698 op: _GC_APTR,
1699 off: 0,
1700 end: _GC_END,
1703 // SliceOf returns the slice type with element type t.
1704 // For example, if t represents int, SliceOf(t) represents []int.
1705 func SliceOf(t Type) Type {
1706 typ := t.(*rtype)
1708 // Look in cache.
1709 ckey := cacheKey{Slice, typ, nil, 0}
1710 if slice := cacheGet(ckey); slice != nil {
1711 return slice
1714 // Look in known types.
1715 s := "[]" + *typ.string
1717 // Make a slice type.
1718 var islice interface{} = ([]unsafe.Pointer)(nil)
1719 prototype := *(**sliceType)(unsafe.Pointer(&islice))
1720 slice := new(sliceType)
1721 *slice = *prototype
1722 slice.string = &s
1724 // gccgo uses a different hash.
1725 // slice.hash = fnv1(typ.hash, '[')
1726 slice.hash = typ.hash + 1 + 13
1728 slice.elem = typ
1729 slice.uncommonType = nil
1730 slice.ptrToThis = nil
1731 slice.zero = unsafe.Pointer(&make([]byte, slice.size)[0])
1733 if typ.size == 0 {
1734 slice.gc = unsafe.Pointer(&sliceEmptyGCProg)
1735 } else {
1736 slice.gc = unsafe.Pointer(&sliceGC{
1737 width: slice.size,
1738 op: _GC_SLICE,
1739 off: 0,
1740 elemgc: typ.gc,
1741 end: _GC_END,
1745 // INCORRECT. Uncomment to check that TestSliceOfOfGC fails when slice.gc is wrong.
1746 // slice.gc = unsafe.Pointer(&badGC{width: slice.size, end: _GC_END})
1748 return cachePut(ckey, &slice.rtype)
1751 // ArrayOf returns the array type with the given count and element type.
1752 // For example, if t represents int, ArrayOf(5, t) represents [5]int.
1754 // If the resulting type would be larger than the available address space,
1755 // ArrayOf panics.
1757 // TODO(rsc): Unexported for now. Export once the alg field is set correctly
1758 // for the type. This may require significant work.
1759 func arrayOf(count int, elem Type) Type {
1760 typ := elem.(*rtype)
1761 slice := SliceOf(elem)
1763 // Look in cache.
1764 ckey := cacheKey{Array, typ, nil, uintptr(count)}
1765 if slice := cacheGet(ckey); slice != nil {
1766 return slice
1769 // Look in known types.
1770 s := "[" + strconv.Itoa(count) + "]" + *typ.string
1772 // Make an array type.
1773 var iarray interface{} = [1]unsafe.Pointer{}
1774 prototype := *(**arrayType)(unsafe.Pointer(&iarray))
1775 array := new(arrayType)
1776 *array = *prototype
1777 array.string = &s
1779 // gccgo uses a different hash.
1780 // array.hash = fnv1(typ.hash, '[')
1781 // for n := uint32(count); n > 0; n >>= 8 {
1782 // array.hash = fnv1(array.hash, byte(n))
1783 // }
1784 // array.hash = fnv1(array.hash, ']')
1785 array.hash = typ.hash + 1 + 13
1787 array.elem = typ
1788 max := ^uintptr(0) / typ.size
1789 if uintptr(count) > max {
1790 panic("reflect.ArrayOf: array size would exceed virtual address space")
1792 array.size = typ.size * uintptr(count)
1793 array.align = typ.align
1794 array.fieldAlign = typ.fieldAlign
1795 // TODO: array.alg
1796 // TODO: array.gc
1797 array.uncommonType = nil
1798 array.ptrToThis = nil
1799 array.zero = unsafe.Pointer(&make([]byte, array.size)[0])
1800 array.len = uintptr(count)
1801 array.slice = slice.(*rtype)
1803 return cachePut(ckey, &array.rtype)
1806 // toType converts from a *rtype to a Type that can be returned
1807 // to the client of package reflect. In gc, the only concern is that
1808 // a nil *rtype must be replaced by a nil Type, but in gccgo this
1809 // function takes care of ensuring that multiple *rtype for the same
1810 // type are coalesced into a single Type.
1811 var canonicalType = make(map[string]Type)
1813 var canonicalTypeLock sync.RWMutex
1815 func canonicalize(t Type) Type {
1816 if t == nil {
1817 return nil
1819 u := t.uncommon()
1820 var s string
1821 if u == nil || u.PkgPath() == "" {
1822 s = t.rawString()
1823 } else {
1824 s = u.PkgPath() + "." + u.Name()
1826 canonicalTypeLock.RLock()
1827 if r, ok := canonicalType[s]; ok {
1828 canonicalTypeLock.RUnlock()
1829 return r
1831 canonicalTypeLock.RUnlock()
1832 canonicalTypeLock.Lock()
1833 if r, ok := canonicalType[s]; ok {
1834 canonicalTypeLock.Unlock()
1835 return r
1837 canonicalType[s] = t
1838 canonicalTypeLock.Unlock()
1839 return t
1842 func toType(p *rtype) Type {
1843 if p == nil {
1844 return nil
1846 return canonicalize(p)