* intrinsic.h (gfc_simplify_mvbits): Remove.
[official-gcc.git] / libgo / go / reflect / type.go
blob7f0c6a85a0dde3fe187b39c8ab5bd3cb74040f2d
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 // Comparable returns true if values of this type are comparable.
103 Comparable() bool
105 // Methods applicable only to some types, depending on Kind.
106 // The methods allowed for each kind are:
108 // Int*, Uint*, Float*, Complex*: Bits
109 // Array: Elem, Len
110 // Chan: ChanDir, Elem
111 // Func: In, NumIn, Out, NumOut, IsVariadic.
112 // Map: Key, Elem
113 // Ptr: Elem
114 // Slice: Elem
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.
120 Bits() int
122 // ChanDir returns a channel type's direction.
123 // It panics if the type's Kind is not Chan.
124 ChanDir() ChanDir
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
132 // t.NumIn() == 2
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.
138 IsVariadic() bool
140 // Elem returns a type's element type.
141 // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
142 Elem() Type
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()).
167 In(i int) Type
169 // Key returns a map type's key type.
170 // It panics if the type's Kind is not Map.
171 Key() Type
173 // Len returns an array type's length.
174 // It panics if the type's Kind is not Array.
175 Len() int
177 // NumField returns a struct type's field count.
178 // It panics if the type's Kind is not Struct.
179 NumField() int
181 // NumIn returns a function type's input parameter count.
182 // It panics if the type's Kind is not Func.
183 NumIn() int
185 // NumOut returns a function type's output parameter count.
186 // It panics if the type's Kind is not Func.
187 NumOut() int
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()).
192 Out(i int) Type
194 common() *rtype
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.
214 type Kind uint
216 const (
217 Invalid Kind = iota
218 Bool
220 Int8
221 Int16
222 Int32
223 Int64
224 Uint
225 Uint8
226 Uint16
227 Uint32
228 Uint64
229 Uintptr
230 Float32
231 Float64
232 Complex64
233 Complex128
234 Array
235 Chan
236 Func
237 Interface
240 Slice
241 String
242 Struct
243 UnsafePointer
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.
250 type rtype struct {
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
255 size uintptr
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
269 type method struct {
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.
288 type ChanDir int
290 const (
291 RecvDir ChanDir = 1 << iota // <-chan
292 SendDir // 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
301 len uintptr
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
351 // Struct field
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.
368 const (
369 _GC_END = iota
370 _GC_PTR
371 _GC_APTR
372 _GC_ARRAY_START
373 _GC_ARRAY_NEXT
374 _GC_CALL
375 _GC_CHAN_PTR
376 _GC_STRING
377 _GC_EFACE
378 _GC_IFACE
379 _GC_SLICE
380 _GC_REGION
381 _GC_NUM_INSTR
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.
390 type Method struct {
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
395 // in a method set.
396 // See http://golang.org/ref/spec#Uniqueness_of_identifiers
397 Name string
398 PkgPath string
400 Type Type // method type
401 Func Value // func with receiver as first argument
402 Index int // index for Type.Method
405 const (
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) {
414 return kindNames[k]
416 return "kind" + strconv.Itoa(int(k))
419 var kindNames = []string{
420 Invalid: "invalid",
421 Bool: "bool",
422 Int: "int",
423 Int8: "int8",
424 Int16: "int16",
425 Int32: "int32",
426 Int64: "int64",
427 Uint: "uint",
428 Uint8: "uint8",
429 Uint16: "uint16",
430 Uint32: "uint32",
431 Uint64: "uint64",
432 Uintptr: "uintptr",
433 Float32: "float32",
434 Float64: "float64",
435 Complex64: "complex64",
436 Complex128: "complex128",
437 Array: "array",
438 Chan: "chan",
439 Func: "func",
440 Interface: "interface",
441 Map: "map",
442 Ptr: "ptr",
443 Slice: "slice",
444 String: "string",
445 Struct: "struct",
446 UnsafePointer: "unsafe.Pointer",
449 func (t *uncommonType) uncommon() *uncommonType {
450 return t
453 func (t *uncommonType) PkgPath() string {
454 if t == nil || t.pkgPath == nil {
455 return ""
457 return *t.pkgPath
460 func (t *uncommonType) Name() string {
461 if t == nil || t.name == nil {
462 return ""
464 return *t.name
467 func (t *rtype) rawString() string { return *t.string }
469 func (t *rtype) String() string {
470 // For gccgo, strip out quoted strings.
471 s := *t.string
472 var q bool
473 r := make([]byte, len(s))
474 j := 0
475 for i := 0; i < len(s); i++ {
476 if s[i] == '\t' {
477 q = !q
478 } else if !q {
479 r[j] = s[i]
483 return string(r[:j])
486 func (t *rtype) Size() uintptr { return t.size }
488 func (t *rtype) Bits() int {
489 if t == nil {
490 panic("reflect: Bits of nil Type")
492 k := t.Kind()
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")
513 p := &t.methods[i]
514 if p.name != nil {
515 m.Name = *p.name
517 fl := flag(Func)
518 if p.pkgPath != nil {
519 m.PkgPath = *p.pkgPath
520 fl |= flagRO
522 mt := p.typ
523 m.Type = toType(mt)
524 x := new(unsafe.Pointer)
525 *x = unsafe.Pointer(&p.tfn)
526 m.Func = Value{mt, unsafe.Pointer(x), fl | flagIndir | flagMethodFn}
527 m.Index = i
528 return
531 func (t *uncommonType) NumMethod() int {
532 if t == nil {
533 return 0
535 return len(t.methods)
538 func (t *uncommonType) MethodByName(name string) (m Method, ok bool) {
539 if t == nil {
540 return
542 var p *method
543 for i := range t.methods {
544 p = &t.methods[i]
545 if p.name != nil && *p.name == name {
546 return t.Method(i), true
549 return
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))
566 return tt.Method(i)
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))
600 return tt.dotdotdot
603 func (t *rtype) Elem() Type {
604 switch t.Kind() {
605 case Array:
606 tt := (*arrayType)(unsafe.Pointer(t))
607 return toType(tt.elem)
608 case Chan:
609 tt := (*chanType)(unsafe.Pointer(t))
610 return toType(tt.elem)
611 case Map:
612 tt := (*mapType)(unsafe.Pointer(t))
613 return toType(tt.elem)
614 case Ptr:
615 tt := (*ptrType)(unsafe.Pointer(t))
616 return toType(tt.elem)
617 case Slice:
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))
629 return tt.Field(i)
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 {
665 if t.Kind() != Map {
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))
677 return int(tt.len)
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))
693 return len(tt.in)
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))
701 return len(tt.out)
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 {
713 switch d {
714 case SendDir:
715 return "chan<-"
716 case RecvDir:
717 return "<-chan"
718 case BothDir:
719 return "chan"
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) {
727 return
729 p := &t.methods[i]
730 m.Name = *p.name
731 if p.pkgPath != nil {
732 m.PkgPath = *p.pkgPath
734 m.Type = toType(p.typ)
735 m.Index = i
736 return
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) {
744 if t == nil {
745 return
747 var p *imethod
748 for i := range t.methods {
749 p = &t.methods[i]
750 if *p.name == name {
751 return t.Method(i), true
754 return
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
763 Name string
764 PkgPath string
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 {
788 for tag != "" {
789 // skip leading space
790 i := 0
791 for i < len(tag) && tag[i] == ' ' {
794 tag = tag[i:]
795 if tag == "" {
796 break
799 // scan to colon.
800 // a space or a quote is a syntax error
801 i = 0
802 for i < len(tag) && tag[i] != ' ' && tag[i] != ':' && tag[i] != '"' {
805 if i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
806 break
808 name := string(tag[:i])
809 tag = tag[i+1:]
811 // scan quoted string to find value
812 i = 1
813 for i < len(tag) && tag[i] != '"' {
814 if tag[i] == '\\' {
819 if i >= len(tag) {
820 break
822 qvalue := string(tag[:i+1])
823 tag = tag[i+1:]
825 if key == name {
826 value, _ := strconv.Unquote(qvalue)
827 return value
830 return ""
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) {
836 return
838 p := &t.fields[i]
839 f.Type = toType(p.typ)
840 if p.name != nil {
841 f.Name = *p.name
842 } else {
843 t := f.Type
844 if t.Kind() == Ptr {
845 t = t.Elem()
847 f.Name = t.Name()
848 f.Anonymous = true
850 if p.pkgPath != nil {
851 f.PkgPath = *p.pkgPath
853 if p.tag != nil {
854 f.Tag = StructTag(*p.tag)
856 f.Offset = p.offset
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.
865 f.Index = []int{i}
866 return
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 {
876 if i > 0 {
877 ft := f.Type
878 if ft.Kind() == Ptr && ft.Elem().Kind() == Struct {
879 ft = ft.Elem()
881 f.Type = ft
883 f = f.Type.Field(x)
885 return
888 // A fieldScan represents an item on the fieldByNameFunc scan work list.
889 type fieldScan struct {
890 typ *structType
891 index []int
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{}
923 for len(next) > 0 {
924 current, next = next, current[:0]
925 count := nextCount
926 nextCount = nil
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 {
933 t := scan.typ
934 if visited[t] {
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.
938 continue
940 visited[t] = true
941 for i := range t.fields {
942 f := &t.fields[i]
943 // Find name and type for field f.
944 var fname string
945 var ntyp *rtype
946 if f.name != nil {
947 fname = *f.name
948 } else {
949 // Anonymous field of type T or *T.
950 // Name taken from type.
951 ntyp = f.typ
952 if ntyp.Kind() == Ptr {
953 ntyp = ntyp.Elem().common()
955 fname = ntyp.Name()
958 // Does it match?
959 if match(fname) {
960 // Potential match
961 if count[t] > 1 || ok {
962 // Name appeared multiple times at this level: annihilate.
963 return StructField{}, false
965 result = t.Field(i)
966 result.Index = nil
967 result.Index = append(result.Index, scan.index...)
968 result.Index = append(result.Index, i)
969 ok = true
970 continue
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 {
977 continue
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
983 continue
985 if nextCount == nil {
986 nextCount = map[*structType]int{}
988 nextCount[styp] = 1
989 if count[t] > 1 {
990 nextCount[styp] = 2 // exact multiple doesn't matter
992 var index []int
993 index = append(index, scan.index...)
994 index = append(index, i)
995 next = append(next, fieldScan{styp, index})
998 if ok {
999 break
1002 return
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.
1009 hasAnon := false
1010 if name != "" {
1011 for i := range t.fields {
1012 tf := &t.fields[i]
1013 if tf.name == nil {
1014 hasAnon = true
1015 continue
1017 if *tf.name == name {
1018 return t.Field(i), true
1022 if !hasAnon {
1023 return
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.
1036 var ptrMap struct {
1037 sync.RWMutex
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
1046 off uintptr // 0
1047 end uintptr // _GC_END
1050 var ptrDataGCProg = ptrDataGC{
1051 width: unsafe.Sizeof((*byte)(nil)),
1052 op: _GC_APTR,
1053 off: 0,
1054 end: _GC_END,
1057 // garbage collection bytecode program for pointer to memory with pointers.
1058 // See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
1059 type ptrGC struct {
1060 width uintptr // sizeof(ptr)
1061 op uintptr // _GC_PTR
1062 off uintptr // 0
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 {
1075 return p
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.
1083 ptrMap.RLock()
1084 if m := ptrMap.m; m != nil {
1085 if p := m[t]; p != nil {
1086 ptrMap.RUnlock()
1087 return &p.rtype
1090 ptrMap.RUnlock()
1091 ptrMap.Lock()
1092 if ptrMap.m == nil {
1093 ptrMap.m = make(map[*rtype]*ptrType)
1095 p := ptrMap.m[t]
1096 if p != nil {
1097 // some other goroutine won the race and created it
1098 ptrMap.Unlock()
1099 return &p.rtype
1102 s := "*" + *t.string
1104 canonicalTypeLock.RLock()
1105 r, ok := canonicalType[s]
1106 canonicalTypeLock.RUnlock()
1107 if ok {
1108 ptrMap.m[t] = (*ptrType)(unsafe.Pointer(r.(*rtype)))
1109 ptrMap.Unlock()
1110 return r.(*rtype)
1113 // initialize p using *byte's ptrType as a prototype.
1114 p = new(ptrType)
1115 var iptr interface{} = (*unsafe.Pointer)(nil)
1116 prototype := *(**ptrType)(unsafe.Pointer(&iptr))
1117 *p = *prototype
1119 p.string = &s
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
1131 p.ptrToThis = nil
1132 p.zero = unsafe.Pointer(&make([]byte, p.size)[0])
1133 p.elem = t
1135 if t.kind&kindNoPointers != 0 {
1136 p.gc = unsafe.Pointer(&ptrDataGCProg)
1137 } else {
1138 p.gc = unsafe.Pointer(&ptrGC{
1139 width: p.size,
1140 op: _GC_PTR,
1141 off: 0,
1142 elemgc: t.gc,
1143 end: _GC_END,
1147 q := canonicalize(&p.rtype)
1148 p = (*ptrType)(unsafe.Pointer(q.(*rtype)))
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 func (t *rtype) Comparable() bool {
1189 switch t.Kind() {
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:
1194 return true
1196 case Func, Map, Slice:
1197 return false
1199 case Array:
1200 return (*arrayType)(unsafe.Pointer(t)).elem.Comparable()
1202 case Struct:
1203 tt := (*structType)(unsafe.Pointer(t))
1204 for i := range tt.fields {
1205 if !tt.fields[i].typ.Comparable() {
1206 return false
1209 return true
1211 default:
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 {
1219 return false
1221 t := (*interfaceType)(unsafe.Pointer(T))
1222 if len(t.methods) == 0 {
1223 return true
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))
1240 i := 0
1241 for j := 0; j < len(v.methods); j++ {
1242 tm := &t.methods[i]
1243 vm := &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) {
1246 return true
1250 return false
1253 v := V.uncommon()
1254 if v == nil {
1255 return false
1257 i := 0
1258 for j := 0; j < len(v.methods); j++ {
1259 tm := &t.methods[i]
1260 vm := &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) {
1263 return true
1267 return false
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?
1277 if T == V {
1278 return true
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() {
1284 return false
1287 // x's type T and V must have identical underlying types.
1288 return haveIdenticalUnderlyingType(T, V)
1291 func haveIdenticalUnderlyingType(T, V *rtype) bool {
1292 if T == V {
1293 return true
1296 kind := T.Kind()
1297 if kind != V.Kind() {
1298 return false
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 {
1304 return true
1307 // Composite types.
1308 switch kind {
1309 case Array:
1310 return T.Elem() == V.Elem() && T.Len() == V.Len()
1312 case Chan:
1313 // Special case:
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() {
1317 return true
1320 // Otherwise continue test for identical underlying type.
1321 return V.ChanDir() == T.ChanDir() && T.Elem() == V.Elem()
1323 case Func:
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) {
1327 return false
1329 for i, typ := range t.in {
1330 if typ != v.in[i] {
1331 return false
1334 for i, typ := range t.out {
1335 if typ != v.out[i] {
1336 return false
1339 return true
1341 case Interface:
1342 t := (*interfaceType)(unsafe.Pointer(T))
1343 v := (*interfaceType)(unsafe.Pointer(V))
1344 if len(t.methods) == 0 && len(v.methods) == 0 {
1345 return true
1347 // Might have the same methods but still
1348 // need a run time conversion.
1349 return false
1351 case Map:
1352 return T.Key() == V.Key() && T.Elem() == V.Elem()
1354 case Ptr, Slice:
1355 return T.Elem() == V.Elem()
1357 case Struct:
1358 t := (*structType)(unsafe.Pointer(T))
1359 v := (*structType)(unsafe.Pointer(V))
1360 if len(t.fields) != len(v.fields) {
1361 return false
1363 for i := range t.fields {
1364 tf := &t.fields[i]
1365 vf := &v.fields[i]
1366 if tf.name != vf.name && (tf.name == nil || vf.name == nil || *tf.name != *vf.name) {
1367 return false
1369 if tf.pkgPath != vf.pkgPath && (tf.pkgPath == nil || vf.pkgPath == nil || *tf.pkgPath != *vf.pkgPath) {
1370 return false
1372 if tf.typ != vf.typ {
1373 return false
1375 if tf.tag != vf.tag && (tf.tag == nil || vf.tag == nil || *tf.tag != *vf.tag) {
1376 return false
1378 if tf.offset != vf.offset {
1379 return false
1382 return true
1385 return false
1388 // The lookupCache caches ChanOf, MapOf, and SliceOf lookups.
1389 var lookupCache struct {
1390 sync.RWMutex
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 {
1398 kind Kind
1399 t1 *rtype
1400 t2 *rtype
1401 extra uintptr
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 {
1409 lookupCache.RLock()
1410 t := lookupCache.m[k]
1411 lookupCache.RUnlock()
1412 if t != nil {
1413 return t
1416 lookupCache.Lock()
1417 t = lookupCache.m[k]
1418 if t != nil {
1419 lookupCache.Unlock()
1420 return t
1423 if lookupCache.m == nil {
1424 lookupCache.m = make(map[cacheKey]*rtype)
1427 return nil
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()
1437 return t
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
1445 off uintptr // 0
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 {
1456 typ := t.(*rtype)
1458 // Look in cache.
1459 ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
1460 if ch := cacheGet(ckey); ch != nil {
1461 return ch
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.
1472 var s string
1473 switch dir {
1474 default:
1475 lookupCache.Unlock()
1476 panic("reflect.ChanOf: invalid dir")
1477 case SendDir:
1478 s = "chan<- " + *typ.string
1479 case RecvDir:
1480 s = "<-chan " + *typ.string
1481 case BothDir:
1482 s = "chan " + *typ.string
1485 // Make a channel type.
1486 var ichan interface{} = (chan unsafe.Pointer)(nil)
1487 prototype := *(**chanType)(unsafe.Pointer(&ichan))
1488 ch := new(chanType)
1489 *ch = *prototype
1490 ch.string = &s
1492 // gccgo uses a different hash.
1493 // ch.hash = fnv1(typ.hash, 'c', byte(dir))
1494 ch.hash = 0
1495 if dir&SendDir != 0 {
1496 ch.hash += 1
1498 if dir&RecvDir != 0 {
1499 ch.hash += 2
1501 ch.hash += typ.hash << 2
1502 ch.hash <<= 3
1503 ch.hash += 15
1505 ch.elem = typ
1506 ch.uncommonType = nil
1507 ch.ptrToThis = nil
1508 ch.zero = unsafe.Pointer(&make([]byte, ch.size)[0])
1510 ch.gc = unsafe.Pointer(&chanGC{
1511 width: ch.size,
1512 op: _GC_CHAN_PTR,
1513 off: 0,
1514 typ: &ch.rtype,
1515 end: _GC_END,
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())
1540 // Look in cache.
1541 ckey := cacheKey{Map, ktyp, etyp, 0}
1542 if mt := cacheGet(ckey); mt != nil {
1543 return mt
1546 // Look in known types.
1547 s := "map[" + *ktyp.string + "]" + *etyp.string
1549 // Make a map type.
1550 var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
1551 prototype := *(**mapType)(unsafe.Pointer(&imap))
1552 mt := new(mapType)
1553 *mt = *prototype
1554 mt.string = &s
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
1560 mt.key = ktyp
1561 mt.elem = etyp
1562 mt.uncommonType = nil
1563 mt.ptrToThis = nil
1564 mt.zero = unsafe.Pointer(&make([]byte, mt.size)[0])
1565 // mt.gc = unsafe.Pointer(&ptrGC{
1566 // width: unsafe.Sizeof(uintptr(0)),
1567 // op: _GC_PTR,
1568 // off: 0,
1569 // elemgc: nil,
1570 // end: _GC_END,
1571 // })
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 {
1585 gc []byte
1586 size uintptr // size of type in bytes
1587 hasPtr bool
1590 func (gc *gcProg) append(v byte) {
1591 gc.align(unsafe.Sizeof(uintptr(0)))
1592 gc.appendWord(v)
1595 // Appends t's type info to the current program.
1596 func (gc *gcProg) appendProg(t *rtype) {
1597 gc.align(uintptr(t.align))
1598 if !t.pointers() {
1599 gc.size += t.size
1600 return
1602 switch t.Kind() {
1603 default:
1604 panic("reflect: non-pointer type marked as having pointers")
1605 case Ptr, UnsafePointer, Chan, Func, Map:
1606 gc.appendWord(bitsPointer)
1607 case Slice:
1608 gc.appendWord(bitsPointer)
1609 gc.appendWord(bitsScalar)
1610 gc.appendWord(bitsScalar)
1611 case String:
1612 gc.appendWord(bitsPointer)
1613 gc.appendWord(bitsScalar)
1614 case Array:
1615 c := t.Len()
1616 e := t.Elem().common()
1617 for i := 0; i < c; i++ {
1618 gc.appendProg(e)
1620 case Interface:
1621 gc.appendWord(bitsMultiWord)
1622 if t.NumMethod() == 0 {
1623 gc.appendWord(bitsEface)
1624 } else {
1625 gc.appendWord(bitsIface)
1627 case Struct:
1628 c := t.NumField()
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)
1647 gc.size += ptrsize
1648 if v == bitsPointer {
1649 gc.hasPtr = true
1653 func (gc *gcProg) finalize() (unsafe.Pointer, bool) {
1654 if gc.size == 0 {
1655 return nil, false
1657 ptrsize := unsafe.Sizeof(uintptr(0))
1658 gc.align(ptrsize)
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.
1665 if nptr%2 != 0 {
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.
1682 const (
1683 bitsScalar = 1
1684 bitsPointer = 2
1685 bitsMultiWord = 3
1687 bitsIface = 2
1688 bitsEface = 3
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.
1695 const (
1696 bucketSize = 8
1697 maxKeySize = 128
1698 maxValSize = 128
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))
1710 var gc gcProg
1711 // topbits
1712 for i := 0; i < int(bucketSize*unsafe.Sizeof(uint8(0))/ptrsize); i++ {
1713 gc.append(bitsScalar)
1715 // keys
1716 for i := 0; i < bucketSize; i++ {
1717 gc.appendProg(ktyp)
1719 // values
1720 for i := 0; i < bucketSize; i++ {
1721 gc.appendProg(etyp)
1723 // overflow
1724 gc.append(bitsPointer)
1725 if runtime.GOARCH == "amd64p32" {
1726 gc.append(bitsScalar)
1729 b := new(rtype)
1730 b.size = gc.size
1731 // b.gc[0], _ = gc.finalize()
1732 b.kind |= kindGCProg
1733 s := "bucket(" + *ktyp.string + "," + *etyp.string + ")"
1734 b.string = &s
1735 return b
1738 // Take the GC program for "t" and append it to the GC program "gc".
1739 func appendGCProgram(gc []uintptr, t *rtype) []uintptr {
1740 p := t.gc
1741 p = unsafe.Pointer(uintptr(p) + unsafe.Sizeof(uintptr(0))) // skip size
1742 loop:
1743 for {
1744 var argcnt int
1745 switch *(*uintptr)(p) {
1746 case _GC_END:
1747 // Note: _GC_END not included in append
1748 break loop
1749 case _GC_ARRAY_NEXT:
1750 argcnt = 0
1751 case _GC_APTR, _GC_STRING, _GC_EFACE, _GC_IFACE:
1752 argcnt = 1
1753 case _GC_PTR, _GC_CALL, _GC_CHAN_PTR, _GC_SLICE:
1754 argcnt = 2
1755 case _GC_ARRAY_START, _GC_REGION:
1756 argcnt = 3
1757 default:
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)))
1765 return gc
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
1782 offset += ptrsize
1783 // gc = append(gc, _GC_PTR, offset, uintptr(bucket.gc)) // oldbuckets
1784 offset += ptrsize
1785 offset += ptrsize // nevacuate
1786 gc = append(gc, _GC_END)
1787 gc[0] = offset
1789 h := new(rtype)
1790 h.size = offset
1791 // h.gc = unsafe.Pointer(&gc[0])
1792 s := "hmap(" + *bucket.string + ")"
1793 h.string = &s
1794 return h
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
1802 off uintptr // 0
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
1812 off uintptr // 0
1813 end uintptr // _GC_END
1816 var sliceEmptyGCProg = sliceEmptyGC{
1817 width: unsafe.Sizeof([]byte(nil)),
1818 op: _GC_APTR,
1819 off: 0,
1820 end: _GC_END,
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 {
1826 typ := t.(*rtype)
1828 // Look in cache.
1829 ckey := cacheKey{Slice, typ, nil, 0}
1830 if slice := cacheGet(ckey); slice != nil {
1831 return slice
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)
1841 *slice = *prototype
1842 slice.string = &s
1844 // gccgo uses a different hash.
1845 // slice.hash = fnv1(typ.hash, '[')
1846 slice.hash = typ.hash + 1 + 13
1848 slice.elem = typ
1849 slice.uncommonType = nil
1850 slice.ptrToThis = nil
1851 slice.zero = unsafe.Pointer(&make([]byte, slice.size)[0])
1853 if typ.size == 0 {
1854 slice.gc = unsafe.Pointer(&sliceEmptyGCProg)
1855 } else {
1856 slice.gc = unsafe.Pointer(&sliceGC{
1857 width: slice.size,
1858 op: _GC_SLICE,
1859 off: 0,
1860 elemgc: typ.gc,
1861 end: _GC_END,
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,
1875 // ArrayOf panics.
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)
1885 // Look in cache.
1886 ckey := cacheKey{Array, typ, nil, uintptr(count)}
1887 if slice := cacheGet(ckey); slice != nil {
1888 return slice
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)
1898 *array = *prototype
1899 // TODO: Set extra kind bits correctly.
1900 array.string = &s
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))
1906 // }
1907 // array.hash = fnv1(array.hash, ']')
1908 array.hash = typ.hash + 1 + 13
1910 array.elem = typ
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
1918 // TODO: array.alg
1919 // TODO: array.gc
1920 // TODO:
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 {
1940 if t == nil {
1941 return nil
1943 s := t.rawString()
1944 canonicalTypeLock.RLock()
1945 if r, ok := canonicalType[s]; ok {
1946 canonicalTypeLock.RUnlock()
1947 return r
1949 canonicalTypeLock.RUnlock()
1950 canonicalTypeLock.Lock()
1951 if r, ok := canonicalType[s]; ok {
1952 canonicalTypeLock.Unlock()
1953 return r
1955 canonicalType[s] = t
1956 canonicalTypeLock.Unlock()
1957 return t
1960 func toType(p *rtype) Type {
1961 if p == nil {
1962 return nil
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
1975 data []byte
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.
1981 if bv.n%8 == 0 {
1982 bv.data = append(bv.data, 0)
1984 bv.data[bv.n/8] |= bits << (bv.n % 8)
1985 bv.n += 2
1988 func addTypeBits(bv *bitVector, offset *uintptr, t *rtype) {
1989 *offset = align(*offset, uintptr(t.align))
1990 if t.kind&kindNoPointers != 0 {
1991 *offset += t.size
1992 return
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)
2003 case Interface:
2004 // 2 pointers
2005 for bv.n < 2*uint32(*offset/uintptr(ptrSize)) {
2006 bv.append2(bitsScalar)
2008 bv.append2(bitsPointer)
2009 bv.append2(bitsPointer)
2011 case Array:
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)
2018 case Struct:
2019 // apply fields
2020 tt := (*structType)(unsafe.Pointer(t))
2021 start := *offset
2022 for i := range tt.fields {
2023 f := &tt.fields[i]
2024 off := start + f.offset
2025 addTypeBits(bv, &off, f.typ)
2029 *offset += t.size