]> Cypherpunks.ru repositories - gostls13.git/blob - src/reflect/type.go
[dev.typeparams] all: merge master (296ddf2) into dev.typeparams
[gostls13.git] / src / reflect / type.go
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.
4
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.
13 //
14 // See "The Laws of Reflection" for an introduction to reflection in Go:
15 // https://golang.org/doc/articles/laws_of_reflection.html
16 package reflect
17
18 import (
19         "internal/goarch"
20         "internal/unsafeheader"
21         "strconv"
22         "sync"
23         "unicode"
24         "unicode/utf8"
25         "unsafe"
26 )
27
28 // Type is the representation of a Go type.
29 //
30 // Not all methods apply to all kinds of types. Restrictions,
31 // if any, are noted in the documentation for each method.
32 // Use the Kind method to find out the kind of type before
33 // calling kind-specific methods. Calling a method
34 // inappropriate to the kind of type causes a run-time panic.
35 //
36 // Type values are comparable, such as with the == operator,
37 // so they can be used as map keys.
38 // Two Type values are equal if they represent identical types.
39 type Type interface {
40         // Methods applicable to all types.
41
42         // Align returns the alignment in bytes of a value of
43         // this type when allocated in memory.
44         Align() int
45
46         // FieldAlign returns the alignment in bytes of a value of
47         // this type when used as a field in a struct.
48         FieldAlign() int
49
50         // Method returns the i'th method in the type's method set.
51         // It panics if i is not in the range [0, NumMethod()).
52         //
53         // For a non-interface type T or *T, the returned Method's Type and Func
54         // fields describe a function whose first argument is the receiver,
55         // and only exported methods are accessible.
56         //
57         // For an interface type, the returned Method's Type field gives the
58         // method signature, without a receiver, and the Func field is nil.
59         //
60         // Methods are sorted in lexicographic order.
61         Method(int) Method
62
63         // MethodByName returns the method with that name in the type's
64         // method set and a boolean indicating if the method was found.
65         //
66         // For a non-interface type T or *T, the returned Method's Type and Func
67         // fields describe a function whose first argument is the receiver.
68         //
69         // For an interface type, the returned Method's Type field gives the
70         // method signature, without a receiver, and the Func field is nil.
71         MethodByName(string) (Method, bool)
72
73         // NumMethod returns the number of methods accessible using Method.
74         //
75         // Note that NumMethod counts unexported methods only for interface types.
76         NumMethod() int
77
78         // Name returns the type's name within its package for a defined type.
79         // For other (non-defined) types it returns the empty string.
80         Name() string
81
82         // PkgPath returns a defined type's package path, that is, the import path
83         // that uniquely identifies the package, such as "encoding/base64".
84         // If the type was predeclared (string, error) or not defined (*T, struct{},
85         // []int, or A where A is an alias for a non-defined type), the package path
86         // will be the empty string.
87         PkgPath() string
88
89         // Size returns the number of bytes needed to store
90         // a value of the given type; it is analogous to unsafe.Sizeof.
91         Size() uintptr
92
93         // String returns a string representation of the type.
94         // The string representation may use shortened package names
95         // (e.g., base64 instead of "encoding/base64") and is not
96         // guaranteed to be unique among types. To test for type identity,
97         // compare the Types directly.
98         String() string
99
100         // Kind returns the specific kind of this type.
101         Kind() Kind
102
103         // Implements reports whether the type implements the interface type u.
104         Implements(u Type) bool
105
106         // AssignableTo reports whether a value of the type is assignable to type u.
107         AssignableTo(u Type) bool
108
109         // ConvertibleTo reports whether a value of the type is convertible to type u.
110         // Even if ConvertibleTo returns true, the conversion may still panic.
111         // For example, a slice of type []T is convertible to *[N]T,
112         // but the conversion will panic if its length is less than N.
113         ConvertibleTo(u Type) bool
114
115         // Comparable reports whether values of this type are comparable.
116         // Even if Comparable returns true, the comparison may still panic.
117         // For example, values of interface type are comparable,
118         // but the comparison will panic if their dynamic type is not comparable.
119         Comparable() bool
120
121         // Methods applicable only to some types, depending on Kind.
122         // The methods allowed for each kind are:
123         //
124         //      Int*, Uint*, Float*, Complex*: Bits
125         //      Array: Elem, Len
126         //      Chan: ChanDir, Elem
127         //      Func: In, NumIn, Out, NumOut, IsVariadic.
128         //      Map: Key, Elem
129         //      Ptr: Elem
130         //      Slice: Elem
131         //      Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
132
133         // Bits returns the size of the type in bits.
134         // It panics if the type's Kind is not one of the
135         // sized or unsized Int, Uint, Float, or Complex kinds.
136         Bits() int
137
138         // ChanDir returns a channel type's direction.
139         // It panics if the type's Kind is not Chan.
140         ChanDir() ChanDir
141
142         // IsVariadic reports whether a function type's final input parameter
143         // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's
144         // implicit actual type []T.
145         //
146         // For concreteness, if t represents func(x int, y ... float64), then
147         //
148         //      t.NumIn() == 2
149         //      t.In(0) is the reflect.Type for "int"
150         //      t.In(1) is the reflect.Type for "[]float64"
151         //      t.IsVariadic() == true
152         //
153         // IsVariadic panics if the type's Kind is not Func.
154         IsVariadic() bool
155
156         // Elem returns a type's element type.
157         // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
158         Elem() Type
159
160         // Field returns a struct type's i'th field.
161         // It panics if the type's Kind is not Struct.
162         // It panics if i is not in the range [0, NumField()).
163         Field(i int) StructField
164
165         // FieldByIndex returns the nested field corresponding
166         // to the index sequence. It is equivalent to calling Field
167         // successively for each index i.
168         // It panics if the type's Kind is not Struct.
169         FieldByIndex(index []int) StructField
170
171         // FieldByName returns the struct field with the given name
172         // and a boolean indicating if the field was found.
173         FieldByName(name string) (StructField, bool)
174
175         // FieldByNameFunc returns the struct field with a name
176         // that satisfies the match function and a boolean indicating if
177         // the field was found.
178         //
179         // FieldByNameFunc considers the fields in the struct itself
180         // and then the fields in any embedded structs, in breadth first order,
181         // stopping at the shallowest nesting depth containing one or more
182         // fields satisfying the match function. If multiple fields at that depth
183         // satisfy the match function, they cancel each other
184         // and FieldByNameFunc returns no match.
185         // This behavior mirrors Go's handling of name lookup in
186         // structs containing embedded fields.
187         FieldByNameFunc(match func(string) bool) (StructField, bool)
188
189         // In returns the type of a function type's i'th input parameter.
190         // It panics if the type's Kind is not Func.
191         // It panics if i is not in the range [0, NumIn()).
192         In(i int) Type
193
194         // Key returns a map type's key type.
195         // It panics if the type's Kind is not Map.
196         Key() Type
197
198         // Len returns an array type's length.
199         // It panics if the type's Kind is not Array.
200         Len() int
201
202         // NumField returns a struct type's field count.
203         // It panics if the type's Kind is not Struct.
204         NumField() int
205
206         // NumIn returns a function type's input parameter count.
207         // It panics if the type's Kind is not Func.
208         NumIn() int
209
210         // NumOut returns a function type's output parameter count.
211         // It panics if the type's Kind is not Func.
212         NumOut() int
213
214         // Out returns the type of a function type's i'th output parameter.
215         // It panics if the type's Kind is not Func.
216         // It panics if i is not in the range [0, NumOut()).
217         Out(i int) Type
218
219         common() *rtype
220         uncommon() *uncommonType
221 }
222
223 // BUG(rsc): FieldByName and related functions consider struct field names to be equal
224 // if the names are equal, even if they are unexported names originating
225 // in different packages. The practical effect of this is that the result of
226 // t.FieldByName("x") is not well defined if the struct type t contains
227 // multiple fields named x (embedded from different packages).
228 // FieldByName may return one of the fields named x or may report that there are none.
229 // See https://golang.org/issue/4876 for more details.
230
231 /*
232  * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
233  * A few are known to ../runtime/type.go to convey to debuggers.
234  * They are also known to ../runtime/type.go.
235  */
236
237 // A Kind represents the specific kind of type that a Type represents.
238 // The zero Kind is not a valid kind.
239 type Kind uint
240
241 const (
242         Invalid Kind = iota
243         Bool
244         Int
245         Int8
246         Int16
247         Int32
248         Int64
249         Uint
250         Uint8
251         Uint16
252         Uint32
253         Uint64
254         Uintptr
255         Float32
256         Float64
257         Complex64
258         Complex128
259         Array
260         Chan
261         Func
262         Interface
263         Map
264         Ptr
265         Slice
266         String
267         Struct
268         UnsafePointer
269 )
270
271 // tflag is used by an rtype to signal what extra type information is
272 // available in the memory directly following the rtype value.
273 //
274 // tflag values must be kept in sync with copies in:
275 //      cmd/compile/internal/reflectdata/reflect.go
276 //      cmd/link/internal/ld/decodesym.go
277 //      runtime/type.go
278 type tflag uint8
279
280 const (
281         // tflagUncommon means that there is a pointer, *uncommonType,
282         // just beyond the outer type structure.
283         //
284         // For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0,
285         // then t has uncommonType data and it can be accessed as:
286         //
287         //      type tUncommon struct {
288         //              structType
289         //              u uncommonType
290         //      }
291         //      u := &(*tUncommon)(unsafe.Pointer(t)).u
292         tflagUncommon tflag = 1 << 0
293
294         // tflagExtraStar means the name in the str field has an
295         // extraneous '*' prefix. This is because for most types T in
296         // a program, the type *T also exists and reusing the str data
297         // saves binary size.
298         tflagExtraStar tflag = 1 << 1
299
300         // tflagNamed means the type has a name.
301         tflagNamed tflag = 1 << 2
302
303         // tflagRegularMemory means that equal and hash functions can treat
304         // this type as a single region of t.size bytes.
305         tflagRegularMemory tflag = 1 << 3
306 )
307
308 // rtype is the common implementation of most values.
309 // It is embedded in other struct types.
310 //
311 // rtype must be kept in sync with ../runtime/type.go:/^type._type.
312 type rtype struct {
313         size       uintptr
314         ptrdata    uintptr // number of bytes in the type that can contain pointers
315         hash       uint32  // hash of type; avoids computation in hash tables
316         tflag      tflag   // extra type information flags
317         align      uint8   // alignment of variable with this type
318         fieldAlign uint8   // alignment of struct field with this type
319         kind       uint8   // enumeration for C
320         // function for comparing objects of this type
321         // (ptr to object A, ptr to object B) -> ==?
322         equal     func(unsafe.Pointer, unsafe.Pointer) bool
323         gcdata    *byte   // garbage collection data
324         str       nameOff // string form
325         ptrToThis typeOff // type for pointer to this type, may be zero
326 }
327
328 // Method on non-interface type
329 type method struct {
330         name nameOff // name of method
331         mtyp typeOff // method type (without receiver)
332         ifn  textOff // fn used in interface call (one-word receiver)
333         tfn  textOff // fn used for normal method call
334 }
335
336 // uncommonType is present only for defined types or types with methods
337 // (if T is a defined type, the uncommonTypes for T and *T have methods).
338 // Using a pointer to this struct reduces the overall size required
339 // to describe a non-defined type with no methods.
340 type uncommonType struct {
341         pkgPath nameOff // import path; empty for built-in types like int, string
342         mcount  uint16  // number of methods
343         xcount  uint16  // number of exported methods
344         moff    uint32  // offset from this uncommontype to [mcount]method
345         _       uint32  // unused
346 }
347
348 // ChanDir represents a channel type's direction.
349 type ChanDir int
350
351 const (
352         RecvDir ChanDir             = 1 << iota // <-chan
353         SendDir                                 // chan<-
354         BothDir = RecvDir | SendDir             // chan
355 )
356
357 // arrayType represents a fixed array type.
358 type arrayType struct {
359         rtype
360         elem  *rtype // array element type
361         slice *rtype // slice type
362         len   uintptr
363 }
364
365 // chanType represents a channel type.
366 type chanType struct {
367         rtype
368         elem *rtype  // channel element type
369         dir  uintptr // channel direction (ChanDir)
370 }
371
372 // funcType represents a function type.
373 //
374 // A *rtype for each in and out parameter is stored in an array that
375 // directly follows the funcType (and possibly its uncommonType). So
376 // a function type with one method, one input, and one output is:
377 //
378 //      struct {
379 //              funcType
380 //              uncommonType
381 //              [2]*rtype    // [0] is in, [1] is out
382 //      }
383 type funcType struct {
384         rtype
385         inCount  uint16
386         outCount uint16 // top bit is set if last input parameter is ...
387 }
388
389 // imethod represents a method on an interface type
390 type imethod struct {
391         name nameOff // name of method
392         typ  typeOff // .(*FuncType) underneath
393 }
394
395 // interfaceType represents an interface type.
396 type interfaceType struct {
397         rtype
398         pkgPath name      // import path
399         methods []imethod // sorted by hash
400 }
401
402 // mapType represents a map type.
403 type mapType struct {
404         rtype
405         key    *rtype // map key type
406         elem   *rtype // map element (value) type
407         bucket *rtype // internal bucket structure
408         // function for hashing keys (ptr to key, seed) -> hash
409         hasher     func(unsafe.Pointer, uintptr) uintptr
410         keysize    uint8  // size of key slot
411         valuesize  uint8  // size of value slot
412         bucketsize uint16 // size of bucket
413         flags      uint32
414 }
415
416 // ptrType represents a pointer type.
417 type ptrType struct {
418         rtype
419         elem *rtype // pointer element (pointed at) type
420 }
421
422 // sliceType represents a slice type.
423 type sliceType struct {
424         rtype
425         elem *rtype // slice element type
426 }
427
428 // Struct field
429 type structField struct {
430         name        name    // name is always non-empty
431         typ         *rtype  // type of field
432         offsetEmbed uintptr // byte offset of field<<1 | isEmbedded
433 }
434
435 func (f *structField) offset() uintptr {
436         return f.offsetEmbed >> 1
437 }
438
439 func (f *structField) embedded() bool {
440         return f.offsetEmbed&1 != 0
441 }
442
443 // structType represents a struct type.
444 type structType struct {
445         rtype
446         pkgPath name
447         fields  []structField // sorted by offset
448 }
449
450 // name is an encoded type name with optional extra data.
451 //
452 // The first byte is a bit field containing:
453 //
454 //      1<<0 the name is exported
455 //      1<<1 tag data follows the name
456 //      1<<2 pkgPath nameOff follows the name and tag
457 //
458 // Following that, there is a varint-encoded length of the name,
459 // followed by the name itself.
460 //
461 // If tag data is present, it also has a varint-encoded length
462 // followed by the tag itself.
463 //
464 // If the import path follows, then 4 bytes at the end of
465 // the data form a nameOff. The import path is only set for concrete
466 // methods that are defined in a different package than their type.
467 //
468 // If a name starts with "*", then the exported bit represents
469 // whether the pointed to type is exported.
470 //
471 // Note: this encoding must match here and in:
472 //   cmd/compile/internal/reflectdata/reflect.go
473 //   runtime/type.go
474 //   internal/reflectlite/type.go
475 //   cmd/link/internal/ld/decodesym.go
476
477 type name struct {
478         bytes *byte
479 }
480
481 func (n name) data(off int, whySafe string) *byte {
482         return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe))
483 }
484
485 func (n name) isExported() bool {
486         return (*n.bytes)&(1<<0) != 0
487 }
488
489 func (n name) hasTag() bool {
490         return (*n.bytes)&(1<<1) != 0
491 }
492
493 // readVarint parses a varint as encoded by encoding/binary.
494 // It returns the number of encoded bytes and the encoded value.
495 func (n name) readVarint(off int) (int, int) {
496         v := 0
497         for i := 0; ; i++ {
498                 x := *n.data(off+i, "read varint")
499                 v += int(x&0x7f) << (7 * i)
500                 if x&0x80 == 0 {
501                         return i + 1, v
502                 }
503         }
504 }
505
506 // writeVarint writes n to buf in varint form. Returns the
507 // number of bytes written. n must be nonnegative.
508 // Writes at most 10 bytes.
509 func writeVarint(buf []byte, n int) int {
510         for i := 0; ; i++ {
511                 b := byte(n & 0x7f)
512                 n >>= 7
513                 if n == 0 {
514                         buf[i] = b
515                         return i + 1
516                 }
517                 buf[i] = b | 0x80
518         }
519 }
520
521 func (n name) name() (s string) {
522         if n.bytes == nil {
523                 return
524         }
525         i, l := n.readVarint(1)
526         hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
527         hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string"))
528         hdr.Len = l
529         return
530 }
531
532 func (n name) tag() (s string) {
533         if !n.hasTag() {
534                 return ""
535         }
536         i, l := n.readVarint(1)
537         i2, l2 := n.readVarint(1 + i + l)
538         hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
539         hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string"))
540         hdr.Len = l2
541         return
542 }
543
544 func (n name) pkgPath() string {
545         if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
546                 return ""
547         }
548         i, l := n.readVarint(1)
549         off := 1 + i + l
550         if n.hasTag() {
551                 i2, l2 := n.readVarint(off)
552                 off += i2 + l2
553         }
554         var nameOff int32
555         // Note that this field may not be aligned in memory,
556         // so we cannot use a direct int32 assignment here.
557         copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:])
558         pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))}
559         return pkgPathName.name()
560 }
561
562 func newName(n, tag string, exported bool) name {
563         if len(n) >= 1<<29 {
564                 panic("reflect.nameFrom: name too long: " + n[:1024] + "...")
565         }
566         if len(tag) >= 1<<29 {
567                 panic("reflect.nameFrom: tag too long: " + tag[:1024] + "...")
568         }
569         var nameLen [10]byte
570         var tagLen [10]byte
571         nameLenLen := writeVarint(nameLen[:], len(n))
572         tagLenLen := writeVarint(tagLen[:], len(tag))
573
574         var bits byte
575         l := 1 + nameLenLen + len(n)
576         if exported {
577                 bits |= 1 << 0
578         }
579         if len(tag) > 0 {
580                 l += tagLenLen + len(tag)
581                 bits |= 1 << 1
582         }
583
584         b := make([]byte, l)
585         b[0] = bits
586         copy(b[1:], nameLen[:nameLenLen])
587         copy(b[1+nameLenLen:], n)
588         if len(tag) > 0 {
589                 tb := b[1+nameLenLen+len(n):]
590                 copy(tb, tagLen[:tagLenLen])
591                 copy(tb[tagLenLen:], tag)
592         }
593
594         return name{bytes: &b[0]}
595 }
596
597 /*
598  * The compiler knows the exact layout of all the data structures above.
599  * The compiler does not know about the data structures and methods below.
600  */
601
602 // Method represents a single method.
603 type Method struct {
604         // Name is the method name.
605         Name string
606
607         // PkgPath is the package path that qualifies a lower case (unexported)
608         // method name. It is empty for upper case (exported) method names.
609         // The combination of PkgPath and Name uniquely identifies a method
610         // in a method set.
611         // See https://golang.org/ref/spec#Uniqueness_of_identifiers
612         PkgPath string
613
614         Type  Type  // method type
615         Func  Value // func with receiver as first argument
616         Index int   // index for Type.Method
617 }
618
619 // IsExported reports whether the method is exported.
620 func (m Method) IsExported() bool {
621         return m.PkgPath == ""
622 }
623
624 const (
625         kindDirectIface = 1 << 5
626         kindGCProg      = 1 << 6 // Type.gc points to GC program
627         kindMask        = (1 << 5) - 1
628 )
629
630 // String returns the name of k.
631 func (k Kind) String() string {
632         if int(k) < len(kindNames) {
633                 return kindNames[k]
634         }
635         return "kind" + strconv.Itoa(int(k))
636 }
637
638 var kindNames = []string{
639         Invalid:       "invalid",
640         Bool:          "bool",
641         Int:           "int",
642         Int8:          "int8",
643         Int16:         "int16",
644         Int32:         "int32",
645         Int64:         "int64",
646         Uint:          "uint",
647         Uint8:         "uint8",
648         Uint16:        "uint16",
649         Uint32:        "uint32",
650         Uint64:        "uint64",
651         Uintptr:       "uintptr",
652         Float32:       "float32",
653         Float64:       "float64",
654         Complex64:     "complex64",
655         Complex128:    "complex128",
656         Array:         "array",
657         Chan:          "chan",
658         Func:          "func",
659         Interface:     "interface",
660         Map:           "map",
661         Ptr:           "ptr",
662         Slice:         "slice",
663         String:        "string",
664         Struct:        "struct",
665         UnsafePointer: "unsafe.Pointer",
666 }
667
668 func (t *uncommonType) methods() []method {
669         if t.mcount == 0 {
670                 return nil
671         }
672         return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount]
673 }
674
675 func (t *uncommonType) exportedMethods() []method {
676         if t.xcount == 0 {
677                 return nil
678         }
679         return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount]
680 }
681
682 // resolveNameOff resolves a name offset from a base pointer.
683 // The (*rtype).nameOff method is a convenience wrapper for this function.
684 // Implemented in the runtime package.
685 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
686
687 // resolveTypeOff resolves an *rtype offset from a base type.
688 // The (*rtype).typeOff method is a convenience wrapper for this function.
689 // Implemented in the runtime package.
690 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
691
692 // resolveTextOff resolves a function pointer offset from a base type.
693 // The (*rtype).textOff method is a convenience wrapper for this function.
694 // Implemented in the runtime package.
695 func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
696
697 // addReflectOff adds a pointer to the reflection lookup map in the runtime.
698 // It returns a new ID that can be used as a typeOff or textOff, and will
699 // be resolved correctly. Implemented in the runtime package.
700 func addReflectOff(ptr unsafe.Pointer) int32
701
702 // resolveReflectName adds a name to the reflection lookup map in the runtime.
703 // It returns a new nameOff that can be used to refer to the pointer.
704 func resolveReflectName(n name) nameOff {
705         return nameOff(addReflectOff(unsafe.Pointer(n.bytes)))
706 }
707
708 // resolveReflectType adds a *rtype to the reflection lookup map in the runtime.
709 // It returns a new typeOff that can be used to refer to the pointer.
710 func resolveReflectType(t *rtype) typeOff {
711         return typeOff(addReflectOff(unsafe.Pointer(t)))
712 }
713
714 // resolveReflectText adds a function pointer to the reflection lookup map in
715 // the runtime. It returns a new textOff that can be used to refer to the
716 // pointer.
717 func resolveReflectText(ptr unsafe.Pointer) textOff {
718         return textOff(addReflectOff(ptr))
719 }
720
721 type nameOff int32 // offset to a name
722 type typeOff int32 // offset to an *rtype
723 type textOff int32 // offset from top of text section
724
725 func (t *rtype) nameOff(off nameOff) name {
726         return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
727 }
728
729 func (t *rtype) typeOff(off typeOff) *rtype {
730         return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
731 }
732
733 func (t *rtype) textOff(off textOff) unsafe.Pointer {
734         return resolveTextOff(unsafe.Pointer(t), int32(off))
735 }
736
737 func (t *rtype) uncommon() *uncommonType {
738         if t.tflag&tflagUncommon == 0 {
739                 return nil
740         }
741         switch t.Kind() {
742         case Struct:
743                 return &(*structTypeUncommon)(unsafe.Pointer(t)).u
744         case Ptr:
745                 type u struct {
746                         ptrType
747                         u uncommonType
748                 }
749                 return &(*u)(unsafe.Pointer(t)).u
750         case Func:
751                 type u struct {
752                         funcType
753                         u uncommonType
754                 }
755                 return &(*u)(unsafe.Pointer(t)).u
756         case Slice:
757                 type u struct {
758                         sliceType
759                         u uncommonType
760                 }
761                 return &(*u)(unsafe.Pointer(t)).u
762         case Array:
763                 type u struct {
764                         arrayType
765                         u uncommonType
766                 }
767                 return &(*u)(unsafe.Pointer(t)).u
768         case Chan:
769                 type u struct {
770                         chanType
771                         u uncommonType
772                 }
773                 return &(*u)(unsafe.Pointer(t)).u
774         case Map:
775                 type u struct {
776                         mapType
777                         u uncommonType
778                 }
779                 return &(*u)(unsafe.Pointer(t)).u
780         case Interface:
781                 type u struct {
782                         interfaceType
783                         u uncommonType
784                 }
785                 return &(*u)(unsafe.Pointer(t)).u
786         default:
787                 type u struct {
788                         rtype
789                         u uncommonType
790                 }
791                 return &(*u)(unsafe.Pointer(t)).u
792         }
793 }
794
795 func (t *rtype) String() string {
796         s := t.nameOff(t.str).name()
797         if t.tflag&tflagExtraStar != 0 {
798                 return s[1:]
799         }
800         return s
801 }
802
803 func (t *rtype) Size() uintptr { return t.size }
804
805 func (t *rtype) Bits() int {
806         if t == nil {
807                 panic("reflect: Bits of nil Type")
808         }
809         k := t.Kind()
810         if k < Int || k > Complex128 {
811                 panic("reflect: Bits of non-arithmetic Type " + t.String())
812         }
813         return int(t.size) * 8
814 }
815
816 func (t *rtype) Align() int { return int(t.align) }
817
818 func (t *rtype) FieldAlign() int { return int(t.fieldAlign) }
819
820 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
821
822 func (t *rtype) pointers() bool { return t.ptrdata != 0 }
823
824 func (t *rtype) common() *rtype { return t }
825
826 func (t *rtype) exportedMethods() []method {
827         ut := t.uncommon()
828         if ut == nil {
829                 return nil
830         }
831         return ut.exportedMethods()
832 }
833
834 func (t *rtype) NumMethod() int {
835         if t.Kind() == Interface {
836                 tt := (*interfaceType)(unsafe.Pointer(t))
837                 return tt.NumMethod()
838         }
839         return len(t.exportedMethods())
840 }
841
842 func (t *rtype) Method(i int) (m Method) {
843         if t.Kind() == Interface {
844                 tt := (*interfaceType)(unsafe.Pointer(t))
845                 return tt.Method(i)
846         }
847         methods := t.exportedMethods()
848         if i < 0 || i >= len(methods) {
849                 panic("reflect: Method index out of range")
850         }
851         p := methods[i]
852         pname := t.nameOff(p.name)
853         m.Name = pname.name()
854         fl := flag(Func)
855         mtyp := t.typeOff(p.mtyp)
856         ft := (*funcType)(unsafe.Pointer(mtyp))
857         in := make([]Type, 0, 1+len(ft.in()))
858         in = append(in, t)
859         for _, arg := range ft.in() {
860                 in = append(in, arg)
861         }
862         out := make([]Type, 0, len(ft.out()))
863         for _, ret := range ft.out() {
864                 out = append(out, ret)
865         }
866         mt := FuncOf(in, out, ft.IsVariadic())
867         m.Type = mt
868         tfn := t.textOff(p.tfn)
869         fn := unsafe.Pointer(&tfn)
870         m.Func = Value{mt.(*rtype), fn, fl}
871
872         m.Index = i
873         return m
874 }
875
876 func (t *rtype) MethodByName(name string) (m Method, ok bool) {
877         if t.Kind() == Interface {
878                 tt := (*interfaceType)(unsafe.Pointer(t))
879                 return tt.MethodByName(name)
880         }
881         ut := t.uncommon()
882         if ut == nil {
883                 return Method{}, false
884         }
885         // TODO(mdempsky): Binary search.
886         for i, p := range ut.exportedMethods() {
887                 if t.nameOff(p.name).name() == name {
888                         return t.Method(i), true
889                 }
890         }
891         return Method{}, false
892 }
893
894 func (t *rtype) PkgPath() string {
895         if t.tflag&tflagNamed == 0 {
896                 return ""
897         }
898         ut := t.uncommon()
899         if ut == nil {
900                 return ""
901         }
902         return t.nameOff(ut.pkgPath).name()
903 }
904
905 func (t *rtype) hasName() bool {
906         return t.tflag&tflagNamed != 0
907 }
908
909 func (t *rtype) Name() string {
910         if !t.hasName() {
911                 return ""
912         }
913         s := t.String()
914         i := len(s) - 1
915         for i >= 0 && s[i] != '.' {
916                 i--
917         }
918         return s[i+1:]
919 }
920
921 func (t *rtype) ChanDir() ChanDir {
922         if t.Kind() != Chan {
923                 panic("reflect: ChanDir of non-chan type " + t.String())
924         }
925         tt := (*chanType)(unsafe.Pointer(t))
926         return ChanDir(tt.dir)
927 }
928
929 func (t *rtype) IsVariadic() bool {
930         if t.Kind() != Func {
931                 panic("reflect: IsVariadic of non-func type " + t.String())
932         }
933         tt := (*funcType)(unsafe.Pointer(t))
934         return tt.outCount&(1<<15) != 0
935 }
936
937 func (t *rtype) Elem() Type {
938         switch t.Kind() {
939         case Array:
940                 tt := (*arrayType)(unsafe.Pointer(t))
941                 return toType(tt.elem)
942         case Chan:
943                 tt := (*chanType)(unsafe.Pointer(t))
944                 return toType(tt.elem)
945         case Map:
946                 tt := (*mapType)(unsafe.Pointer(t))
947                 return toType(tt.elem)
948         case Ptr:
949                 tt := (*ptrType)(unsafe.Pointer(t))
950                 return toType(tt.elem)
951         case Slice:
952                 tt := (*sliceType)(unsafe.Pointer(t))
953                 return toType(tt.elem)
954         }
955         panic("reflect: Elem of invalid type " + t.String())
956 }
957
958 func (t *rtype) Field(i int) StructField {
959         if t.Kind() != Struct {
960                 panic("reflect: Field of non-struct type " + t.String())
961         }
962         tt := (*structType)(unsafe.Pointer(t))
963         return tt.Field(i)
964 }
965
966 func (t *rtype) FieldByIndex(index []int) StructField {
967         if t.Kind() != Struct {
968                 panic("reflect: FieldByIndex of non-struct type " + t.String())
969         }
970         tt := (*structType)(unsafe.Pointer(t))
971         return tt.FieldByIndex(index)
972 }
973
974 func (t *rtype) FieldByName(name string) (StructField, bool) {
975         if t.Kind() != Struct {
976                 panic("reflect: FieldByName of non-struct type " + t.String())
977         }
978         tt := (*structType)(unsafe.Pointer(t))
979         return tt.FieldByName(name)
980 }
981
982 func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
983         if t.Kind() != Struct {
984                 panic("reflect: FieldByNameFunc of non-struct type " + t.String())
985         }
986         tt := (*structType)(unsafe.Pointer(t))
987         return tt.FieldByNameFunc(match)
988 }
989
990 func (t *rtype) In(i int) Type {
991         if t.Kind() != Func {
992                 panic("reflect: In of non-func type " + t.String())
993         }
994         tt := (*funcType)(unsafe.Pointer(t))
995         return toType(tt.in()[i])
996 }
997
998 func (t *rtype) Key() Type {
999         if t.Kind() != Map {
1000                 panic("reflect: Key of non-map type " + t.String())
1001         }
1002         tt := (*mapType)(unsafe.Pointer(t))
1003         return toType(tt.key)
1004 }
1005
1006 func (t *rtype) Len() int {
1007         if t.Kind() != Array {
1008                 panic("reflect: Len of non-array type " + t.String())
1009         }
1010         tt := (*arrayType)(unsafe.Pointer(t))
1011         return int(tt.len)
1012 }
1013
1014 func (t *rtype) NumField() int {
1015         if t.Kind() != Struct {
1016                 panic("reflect: NumField of non-struct type " + t.String())
1017         }
1018         tt := (*structType)(unsafe.Pointer(t))
1019         return len(tt.fields)
1020 }
1021
1022 func (t *rtype) NumIn() int {
1023         if t.Kind() != Func {
1024                 panic("reflect: NumIn of non-func type " + t.String())
1025         }
1026         tt := (*funcType)(unsafe.Pointer(t))
1027         return int(tt.inCount)
1028 }
1029
1030 func (t *rtype) NumOut() int {
1031         if t.Kind() != Func {
1032                 panic("reflect: NumOut of non-func type " + t.String())
1033         }
1034         tt := (*funcType)(unsafe.Pointer(t))
1035         return len(tt.out())
1036 }
1037
1038 func (t *rtype) Out(i int) Type {
1039         if t.Kind() != Func {
1040                 panic("reflect: Out of non-func type " + t.String())
1041         }
1042         tt := (*funcType)(unsafe.Pointer(t))
1043         return toType(tt.out()[i])
1044 }
1045
1046 func (t *funcType) in() []*rtype {
1047         uadd := unsafe.Sizeof(*t)
1048         if t.tflag&tflagUncommon != 0 {
1049                 uadd += unsafe.Sizeof(uncommonType{})
1050         }
1051         if t.inCount == 0 {
1052                 return nil
1053         }
1054         return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount]
1055 }
1056
1057 func (t *funcType) out() []*rtype {
1058         uadd := unsafe.Sizeof(*t)
1059         if t.tflag&tflagUncommon != 0 {
1060                 uadd += unsafe.Sizeof(uncommonType{})
1061         }
1062         outCount := t.outCount & (1<<15 - 1)
1063         if outCount == 0 {
1064                 return nil
1065         }
1066         return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount]
1067 }
1068
1069 // add returns p+x.
1070 //
1071 // The whySafe string is ignored, so that the function still inlines
1072 // as efficiently as p+x, but all call sites should use the string to
1073 // record why the addition is safe, which is to say why the addition
1074 // does not cause x to advance to the very end of p's allocation
1075 // and therefore point incorrectly at the next block in memory.
1076 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
1077         return unsafe.Pointer(uintptr(p) + x)
1078 }
1079
1080 func (d ChanDir) String() string {
1081         switch d {
1082         case SendDir:
1083                 return "chan<-"
1084         case RecvDir:
1085                 return "<-chan"
1086         case BothDir:
1087                 return "chan"
1088         }
1089         return "ChanDir" + strconv.Itoa(int(d))
1090 }
1091
1092 // Method returns the i'th method in the type's method set.
1093 func (t *interfaceType) Method(i int) (m Method) {
1094         if i < 0 || i >= len(t.methods) {
1095                 return
1096         }
1097         p := &t.methods[i]
1098         pname := t.nameOff(p.name)
1099         m.Name = pname.name()
1100         if !pname.isExported() {
1101                 m.PkgPath = pname.pkgPath()
1102                 if m.PkgPath == "" {
1103                         m.PkgPath = t.pkgPath.name()
1104                 }
1105         }
1106         m.Type = toType(t.typeOff(p.typ))
1107         m.Index = i
1108         return
1109 }
1110
1111 // NumMethod returns the number of interface methods in the type's method set.
1112 func (t *interfaceType) NumMethod() int { return len(t.methods) }
1113
1114 // MethodByName method with the given name in the type's method set.
1115 func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
1116         if t == nil {
1117                 return
1118         }
1119         var p *imethod
1120         for i := range t.methods {
1121                 p = &t.methods[i]
1122                 if t.nameOff(p.name).name() == name {
1123                         return t.Method(i), true
1124                 }
1125         }
1126         return
1127 }
1128
1129 // A StructField describes a single field in a struct.
1130 type StructField struct {
1131         // Name is the field name.
1132         Name string
1133
1134         // PkgPath is the package path that qualifies a lower case (unexported)
1135         // field name. It is empty for upper case (exported) field names.
1136         // See https://golang.org/ref/spec#Uniqueness_of_identifiers
1137         PkgPath string
1138
1139         Type      Type      // field type
1140         Tag       StructTag // field tag string
1141         Offset    uintptr   // offset within struct, in bytes
1142         Index     []int     // index sequence for Type.FieldByIndex
1143         Anonymous bool      // is an embedded field
1144 }
1145
1146 // IsExported reports whether the field is exported.
1147 func (f StructField) IsExported() bool {
1148         return f.PkgPath == ""
1149 }
1150
1151 // A StructTag is the tag string in a struct field.
1152 //
1153 // By convention, tag strings are a concatenation of
1154 // optionally space-separated key:"value" pairs.
1155 // Each key is a non-empty string consisting of non-control
1156 // characters other than space (U+0020 ' '), quote (U+0022 '"'),
1157 // and colon (U+003A ':').  Each value is quoted using U+0022 '"'
1158 // characters and Go string literal syntax.
1159 type StructTag string
1160
1161 // Get returns the value associated with key in the tag string.
1162 // If there is no such key in the tag, Get returns the empty string.
1163 // If the tag does not have the conventional format, the value
1164 // returned by Get is unspecified. To determine whether a tag is
1165 // explicitly set to the empty string, use Lookup.
1166 func (tag StructTag) Get(key string) string {
1167         v, _ := tag.Lookup(key)
1168         return v
1169 }
1170
1171 // Lookup returns the value associated with key in the tag string.
1172 // If the key is present in the tag the value (which may be empty)
1173 // is returned. Otherwise the returned value will be the empty string.
1174 // The ok return value reports whether the value was explicitly set in
1175 // the tag string. If the tag does not have the conventional format,
1176 // the value returned by Lookup is unspecified.
1177 func (tag StructTag) Lookup(key string) (value string, ok bool) {
1178         // When modifying this code, also update the validateStructTag code
1179         // in cmd/vet/structtag.go.
1180
1181         for tag != "" {
1182                 // Skip leading space.
1183                 i := 0
1184                 for i < len(tag) && tag[i] == ' ' {
1185                         i++
1186                 }
1187                 tag = tag[i:]
1188                 if tag == "" {
1189                         break
1190                 }
1191
1192                 // Scan to colon. A space, a quote or a control character is a syntax error.
1193                 // Strictly speaking, control chars include the range [0x7f, 0x9f], not just
1194                 // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
1195                 // as it is simpler to inspect the tag's bytes than the tag's runes.
1196                 i = 0
1197                 for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
1198                         i++
1199                 }
1200                 if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
1201                         break
1202                 }
1203                 name := string(tag[:i])
1204                 tag = tag[i+1:]
1205
1206                 // Scan quoted string to find value.
1207                 i = 1
1208                 for i < len(tag) && tag[i] != '"' {
1209                         if tag[i] == '\\' {
1210                                 i++
1211                         }
1212                         i++
1213                 }
1214                 if i >= len(tag) {
1215                         break
1216                 }
1217                 qvalue := string(tag[:i+1])
1218                 tag = tag[i+1:]
1219
1220                 if key == name {
1221                         value, err := strconv.Unquote(qvalue)
1222                         if err != nil {
1223                                 break
1224                         }
1225                         return value, true
1226                 }
1227         }
1228         return "", false
1229 }
1230
1231 // Field returns the i'th struct field.
1232 func (t *structType) Field(i int) (f StructField) {
1233         if i < 0 || i >= len(t.fields) {
1234                 panic("reflect: Field index out of bounds")
1235         }
1236         p := &t.fields[i]
1237         f.Type = toType(p.typ)
1238         f.Name = p.name.name()
1239         f.Anonymous = p.embedded()
1240         if !p.name.isExported() {
1241                 f.PkgPath = t.pkgPath.name()
1242         }
1243         if tag := p.name.tag(); tag != "" {
1244                 f.Tag = StructTag(tag)
1245         }
1246         f.Offset = p.offset()
1247
1248         // NOTE(rsc): This is the only allocation in the interface
1249         // presented by a reflect.Type. It would be nice to avoid,
1250         // at least in the common cases, but we need to make sure
1251         // that misbehaving clients of reflect cannot affect other
1252         // uses of reflect. One possibility is CL 5371098, but we
1253         // postponed that ugliness until there is a demonstrated
1254         // need for the performance. This is issue 2320.
1255         f.Index = []int{i}
1256         return
1257 }
1258
1259 // TODO(gri): Should there be an error/bool indicator if the index
1260 //            is wrong for FieldByIndex?
1261
1262 // FieldByIndex returns the nested field corresponding to index.
1263 func (t *structType) FieldByIndex(index []int) (f StructField) {
1264         f.Type = toType(&t.rtype)
1265         for i, x := range index {
1266                 if i > 0 {
1267                         ft := f.Type
1268                         if ft.Kind() == Ptr && ft.Elem().Kind() == Struct {
1269                                 ft = ft.Elem()
1270                         }
1271                         f.Type = ft
1272                 }
1273                 f = f.Type.Field(x)
1274         }
1275         return
1276 }
1277
1278 // A fieldScan represents an item on the fieldByNameFunc scan work list.
1279 type fieldScan struct {
1280         typ   *structType
1281         index []int
1282 }
1283
1284 // FieldByNameFunc returns the struct field with a name that satisfies the
1285 // match function and a boolean to indicate if the field was found.
1286 func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) {
1287         // This uses the same condition that the Go language does: there must be a unique instance
1288         // of the match at a given depth level. If there are multiple instances of a match at the
1289         // same depth, they annihilate each other and inhibit any possible match at a lower level.
1290         // The algorithm is breadth first search, one depth level at a time.
1291
1292         // The current and next slices are work queues:
1293         // current lists the fields to visit on this depth level,
1294         // and next lists the fields on the next lower level.
1295         current := []fieldScan{}
1296         next := []fieldScan{{typ: t}}
1297
1298         // nextCount records the number of times an embedded type has been
1299         // encountered and considered for queueing in the 'next' slice.
1300         // We only queue the first one, but we increment the count on each.
1301         // If a struct type T can be reached more than once at a given depth level,
1302         // then it annihilates itself and need not be considered at all when we
1303         // process that next depth level.
1304         var nextCount map[*structType]int
1305
1306         // visited records the structs that have been considered already.
1307         // Embedded pointer fields can create cycles in the graph of
1308         // reachable embedded types; visited avoids following those cycles.
1309         // It also avoids duplicated effort: if we didn't find the field in an
1310         // embedded type T at level 2, we won't find it in one at level 4 either.
1311         visited := map[*structType]bool{}
1312
1313         for len(next) > 0 {
1314                 current, next = next, current[:0]
1315                 count := nextCount
1316                 nextCount = nil
1317
1318                 // Process all the fields at this depth, now listed in 'current'.
1319                 // The loop queues embedded fields found in 'next', for processing during the next
1320                 // iteration. The multiplicity of the 'current' field counts is recorded
1321                 // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
1322                 for _, scan := range current {
1323                         t := scan.typ
1324                         if visited[t] {
1325                                 // We've looked through this type before, at a higher level.
1326                                 // That higher level would shadow the lower level we're now at,
1327                                 // so this one can't be useful to us. Ignore it.
1328                                 continue
1329                         }
1330                         visited[t] = true
1331                         for i := range t.fields {
1332                                 f := &t.fields[i]
1333                                 // Find name and (for embedded field) type for field f.
1334                                 fname := f.name.name()
1335                                 var ntyp *rtype
1336                                 if f.embedded() {
1337                                         // Embedded field of type T or *T.
1338                                         ntyp = f.typ
1339                                         if ntyp.Kind() == Ptr {
1340                                                 ntyp = ntyp.Elem().common()
1341                                         }
1342                                 }
1343
1344                                 // Does it match?
1345                                 if match(fname) {
1346                                         // Potential match
1347                                         if count[t] > 1 || ok {
1348                                                 // Name appeared multiple times at this level: annihilate.
1349                                                 return StructField{}, false
1350                                         }
1351                                         result = t.Field(i)
1352                                         result.Index = nil
1353                                         result.Index = append(result.Index, scan.index...)
1354                                         result.Index = append(result.Index, i)
1355                                         ok = true
1356                                         continue
1357                                 }
1358
1359                                 // Queue embedded struct fields for processing with next level,
1360                                 // but only if we haven't seen a match yet at this level and only
1361                                 // if the embedded types haven't already been queued.
1362                                 if ok || ntyp == nil || ntyp.Kind() != Struct {
1363                                         continue
1364                                 }
1365                                 styp := (*structType)(unsafe.Pointer(ntyp))
1366                                 if nextCount[styp] > 0 {
1367                                         nextCount[styp] = 2 // exact multiple doesn't matter
1368                                         continue
1369                                 }
1370                                 if nextCount == nil {
1371                                         nextCount = map[*structType]int{}
1372                                 }
1373                                 nextCount[styp] = 1
1374                                 if count[t] > 1 {
1375                                         nextCount[styp] = 2 // exact multiple doesn't matter
1376                                 }
1377                                 var index []int
1378                                 index = append(index, scan.index...)
1379                                 index = append(index, i)
1380                                 next = append(next, fieldScan{styp, index})
1381                         }
1382                 }
1383                 if ok {
1384                         break
1385                 }
1386         }
1387         return
1388 }
1389
1390 // FieldByName returns the struct field with the given name
1391 // and a boolean to indicate if the field was found.
1392 func (t *structType) FieldByName(name string) (f StructField, present bool) {
1393         // Quick check for top-level name, or struct without embedded fields.
1394         hasEmbeds := false
1395         if name != "" {
1396                 for i := range t.fields {
1397                         tf := &t.fields[i]
1398                         if tf.name.name() == name {
1399                                 return t.Field(i), true
1400                         }
1401                         if tf.embedded() {
1402                                 hasEmbeds = true
1403                         }
1404                 }
1405         }
1406         if !hasEmbeds {
1407                 return
1408         }
1409         return t.FieldByNameFunc(func(s string) bool { return s == name })
1410 }
1411
1412 // TypeOf returns the reflection Type that represents the dynamic type of i.
1413 // If i is a nil interface value, TypeOf returns nil.
1414 func TypeOf(i interface{}) Type {
1415         eface := *(*emptyInterface)(unsafe.Pointer(&i))
1416         return toType(eface.typ)
1417 }
1418
1419 // ptrMap is the cache for PtrTo.
1420 var ptrMap sync.Map // map[*rtype]*ptrType
1421
1422 // PtrTo returns the pointer type with element t.
1423 // For example, if t represents type Foo, PtrTo(t) represents *Foo.
1424 func PtrTo(t Type) Type {
1425         return t.(*rtype).ptrTo()
1426 }
1427
1428 func (t *rtype) ptrTo() *rtype {
1429         if t.ptrToThis != 0 {
1430                 return t.typeOff(t.ptrToThis)
1431         }
1432
1433         // Check the cache.
1434         if pi, ok := ptrMap.Load(t); ok {
1435                 return &pi.(*ptrType).rtype
1436         }
1437
1438         // Look in known types.
1439         s := "*" + t.String()
1440         for _, tt := range typesByString(s) {
1441                 p := (*ptrType)(unsafe.Pointer(tt))
1442                 if p.elem != t {
1443                         continue
1444                 }
1445                 pi, _ := ptrMap.LoadOrStore(t, p)
1446                 return &pi.(*ptrType).rtype
1447         }
1448
1449         // Create a new ptrType starting with the description
1450         // of an *unsafe.Pointer.
1451         var iptr interface{} = (*unsafe.Pointer)(nil)
1452         prototype := *(**ptrType)(unsafe.Pointer(&iptr))
1453         pp := *prototype
1454
1455         pp.str = resolveReflectName(newName(s, "", false))
1456         pp.ptrToThis = 0
1457
1458         // For the type structures linked into the binary, the
1459         // compiler provides a good hash of the string.
1460         // Create a good hash for the new string by using
1461         // the FNV-1 hash's mixing function to combine the
1462         // old hash and the new "*".
1463         pp.hash = fnv1(t.hash, '*')
1464
1465         pp.elem = t
1466
1467         pi, _ := ptrMap.LoadOrStore(t, &pp)
1468         return &pi.(*ptrType).rtype
1469 }
1470
1471 // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
1472 func fnv1(x uint32, list ...byte) uint32 {
1473         for _, b := range list {
1474                 x = x*16777619 ^ uint32(b)
1475         }
1476         return x
1477 }
1478
1479 func (t *rtype) Implements(u Type) bool {
1480         if u == nil {
1481                 panic("reflect: nil type passed to Type.Implements")
1482         }
1483         if u.Kind() != Interface {
1484                 panic("reflect: non-interface type passed to Type.Implements")
1485         }
1486         return implements(u.(*rtype), t)
1487 }
1488
1489 func (t *rtype) AssignableTo(u Type) bool {
1490         if u == nil {
1491                 panic("reflect: nil type passed to Type.AssignableTo")
1492         }
1493         uu := u.(*rtype)
1494         return directlyAssignable(uu, t) || implements(uu, t)
1495 }
1496
1497 func (t *rtype) ConvertibleTo(u Type) bool {
1498         if u == nil {
1499                 panic("reflect: nil type passed to Type.ConvertibleTo")
1500         }
1501         uu := u.(*rtype)
1502         return convertOp(uu, t) != nil
1503 }
1504
1505 func (t *rtype) Comparable() bool {
1506         return t.equal != nil
1507 }
1508
1509 // implements reports whether the type V implements the interface type T.
1510 func implements(T, V *rtype) bool {
1511         if T.Kind() != Interface {
1512                 return false
1513         }
1514         t := (*interfaceType)(unsafe.Pointer(T))
1515         if len(t.methods) == 0 {
1516                 return true
1517         }
1518
1519         // The same algorithm applies in both cases, but the
1520         // method tables for an interface type and a concrete type
1521         // are different, so the code is duplicated.
1522         // In both cases the algorithm is a linear scan over the two
1523         // lists - T's methods and V's methods - simultaneously.
1524         // Since method tables are stored in a unique sorted order
1525         // (alphabetical, with no duplicate method names), the scan
1526         // through V's methods must hit a match for each of T's
1527         // methods along the way, or else V does not implement T.
1528         // This lets us run the scan in overall linear time instead of
1529         // the quadratic time  a naive search would require.
1530         // See also ../runtime/iface.go.
1531         if V.Kind() == Interface {
1532                 v := (*interfaceType)(unsafe.Pointer(V))
1533                 i := 0
1534                 for j := 0; j < len(v.methods); j++ {
1535                         tm := &t.methods[i]
1536                         tmName := t.nameOff(tm.name)
1537                         vm := &v.methods[j]
1538                         vmName := V.nameOff(vm.name)
1539                         if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) {
1540                                 if !tmName.isExported() {
1541                                         tmPkgPath := tmName.pkgPath()
1542                                         if tmPkgPath == "" {
1543                                                 tmPkgPath = t.pkgPath.name()
1544                                         }
1545                                         vmPkgPath := vmName.pkgPath()
1546                                         if vmPkgPath == "" {
1547                                                 vmPkgPath = v.pkgPath.name()
1548                                         }
1549                                         if tmPkgPath != vmPkgPath {
1550                                                 continue
1551                                         }
1552                                 }
1553                                 if i++; i >= len(t.methods) {
1554                                         return true
1555                                 }
1556                         }
1557                 }
1558                 return false
1559         }
1560
1561         v := V.uncommon()
1562         if v == nil {
1563                 return false
1564         }
1565         i := 0
1566         vmethods := v.methods()
1567         for j := 0; j < int(v.mcount); j++ {
1568                 tm := &t.methods[i]
1569                 tmName := t.nameOff(tm.name)
1570                 vm := vmethods[j]
1571                 vmName := V.nameOff(vm.name)
1572                 if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) {
1573                         if !tmName.isExported() {
1574                                 tmPkgPath := tmName.pkgPath()
1575                                 if tmPkgPath == "" {
1576                                         tmPkgPath = t.pkgPath.name()
1577                                 }
1578                                 vmPkgPath := vmName.pkgPath()
1579                                 if vmPkgPath == "" {
1580                                         vmPkgPath = V.nameOff(v.pkgPath).name()
1581                                 }
1582                                 if tmPkgPath != vmPkgPath {
1583                                         continue
1584                                 }
1585                         }
1586                         if i++; i >= len(t.methods) {
1587                                 return true
1588                         }
1589                 }
1590         }
1591         return false
1592 }
1593
1594 // specialChannelAssignability reports whether a value x of channel type V
1595 // can be directly assigned (using memmove) to another channel type T.
1596 // https://golang.org/doc/go_spec.html#Assignability
1597 // T and V must be both of Chan kind.
1598 func specialChannelAssignability(T, V *rtype) bool {
1599         // Special case:
1600         // x is a bidirectional channel value, T is a channel type,
1601         // x's type V and T have identical element types,
1602         // and at least one of V or T is not a defined type.
1603         return V.ChanDir() == BothDir && (T.Name() == "" || V.Name() == "") && haveIdenticalType(T.Elem(), V.Elem(), true)
1604 }
1605
1606 // directlyAssignable reports whether a value x of type V can be directly
1607 // assigned (using memmove) to a value of type T.
1608 // https://golang.org/doc/go_spec.html#Assignability
1609 // Ignoring the interface rules (implemented elsewhere)
1610 // and the ideal constant rules (no ideal constants at run time).
1611 func directlyAssignable(T, V *rtype) bool {
1612         // x's type V is identical to T?
1613         if T == V {
1614                 return true
1615         }
1616
1617         // Otherwise at least one of T and V must not be defined
1618         // and they must have the same kind.
1619         if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
1620                 return false
1621         }
1622
1623         if T.Kind() == Chan && specialChannelAssignability(T, V) {
1624                 return true
1625         }
1626
1627         // x's type T and V must have identical underlying types.
1628         return haveIdenticalUnderlyingType(T, V, true)
1629 }
1630
1631 func haveIdenticalType(T, V Type, cmpTags bool) bool {
1632         if cmpTags {
1633                 return T == V
1634         }
1635
1636         if T.Name() != V.Name() || T.Kind() != V.Kind() || T.PkgPath() != V.PkgPath() {
1637                 return false
1638         }
1639
1640         return haveIdenticalUnderlyingType(T.common(), V.common(), false)
1641 }
1642
1643 func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
1644         if T == V {
1645                 return true
1646         }
1647
1648         kind := T.Kind()
1649         if kind != V.Kind() {
1650                 return false
1651         }
1652
1653         // Non-composite types of equal kind have same underlying type
1654         // (the predefined instance of the type).
1655         if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
1656                 return true
1657         }
1658
1659         // Composite types.
1660         switch kind {
1661         case Array:
1662                 return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
1663
1664         case Chan:
1665                 return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
1666
1667         case Func:
1668                 t := (*funcType)(unsafe.Pointer(T))
1669                 v := (*funcType)(unsafe.Pointer(V))
1670                 if t.outCount != v.outCount || t.inCount != v.inCount {
1671                         return false
1672                 }
1673                 for i := 0; i < t.NumIn(); i++ {
1674                         if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
1675                                 return false
1676                         }
1677                 }
1678                 for i := 0; i < t.NumOut(); i++ {
1679                         if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
1680                                 return false
1681                         }
1682                 }
1683                 return true
1684
1685         case Interface:
1686                 t := (*interfaceType)(unsafe.Pointer(T))
1687                 v := (*interfaceType)(unsafe.Pointer(V))
1688                 if len(t.methods) == 0 && len(v.methods) == 0 {
1689                         return true
1690                 }
1691                 // Might have the same methods but still
1692                 // need a run time conversion.
1693                 return false
1694
1695         case Map:
1696                 return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
1697
1698         case Ptr, Slice:
1699                 return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
1700
1701         case Struct:
1702                 t := (*structType)(unsafe.Pointer(T))
1703                 v := (*structType)(unsafe.Pointer(V))
1704                 if len(t.fields) != len(v.fields) {
1705                         return false
1706                 }
1707                 if t.pkgPath.name() != v.pkgPath.name() {
1708                         return false
1709                 }
1710                 for i := range t.fields {
1711                         tf := &t.fields[i]
1712                         vf := &v.fields[i]
1713                         if tf.name.name() != vf.name.name() {
1714                                 return false
1715                         }
1716                         if !haveIdenticalType(tf.typ, vf.typ, cmpTags) {
1717                                 return false
1718                         }
1719                         if cmpTags && tf.name.tag() != vf.name.tag() {
1720                                 return false
1721                         }
1722                         if tf.offsetEmbed != vf.offsetEmbed {
1723                                 return false
1724                         }
1725                 }
1726                 return true
1727         }
1728
1729         return false
1730 }
1731
1732 // typelinks is implemented in package runtime.
1733 // It returns a slice of the sections in each module,
1734 // and a slice of *rtype offsets in each module.
1735 //
1736 // The types in each module are sorted by string. That is, the first
1737 // two linked types of the first module are:
1738 //
1739 //      d0 := sections[0]
1740 //      t1 := (*rtype)(add(d0, offset[0][0]))
1741 //      t2 := (*rtype)(add(d0, offset[0][1]))
1742 //
1743 // and
1744 //
1745 //      t1.String() < t2.String()
1746 //
1747 // Note that strings are not unique identifiers for types:
1748 // there can be more than one with a given string.
1749 // Only types we might want to look up are included:
1750 // pointers, channels, maps, slices, and arrays.
1751 func typelinks() (sections []unsafe.Pointer, offset [][]int32)
1752
1753 func rtypeOff(section unsafe.Pointer, off int32) *rtype {
1754         return (*rtype)(add(section, uintptr(off), "sizeof(rtype) > 0"))
1755 }
1756
1757 // typesByString returns the subslice of typelinks() whose elements have
1758 // the given string representation.
1759 // It may be empty (no known types with that string) or may have
1760 // multiple elements (multiple types with that string).
1761 func typesByString(s string) []*rtype {
1762         sections, offset := typelinks()
1763         var ret []*rtype
1764
1765         for offsI, offs := range offset {
1766                 section := sections[offsI]
1767
1768                 // We are looking for the first index i where the string becomes >= s.
1769                 // This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s).
1770                 i, j := 0, len(offs)
1771                 for i < j {
1772                         h := i + (j-i)>>1 // avoid overflow when computing h
1773                         // i â‰¤ h < j
1774                         if !(rtypeOff(section, offs[h]).String() >= s) {
1775                                 i = h + 1 // preserves f(i-1) == false
1776                         } else {
1777                                 j = h // preserves f(j) == true
1778                         }
1779                 }
1780                 // i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
1781
1782                 // Having found the first, linear scan forward to find the last.
1783                 // We could do a second binary search, but the caller is going
1784                 // to do a linear scan anyway.
1785                 for j := i; j < len(offs); j++ {
1786                         typ := rtypeOff(section, offs[j])
1787                         if typ.String() != s {
1788                                 break
1789                         }
1790                         ret = append(ret, typ)
1791                 }
1792         }
1793         return ret
1794 }
1795
1796 // The lookupCache caches ArrayOf, ChanOf, MapOf and SliceOf lookups.
1797 var lookupCache sync.Map // map[cacheKey]*rtype
1798
1799 // A cacheKey is the key for use in the lookupCache.
1800 // Four values describe any of the types we are looking for:
1801 // type kind, one or two subtypes, and an extra integer.
1802 type cacheKey struct {
1803         kind  Kind
1804         t1    *rtype
1805         t2    *rtype
1806         extra uintptr
1807 }
1808
1809 // The funcLookupCache caches FuncOf lookups.
1810 // FuncOf does not share the common lookupCache since cacheKey is not
1811 // sufficient to represent functions unambiguously.
1812 var funcLookupCache struct {
1813         sync.Mutex // Guards stores (but not loads) on m.
1814
1815         // m is a map[uint32][]*rtype keyed by the hash calculated in FuncOf.
1816         // Elements of m are append-only and thus safe for concurrent reading.
1817         m sync.Map
1818 }
1819
1820 // ChanOf returns the channel type with the given direction and element type.
1821 // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
1822 //
1823 // The gc runtime imposes a limit of 64 kB on channel element types.
1824 // If t's size is equal to or exceeds this limit, ChanOf panics.
1825 func ChanOf(dir ChanDir, t Type) Type {
1826         typ := t.(*rtype)
1827
1828         // Look in cache.
1829         ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
1830         if ch, ok := lookupCache.Load(ckey); ok {
1831                 return ch.(*rtype)
1832         }
1833
1834         // This restriction is imposed by the gc compiler and the runtime.
1835         if typ.size >= 1<<16 {
1836                 panic("reflect.ChanOf: element size too large")
1837         }
1838
1839         // Look in known types.
1840         var s string
1841         switch dir {
1842         default:
1843                 panic("reflect.ChanOf: invalid dir")
1844         case SendDir:
1845                 s = "chan<- " + typ.String()
1846         case RecvDir:
1847                 s = "<-chan " + typ.String()
1848         case BothDir:
1849                 typeStr := typ.String()
1850                 if typeStr[0] == '<' {
1851                         // typ is recv chan, need parentheses as "<-" associates with leftmost
1852                         // chan possible, see:
1853                         // * https://golang.org/ref/spec#Channel_types
1854                         // * https://github.com/golang/go/issues/39897
1855                         s = "chan (" + typeStr + ")"
1856                 } else {
1857                         s = "chan " + typeStr
1858                 }
1859         }
1860         for _, tt := range typesByString(s) {
1861                 ch := (*chanType)(unsafe.Pointer(tt))
1862                 if ch.elem == typ && ch.dir == uintptr(dir) {
1863                         ti, _ := lookupCache.LoadOrStore(ckey, tt)
1864                         return ti.(Type)
1865                 }
1866         }
1867
1868         // Make a channel type.
1869         var ichan interface{} = (chan unsafe.Pointer)(nil)
1870         prototype := *(**chanType)(unsafe.Pointer(&ichan))
1871         ch := *prototype
1872         ch.tflag = tflagRegularMemory
1873         ch.dir = uintptr(dir)
1874         ch.str = resolveReflectName(newName(s, "", false))
1875         ch.hash = fnv1(typ.hash, 'c', byte(dir))
1876         ch.elem = typ
1877
1878         ti, _ := lookupCache.LoadOrStore(ckey, &ch.rtype)
1879         return ti.(Type)
1880 }
1881
1882 // MapOf returns the map type with the given key and element types.
1883 // For example, if k represents int and e represents string,
1884 // MapOf(k, e) represents map[int]string.
1885 //
1886 // If the key type is not a valid map key type (that is, if it does
1887 // not implement Go's == operator), MapOf panics.
1888 func MapOf(key, elem Type) Type {
1889         ktyp := key.(*rtype)
1890         etyp := elem.(*rtype)
1891
1892         if ktyp.equal == nil {
1893                 panic("reflect.MapOf: invalid key type " + ktyp.String())
1894         }
1895
1896         // Look in cache.
1897         ckey := cacheKey{Map, ktyp, etyp, 0}
1898         if mt, ok := lookupCache.Load(ckey); ok {
1899                 return mt.(Type)
1900         }
1901
1902         // Look in known types.
1903         s := "map[" + ktyp.String() + "]" + etyp.String()
1904         for _, tt := range typesByString(s) {
1905                 mt := (*mapType)(unsafe.Pointer(tt))
1906                 if mt.key == ktyp && mt.elem == etyp {
1907                         ti, _ := lookupCache.LoadOrStore(ckey, tt)
1908                         return ti.(Type)
1909                 }
1910         }
1911
1912         // Make a map type.
1913         // Note: flag values must match those used in the TMAP case
1914         // in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
1915         var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
1916         mt := **(**mapType)(unsafe.Pointer(&imap))
1917         mt.str = resolveReflectName(newName(s, "", false))
1918         mt.tflag = 0
1919         mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
1920         mt.key = ktyp
1921         mt.elem = etyp
1922         mt.bucket = bucketOf(ktyp, etyp)
1923         mt.hasher = func(p unsafe.Pointer, seed uintptr) uintptr {
1924                 return typehash(ktyp, p, seed)
1925         }
1926         mt.flags = 0
1927         if ktyp.size > maxKeySize {
1928                 mt.keysize = uint8(goarch.PtrSize)
1929                 mt.flags |= 1 // indirect key
1930         } else {
1931                 mt.keysize = uint8(ktyp.size)
1932         }
1933         if etyp.size > maxValSize {
1934                 mt.valuesize = uint8(goarch.PtrSize)
1935                 mt.flags |= 2 // indirect value
1936         } else {
1937                 mt.valuesize = uint8(etyp.size)
1938         }
1939         mt.bucketsize = uint16(mt.bucket.size)
1940         if isReflexive(ktyp) {
1941                 mt.flags |= 4
1942         }
1943         if needKeyUpdate(ktyp) {
1944                 mt.flags |= 8
1945         }
1946         if hashMightPanic(ktyp) {
1947                 mt.flags |= 16
1948         }
1949         mt.ptrToThis = 0
1950
1951         ti, _ := lookupCache.LoadOrStore(ckey, &mt.rtype)
1952         return ti.(Type)
1953 }
1954
1955 // TODO(crawshaw): as these funcTypeFixedN structs have no methods,
1956 // they could be defined at runtime using the StructOf function.
1957 type funcTypeFixed4 struct {
1958         funcType
1959         args [4]*rtype
1960 }
1961 type funcTypeFixed8 struct {
1962         funcType
1963         args [8]*rtype
1964 }
1965 type funcTypeFixed16 struct {
1966         funcType
1967         args [16]*rtype
1968 }
1969 type funcTypeFixed32 struct {
1970         funcType
1971         args [32]*rtype
1972 }
1973 type funcTypeFixed64 struct {
1974         funcType
1975         args [64]*rtype
1976 }
1977 type funcTypeFixed128 struct {
1978         funcType
1979         args [128]*rtype
1980 }
1981
1982 // FuncOf returns the function type with the given argument and result types.
1983 // For example if k represents int and e represents string,
1984 // FuncOf([]Type{k}, []Type{e}, false) represents func(int) string.
1985 //
1986 // The variadic argument controls whether the function is variadic. FuncOf
1987 // panics if the in[len(in)-1] does not represent a slice and variadic is
1988 // true.
1989 func FuncOf(in, out []Type, variadic bool) Type {
1990         if variadic && (len(in) == 0 || in[len(in)-1].Kind() != Slice) {
1991                 panic("reflect.FuncOf: last arg of variadic func must be slice")
1992         }
1993
1994         // Make a func type.
1995         var ifunc interface{} = (func())(nil)
1996         prototype := *(**funcType)(unsafe.Pointer(&ifunc))
1997         n := len(in) + len(out)
1998
1999         var ft *funcType
2000         var args []*rtype
2001         switch {
2002         case n <= 4:
2003                 fixed := new(funcTypeFixed4)
2004                 args = fixed.args[:0:len(fixed.args)]
2005                 ft = &fixed.funcType
2006         case n <= 8:
2007                 fixed := new(funcTypeFixed8)
2008                 args = fixed.args[:0:len(fixed.args)]
2009                 ft = &fixed.funcType
2010         case n <= 16:
2011                 fixed := new(funcTypeFixed16)
2012                 args = fixed.args[:0:len(fixed.args)]
2013                 ft = &fixed.funcType
2014         case n <= 32:
2015                 fixed := new(funcTypeFixed32)
2016                 args = fixed.args[:0:len(fixed.args)]
2017                 ft = &fixed.funcType
2018         case n <= 64:
2019                 fixed := new(funcTypeFixed64)
2020                 args = fixed.args[:0:len(fixed.args)]
2021                 ft = &fixed.funcType
2022         case n <= 128:
2023                 fixed := new(funcTypeFixed128)
2024                 args = fixed.args[:0:len(fixed.args)]
2025                 ft = &fixed.funcType
2026         default:
2027                 panic("reflect.FuncOf: too many arguments")
2028         }
2029         *ft = *prototype
2030
2031         // Build a hash and minimally populate ft.
2032         var hash uint32
2033         for _, in := range in {
2034                 t := in.(*rtype)
2035                 args = append(args, t)
2036                 hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash))
2037         }
2038         if variadic {
2039                 hash = fnv1(hash, 'v')
2040         }
2041         hash = fnv1(hash, '.')
2042         for _, out := range out {
2043                 t := out.(*rtype)
2044                 args = append(args, t)
2045                 hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash))
2046         }
2047         if len(args) > 50 {
2048                 panic("reflect.FuncOf does not support more than 50 arguments")
2049         }
2050         ft.tflag = 0
2051         ft.hash = hash
2052         ft.inCount = uint16(len(in))
2053         ft.outCount = uint16(len(out))
2054         if variadic {
2055                 ft.outCount |= 1 << 15
2056         }
2057
2058         // Look in cache.
2059         if ts, ok := funcLookupCache.m.Load(hash); ok {
2060                 for _, t := range ts.([]*rtype) {
2061                         if haveIdenticalUnderlyingType(&ft.rtype, t, true) {
2062                                 return t
2063                         }
2064                 }
2065         }
2066
2067         // Not in cache, lock and retry.
2068         funcLookupCache.Lock()
2069         defer funcLookupCache.Unlock()
2070         if ts, ok := funcLookupCache.m.Load(hash); ok {
2071                 for _, t := range ts.([]*rtype) {
2072                         if haveIdenticalUnderlyingType(&ft.rtype, t, true) {
2073                                 return t
2074                         }
2075                 }
2076         }
2077
2078         addToCache := func(tt *rtype) Type {
2079                 var rts []*rtype
2080                 if rti, ok := funcLookupCache.m.Load(hash); ok {
2081                         rts = rti.([]*rtype)
2082                 }
2083                 funcLookupCache.m.Store(hash, append(rts, tt))
2084                 return tt
2085         }
2086
2087         // Look in known types for the same string representation.
2088         str := funcStr(ft)
2089         for _, tt := range typesByString(str) {
2090                 if haveIdenticalUnderlyingType(&ft.rtype, tt, true) {
2091                         return addToCache(tt)
2092                 }
2093         }
2094
2095         // Populate the remaining fields of ft and store in cache.
2096         ft.str = resolveReflectName(newName(str, "", false))
2097         ft.ptrToThis = 0
2098         return addToCache(&ft.rtype)
2099 }
2100
2101 // funcStr builds a string representation of a funcType.
2102 func funcStr(ft *funcType) string {
2103         repr := make([]byte, 0, 64)
2104         repr = append(repr, "func("...)
2105         for i, t := range ft.in() {
2106                 if i > 0 {
2107                         repr = append(repr, ", "...)
2108                 }
2109                 if ft.IsVariadic() && i == int(ft.inCount)-1 {
2110                         repr = append(repr, "..."...)
2111                         repr = append(repr, (*sliceType)(unsafe.Pointer(t)).elem.String()...)
2112                 } else {
2113                         repr = append(repr, t.String()...)
2114                 }
2115         }
2116         repr = append(repr, ')')
2117         out := ft.out()
2118         if len(out) == 1 {
2119                 repr = append(repr, ' ')
2120         } else if len(out) > 1 {
2121                 repr = append(repr, " ("...)
2122         }
2123         for i, t := range out {
2124                 if i > 0 {
2125                         repr = append(repr, ", "...)
2126                 }
2127                 repr = append(repr, t.String()...)
2128         }
2129         if len(out) > 1 {
2130                 repr = append(repr, ')')
2131         }
2132         return string(repr)
2133 }
2134
2135 // isReflexive reports whether the == operation on the type is reflexive.
2136 // That is, x == x for all values x of type t.
2137 func isReflexive(t *rtype) bool {
2138         switch t.Kind() {
2139         case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Ptr, String, UnsafePointer:
2140                 return true
2141         case Float32, Float64, Complex64, Complex128, Interface:
2142                 return false
2143         case Array:
2144                 tt := (*arrayType)(unsafe.Pointer(t))
2145                 return isReflexive(tt.elem)
2146         case Struct:
2147                 tt := (*structType)(unsafe.Pointer(t))
2148                 for _, f := range tt.fields {
2149                         if !isReflexive(f.typ) {
2150                                 return false
2151                         }
2152                 }
2153                 return true
2154         default:
2155                 // Func, Map, Slice, Invalid
2156                 panic("isReflexive called on non-key type " + t.String())
2157         }
2158 }
2159
2160 // needKeyUpdate reports whether map overwrites require the key to be copied.
2161 func needKeyUpdate(t *rtype) bool {
2162         switch t.Kind() {
2163         case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Ptr, UnsafePointer:
2164                 return false
2165         case Float32, Float64, Complex64, Complex128, Interface, String:
2166                 // Float keys can be updated from +0 to -0.
2167                 // String keys can be updated to use a smaller backing store.
2168                 // Interfaces might have floats of strings in them.
2169                 return true
2170         case Array:
2171                 tt := (*arrayType)(unsafe.Pointer(t))
2172                 return needKeyUpdate(tt.elem)
2173         case Struct:
2174                 tt := (*structType)(unsafe.Pointer(t))
2175                 for _, f := range tt.fields {
2176                         if needKeyUpdate(f.typ) {
2177                                 return true
2178                         }
2179                 }
2180                 return false
2181         default:
2182                 // Func, Map, Slice, Invalid
2183                 panic("needKeyUpdate called on non-key type " + t.String())
2184         }
2185 }
2186
2187 // hashMightPanic reports whether the hash of a map key of type t might panic.
2188 func hashMightPanic(t *rtype) bool {
2189         switch t.Kind() {
2190         case Interface:
2191                 return true
2192         case Array:
2193                 tt := (*arrayType)(unsafe.Pointer(t))
2194                 return hashMightPanic(tt.elem)
2195         case Struct:
2196                 tt := (*structType)(unsafe.Pointer(t))
2197                 for _, f := range tt.fields {
2198                         if hashMightPanic(f.typ) {
2199                                 return true
2200                         }
2201                 }
2202                 return false
2203         default:
2204                 return false
2205         }
2206 }
2207
2208 // Make sure these routines stay in sync with ../../runtime/map.go!
2209 // These types exist only for GC, so we only fill out GC relevant info.
2210 // Currently, that's just size and the GC program. We also fill in string
2211 // for possible debugging use.
2212 const (
2213         bucketSize uintptr = 8
2214         maxKeySize uintptr = 128
2215         maxValSize uintptr = 128
2216 )
2217
2218 func bucketOf(ktyp, etyp *rtype) *rtype {
2219         if ktyp.size > maxKeySize {
2220                 ktyp = PtrTo(ktyp).(*rtype)
2221         }
2222         if etyp.size > maxValSize {
2223                 etyp = PtrTo(etyp).(*rtype)
2224         }
2225
2226         // Prepare GC data if any.
2227         // A bucket is at most bucketSize*(1+maxKeySize+maxValSize)+2*ptrSize bytes,
2228         // or 2072 bytes, or 259 pointer-size words, or 33 bytes of pointer bitmap.
2229         // Note that since the key and value are known to be <= 128 bytes,
2230         // they're guaranteed to have bitmaps instead of GC programs.
2231         var gcdata *byte
2232         var ptrdata uintptr
2233         var overflowPad uintptr
2234
2235         size := bucketSize*(1+ktyp.size+etyp.size) + overflowPad + goarch.PtrSize
2236         if size&uintptr(ktyp.align-1) != 0 || size&uintptr(etyp.align-1) != 0 {
2237                 panic("reflect: bad size computation in MapOf")
2238         }
2239
2240         if ktyp.ptrdata != 0 || etyp.ptrdata != 0 {
2241                 nptr := (bucketSize*(1+ktyp.size+etyp.size) + goarch.PtrSize) / goarch.PtrSize
2242                 mask := make([]byte, (nptr+7)/8)
2243                 base := bucketSize / goarch.PtrSize
2244
2245                 if ktyp.ptrdata != 0 {
2246                         emitGCMask(mask, base, ktyp, bucketSize)
2247                 }
2248                 base += bucketSize * ktyp.size / goarch.PtrSize
2249
2250                 if etyp.ptrdata != 0 {
2251                         emitGCMask(mask, base, etyp, bucketSize)
2252                 }
2253                 base += bucketSize * etyp.size / goarch.PtrSize
2254                 base += overflowPad / goarch.PtrSize
2255
2256                 word := base
2257                 mask[word/8] |= 1 << (word % 8)
2258                 gcdata = &mask[0]
2259                 ptrdata = (word + 1) * goarch.PtrSize
2260
2261                 // overflow word must be last
2262                 if ptrdata != size {
2263                         panic("reflect: bad layout computation in MapOf")
2264                 }
2265         }
2266
2267         b := &rtype{
2268                 align:   goarch.PtrSize,
2269                 size:    size,
2270                 kind:    uint8(Struct),
2271                 ptrdata: ptrdata,
2272                 gcdata:  gcdata,
2273         }
2274         if overflowPad > 0 {
2275                 b.align = 8
2276         }
2277         s := "bucket(" + ktyp.String() + "," + etyp.String() + ")"
2278         b.str = resolveReflectName(newName(s, "", false))
2279         return b
2280 }
2281
2282 func (t *rtype) gcSlice(begin, end uintptr) []byte {
2283         return (*[1 << 30]byte)(unsafe.Pointer(t.gcdata))[begin:end:end]
2284 }
2285
2286 // emitGCMask writes the GC mask for [n]typ into out, starting at bit
2287 // offset base.
2288 func emitGCMask(out []byte, base uintptr, typ *rtype, n uintptr) {
2289         if typ.kind&kindGCProg != 0 {
2290                 panic("reflect: unexpected GC program")
2291         }
2292         ptrs := typ.ptrdata / goarch.PtrSize
2293         words := typ.size / goarch.PtrSize
2294         mask := typ.gcSlice(0, (ptrs+7)/8)
2295         for j := uintptr(0); j < ptrs; j++ {
2296                 if (mask[j/8]>>(j%8))&1 != 0 {
2297                         for i := uintptr(0); i < n; i++ {
2298                                 k := base + i*words + j
2299                                 out[k/8] |= 1 << (k % 8)
2300                         }
2301                 }
2302         }
2303 }
2304
2305 // appendGCProg appends the GC program for the first ptrdata bytes of
2306 // typ to dst and returns the extended slice.
2307 func appendGCProg(dst []byte, typ *rtype) []byte {
2308         if typ.kind&kindGCProg != 0 {
2309                 // Element has GC program; emit one element.
2310                 n := uintptr(*(*uint32)(unsafe.Pointer(typ.gcdata)))
2311                 prog := typ.gcSlice(4, 4+n-1)
2312                 return append(dst, prog...)
2313         }
2314
2315         // Element is small with pointer mask; use as literal bits.
2316         ptrs := typ.ptrdata / goarch.PtrSize
2317         mask := typ.gcSlice(0, (ptrs+7)/8)
2318
2319         // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes).
2320         for ; ptrs > 120; ptrs -= 120 {
2321                 dst = append(dst, 120)
2322                 dst = append(dst, mask[:15]...)
2323                 mask = mask[15:]
2324         }
2325
2326         dst = append(dst, byte(ptrs))
2327         dst = append(dst, mask...)
2328         return dst
2329 }
2330
2331 // SliceOf returns the slice type with element type t.
2332 // For example, if t represents int, SliceOf(t) represents []int.
2333 func SliceOf(t Type) Type {
2334         typ := t.(*rtype)
2335
2336         // Look in cache.
2337         ckey := cacheKey{Slice, typ, nil, 0}
2338         if slice, ok := lookupCache.Load(ckey); ok {
2339                 return slice.(Type)
2340         }
2341
2342         // Look in known types.
2343         s := "[]" + typ.String()
2344         for _, tt := range typesByString(s) {
2345                 slice := (*sliceType)(unsafe.Pointer(tt))
2346                 if slice.elem == typ {
2347                         ti, _ := lookupCache.LoadOrStore(ckey, tt)
2348                         return ti.(Type)
2349                 }
2350         }
2351
2352         // Make a slice type.
2353         var islice interface{} = ([]unsafe.Pointer)(nil)
2354         prototype := *(**sliceType)(unsafe.Pointer(&islice))
2355         slice := *prototype
2356         slice.tflag = 0
2357         slice.str = resolveReflectName(newName(s, "", false))
2358         slice.hash = fnv1(typ.hash, '[')
2359         slice.elem = typ
2360         slice.ptrToThis = 0
2361
2362         ti, _ := lookupCache.LoadOrStore(ckey, &slice.rtype)
2363         return ti.(Type)
2364 }
2365
2366 // The structLookupCache caches StructOf lookups.
2367 // StructOf does not share the common lookupCache since we need to pin
2368 // the memory associated with *structTypeFixedN.
2369 var structLookupCache struct {
2370         sync.Mutex // Guards stores (but not loads) on m.
2371
2372         // m is a map[uint32][]Type keyed by the hash calculated in StructOf.
2373         // Elements in m are append-only and thus safe for concurrent reading.
2374         m sync.Map
2375 }
2376
2377 type structTypeUncommon struct {
2378         structType
2379         u uncommonType
2380 }
2381
2382 // isLetter reports whether a given 'rune' is classified as a Letter.
2383 func isLetter(ch rune) bool {
2384         return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
2385 }
2386
2387 // isValidFieldName checks if a string is a valid (struct) field name or not.
2388 //
2389 // According to the language spec, a field name should be an identifier.
2390 //
2391 // identifier = letter { letter | unicode_digit } .
2392 // letter = unicode_letter | "_" .
2393 func isValidFieldName(fieldName string) bool {
2394         for i, c := range fieldName {
2395                 if i == 0 && !isLetter(c) {
2396                         return false
2397                 }
2398
2399                 if !(isLetter(c) || unicode.IsDigit(c)) {
2400                         return false
2401                 }
2402         }
2403
2404         return len(fieldName) > 0
2405 }
2406
2407 // StructOf returns the struct type containing fields.
2408 // The Offset and Index fields are ignored and computed as they would be
2409 // by the compiler.
2410 //
2411 // StructOf currently does not generate wrapper methods for embedded
2412 // fields and panics if passed unexported StructFields.
2413 // These limitations may be lifted in a future version.
2414 func StructOf(fields []StructField) Type {
2415         var (
2416                 hash       = fnv1(0, []byte("struct {")...)
2417                 size       uintptr
2418                 typalign   uint8
2419                 comparable = true
2420                 methods    []method
2421
2422                 fs   = make([]structField, len(fields))
2423                 repr = make([]byte, 0, 64)
2424                 fset = map[string]struct{}{} // fields' names
2425
2426                 hasGCProg = false // records whether a struct-field type has a GCProg
2427         )
2428
2429         lastzero := uintptr(0)
2430         repr = append(repr, "struct {"...)
2431         pkgpath := ""
2432         for i, field := range fields {
2433                 if field.Name == "" {
2434                         panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no name")
2435                 }
2436                 if !isValidFieldName(field.Name) {
2437                         panic("reflect.StructOf: field " + strconv.Itoa(i) + " has invalid name")
2438                 }
2439                 if field.Type == nil {
2440                         panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no type")
2441                 }
2442                 f, fpkgpath := runtimeStructField(field)
2443                 ft := f.typ
2444                 if ft.kind&kindGCProg != 0 {
2445                         hasGCProg = true
2446                 }
2447                 if fpkgpath != "" {
2448                         if pkgpath == "" {
2449                                 pkgpath = fpkgpath
2450                         } else if pkgpath != fpkgpath {
2451                                 panic("reflect.Struct: fields with different PkgPath " + pkgpath + " and " + fpkgpath)
2452                         }
2453                 }
2454
2455                 // Update string and hash
2456                 name := f.name.name()
2457                 hash = fnv1(hash, []byte(name)...)
2458                 repr = append(repr, (" " + name)...)
2459                 if f.embedded() {
2460                         // Embedded field
2461                         if f.typ.Kind() == Ptr {
2462                                 // Embedded ** and *interface{} are illegal
2463                                 elem := ft.Elem()
2464                                 if k := elem.Kind(); k == Ptr || k == Interface {
2465                                         panic("reflect.StructOf: illegal embedded field type " + ft.String())
2466                                 }
2467                         }
2468
2469                         switch f.typ.Kind() {
2470                         case Interface:
2471                                 ift := (*interfaceType)(unsafe.Pointer(ft))
2472                                 for im, m := range ift.methods {
2473                                         if ift.nameOff(m.name).pkgPath() != "" {
2474                                                 // TODO(sbinet).  Issue 15924.
2475                                                 panic("reflect: embedded interface with unexported method(s) not implemented")
2476                                         }
2477
2478                                         var (
2479                                                 mtyp    = ift.typeOff(m.typ)
2480                                                 ifield  = i
2481                                                 imethod = im
2482                                                 ifn     Value
2483                                                 tfn     Value
2484                                         )
2485
2486                                         if ft.kind&kindDirectIface != 0 {
2487                                                 tfn = MakeFunc(mtyp, func(in []Value) []Value {
2488                                                         var args []Value
2489                                                         var recv = in[0]
2490                                                         if len(in) > 1 {
2491                                                                 args = in[1:]
2492                                                         }
2493                                                         return recv.Field(ifield).Method(imethod).Call(args)
2494                                                 })
2495                                                 ifn = MakeFunc(mtyp, func(in []Value) []Value {
2496                                                         var args []Value
2497                                                         var recv = in[0]
2498                                                         if len(in) > 1 {
2499                                                                 args = in[1:]
2500                                                         }
2501                                                         return recv.Field(ifield).Method(imethod).Call(args)
2502                                                 })
2503                                         } else {
2504                                                 tfn = MakeFunc(mtyp, func(in []Value) []Value {
2505                                                         var args []Value
2506                                                         var recv = in[0]
2507                                                         if len(in) > 1 {
2508                                                                 args = in[1:]
2509                                                         }
2510                                                         return recv.Field(ifield).Method(imethod).Call(args)
2511                                                 })
2512                                                 ifn = MakeFunc(mtyp, func(in []Value) []Value {
2513                                                         var args []Value
2514                                                         var recv = Indirect(in[0])
2515                                                         if len(in) > 1 {
2516                                                                 args = in[1:]
2517                                                         }
2518                                                         return recv.Field(ifield).Method(imethod).Call(args)
2519                                                 })
2520                                         }
2521
2522                                         methods = append(methods, method{
2523                                                 name: resolveReflectName(ift.nameOff(m.name)),
2524                                                 mtyp: resolveReflectType(mtyp),
2525                                                 ifn:  resolveReflectText(unsafe.Pointer(&ifn)),
2526                                                 tfn:  resolveReflectText(unsafe.Pointer(&tfn)),
2527                                         })
2528                                 }
2529                         case Ptr:
2530                                 ptr := (*ptrType)(unsafe.Pointer(ft))
2531                                 if unt := ptr.uncommon(); unt != nil {
2532                                         if i > 0 && unt.mcount > 0 {
2533                                                 // Issue 15924.
2534                                                 panic("reflect: embedded type with methods not implemented if type is not first field")
2535                                         }
2536                                         if len(fields) > 1 {
2537                                                 panic("reflect: embedded type with methods not implemented if there is more than one field")
2538                                         }
2539                                         for _, m := range unt.methods() {
2540                                                 mname := ptr.nameOff(m.name)
2541                                                 if mname.pkgPath() != "" {
2542                                                         // TODO(sbinet).
2543                                                         // Issue 15924.
2544                                                         panic("reflect: embedded interface with unexported method(s) not implemented")
2545                                                 }
2546                                                 methods = append(methods, method{
2547                                                         name: resolveReflectName(mname),
2548                                                         mtyp: resolveReflectType(ptr.typeOff(m.mtyp)),
2549                                                         ifn:  resolveReflectText(ptr.textOff(m.ifn)),
2550                                                         tfn:  resolveReflectText(ptr.textOff(m.tfn)),
2551                                                 })
2552                                         }
2553                                 }
2554                                 if unt := ptr.elem.uncommon(); unt != nil {
2555                                         for _, m := range unt.methods() {
2556                                                 mname := ptr.nameOff(m.name)
2557                                                 if mname.pkgPath() != "" {
2558                                                         // TODO(sbinet)
2559                                                         // Issue 15924.
2560                                                         panic("reflect: embedded interface with unexported method(s) not implemented")
2561                                                 }
2562                                                 methods = append(methods, method{
2563                                                         name: resolveReflectName(mname),
2564                                                         mtyp: resolveReflectType(ptr.elem.typeOff(m.mtyp)),
2565                                                         ifn:  resolveReflectText(ptr.elem.textOff(m.ifn)),
2566                                                         tfn:  resolveReflectText(ptr.elem.textOff(m.tfn)),
2567                                                 })
2568                                         }
2569                                 }
2570                         default:
2571                                 if unt := ft.uncommon(); unt != nil {
2572                                         if i > 0 && unt.mcount > 0 {
2573                                                 // Issue 15924.
2574                                                 panic("reflect: embedded type with methods not implemented if type is not first field")
2575                                         }
2576                                         if len(fields) > 1 && ft.kind&kindDirectIface != 0 {
2577                                                 panic("reflect: embedded type with methods not implemented for non-pointer type")
2578                                         }
2579                                         for _, m := range unt.methods() {
2580                                                 mname := ft.nameOff(m.name)
2581                                                 if mname.pkgPath() != "" {
2582                                                         // TODO(sbinet)
2583                                                         // Issue 15924.
2584                                                         panic("reflect: embedded interface with unexported method(s) not implemented")
2585                                                 }
2586                                                 methods = append(methods, method{
2587                                                         name: resolveReflectName(mname),
2588                                                         mtyp: resolveReflectType(ft.typeOff(m.mtyp)),
2589                                                         ifn:  resolveReflectText(ft.textOff(m.ifn)),
2590                                                         tfn:  resolveReflectText(ft.textOff(m.tfn)),
2591                                                 })
2592
2593                                         }
2594                                 }
2595                         }
2596                 }
2597                 if _, dup := fset[name]; dup {
2598                         panic("reflect.StructOf: duplicate field " + name)
2599                 }
2600                 fset[name] = struct{}{}
2601
2602                 hash = fnv1(hash, byte(ft.hash>>24), byte(ft.hash>>16), byte(ft.hash>>8), byte(ft.hash))
2603
2604                 repr = append(repr, (" " + ft.String())...)
2605                 if f.name.hasTag() {
2606                         hash = fnv1(hash, []byte(f.name.tag())...)
2607                         repr = append(repr, (" " + strconv.Quote(f.name.tag()))...)
2608                 }
2609                 if i < len(fields)-1 {
2610                         repr = append(repr, ';')
2611                 }
2612
2613                 comparable = comparable && (ft.equal != nil)
2614
2615                 offset := align(size, uintptr(ft.align))
2616                 if ft.align > typalign {
2617                         typalign = ft.align
2618                 }
2619                 size = offset + ft.size
2620                 f.offsetEmbed |= offset << 1
2621
2622                 if ft.size == 0 {
2623                         lastzero = size
2624                 }
2625
2626                 fs[i] = f
2627         }
2628
2629         if size > 0 && lastzero == size {
2630                 // This is a non-zero sized struct that ends in a
2631                 // zero-sized field. We add an extra byte of padding,
2632                 // to ensure that taking the address of the final
2633                 // zero-sized field can't manufacture a pointer to the
2634                 // next object in the heap. See issue 9401.
2635                 size++
2636         }
2637
2638         var typ *structType
2639         var ut *uncommonType
2640
2641         if len(methods) == 0 {
2642                 t := new(structTypeUncommon)
2643                 typ = &t.structType
2644                 ut = &t.u
2645         } else {
2646                 // A *rtype representing a struct is followed directly in memory by an
2647                 // array of method objects representing the methods attached to the
2648                 // struct. To get the same layout for a run time generated type, we
2649                 // need an array directly following the uncommonType memory.
2650                 // A similar strategy is used for funcTypeFixed4, ...funcTypeFixedN.
2651                 tt := New(StructOf([]StructField{
2652                         {Name: "S", Type: TypeOf(structType{})},
2653                         {Name: "U", Type: TypeOf(uncommonType{})},
2654                         {Name: "M", Type: ArrayOf(len(methods), TypeOf(methods[0]))},
2655                 }))
2656
2657                 typ = (*structType)(unsafe.Pointer(tt.Elem().Field(0).UnsafeAddr()))
2658                 ut = (*uncommonType)(unsafe.Pointer(tt.Elem().Field(1).UnsafeAddr()))
2659
2660                 copy(tt.Elem().Field(2).Slice(0, len(methods)).Interface().([]method), methods)
2661         }
2662         // TODO(sbinet): Once we allow embedding multiple types,
2663         // methods will need to be sorted like the compiler does.
2664         // TODO(sbinet): Once we allow non-exported methods, we will
2665         // need to compute xcount as the number of exported methods.
2666         ut.mcount = uint16(len(methods))
2667         ut.xcount = ut.mcount
2668         ut.moff = uint32(unsafe.Sizeof(uncommonType{}))
2669
2670         if len(fs) > 0 {
2671                 repr = append(repr, ' ')
2672         }
2673         repr = append(repr, '}')
2674         hash = fnv1(hash, '}')
2675         str := string(repr)
2676
2677         // Round the size up to be a multiple of the alignment.
2678         size = align(size, uintptr(typalign))
2679
2680         // Make the struct type.
2681         var istruct interface{} = struct{}{}
2682         prototype := *(**structType)(unsafe.Pointer(&istruct))
2683         *typ = *prototype
2684         typ.fields = fs
2685         if pkgpath != "" {
2686                 typ.pkgPath = newName(pkgpath, "", false)
2687         }
2688
2689         // Look in cache.
2690         if ts, ok := structLookupCache.m.Load(hash); ok {
2691                 for _, st := range ts.([]Type) {
2692                         t := st.common()
2693                         if haveIdenticalUnderlyingType(&typ.rtype, t, true) {
2694                                 return t
2695                         }
2696                 }
2697         }
2698
2699         // Not in cache, lock and retry.
2700         structLookupCache.Lock()
2701         defer structLookupCache.Unlock()
2702         if ts, ok := structLookupCache.m.Load(hash); ok {
2703                 for _, st := range ts.([]Type) {
2704                         t := st.common()
2705                         if haveIdenticalUnderlyingType(&typ.rtype, t, true) {
2706                                 return t
2707                         }
2708                 }
2709         }
2710
2711         addToCache := func(t Type) Type {
2712                 var ts []Type
2713                 if ti, ok := structLookupCache.m.Load(hash); ok {
2714                         ts = ti.([]Type)
2715                 }
2716                 structLookupCache.m.Store(hash, append(ts, t))
2717                 return t
2718         }
2719
2720         // Look in known types.
2721         for _, t := range typesByString(str) {
2722                 if haveIdenticalUnderlyingType(&typ.rtype, t, true) {
2723                         // even if 't' wasn't a structType with methods, we should be ok
2724                         // as the 'u uncommonType' field won't be accessed except when
2725                         // tflag&tflagUncommon is set.
2726                         return addToCache(t)
2727                 }
2728         }
2729
2730         typ.str = resolveReflectName(newName(str, "", false))
2731         typ.tflag = 0 // TODO: set tflagRegularMemory
2732         typ.hash = hash
2733         typ.size = size
2734         typ.ptrdata = typeptrdata(typ.common())
2735         typ.align = typalign
2736         typ.fieldAlign = typalign
2737         typ.ptrToThis = 0
2738         if len(methods) > 0 {
2739                 typ.tflag |= tflagUncommon
2740         }
2741
2742         if hasGCProg {
2743                 lastPtrField := 0
2744                 for i, ft := range fs {
2745                         if ft.typ.pointers() {
2746                                 lastPtrField = i
2747                         }
2748                 }
2749                 prog := []byte{0, 0, 0, 0} // will be length of prog
2750                 var off uintptr
2751                 for i, ft := range fs {
2752                         if i > lastPtrField {
2753                                 // gcprog should not include anything for any field after
2754                                 // the last field that contains pointer data
2755                                 break
2756                         }
2757                         if !ft.typ.pointers() {
2758                                 // Ignore pointerless fields.
2759                                 continue
2760                         }
2761                         // Pad to start of this field with zeros.
2762                         if ft.offset() > off {
2763                                 n := (ft.offset() - off) / goarch.PtrSize
2764                                 prog = append(prog, 0x01, 0x00) // emit a 0 bit
2765                                 if n > 1 {
2766                                         prog = append(prog, 0x81)      // repeat previous bit
2767                                         prog = appendVarint(prog, n-1) // n-1 times
2768                                 }
2769                                 off = ft.offset()
2770                         }
2771
2772                         prog = appendGCProg(prog, ft.typ)
2773                         off += ft.typ.ptrdata
2774                 }
2775                 prog = append(prog, 0)
2776                 *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4)
2777                 typ.kind |= kindGCProg
2778                 typ.gcdata = &prog[0]
2779         } else {
2780                 typ.kind &^= kindGCProg
2781                 bv := new(bitVector)
2782                 addTypeBits(bv, 0, typ.common())
2783                 if len(bv.data) > 0 {
2784                         typ.gcdata = &bv.data[0]
2785                 }
2786         }
2787         typ.equal = nil
2788         if comparable {
2789                 typ.equal = func(p, q unsafe.Pointer) bool {
2790                         for _, ft := range typ.fields {
2791                                 pi := add(p, ft.offset(), "&x.field safe")
2792                                 qi := add(q, ft.offset(), "&x.field safe")
2793                                 if !ft.typ.equal(pi, qi) {
2794                                         return false
2795                                 }
2796                         }
2797                         return true
2798                 }
2799         }
2800
2801         switch {
2802         case len(fs) == 1 && !ifaceIndir(fs[0].typ):
2803                 // structs of 1 direct iface type can be direct
2804                 typ.kind |= kindDirectIface
2805         default:
2806                 typ.kind &^= kindDirectIface
2807         }
2808
2809         return addToCache(&typ.rtype)
2810 }
2811
2812 // runtimeStructField takes a StructField value passed to StructOf and
2813 // returns both the corresponding internal representation, of type
2814 // structField, and the pkgpath value to use for this field.
2815 func runtimeStructField(field StructField) (structField, string) {
2816         if field.Anonymous && field.PkgPath != "" {
2817                 panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
2818         }
2819
2820         if field.IsExported() {
2821                 // Best-effort check for misuse.
2822                 // Since this field will be treated as exported, not much harm done if Unicode lowercase slips through.
2823                 c := field.Name[0]
2824                 if 'a' <= c && c <= 'z' || c == '_' {
2825                         panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath")
2826                 }
2827         }
2828
2829         offsetEmbed := uintptr(0)
2830         if field.Anonymous {
2831                 offsetEmbed |= 1
2832         }
2833
2834         resolveReflectType(field.Type.common()) // install in runtime
2835         f := structField{
2836                 name:        newName(field.Name, string(field.Tag), field.IsExported()),
2837                 typ:         field.Type.common(),
2838                 offsetEmbed: offsetEmbed,
2839         }
2840         return f, field.PkgPath
2841 }
2842
2843 // typeptrdata returns the length in bytes of the prefix of t
2844 // containing pointer data. Anything after this offset is scalar data.
2845 // keep in sync with ../cmd/compile/internal/reflectdata/reflect.go
2846 func typeptrdata(t *rtype) uintptr {
2847         switch t.Kind() {
2848         case Struct:
2849                 st := (*structType)(unsafe.Pointer(t))
2850                 // find the last field that has pointers.
2851                 field := -1
2852                 for i := range st.fields {
2853                         ft := st.fields[i].typ
2854                         if ft.pointers() {
2855                                 field = i
2856                         }
2857                 }
2858                 if field == -1 {
2859                         return 0
2860                 }
2861                 f := st.fields[field]
2862                 return f.offset() + f.typ.ptrdata
2863
2864         default:
2865                 panic("reflect.typeptrdata: unexpected type, " + t.String())
2866         }
2867 }
2868
2869 // See cmd/compile/internal/reflectdata/reflect.go for derivation of constant.
2870 const maxPtrmaskBytes = 2048
2871
2872 // ArrayOf returns the array type with the given length and element type.
2873 // For example, if t represents int, ArrayOf(5, t) represents [5]int.
2874 //
2875 // If the resulting type would be larger than the available address space,
2876 // ArrayOf panics.
2877 func ArrayOf(length int, elem Type) Type {
2878         if length < 0 {
2879                 panic("reflect: negative length passed to ArrayOf")
2880         }
2881
2882         typ := elem.(*rtype)
2883
2884         // Look in cache.
2885         ckey := cacheKey{Array, typ, nil, uintptr(length)}
2886         if array, ok := lookupCache.Load(ckey); ok {
2887                 return array.(Type)
2888         }
2889
2890         // Look in known types.
2891         s := "[" + strconv.Itoa(length) + "]" + typ.String()
2892         for _, tt := range typesByString(s) {
2893                 array := (*arrayType)(unsafe.Pointer(tt))
2894                 if array.elem == typ {
2895                         ti, _ := lookupCache.LoadOrStore(ckey, tt)
2896                         return ti.(Type)
2897                 }
2898         }
2899
2900         // Make an array type.
2901         var iarray interface{} = [1]unsafe.Pointer{}
2902         prototype := *(**arrayType)(unsafe.Pointer(&iarray))
2903         array := *prototype
2904         array.tflag = typ.tflag & tflagRegularMemory
2905         array.str = resolveReflectName(newName(s, "", false))
2906         array.hash = fnv1(typ.hash, '[')
2907         for n := uint32(length); n > 0; n >>= 8 {
2908                 array.hash = fnv1(array.hash, byte(n))
2909         }
2910         array.hash = fnv1(array.hash, ']')
2911         array.elem = typ
2912         array.ptrToThis = 0
2913         if typ.size > 0 {
2914                 max := ^uintptr(0) / typ.size
2915                 if uintptr(length) > max {
2916                         panic("reflect.ArrayOf: array size would exceed virtual address space")
2917                 }
2918         }
2919         array.size = typ.size * uintptr(length)
2920         if length > 0 && typ.ptrdata != 0 {
2921                 array.ptrdata = typ.size*uintptr(length-1) + typ.ptrdata
2922         }
2923         array.align = typ.align
2924         array.fieldAlign = typ.fieldAlign
2925         array.len = uintptr(length)
2926         array.slice = SliceOf(elem).(*rtype)
2927
2928         switch {
2929         case typ.ptrdata == 0 || array.size == 0:
2930                 // No pointers.
2931                 array.gcdata = nil
2932                 array.ptrdata = 0
2933
2934         case length == 1:
2935                 // In memory, 1-element array looks just like the element.
2936                 array.kind |= typ.kind & kindGCProg
2937                 array.gcdata = typ.gcdata
2938                 array.ptrdata = typ.ptrdata
2939
2940         case typ.kind&kindGCProg == 0 && array.size <= maxPtrmaskBytes*8*goarch.PtrSize:
2941                 // Element is small with pointer mask; array is still small.
2942                 // Create direct pointer mask by turning each 1 bit in elem
2943                 // into length 1 bits in larger mask.
2944                 mask := make([]byte, (array.ptrdata/goarch.PtrSize+7)/8)
2945                 emitGCMask(mask, 0, typ, array.len)
2946                 array.gcdata = &mask[0]
2947
2948         default:
2949                 // Create program that emits one element
2950                 // and then repeats to make the array.
2951                 prog := []byte{0, 0, 0, 0} // will be length of prog
2952                 prog = appendGCProg(prog, typ)
2953                 // Pad from ptrdata to size.
2954                 elemPtrs := typ.ptrdata / goarch.PtrSize
2955                 elemWords := typ.size / goarch.PtrSize
2956                 if elemPtrs < elemWords {
2957                         // Emit literal 0 bit, then repeat as needed.
2958                         prog = append(prog, 0x01, 0x00)
2959                         if elemPtrs+1 < elemWords {
2960                                 prog = append(prog, 0x81)
2961                                 prog = appendVarint(prog, elemWords-elemPtrs-1)
2962                         }
2963                 }
2964                 // Repeat length-1 times.
2965                 if elemWords < 0x80 {
2966                         prog = append(prog, byte(elemWords|0x80))
2967                 } else {
2968                         prog = append(prog, 0x80)
2969                         prog = appendVarint(prog, elemWords)
2970                 }
2971                 prog = appendVarint(prog, uintptr(length)-1)
2972                 prog = append(prog, 0)
2973                 *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4)
2974                 array.kind |= kindGCProg
2975                 array.gcdata = &prog[0]
2976                 array.ptrdata = array.size // overestimate but ok; must match program
2977         }
2978
2979         etyp := typ.common()
2980         esize := etyp.Size()
2981
2982         array.equal = nil
2983         if eequal := etyp.equal; eequal != nil {
2984                 array.equal = func(p, q unsafe.Pointer) bool {
2985                         for i := 0; i < length; i++ {
2986                                 pi := arrayAt(p, i, esize, "i < length")
2987                                 qi := arrayAt(q, i, esize, "i < length")
2988                                 if !eequal(pi, qi) {
2989                                         return false
2990                                 }
2991
2992                         }
2993                         return true
2994                 }
2995         }
2996
2997         switch {
2998         case length == 1 && !ifaceIndir(typ):
2999                 // array of 1 direct iface type can be direct
3000                 array.kind |= kindDirectIface
3001         default:
3002                 array.kind &^= kindDirectIface
3003         }
3004
3005         ti, _ := lookupCache.LoadOrStore(ckey, &array.rtype)
3006         return ti.(Type)
3007 }
3008
3009 func appendVarint(x []byte, v uintptr) []byte {
3010         for ; v >= 0x80; v >>= 7 {
3011                 x = append(x, byte(v|0x80))
3012         }
3013         x = append(x, byte(v))
3014         return x
3015 }
3016
3017 // toType converts from a *rtype to a Type that can be returned
3018 // to the client of package reflect. In gc, the only concern is that
3019 // a nil *rtype must be replaced by a nil Type, but in gccgo this
3020 // function takes care of ensuring that multiple *rtype for the same
3021 // type are coalesced into a single Type.
3022 func toType(t *rtype) Type {
3023         if t == nil {
3024                 return nil
3025         }
3026         return t
3027 }
3028
3029 type layoutKey struct {
3030         ftyp *funcType // function signature
3031         rcvr *rtype    // receiver type, or nil if none
3032 }
3033
3034 type layoutType struct {
3035         t         *rtype
3036         framePool *sync.Pool
3037         abi       abiDesc
3038 }
3039
3040 var layoutCache sync.Map // map[layoutKey]layoutType
3041
3042 // funcLayout computes a struct type representing the layout of the
3043 // stack-assigned function arguments and return values for the function
3044 // type t.
3045 // If rcvr != nil, rcvr specifies the type of the receiver.
3046 // The returned type exists only for GC, so we only fill out GC relevant info.
3047 // Currently, that's just size and the GC program. We also fill in
3048 // the name for possible debugging use.
3049 func funcLayout(t *funcType, rcvr *rtype) (frametype *rtype, framePool *sync.Pool, abi abiDesc) {
3050         if t.Kind() != Func {
3051                 panic("reflect: funcLayout of non-func type " + t.String())
3052         }
3053         if rcvr != nil && rcvr.Kind() == Interface {
3054                 panic("reflect: funcLayout with interface receiver " + rcvr.String())
3055         }
3056         k := layoutKey{t, rcvr}
3057         if lti, ok := layoutCache.Load(k); ok {
3058                 lt := lti.(layoutType)
3059                 return lt.t, lt.framePool, lt.abi
3060         }
3061
3062         // Compute the ABI layout.
3063         abi = newAbiDesc(t, rcvr)
3064
3065         // build dummy rtype holding gc program
3066         x := &rtype{
3067                 align: goarch.PtrSize,
3068                 // Don't add spill space here; it's only necessary in
3069                 // reflectcall's frame, not in the allocated frame.
3070                 // TODO(mknyszek): Remove this comment when register
3071                 // spill space in the frame is no longer required.
3072                 size:    align(abi.retOffset+abi.ret.stackBytes, goarch.PtrSize),
3073                 ptrdata: uintptr(abi.stackPtrs.n) * goarch.PtrSize,
3074         }
3075         if abi.stackPtrs.n > 0 {
3076                 x.gcdata = &abi.stackPtrs.data[0]
3077         }
3078
3079         var s string
3080         if rcvr != nil {
3081                 s = "methodargs(" + rcvr.String() + ")(" + t.String() + ")"
3082         } else {
3083                 s = "funcargs(" + t.String() + ")"
3084         }
3085         x.str = resolveReflectName(newName(s, "", false))
3086
3087         // cache result for future callers
3088         framePool = &sync.Pool{New: func() interface{} {
3089                 return unsafe_New(x)
3090         }}
3091         lti, _ := layoutCache.LoadOrStore(k, layoutType{
3092                 t:         x,
3093                 framePool: framePool,
3094                 abi:       abi,
3095         })
3096         lt := lti.(layoutType)
3097         return lt.t, lt.framePool, lt.abi
3098 }
3099
3100 // ifaceIndir reports whether t is stored indirectly in an interface value.
3101 func ifaceIndir(t *rtype) bool {
3102         return t.kind&kindDirectIface == 0
3103 }
3104
3105 // Note: this type must agree with runtime.bitvector.
3106 type bitVector struct {
3107         n    uint32 // number of bits
3108         data []byte
3109 }
3110
3111 // append a bit to the bitmap.
3112 func (bv *bitVector) append(bit uint8) {
3113         if bv.n%8 == 0 {
3114                 bv.data = append(bv.data, 0)
3115         }
3116         bv.data[bv.n/8] |= bit << (bv.n % 8)
3117         bv.n++
3118 }
3119
3120 func addTypeBits(bv *bitVector, offset uintptr, t *rtype) {
3121         if t.ptrdata == 0 {
3122                 return
3123         }
3124
3125         switch Kind(t.kind & kindMask) {
3126         case Chan, Func, Map, Ptr, Slice, String, UnsafePointer:
3127                 // 1 pointer at start of representation
3128                 for bv.n < uint32(offset/uintptr(goarch.PtrSize)) {
3129                         bv.append(0)
3130                 }
3131                 bv.append(1)
3132
3133         case Interface:
3134                 // 2 pointers
3135                 for bv.n < uint32(offset/uintptr(goarch.PtrSize)) {
3136                         bv.append(0)
3137                 }
3138                 bv.append(1)
3139                 bv.append(1)
3140
3141         case Array:
3142                 // repeat inner type
3143                 tt := (*arrayType)(unsafe.Pointer(t))
3144                 for i := 0; i < int(tt.len); i++ {
3145                         addTypeBits(bv, offset+uintptr(i)*tt.elem.size, tt.elem)
3146                 }
3147
3148         case Struct:
3149                 // apply fields
3150                 tt := (*structType)(unsafe.Pointer(t))
3151                 for i := range tt.fields {
3152                         f := &tt.fields[i]
3153                         addTypeBits(bv, offset+f.offset(), f.typ)
3154                 }
3155         }
3156 }