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

View as plain text