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