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