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

View as plain text