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, 1)
   910  	case Pointer:
   911  		return t.Elem().Kind() == Array
   912  	}
   913  	return false
   914  }
   915  
   916  func (t *rtype) CanSeq2() bool {
   917  	switch t.Kind() {
   918  	case Array, Slice, String, Map:
   919  		return true
   920  	case Func:
   921  		return canRangeFunc(&t.t, 2)
   922  	case Pointer:
   923  		return t.Elem().Kind() == Array
   924  	}
   925  	return false
   926  }
   927  
   928  func canRangeFunc(t *abi.Type, seq uint16) bool {
   929  	if t.Kind() != abi.Func {
   930  		return false
   931  	}
   932  	f := t.FuncType()
   933  	if f.InCount != 1 || f.OutCount != 0 {
   934  		return false
   935  	}
   936  	y := f.In(0)
   937  	if y.Kind() != abi.Func {
   938  		return false
   939  	}
   940  	yield := y.FuncType()
   941  	return yield.InCount == seq && yield.OutCount == 1 && yield.Out(0).Kind() == abi.Bool && toRType(yield.Out(0)).PkgPath() == ""
   942  }
   943  
   944  func (t *rtype) Fields() iter.Seq[StructField] {
   945  	if t.Kind() != Struct {
   946  		panic("reflect: Fields of non-struct type " + t.String())
   947  	}
   948  	return func(yield func(StructField) bool) {
   949  		for i := range t.NumField() {
   950  			if !yield(t.Field(i)) {
   951  				return
   952  			}
   953  		}
   954  	}
   955  }
   956  
   957  func (t *rtype) Methods() iter.Seq[Method] {
   958  	return func(yield func(Method) bool) {
   959  		for i := range t.NumMethod() {
   960  			if !yield(t.Method(i)) {
   961  				return
   962  			}
   963  		}
   964  	}
   965  }
   966  
   967  func (t *rtype) Ins() iter.Seq[Type] {
   968  	if t.Kind() != Func {
   969  		panic("reflect: Ins of non-func type " + t.String())
   970  	}
   971  	return func(yield func(Type) bool) {
   972  		for i := range t.NumIn() {
   973  			if !yield(t.In(i)) {
   974  				return
   975  			}
   976  		}
   977  	}
   978  }
   979  
   980  func (t *rtype) Outs() iter.Seq[Type] {
   981  	if t.Kind() != Func {
   982  		panic("reflect: Outs of non-func type " + t.String())
   983  	}
   984  	return func(yield func(Type) bool) {
   985  		for i := range t.NumOut() {
   986  			if !yield(t.Out(i)) {
   987  				return
   988  			}
   989  		}
   990  	}
   991  }
   992  
   993  // add returns p+x.
   994  //
   995  // The whySafe string is ignored, so that the function still inlines
   996  // as efficiently as p+x, but all call sites should use the string to
   997  // record why the addition is safe, which is to say why the addition
   998  // does not cause x to advance to the very end of p's allocation
   999  // and therefore point incorrectly at the next block in memory.
  1000  //
  1001  // add should be an internal detail (and is trivially copyable),
  1002  // but widely used packages access it using linkname.
  1003  // Notable members of the hall of shame include:
  1004  //   - github.com/pinpoint-apm/pinpoint-go-agent
  1005  //   - github.com/vmware/govmomi
  1006  //
  1007  // Do not remove or change the type signature.
  1008  // See go.dev/issue/67401.
  1009  //
  1010  //go:linkname add
  1011  func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
  1012  	return unsafe.Pointer(uintptr(p) + x)
  1013  }
  1014  
  1015  func (d ChanDir) String() string {
  1016  	switch d {
  1017  	case SendDir:
  1018  		return "chan<-"
  1019  	case RecvDir:
  1020  		return "<-chan"
  1021  	case BothDir:
  1022  		return "chan"
  1023  	}
  1024  	return "ChanDir" + strconv.Itoa(int(d))
  1025  }
  1026  
  1027  // Method returns the i'th method in the type's method set.
  1028  func (t *interfaceType) Method(i int) (m Method) {
  1029  	if i < 0 || i >= len(t.Methods) {
  1030  		return
  1031  	}
  1032  	p := &t.Methods[i]
  1033  	pname := t.nameOff(p.Name)
  1034  	m.Name = pname.Name()
  1035  	if !pname.IsExported() {
  1036  		m.PkgPath = pkgPath(pname)
  1037  		if m.PkgPath == "" {
  1038  			m.PkgPath = t.PkgPath.Name()
  1039  		}
  1040  	}
  1041  	m.Type = toType(t.typeOff(p.Typ))
  1042  	m.Index = i
  1043  	return
  1044  }
  1045  
  1046  // NumMethod returns the number of interface methods in the type's method set.
  1047  func (t *interfaceType) NumMethod() int { return len(t.Methods) }
  1048  
  1049  // MethodByName method with the given name in the type's method set.
  1050  func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
  1051  	if t == nil {
  1052  		return
  1053  	}
  1054  	var p *abi.Imethod
  1055  	for i := range t.Methods {
  1056  		p = &t.Methods[i]
  1057  		if t.nameOff(p.Name).Name() == name {
  1058  			return t.Method(i), true
  1059  		}
  1060  	}
  1061  	return
  1062  }
  1063  
  1064  // A StructField describes a single field in a struct.
  1065  type StructField struct {
  1066  	// Name is the field name.
  1067  	Name string
  1068  
  1069  	// PkgPath is the package path that qualifies a lower case (unexported)
  1070  	// field name. It is empty for upper case (exported) field names.
  1071  	// See https://golang.org/ref/spec#Uniqueness_of_identifiers
  1072  	PkgPath string
  1073  
  1074  	Type      Type      // field type
  1075  	Tag       StructTag // field tag string
  1076  	Offset    uintptr   // offset within struct, in bytes
  1077  	Index     []int     // index sequence for Type.FieldByIndex
  1078  	Anonymous bool      // is an embedded field
  1079  }
  1080  
  1081  // IsExported reports whether the field is exported.
  1082  func (f StructField) IsExported() bool {
  1083  	return f.PkgPath == ""
  1084  }
  1085  
  1086  // A StructTag is the tag string in a struct field.
  1087  //
  1088  // By convention, tag strings are a concatenation of
  1089  // optionally space-separated key:"value" pairs.
  1090  // Each key is a non-empty string consisting of non-control
  1091  // characters other than space (U+0020 ' '), quote (U+0022 '"'),
  1092  // and colon (U+003A ':').  Each value is quoted using U+0022 '"'
  1093  // characters and Go string literal syntax.
  1094  type StructTag string
  1095  
  1096  // Get returns the value associated with key in the tag string.
  1097  // If there is no such key in the tag, Get returns the empty string.
  1098  // If the tag does not have the conventional format, the value
  1099  // returned by Get is unspecified. To determine whether a tag is
  1100  // explicitly set to the empty string, use [StructTag.Lookup].
  1101  func (tag StructTag) Get(key string) string {
  1102  	v, _ := tag.Lookup(key)
  1103  	return v
  1104  }
  1105  
  1106  // Lookup returns the value associated with key in the tag string.
  1107  // If the key is present in the tag the value (which may be empty)
  1108  // is returned. Otherwise the returned value will be the empty string.
  1109  // The ok return value reports whether the value was explicitly set in
  1110  // the tag string. If the tag does not have the conventional format,
  1111  // the value returned by Lookup is unspecified.
  1112  func (tag StructTag) Lookup(key string) (value string, ok bool) {
  1113  	// When modifying this code, also update the validateStructTag code
  1114  	// in cmd/vet/structtag.go.
  1115  
  1116  	for tag != "" {
  1117  		// Skip leading space.
  1118  		i := 0
  1119  		for i < len(tag) && tag[i] == ' ' {
  1120  			i++
  1121  		}
  1122  		tag = tag[i:]
  1123  		if tag == "" {
  1124  			break
  1125  		}
  1126  
  1127  		// Scan to colon. A space, a quote or a control character is a syntax error.
  1128  		// Strictly speaking, control chars include the range [0x7f, 0x9f], not just
  1129  		// [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
  1130  		// as it is simpler to inspect the tag's bytes than the tag's runes.
  1131  		i = 0
  1132  		for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
  1133  			i++
  1134  		}
  1135  		if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
  1136  			break
  1137  		}
  1138  		name := string(tag[:i])
  1139  		tag = tag[i+1:]
  1140  
  1141  		// Scan quoted string to find value.
  1142  		i = 1
  1143  		for i < len(tag) && tag[i] != '"' {
  1144  			if tag[i] == '\\' {
  1145  				i++
  1146  			}
  1147  			i++
  1148  		}
  1149  		if i >= len(tag) {
  1150  			break
  1151  		}
  1152  		qvalue := string(tag[:i+1])
  1153  		tag = tag[i+1:]
  1154  
  1155  		if key == name {
  1156  			value, err := strconv.Unquote(qvalue)
  1157  			if err != nil {
  1158  				break
  1159  			}
  1160  			return value, true
  1161  		}
  1162  	}
  1163  	return "", false
  1164  }
  1165  
  1166  // Field returns the i'th struct field.
  1167  func (t *structType) Field(i int) (f StructField) {
  1168  	if i < 0 || i >= len(t.Fields) {
  1169  		panic("reflect: Field index out of bounds")
  1170  	}
  1171  	p := &t.Fields[i]
  1172  	f.Type = toType(p.Typ)
  1173  	f.Name = p.Name.Name()
  1174  	f.Anonymous = p.Embedded()
  1175  	if !p.Name.IsExported() {
  1176  		f.PkgPath = t.PkgPath.Name()
  1177  	}
  1178  	if tag := p.Name.Tag(); tag != "" {
  1179  		f.Tag = StructTag(tag)
  1180  	}
  1181  	f.Offset = p.Offset
  1182  
  1183  	// We can't safely use this optimization on js or wasi,
  1184  	// which do not appear to support read-only data.
  1185  	if i < 256 && runtime.GOOS != "js" && runtime.GOOS != "wasip1" {
  1186  		staticuint64s := getStaticuint64s()
  1187  		p := unsafe.Pointer(&(*staticuint64s)[i])
  1188  		if unsafe.Sizeof(int(0)) == 4 && goarch.BigEndian {
  1189  			p = unsafe.Add(p, 4)
  1190  		}
  1191  		f.Index = unsafe.Slice((*int)(p), 1)
  1192  	} else {
  1193  		// NOTE(rsc): This is the only allocation in the interface
  1194  		// presented by a reflect.Type. It would be nice to avoid,
  1195  		// but we need to make sure that misbehaving clients of
  1196  		// reflect cannot affect other uses of reflect.
  1197  		// One possibility is CL 5371098, but we postponed that
  1198  		// ugliness until there is a demonstrated
  1199  		// need for the performance. This is issue 2320.
  1200  		f.Index = []int{i}
  1201  	}
  1202  	return
  1203  }
  1204  
  1205  // getStaticuint64s returns a pointer to an array of 256 uint64 values,
  1206  // defined in the runtime package in read-only memory.
  1207  // staticuint64s[0] == 0, staticuint64s[1] == 1, and so forth.
  1208  //
  1209  //go:linkname getStaticuint64s runtime.getStaticuint64s
  1210  func getStaticuint64s() *[256]uint64
  1211  
  1212  // TODO(gri): Should there be an error/bool indicator if the index
  1213  // is wrong for FieldByIndex?
  1214  
  1215  // FieldByIndex returns the nested field corresponding to index.
  1216  func (t *structType) FieldByIndex(index []int) (f StructField) {
  1217  	f.Type = toType(&t.Type)
  1218  	for i, x := range index {
  1219  		if i > 0 {
  1220  			ft := f.Type
  1221  			if ft.Kind() == Pointer && ft.Elem().Kind() == Struct {
  1222  				ft = ft.Elem()
  1223  			}
  1224  			f.Type = ft
  1225  		}
  1226  		f = f.Type.Field(x)
  1227  	}
  1228  	return
  1229  }
  1230  
  1231  // A fieldScan represents an item on the fieldByNameFunc scan work list.
  1232  type fieldScan struct {
  1233  	typ   *structType
  1234  	index []int
  1235  }
  1236  
  1237  // FieldByNameFunc returns the struct field with a name that satisfies the
  1238  // match function and a boolean to indicate if the field was found.
  1239  func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) {
  1240  	// This uses the same condition that the Go language does: there must be a unique instance
  1241  	// of the match at a given depth level. If there are multiple instances of a match at the
  1242  	// same depth, they annihilate each other and inhibit any possible match at a lower level.
  1243  	// The algorithm is breadth first search, one depth level at a time.
  1244  
  1245  	// The current and next slices are work queues:
  1246  	// current lists the fields to visit on this depth level,
  1247  	// and next lists the fields on the next lower level.
  1248  	current := []fieldScan{}
  1249  	next := []fieldScan{{typ: t}}
  1250  
  1251  	// nextCount records the number of times an embedded type has been
  1252  	// encountered and considered for queueing in the 'next' slice.
  1253  	// We only queue the first one, but we increment the count on each.
  1254  	// If a struct type T can be reached more than once at a given depth level,
  1255  	// then it annihilates itself and need not be considered at all when we
  1256  	// process that next depth level.
  1257  	var nextCount map[*structType]int
  1258  
  1259  	// visited records the structs that have been considered already.
  1260  	// Embedded pointer fields can create cycles in the graph of
  1261  	// reachable embedded types; visited avoids following those cycles.
  1262  	// It also avoids duplicated effort: if we didn't find the field in an
  1263  	// embedded type T at level 2, we won't find it in one at level 4 either.
  1264  	visited := map[*structType]bool{}
  1265  
  1266  	for len(next) > 0 {
  1267  		current, next = next, current[:0]
  1268  		count := nextCount
  1269  		nextCount = nil
  1270  
  1271  		// Process all the fields at this depth, now listed in 'current'.
  1272  		// The loop queues embedded fields found in 'next', for processing during the next
  1273  		// iteration. The multiplicity of the 'current' field counts is recorded
  1274  		// in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
  1275  		for _, scan := range current {
  1276  			t := scan.typ
  1277  			if visited[t] {
  1278  				// We've looked through this type before, at a higher level.
  1279  				// That higher level would shadow the lower level we're now at,
  1280  				// so this one can't be useful to us. Ignore it.
  1281  				continue
  1282  			}
  1283  			visited[t] = true
  1284  			for i := range t.Fields {
  1285  				f := &t.Fields[i]
  1286  				// Find name and (for embedded field) type for field f.
  1287  				fname := f.Name.Name()
  1288  				var ntyp *abi.Type
  1289  				if f.Embedded() {
  1290  					// Embedded field of type T or *T.
  1291  					ntyp = f.Typ
  1292  					if ntyp.Kind() == abi.Pointer {
  1293  						ntyp = ntyp.Elem()
  1294  					}
  1295  				}
  1296  
  1297  				// Does it match?
  1298  				if match(fname) {
  1299  					// Potential match
  1300  					if count[t] > 1 || ok {
  1301  						// Name appeared multiple times at this level: annihilate.
  1302  						return StructField{}, false
  1303  					}
  1304  					result = t.Field(i)
  1305  					result.Index = nil
  1306  					result.Index = append(result.Index, scan.index...)
  1307  					result.Index = append(result.Index, i)
  1308  					ok = true
  1309  					continue
  1310  				}
  1311  
  1312  				// Queue embedded struct fields for processing with next level,
  1313  				// but only if we haven't seen a match yet at this level and only
  1314  				// if the embedded types haven't already been queued.
  1315  				if ok || ntyp == nil || ntyp.Kind() != abi.Struct {
  1316  					continue
  1317  				}
  1318  				styp := (*structType)(unsafe.Pointer(ntyp))
  1319  				if nextCount[styp] > 0 {
  1320  					nextCount[styp] = 2 // exact multiple doesn't matter
  1321  					continue
  1322  				}
  1323  				if nextCount == nil {
  1324  					nextCount = map[*structType]int{}
  1325  				}
  1326  				nextCount[styp] = 1
  1327  				if count[t] > 1 {
  1328  					nextCount[styp] = 2 // exact multiple doesn't matter
  1329  				}
  1330  				var index []int
  1331  				index = append(index, scan.index...)
  1332  				index = append(index, i)
  1333  				next = append(next, fieldScan{styp, index})
  1334  			}
  1335  		}
  1336  		if ok {
  1337  			break
  1338  		}
  1339  	}
  1340  	return
  1341  }
  1342  
  1343  // FieldByName returns the struct field with the given name
  1344  // and a boolean to indicate if the field was found.
  1345  func (t *structType) FieldByName(name string) (f StructField, present bool) {
  1346  	// Quick check for top-level name, or struct without embedded fields.
  1347  	hasEmbeds := false
  1348  	if name != "" {
  1349  		for i := range t.Fields {
  1350  			tf := &t.Fields[i]
  1351  			if tf.Name.Name() == name {
  1352  				return t.Field(i), true
  1353  			}
  1354  			if tf.Embedded() {
  1355  				hasEmbeds = true
  1356  			}
  1357  		}
  1358  	}
  1359  	if !hasEmbeds {
  1360  		return
  1361  	}
  1362  	return t.FieldByNameFunc(func(s string) bool { return s == name })
  1363  }
  1364  
  1365  // TypeOf returns the reflection [Type] that represents the dynamic type of i.
  1366  // If i is a nil interface value, TypeOf returns nil.
  1367  func TypeOf(i any) Type {
  1368  	return toType(abi.TypeOf(i))
  1369  }
  1370  
  1371  // TypeFor returns the [Type] that represents the type argument T.
  1372  func TypeFor[T any]() Type {
  1373  	// toRType is safe to use here; type is never nil as T is statically known.
  1374  	return toRType(abi.TypeFor[T]())
  1375  }
  1376  
  1377  // rtypeOf directly extracts the *rtype of the provided value.
  1378  func rtypeOf(i any) *abi.Type {
  1379  	return abi.TypeOf(i)
  1380  }
  1381  
  1382  // ptrMap is the cache for PointerTo.
  1383  var ptrMap sync.Map // map[*rtype]*ptrType
  1384  
  1385  // PtrTo returns the pointer type with element t.
  1386  // For example, if t represents type Foo, PtrTo(t) represents *Foo.
  1387  //
  1388  // PtrTo is the old spelling of [PointerTo].
  1389  // The two functions behave identically.
  1390  //
  1391  // Deprecated: Superseded by [PointerTo].
  1392  //
  1393  //go:fix inline
  1394  func PtrTo(t Type) Type { return PointerTo(t) }
  1395  
  1396  // PointerTo returns the pointer type with element t.
  1397  // For example, if t represents type Foo, PointerTo(t) represents *Foo.
  1398  func PointerTo(t Type) Type {
  1399  	return toRType(t.(*rtype).ptrTo())
  1400  }
  1401  
  1402  func (t *rtype) ptrTo() *abi.Type {
  1403  	at := &t.t
  1404  	if at.PtrToThis != 0 {
  1405  		return t.typeOff(at.PtrToThis)
  1406  	}
  1407  
  1408  	// Check the cache.
  1409  	if pi, ok := ptrMap.Load(t); ok {
  1410  		return &pi.(*ptrType).Type
  1411  	}
  1412  
  1413  	// Look in known types.
  1414  	s := "*" + t.String()
  1415  	for _, tt := range typesByString(s) {
  1416  		p := (*ptrType)(unsafe.Pointer(tt))
  1417  		if p.Elem != &t.t {
  1418  			continue
  1419  		}
  1420  		pi, _ := ptrMap.LoadOrStore(t, p)
  1421  		return &pi.(*ptrType).Type
  1422  	}
  1423  
  1424  	// Create a new ptrType starting with the description
  1425  	// of an *unsafe.Pointer.
  1426  	var iptr any = (*unsafe.Pointer)(nil)
  1427  	prototype := *(**ptrType)(unsafe.Pointer(&iptr))
  1428  	pp := *prototype
  1429  
  1430  	pp.Str = resolveReflectName(newName(s, "", false, false))
  1431  	pp.PtrToThis = 0
  1432  
  1433  	// For the type structures linked into the binary, the
  1434  	// compiler provides a good hash of the string.
  1435  	// Create a good hash for the new string by using
  1436  	// the FNV-1 hash's mixing function to combine the
  1437  	// old hash and the new "*".
  1438  	pp.Hash = fnv1(t.t.Hash, '*')
  1439  
  1440  	pp.Elem = at
  1441  
  1442  	pi, _ := ptrMap.LoadOrStore(t, &pp)
  1443  	return &pi.(*ptrType).Type
  1444  }
  1445  
  1446  func ptrTo(t *abi.Type) *abi.Type {
  1447  	return toRType(t).ptrTo()
  1448  }
  1449  
  1450  // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
  1451  func fnv1(x uint32, list ...byte) uint32 {
  1452  	for _, b := range list {
  1453  		x = x*16777619 ^ uint32(b)
  1454  	}
  1455  	return x
  1456  }
  1457  
  1458  func (t *rtype) Implements(u Type) bool {
  1459  	if u == nil {
  1460  		panic("reflect: nil type passed to Type.Implements")
  1461  	}
  1462  	if u.Kind() != Interface {
  1463  		panic("reflect: non-interface type passed to Type.Implements")
  1464  	}
  1465  	return implements(u.common(), t.common())
  1466  }
  1467  
  1468  func (t *rtype) AssignableTo(u Type) bool {
  1469  	if u == nil {
  1470  		panic("reflect: nil type passed to Type.AssignableTo")
  1471  	}
  1472  	uu := u.common()
  1473  	return directlyAssignable(uu, t.common()) || implements(uu, t.common())
  1474  }
  1475  
  1476  func (t *rtype) ConvertibleTo(u Type) bool {
  1477  	if u == nil {
  1478  		panic("reflect: nil type passed to Type.ConvertibleTo")
  1479  	}
  1480  	return convertOp(u.common(), t.common()) != nil
  1481  }
  1482  
  1483  func (t *rtype) Comparable() bool {
  1484  	return t.t.Equal != nil
  1485  }
  1486  
  1487  // implements reports whether the type V implements the interface type T.
  1488  func implements(T, V *abi.Type) bool {
  1489  	if T.Kind() != abi.Interface {
  1490  		return false
  1491  	}
  1492  	t := (*interfaceType)(unsafe.Pointer(T))
  1493  	if len(t.Methods) == 0 {
  1494  		return true
  1495  	}
  1496  
  1497  	// The same algorithm applies in both cases, but the
  1498  	// method tables for an interface type and a concrete type
  1499  	// are different, so the code is duplicated.
  1500  	// In both cases the algorithm is a linear scan over the two
  1501  	// lists - T's methods and V's methods - simultaneously.
  1502  	// Since method tables are stored in a unique sorted order
  1503  	// (alphabetical, with no duplicate method names), the scan
  1504  	// through V's methods must hit a match for each of T's
  1505  	// methods along the way, or else V does not implement T.
  1506  	// This lets us run the scan in overall linear time instead of
  1507  	// the quadratic time  a naive search would require.
  1508  	// See also ../runtime/iface.go.
  1509  	if V.Kind() == abi.Interface {
  1510  		v := (*interfaceType)(unsafe.Pointer(V))
  1511  		i := 0
  1512  		for j := 0; j < len(v.Methods); j++ {
  1513  			tm := &t.Methods[i]
  1514  			tmName := t.nameOff(tm.Name)
  1515  			vm := &v.Methods[j]
  1516  			vmName := nameOffFor(V, vm.Name)
  1517  			if vmName.Name() == tmName.Name() && typeOffFor(V, vm.Typ) == t.typeOff(tm.Typ) {
  1518  				if !tmName.IsExported() {
  1519  					tmPkgPath := pkgPath(tmName)
  1520  					if tmPkgPath == "" {
  1521  						tmPkgPath = t.PkgPath.Name()
  1522  					}
  1523  					vmPkgPath := pkgPath(vmName)
  1524  					if vmPkgPath == "" {
  1525  						vmPkgPath = v.PkgPath.Name()
  1526  					}
  1527  					if tmPkgPath != vmPkgPath {
  1528  						continue
  1529  					}
  1530  				}
  1531  				if i++; i >= len(t.Methods) {
  1532  					return true
  1533  				}
  1534  			}
  1535  		}
  1536  		return false
  1537  	}
  1538  
  1539  	v := V.Uncommon()
  1540  	if v == nil {
  1541  		return false
  1542  	}
  1543  	i := 0
  1544  	vmethods := v.Methods()
  1545  	for j := 0; j < int(v.Mcount); j++ {
  1546  		tm := &t.Methods[i]
  1547  		tmName := t.nameOff(tm.Name)
  1548  		vm := vmethods[j]
  1549  		vmName := nameOffFor(V, vm.Name)
  1550  		if vmName.Name() == tmName.Name() && typeOffFor(V, vm.Mtyp) == t.typeOff(tm.Typ) {
  1551  			if !tmName.IsExported() {
  1552  				tmPkgPath := pkgPath(tmName)
  1553  				if tmPkgPath == "" {
  1554  					tmPkgPath = t.PkgPath.Name()
  1555  				}
  1556  				vmPkgPath := pkgPath(vmName)
  1557  				if vmPkgPath == "" {
  1558  					vmPkgPath = nameOffFor(V, v.PkgPath).Name()
  1559  				}
  1560  				if tmPkgPath != vmPkgPath {
  1561  					continue
  1562  				}
  1563  			}
  1564  			if i++; i >= len(t.Methods) {
  1565  				return true
  1566  			}
  1567  		}
  1568  	}
  1569  	return false
  1570  }
  1571  
  1572  // specialChannelAssignability reports whether a value x of channel type V
  1573  // can be directly assigned (using memmove) to another channel type T.
  1574  // https://golang.org/doc/go_spec.html#Assignability
  1575  // T and V must be both of Chan kind.
  1576  func specialChannelAssignability(T, V *abi.Type) bool {
  1577  	// Special case:
  1578  	// x is a bidirectional channel value, T is a channel type,
  1579  	// x's type V and T have identical element types,
  1580  	// and at least one of V or T is not a defined type.
  1581  	return V.ChanDir() == abi.BothDir && (nameFor(T) == "" || nameFor(V) == "") && haveIdenticalType(T.Elem(), V.Elem(), true)
  1582  }
  1583  
  1584  // directlyAssignable reports whether a value x of type V can be directly
  1585  // assigned (using memmove) to a value of type T.
  1586  // https://golang.org/doc/go_spec.html#Assignability
  1587  // Ignoring the interface rules (implemented elsewhere)
  1588  // and the ideal constant rules (no ideal constants at run time).
  1589  func directlyAssignable(T, V *abi.Type) bool {
  1590  	// x's type V is identical to T?
  1591  	if T == V {
  1592  		return true
  1593  	}
  1594  
  1595  	// Otherwise at least one of T and V must not be defined
  1596  	// and they must have the same kind.
  1597  	if T.HasName() && V.HasName() || T.Kind() != V.Kind() {
  1598  		return false
  1599  	}
  1600  
  1601  	if T.Kind() == abi.Chan && specialChannelAssignability(T, V) {
  1602  		return true
  1603  	}
  1604  
  1605  	// x's type T and V must have identical underlying types.
  1606  	return haveIdenticalUnderlyingType(T, V, true)
  1607  }
  1608  
  1609  func haveIdenticalType(T, V *abi.Type, cmpTags bool) bool {
  1610  	if cmpTags {
  1611  		return T == V
  1612  	}
  1613  
  1614  	if nameFor(T) != nameFor(V) || T.Kind() != V.Kind() || pkgPathFor(T) != pkgPathFor(V) {
  1615  		return false
  1616  	}
  1617  
  1618  	return haveIdenticalUnderlyingType(T, V, false)
  1619  }
  1620  
  1621  func haveIdenticalUnderlyingType(T, V *abi.Type, cmpTags bool) bool {
  1622  	if T == V {
  1623  		return true
  1624  	}
  1625  
  1626  	kind := Kind(T.Kind())
  1627  	if kind != Kind(V.Kind()) {
  1628  		return false
  1629  	}
  1630  
  1631  	// Non-composite types of equal kind have same underlying type
  1632  	// (the predefined instance of the type).
  1633  	if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
  1634  		return true
  1635  	}
  1636  
  1637  	// Composite types.
  1638  	switch kind {
  1639  	case Array:
  1640  		return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
  1641  
  1642  	case Chan:
  1643  		return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
  1644  
  1645  	case Func:
  1646  		t := (*funcType)(unsafe.Pointer(T))
  1647  		v := (*funcType)(unsafe.Pointer(V))
  1648  		if t.OutCount != v.OutCount || t.InCount != v.InCount {
  1649  			return false
  1650  		}
  1651  		for i := 0; i < t.NumIn(); i++ {
  1652  			if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
  1653  				return false
  1654  			}
  1655  		}
  1656  		for i := 0; i < t.NumOut(); i++ {
  1657  			if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
  1658  				return false
  1659  			}
  1660  		}
  1661  		return true
  1662  
  1663  	case Interface:
  1664  		t := (*interfaceType)(unsafe.Pointer(T))
  1665  		v := (*interfaceType)(unsafe.Pointer(V))
  1666  		if len(t.Methods) == 0 && len(v.Methods) == 0 {
  1667  			return true
  1668  		}
  1669  		// Might have the same methods but still
  1670  		// need a run time conversion.
  1671  		return false
  1672  
  1673  	case Map:
  1674  		return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
  1675  
  1676  	case Pointer, Slice:
  1677  		return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
  1678  
  1679  	case Struct:
  1680  		t := (*structType)(unsafe.Pointer(T))
  1681  		v := (*structType)(unsafe.Pointer(V))
  1682  		if len(t.Fields) != len(v.Fields) {
  1683  			return false
  1684  		}
  1685  		if t.PkgPath.Name() != v.PkgPath.Name() {
  1686  			return false
  1687  		}
  1688  		for i := range t.Fields {
  1689  			tf := &t.Fields[i]
  1690  			vf := &v.Fields[i]
  1691  			if tf.Name.Name() != vf.Name.Name() {
  1692  				return false
  1693  			}
  1694  			if !haveIdenticalType(tf.Typ, vf.Typ, cmpTags) {
  1695  				return false
  1696  			}
  1697  			if cmpTags && tf.Name.Tag() != vf.Name.Tag() {
  1698  				return false
  1699  			}
  1700  			if tf.Offset != vf.Offset {
  1701  				return false
  1702  			}
  1703  			if tf.Embedded() != vf.Embedded() {
  1704  				return false
  1705  			}
  1706  		}
  1707  		return true
  1708  	}
  1709  
  1710  	return false
  1711  }
  1712  
  1713  // typelinks is implemented in package runtime.
  1714  // It returns a slice of the sections in each module,
  1715  // and a slice of *rtype offsets in each module.
  1716  //
  1717  // The types in each module are sorted by string. That is, the first
  1718  // two linked types of the first module are:
  1719  //
  1720  //	d0 := sections[0]
  1721  //	t1 := (*rtype)(add(d0, offset[0][0]))
  1722  //	t2 := (*rtype)(add(d0, offset[0][1]))
  1723  //
  1724  // and
  1725  //
  1726  //	t1.String() < t2.String()
  1727  //
  1728  // Note that strings are not unique identifiers for types:
  1729  // there can be more than one with a given string.
  1730  // Only types we might want to look up are included:
  1731  // pointers, channels, maps, slices, and arrays.
  1732  func typelinks() (sections []unsafe.Pointer, offset [][]int32)
  1733  
  1734  // rtypeOff should be an internal detail,
  1735  // but widely used packages access it using linkname.
  1736  // Notable members of the hall of shame include:
  1737  //   - github.com/goccy/go-json
  1738  //
  1739  // Do not remove or change the type signature.
  1740  // See go.dev/issue/67401.
  1741  //
  1742  //go:linkname rtypeOff
  1743  func rtypeOff(section unsafe.Pointer, off int32) *abi.Type {
  1744  	return (*abi.Type)(add(section, uintptr(off), "sizeof(rtype) > 0"))
  1745  }
  1746  
  1747  // typesByString returns the subslice of typelinks() whose elements have
  1748  // the given string representation.
  1749  // It may be empty (no known types with that string) or may have
  1750  // multiple elements (multiple types with that string).
  1751  //
  1752  // typesByString should be an internal detail,
  1753  // but widely used packages access it using linkname.
  1754  // Notable members of the hall of shame include:
  1755  //   - github.com/aristanetworks/goarista
  1756  //   - fortio.org/log
  1757  //
  1758  // Do not remove or change the type signature.
  1759  // See go.dev/issue/67401.
  1760  //
  1761  //go:linkname typesByString
  1762  func typesByString(s string) []*abi.Type {
  1763  	sections, offset := typelinks()
  1764  	var ret []*abi.Type
  1765  
  1766  	for offsI, offs := range offset {
  1767  		section := sections[offsI]
  1768  
  1769  		// We are looking for the first index i where the string becomes >= s.
  1770  		// This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s).
  1771  		i, j := 0, len(offs)
  1772  		for i < j {
  1773  			h := int(uint(i+j) >> 1) // avoid overflow when computing h
  1774  			// i ≤ h < j
  1775  			if !(stringFor(rtypeOff(section, offs[h])) >= s) {
  1776  				i = h + 1 // preserves f(i-1) == false
  1777  			} else {
  1778  				j = h // preserves f(j) == true
  1779  			}
  1780  		}
  1781  		// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
  1782  
  1783  		// Having found the first, linear scan forward to find the last.
  1784  		// We could do a second binary search, but the caller is going
  1785  		// to do a linear scan anyway.
  1786  		for j := i; j < len(offs); j++ {
  1787  			typ := rtypeOff(section, offs[j])
  1788  			if stringFor(typ) != s {
  1789  				break
  1790  			}
  1791  			ret = append(ret, typ)
  1792  		}
  1793  	}
  1794  	return ret
  1795  }
  1796  
  1797  // The lookupCache caches ArrayOf, ChanOf, MapOf and SliceOf lookups.
  1798  var lookupCache sync.Map // map[cacheKey]*rtype
  1799  
  1800  // A cacheKey is the key for use in the lookupCache.
  1801  // Four values describe any of the types we are looking for:
  1802  // type kind, one or two subtypes, and an extra integer.
  1803  type cacheKey struct {
  1804  	kind  Kind
  1805  	t1    *abi.Type
  1806  	t2    *abi.Type
  1807  	extra uintptr
  1808  }
  1809  
  1810  // The funcLookupCache caches FuncOf lookups.
  1811  // FuncOf does not share the common lookupCache since cacheKey is not
  1812  // sufficient to represent functions unambiguously.
  1813  var funcLookupCache struct {
  1814  	sync.Mutex // Guards stores (but not loads) on m.
  1815  
  1816  	// m is a map[uint32][]*rtype keyed by the hash calculated in FuncOf.
  1817  	// Elements of m are append-only and thus safe for concurrent reading.
  1818  	m sync.Map
  1819  }
  1820  
  1821  // ChanOf returns the channel type with the given direction and element type.
  1822  // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
  1823  //
  1824  // The gc runtime imposes a limit of 64 kB on channel element types.
  1825  // If t's size is equal to or exceeds this limit, ChanOf panics.
  1826  func ChanOf(dir ChanDir, t Type) Type {
  1827  	typ := t.common()
  1828  
  1829  	// Look in cache.
  1830  	ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
  1831  	if ch, ok := lookupCache.Load(ckey); ok {
  1832  		return ch.(*rtype)
  1833  	}
  1834  
  1835  	// This restriction is imposed by the gc compiler and the runtime.
  1836  	if typ.Size_ >= 1<<16 {
  1837  		panic("reflect.ChanOf: element size too large")
  1838  	}
  1839  
  1840  	// Look in known types.
  1841  	var s string
  1842  	switch dir {
  1843  	default:
  1844  		panic("reflect.ChanOf: invalid dir")
  1845  	case SendDir:
  1846  		s = "chan<- " + stringFor(typ)
  1847  	case RecvDir:
  1848  		s = "<-chan " + stringFor(typ)
  1849  	case BothDir:
  1850  		typeStr := stringFor(typ)
  1851  		if typeStr[0] == '<' {
  1852  			// typ is recv chan, need parentheses as "<-" associates with leftmost
  1853  			// chan possible, see:
  1854  			// * https://golang.org/ref/spec#Channel_types
  1855  			// * https://github.com/golang/go/issues/39897
  1856  			s = "chan (" + typeStr + ")"
  1857  		} else {
  1858  			s = "chan " + typeStr
  1859  		}
  1860  	}
  1861  	for _, tt := range typesByString(s) {
  1862  		ch := (*chanType)(unsafe.Pointer(tt))
  1863  		if ch.Elem == typ && ch.Dir == abi.ChanDir(dir) {
  1864  			ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt))
  1865  			return ti.(Type)
  1866  		}
  1867  	}
  1868  
  1869  	// Make a channel type.
  1870  	var ichan any = (chan unsafe.Pointer)(nil)
  1871  	prototype := *(**chanType)(unsafe.Pointer(&ichan))
  1872  	ch := *prototype
  1873  	ch.TFlag = abi.TFlagRegularMemory | abi.TFlagDirectIface
  1874  	ch.Dir = abi.ChanDir(dir)
  1875  	ch.Str = resolveReflectName(newName(s, "", false, false))
  1876  	ch.Hash = fnv1(typ.Hash, 'c', byte(dir))
  1877  	ch.Elem = typ
  1878  
  1879  	ti, _ := lookupCache.LoadOrStore(ckey, toRType(&ch.Type))
  1880  	return ti.(Type)
  1881  }
  1882  
  1883  var funcTypes []Type
  1884  var funcTypesMutex sync.Mutex
  1885  
  1886  func initFuncTypes(n int) Type {
  1887  	funcTypesMutex.Lock()
  1888  	defer funcTypesMutex.Unlock()
  1889  	if n >= len(funcTypes) {
  1890  		newFuncTypes := make([]Type, n+1)
  1891  		copy(newFuncTypes, funcTypes)
  1892  		funcTypes = newFuncTypes
  1893  	}
  1894  	if funcTypes[n] != nil {
  1895  		return funcTypes[n]
  1896  	}
  1897  
  1898  	funcTypes[n] = StructOf([]StructField{
  1899  		{
  1900  			Name: "FuncType",
  1901  			Type: TypeOf(funcType{}),
  1902  		},
  1903  		{
  1904  			Name: "Args",
  1905  			Type: ArrayOf(n, TypeOf(&rtype{})),
  1906  		},
  1907  	})
  1908  	return funcTypes[n]
  1909  }
  1910  
  1911  // FuncOf returns the function type with the given argument and result types.
  1912  // For example if k represents int and e represents string,
  1913  // FuncOf([]Type{k}, []Type{e}, false) represents func(int) string.
  1914  //
  1915  // The variadic argument controls whether the function is variadic. FuncOf
  1916  // panics if the in[len(in)-1] does not represent a slice and variadic is
  1917  // true.
  1918  func FuncOf(in, out []Type, variadic bool) Type {
  1919  	if variadic && (len(in) == 0 || in[len(in)-1].Kind() != Slice) {
  1920  		panic("reflect.FuncOf: last arg of variadic func must be slice")
  1921  	}
  1922  
  1923  	// Make a func type.
  1924  	var ifunc any = (func())(nil)
  1925  	prototype := *(**funcType)(unsafe.Pointer(&ifunc))
  1926  	n := len(in) + len(out)
  1927  
  1928  	if n > 128 {
  1929  		panic("reflect.FuncOf: too many arguments")
  1930  	}
  1931  
  1932  	o := New(initFuncTypes(n)).Elem()
  1933  	ft := (*funcType)(unsafe.Pointer(o.Field(0).Addr().Pointer()))
  1934  	args := unsafe.Slice((**rtype)(unsafe.Pointer(o.Field(1).Addr().Pointer())), n)[0:0:n]
  1935  	*ft = *prototype
  1936  
  1937  	// Build a hash and minimally populate ft.
  1938  	var hash uint32
  1939  	for _, in := range in {
  1940  		t := in.(*rtype)
  1941  		args = append(args, t)
  1942  		hash = fnv1(hash, byte(t.t.Hash>>24), byte(t.t.Hash>>16), byte(t.t.Hash>>8), byte(t.t.Hash))
  1943  	}
  1944  	if variadic {
  1945  		hash = fnv1(hash, 'v')
  1946  	}
  1947  	hash = fnv1(hash, '.')
  1948  	for _, out := range out {
  1949  		t := out.(*rtype)
  1950  		args = append(args, t)
  1951  		hash = fnv1(hash, byte(t.t.Hash>>24), byte(t.t.Hash>>16), byte(t.t.Hash>>8), byte(t.t.Hash))
  1952  	}
  1953  
  1954  	ft.TFlag = abi.TFlagDirectIface
  1955  	ft.Hash = hash
  1956  	ft.InCount = uint16(len(in))
  1957  	ft.OutCount = uint16(len(out))
  1958  	if variadic {
  1959  		ft.OutCount |= 1 << 15
  1960  	}
  1961  
  1962  	// Look in cache.
  1963  	if ts, ok := funcLookupCache.m.Load(hash); ok {
  1964  		for _, t := range ts.([]*abi.Type) {
  1965  			if haveIdenticalUnderlyingType(&ft.Type, t, true) {
  1966  				return toRType(t)
  1967  			}
  1968  		}
  1969  	}
  1970  
  1971  	// Not in cache, lock and retry.
  1972  	funcLookupCache.Lock()
  1973  	defer funcLookupCache.Unlock()
  1974  	if ts, ok := funcLookupCache.m.Load(hash); ok {
  1975  		for _, t := range ts.([]*abi.Type) {
  1976  			if haveIdenticalUnderlyingType(&ft.Type, t, true) {
  1977  				return toRType(t)
  1978  			}
  1979  		}
  1980  	}
  1981  
  1982  	addToCache := func(tt *abi.Type) Type {
  1983  		var rts []*abi.Type
  1984  		if rti, ok := funcLookupCache.m.Load(hash); ok {
  1985  			rts = rti.([]*abi.Type)
  1986  		}
  1987  		funcLookupCache.m.Store(hash, append(rts, tt))
  1988  		return toType(tt)
  1989  	}
  1990  
  1991  	// Look in known types for the same string representation.
  1992  	str := funcStr(ft)
  1993  	for _, tt := range typesByString(str) {
  1994  		if haveIdenticalUnderlyingType(&ft.Type, tt, true) {
  1995  			return addToCache(tt)
  1996  		}
  1997  	}
  1998  
  1999  	// Populate the remaining fields of ft and store in cache.
  2000  	ft.Str = resolveReflectName(newName(str, "", false, false))
  2001  	ft.PtrToThis = 0
  2002  	return addToCache(&ft.Type)
  2003  }
  2004  func stringFor(t *abi.Type) string {
  2005  	return toRType(t).String()
  2006  }
  2007  
  2008  // funcStr builds a string representation of a funcType.
  2009  func funcStr(ft *funcType) string {
  2010  	repr := make([]byte, 0, 64)
  2011  	repr = append(repr, "func("...)
  2012  	for i, t := range ft.InSlice() {
  2013  		if i > 0 {
  2014  			repr = append(repr, ", "...)
  2015  		}
  2016  		if ft.IsVariadic() && i == int(ft.InCount)-1 {
  2017  			repr = append(repr, "..."...)
  2018  			repr = append(repr, stringFor((*sliceType)(unsafe.Pointer(t)).Elem)...)
  2019  		} else {
  2020  			repr = append(repr, stringFor(t)...)
  2021  		}
  2022  	}
  2023  	repr = append(repr, ')')
  2024  	out := ft.OutSlice()
  2025  	if len(out) == 1 {
  2026  		repr = append(repr, ' ')
  2027  	} else if len(out) > 1 {
  2028  		repr = append(repr, " ("...)
  2029  	}
  2030  	for i, t := range out {
  2031  		if i > 0 {
  2032  			repr = append(repr, ", "...)
  2033  		}
  2034  		repr = append(repr, stringFor(t)...)
  2035  	}
  2036  	if len(out) > 1 {
  2037  		repr = append(repr, ')')
  2038  	}
  2039  	return string(repr)
  2040  }
  2041  
  2042  // isReflexive reports whether the == operation on the type is reflexive.
  2043  // That is, x == x for all values x of type t.
  2044  func isReflexive(t *abi.Type) bool {
  2045  	switch Kind(t.Kind()) {
  2046  	case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, String, UnsafePointer:
  2047  		return true
  2048  	case Float32, Float64, Complex64, Complex128, Interface:
  2049  		return false
  2050  	case Array:
  2051  		tt := (*arrayType)(unsafe.Pointer(t))
  2052  		return isReflexive(tt.Elem)
  2053  	case Struct:
  2054  		tt := (*structType)(unsafe.Pointer(t))
  2055  		for _, f := range tt.Fields {
  2056  			if !isReflexive(f.Typ) {
  2057  				return false
  2058  			}
  2059  		}
  2060  		return true
  2061  	default:
  2062  		// Func, Map, Slice, Invalid
  2063  		panic("isReflexive called on non-key type " + stringFor(t))
  2064  	}
  2065  }
  2066  
  2067  // needKeyUpdate reports whether map overwrites require the key to be copied.
  2068  func needKeyUpdate(t *abi.Type) bool {
  2069  	switch Kind(t.Kind()) {
  2070  	case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, UnsafePointer:
  2071  		return false
  2072  	case Float32, Float64, Complex64, Complex128, Interface, String:
  2073  		// Float keys can be updated from +0 to -0.
  2074  		// String keys can be updated to use a smaller backing store.
  2075  		// Interfaces might have floats or strings in them.
  2076  		return true
  2077  	case Array:
  2078  		tt := (*arrayType)(unsafe.Pointer(t))
  2079  		return needKeyUpdate(tt.Elem)
  2080  	case Struct:
  2081  		tt := (*structType)(unsafe.Pointer(t))
  2082  		for _, f := range tt.Fields {
  2083  			if needKeyUpdate(f.Typ) {
  2084  				return true
  2085  			}
  2086  		}
  2087  		return false
  2088  	default:
  2089  		// Func, Map, Slice, Invalid
  2090  		panic("needKeyUpdate called on non-key type " + stringFor(t))
  2091  	}
  2092  }
  2093  
  2094  // hashMightPanic reports whether the hash of a map key of type t might panic.
  2095  func hashMightPanic(t *abi.Type) bool {
  2096  	switch Kind(t.Kind()) {
  2097  	case Interface:
  2098  		return true
  2099  	case Array:
  2100  		tt := (*arrayType)(unsafe.Pointer(t))
  2101  		return hashMightPanic(tt.Elem)
  2102  	case Struct:
  2103  		tt := (*structType)(unsafe.Pointer(t))
  2104  		for _, f := range tt.Fields {
  2105  			if hashMightPanic(f.Typ) {
  2106  				return true
  2107  			}
  2108  		}
  2109  		return false
  2110  	default:
  2111  		return false
  2112  	}
  2113  }
  2114  
  2115  // emitGCMask writes the GC mask for [n]typ into out, starting at bit
  2116  // offset base.
  2117  func emitGCMask(out []byte, base uintptr, typ *abi.Type, n uintptr) {
  2118  	ptrs := typ.PtrBytes / goarch.PtrSize
  2119  	words := typ.Size_ / goarch.PtrSize
  2120  	mask := typ.GcSlice(0, (ptrs+7)/8)
  2121  	for j := uintptr(0); j < ptrs; j++ {
  2122  		if (mask[j/8]>>(j%8))&1 != 0 {
  2123  			for i := uintptr(0); i < n; i++ {
  2124  				k := base + i*words + j
  2125  				out[k/8] |= 1 << (k % 8)
  2126  			}
  2127  		}
  2128  	}
  2129  }
  2130  
  2131  // SliceOf returns the slice type with element type t.
  2132  // For example, if t represents int, SliceOf(t) represents []int.
  2133  func SliceOf(t Type) Type {
  2134  	typ := t.common()
  2135  
  2136  	// Look in cache.
  2137  	ckey := cacheKey{Slice, typ, nil, 0}
  2138  	if slice, ok := lookupCache.Load(ckey); ok {
  2139  		return slice.(Type)
  2140  	}
  2141  
  2142  	// Look in known types.
  2143  	s := "[]" + stringFor(typ)
  2144  	for _, tt := range typesByString(s) {
  2145  		slice := (*sliceType)(unsafe.Pointer(tt))
  2146  		if slice.Elem == typ {
  2147  			ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt))
  2148  			return ti.(Type)
  2149  		}
  2150  	}
  2151  
  2152  	// Make a slice type.
  2153  	var islice any = ([]unsafe.Pointer)(nil)
  2154  	prototype := *(**sliceType)(unsafe.Pointer(&islice))
  2155  	slice := *prototype
  2156  	slice.TFlag = 0
  2157  	slice.Str = resolveReflectName(newName(s, "", false, false))
  2158  	slice.Hash = fnv1(typ.Hash, '[')
  2159  	slice.Elem = typ
  2160  	slice.PtrToThis = 0
  2161  
  2162  	ti, _ := lookupCache.LoadOrStore(ckey, toRType(&slice.Type))
  2163  	return ti.(Type)
  2164  }
  2165  
  2166  // The structLookupCache caches StructOf lookups.
  2167  // StructOf does not share the common lookupCache since we need to pin
  2168  // the memory associated with *structTypeFixedN.
  2169  var structLookupCache struct {
  2170  	sync.Mutex // Guards stores (but not loads) on m.
  2171  
  2172  	// m is a map[uint32][]Type keyed by the hash calculated in StructOf.
  2173  	// Elements in m are append-only and thus safe for concurrent reading.
  2174  	m sync.Map
  2175  }
  2176  
  2177  type structTypeUncommon struct {
  2178  	structType
  2179  	u uncommonType
  2180  }
  2181  
  2182  // isLetter reports whether a given 'rune' is classified as a Letter.
  2183  func isLetter(ch rune) bool {
  2184  	return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
  2185  }
  2186  
  2187  // isValidFieldName checks if a string is a valid (struct) field name or not.
  2188  //
  2189  // According to the language spec, a field name should be an identifier.
  2190  //
  2191  // identifier = letter { letter | unicode_digit } .
  2192  // letter = unicode_letter | "_" .
  2193  func isValidFieldName(fieldName string) bool {
  2194  	for i, c := range fieldName {
  2195  		if i == 0 && !isLetter(c) {
  2196  			return false
  2197  		}
  2198  
  2199  		if !(isLetter(c) || unicode.IsDigit(c)) {
  2200  			return false
  2201  		}
  2202  	}
  2203  
  2204  	return len(fieldName) > 0
  2205  }
  2206  
  2207  // This must match cmd/compile/internal/compare.IsRegularMemory
  2208  func isRegularMemory(t Type) bool {
  2209  	switch t.Kind() {
  2210  	case Array:
  2211  		elem := t.Elem()
  2212  		if isRegularMemory(elem) {
  2213  			return true
  2214  		}
  2215  		return elem.Comparable() && t.Len() == 0
  2216  	case Int8, Int16, Int32, Int64, Int, Uint8, Uint16, Uint32, Uint64, Uint, Uintptr, Chan, Pointer, Bool, UnsafePointer:
  2217  		return true
  2218  	case Struct:
  2219  		num := t.NumField()
  2220  		switch num {
  2221  		case 0:
  2222  			return true
  2223  		case 1:
  2224  			field := t.Field(0)
  2225  			if field.Name == "_" {
  2226  				return false
  2227  			}
  2228  			return isRegularMemory(field.Type)
  2229  		default:
  2230  			for i := range num {
  2231  				field := t.Field(i)
  2232  				if field.Name == "_" || !isRegularMemory(field.Type) || isPaddedField(t, i) {
  2233  					return false
  2234  				}
  2235  			}
  2236  			return true
  2237  		}
  2238  	}
  2239  	return false
  2240  }
  2241  
  2242  // isPaddedField reports whether the i'th field of struct type t is followed
  2243  // by padding.
  2244  func isPaddedField(t Type, i int) bool {
  2245  	field := t.Field(i)
  2246  	if i+1 < t.NumField() {
  2247  		return field.Offset+field.Type.Size() != t.Field(i+1).Offset
  2248  	}
  2249  	return field.Offset+field.Type.Size() != t.Size()
  2250  }
  2251  
  2252  // StructOf returns the struct type containing fields.
  2253  // The Offset and Index fields are ignored and computed as they would be
  2254  // by the compiler.
  2255  //
  2256  // StructOf currently does not support promoted methods of embedded fields
  2257  // and panics if passed unexported StructFields.
  2258  func StructOf(fields []StructField) Type {
  2259  	var (
  2260  		hash       = fnv1(0, []byte("struct {")...)
  2261  		size       uintptr
  2262  		typalign   uint8
  2263  		comparable = true
  2264  		methods    []abi.Method
  2265  
  2266  		fs   = make([]structField, len(fields))
  2267  		repr = make([]byte, 0, 64)
  2268  		fset = map[string]struct{}{} // fields' names
  2269  	)
  2270  
  2271  	lastzero := uintptr(0)
  2272  	repr = append(repr, "struct {"...)
  2273  	pkgpath := ""
  2274  	for i, field := range fields {
  2275  		if field.Name == "" {
  2276  			panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no name")
  2277  		}
  2278  		if !isValidFieldName(field.Name) {
  2279  			panic("reflect.StructOf: field " + strconv.Itoa(i) + " has invalid name")
  2280  		}
  2281  		if field.Type == nil {
  2282  			panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no type")
  2283  		}
  2284  		f, fpkgpath := runtimeStructField(field)
  2285  		ft := f.Typ
  2286  		if fpkgpath != "" {
  2287  			if pkgpath == "" {
  2288  				pkgpath = fpkgpath
  2289  			} else if pkgpath != fpkgpath {
  2290  				panic("reflect.Struct: fields with different PkgPath " + pkgpath + " and " + fpkgpath)
  2291  			}
  2292  		}
  2293  
  2294  		// Update string and hash
  2295  		name := f.Name.Name()
  2296  		hash = fnv1(hash, []byte(name)...)
  2297  		if !f.Embedded() {
  2298  			repr = append(repr, (" " + name)...)
  2299  		} else {
  2300  			// Embedded field
  2301  			if f.Typ.Kind() == abi.Pointer {
  2302  				// Embedded ** and *interface{} are illegal
  2303  				elem := ft.Elem()
  2304  				if k := elem.Kind(); k == abi.Pointer || k == abi.Interface {
  2305  					panic("reflect.StructOf: illegal embedded field type " + stringFor(ft))
  2306  				}
  2307  			}
  2308  
  2309  			switch Kind(f.Typ.Kind()) {
  2310  			case Interface:
  2311  				ift := (*interfaceType)(unsafe.Pointer(ft))
  2312  				for _, m := range ift.Methods {
  2313  					if pkgPath(ift.nameOff(m.Name)) != "" {
  2314  						// TODO(sbinet).  Issue 15924.
  2315  						panic("reflect: embedded interface with unexported method(s) not implemented")
  2316  					}
  2317  
  2318  					fnStub := resolveReflectText(unsafe.Pointer(abi.FuncPCABIInternal(embeddedIfaceMethStub)))
  2319  					methods = append(methods, abi.Method{
  2320  						Name: resolveReflectName(ift.nameOff(m.Name)),
  2321  						Mtyp: resolveReflectType(ift.typeOff(m.Typ)),
  2322  						Ifn:  fnStub,
  2323  						Tfn:  fnStub,
  2324  					})
  2325  				}
  2326  			case Pointer:
  2327  				ptr := (*ptrType)(unsafe.Pointer(ft))
  2328  				if unt := ptr.Uncommon(); unt != nil {
  2329  					if i > 0 && unt.Mcount > 0 {
  2330  						// Issue 15924.
  2331  						panic("reflect: embedded type with methods not implemented if type is not first field")
  2332  					}
  2333  					if len(fields) > 1 {
  2334  						panic("reflect: embedded type with methods not implemented if there is more than one field")
  2335  					}
  2336  					for _, m := range unt.Methods() {
  2337  						mname := nameOffFor(ft, m.Name)
  2338  						if pkgPath(mname) != "" {
  2339  							// TODO(sbinet).
  2340  							// Issue 15924.
  2341  							panic("reflect: embedded interface with unexported method(s) not implemented")
  2342  						}
  2343  						methods = append(methods, abi.Method{
  2344  							Name: resolveReflectName(mname),
  2345  							Mtyp: resolveReflectType(typeOffFor(ft, m.Mtyp)),
  2346  							Ifn:  resolveReflectText(textOffFor(ft, m.Ifn)),
  2347  							Tfn:  resolveReflectText(textOffFor(ft, m.Tfn)),
  2348  						})
  2349  					}
  2350  				}
  2351  				if unt := ptr.Elem.Uncommon(); unt != nil {
  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(ptr.Elem, m.Mtyp)),
  2362  							Ifn:  resolveReflectText(textOffFor(ptr.Elem, m.Ifn)),
  2363  							Tfn:  resolveReflectText(textOffFor(ptr.Elem, m.Tfn)),
  2364  						})
  2365  					}
  2366  				}
  2367  			default:
  2368  				if unt := ft.Uncommon(); unt != nil {
  2369  					if i > 0 && unt.Mcount > 0 {
  2370  						// Issue 15924.
  2371  						panic("reflect: embedded type with methods not implemented if type is not first field")
  2372  					}
  2373  					if len(fields) > 1 && ft.IsDirectIface() {
  2374  						panic("reflect: embedded type with methods not implemented for non-pointer type")
  2375  					}
  2376  					for _, m := range unt.Methods() {
  2377  						mname := nameOffFor(ft, m.Name)
  2378  						if pkgPath(mname) != "" {
  2379  							// TODO(sbinet)
  2380  							// Issue 15924.
  2381  							panic("reflect: embedded interface with unexported method(s) not implemented")
  2382  						}
  2383  						methods = append(methods, abi.Method{
  2384  							Name: resolveReflectName(mname),
  2385  							Mtyp: resolveReflectType(typeOffFor(ft, m.Mtyp)),
  2386  							Ifn:  resolveReflectText(textOffFor(ft, m.Ifn)),
  2387  							Tfn:  resolveReflectText(textOffFor(ft, m.Tfn)),
  2388  						})
  2389  
  2390  					}
  2391  				}
  2392  			}
  2393  		}
  2394  		if _, dup := fset[name]; dup && name != "_" {
  2395  			panic("reflect.StructOf: duplicate field " + name)
  2396  		}
  2397  		fset[name] = struct{}{}
  2398  
  2399  		hash = fnv1(hash, byte(ft.Hash>>24), byte(ft.Hash>>16), byte(ft.Hash>>8), byte(ft.Hash))
  2400  
  2401  		repr = append(repr, (" " + stringFor(ft))...)
  2402  		if f.Name.HasTag() {
  2403  			hash = fnv1(hash, []byte(f.Name.Tag())...)
  2404  			repr = append(repr, (" " + strconv.Quote(f.Name.Tag()))...)
  2405  		}
  2406  		if i < len(fields)-1 {
  2407  			repr = append(repr, ';')
  2408  		}
  2409  
  2410  		comparable = comparable && (ft.Equal != nil)
  2411  
  2412  		offset := align(size, uintptr(ft.Align_))
  2413  		if offset < size {
  2414  			panic("reflect.StructOf: struct size would exceed virtual address space")
  2415  		}
  2416  		if ft.Align_ > typalign {
  2417  			typalign = ft.Align_
  2418  		}
  2419  		size = offset + ft.Size_
  2420  		if size < offset {
  2421  			panic("reflect.StructOf: struct size would exceed virtual address space")
  2422  		}
  2423  		f.Offset = offset
  2424  
  2425  		if ft.Size_ == 0 {
  2426  			lastzero = size
  2427  		}
  2428  
  2429  		fs[i] = f
  2430  	}
  2431  
  2432  	if size > 0 && lastzero == size {
  2433  		// This is a non-zero sized struct that ends in a
  2434  		// zero-sized field. We add an extra byte of padding,
  2435  		// to ensure that taking the address of the final
  2436  		// zero-sized field can't manufacture a pointer to the
  2437  		// next object in the heap. See issue 9401.
  2438  		size++
  2439  		if size == 0 {
  2440  			panic("reflect.StructOf: struct size would exceed virtual address space")
  2441  		}
  2442  	}
  2443  
  2444  	var typ *structType
  2445  	var ut *uncommonType
  2446  
  2447  	if len(methods) == 0 {
  2448  		t := new(structTypeUncommon)
  2449  		typ = &t.structType
  2450  		ut = &t.u
  2451  	} else {
  2452  		// A *rtype representing a struct is followed directly in memory by an
  2453  		// array of method objects representing the methods attached to the
  2454  		// struct. To get the same layout for a run time generated type, we
  2455  		// need an array directly following the uncommonType memory.
  2456  		// A similar strategy is used for funcTypeFixed4, ...funcTypeFixedN.
  2457  		tt := New(StructOf([]StructField{
  2458  			{Name: "S", Type: TypeOf(structType{})},
  2459  			{Name: "U", Type: TypeOf(uncommonType{})},
  2460  			{Name: "M", Type: ArrayOf(len(methods), TypeOf(methods[0]))},
  2461  		}))
  2462  
  2463  		typ = (*structType)(tt.Elem().Field(0).Addr().UnsafePointer())
  2464  		ut = (*uncommonType)(tt.Elem().Field(1).Addr().UnsafePointer())
  2465  
  2466  		copy(tt.Elem().Field(2).Slice(0, len(methods)).Interface().([]abi.Method), methods)
  2467  	}
  2468  	// TODO(sbinet): Once we allow embedding multiple types,
  2469  	// methods will need to be sorted like the compiler does.
  2470  	// TODO(sbinet): Once we allow non-exported methods, we will
  2471  	// need to compute xcount as the number of exported methods.
  2472  	ut.Mcount = uint16(len(methods))
  2473  	ut.Xcount = ut.Mcount
  2474  	ut.Moff = uint32(unsafe.Sizeof(uncommonType{}))
  2475  
  2476  	if len(fs) > 0 {
  2477  		repr = append(repr, ' ')
  2478  	}
  2479  	repr = append(repr, '}')
  2480  	hash = fnv1(hash, '}')
  2481  	str := string(repr)
  2482  
  2483  	// Round the size up to be a multiple of the alignment.
  2484  	s := align(size, uintptr(typalign))
  2485  	if s < size {
  2486  		panic("reflect.StructOf: struct size would exceed virtual address space")
  2487  	}
  2488  	size = s
  2489  
  2490  	// Make the struct type.
  2491  	var istruct any = struct{}{}
  2492  	prototype := *(**structType)(unsafe.Pointer(&istruct))
  2493  	*typ = *prototype
  2494  	typ.Fields = fs
  2495  	if pkgpath != "" {
  2496  		typ.PkgPath = newName(pkgpath, "", false, false)
  2497  	}
  2498  
  2499  	// Look in cache.
  2500  	if ts, ok := structLookupCache.m.Load(hash); ok {
  2501  		for _, st := range ts.([]Type) {
  2502  			t := st.common()
  2503  			if haveIdenticalUnderlyingType(&typ.Type, t, true) {
  2504  				return toType(t)
  2505  			}
  2506  		}
  2507  	}
  2508  
  2509  	// Not in cache, lock and retry.
  2510  	structLookupCache.Lock()
  2511  	defer structLookupCache.Unlock()
  2512  	if ts, ok := structLookupCache.m.Load(hash); ok {
  2513  		for _, st := range ts.([]Type) {
  2514  			t := st.common()
  2515  			if haveIdenticalUnderlyingType(&typ.Type, t, true) {
  2516  				return toType(t)
  2517  			}
  2518  		}
  2519  	}
  2520  
  2521  	addToCache := func(t Type) Type {
  2522  		var ts []Type
  2523  		if ti, ok := structLookupCache.m.Load(hash); ok {
  2524  			ts = ti.([]Type)
  2525  		}
  2526  		structLookupCache.m.Store(hash, append(ts, t))
  2527  		return t
  2528  	}
  2529  
  2530  	// Look in known types.
  2531  	for _, t := range typesByString(str) {
  2532  		if haveIdenticalUnderlyingType(&typ.Type, t, true) {
  2533  			// even if 't' wasn't a structType with methods, we should be ok
  2534  			// as the 'u uncommonType' field won't be accessed except when
  2535  			// tflag&abi.TFlagUncommon is set.
  2536  			return addToCache(toType(t))
  2537  		}
  2538  	}
  2539  
  2540  	typ.Str = resolveReflectName(newName(str, "", false, false))
  2541  	if isRegularMemory(toType(&typ.Type)) {
  2542  		typ.TFlag = abi.TFlagRegularMemory
  2543  	} else {
  2544  		typ.TFlag = 0
  2545  	}
  2546  	typ.Hash = hash
  2547  	typ.Size_ = size
  2548  	typ.PtrBytes = typeptrdata(&typ.Type)
  2549  	typ.Align_ = typalign
  2550  	typ.FieldAlign_ = typalign
  2551  	typ.PtrToThis = 0
  2552  	if len(methods) > 0 {
  2553  		typ.TFlag |= abi.TFlagUncommon
  2554  	}
  2555  
  2556  	if typ.PtrBytes == 0 {
  2557  		typ.GCData = nil
  2558  	} else if typ.PtrBytes <= abi.MaxPtrmaskBytes*8*goarch.PtrSize {
  2559  		bv := new(bitVector)
  2560  		addTypeBits(bv, 0, &typ.Type)
  2561  		typ.GCData = &bv.data[0]
  2562  	} else {
  2563  		// Runtime will build the mask if needed. We just need to allocate
  2564  		// space to store it.
  2565  		typ.TFlag |= abi.TFlagGCMaskOnDemand
  2566  		typ.GCData = (*byte)(unsafe.Pointer(new(uintptr)))
  2567  		if runtime.GOOS == "aix" {
  2568  			typ.GCData = adjustAIXGCData(typ.GCData)
  2569  		}
  2570  	}
  2571  
  2572  	typ.Equal = nil
  2573  	if comparable {
  2574  		typ.Equal = func(p, q unsafe.Pointer) bool {
  2575  			for _, ft := range typ.Fields {
  2576  				pi := add(p, ft.Offset, "&x.field safe")
  2577  				qi := add(q, ft.Offset, "&x.field safe")
  2578  				if !ft.Typ.Equal(pi, qi) {
  2579  					return false
  2580  				}
  2581  			}
  2582  			return true
  2583  		}
  2584  	}
  2585  
  2586  	switch {
  2587  	case typ.Size_ == goarch.PtrSize && typ.PtrBytes == goarch.PtrSize:
  2588  		typ.TFlag |= abi.TFlagDirectIface
  2589  	default:
  2590  		typ.TFlag &^= abi.TFlagDirectIface
  2591  	}
  2592  
  2593  	return addToCache(toType(&typ.Type))
  2594  }
  2595  
  2596  func embeddedIfaceMethStub() {
  2597  	panic("reflect: StructOf does not support methods of embedded interfaces")
  2598  }
  2599  
  2600  // runtimeStructField takes a StructField value passed to StructOf and
  2601  // returns both the corresponding internal representation, of type
  2602  // structField, and the pkgpath value to use for this field.
  2603  func runtimeStructField(field StructField) (structField, string) {
  2604  	if field.Anonymous && field.PkgPath != "" {
  2605  		panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
  2606  	}
  2607  
  2608  	if field.IsExported() {
  2609  		// Best-effort check for misuse.
  2610  		// Since this field will be treated as exported, not much harm done if Unicode lowercase slips through.
  2611  		c := field.Name[0]
  2612  		if 'a' <= c && c <= 'z' || c == '_' {
  2613  			panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath")
  2614  		}
  2615  	}
  2616  
  2617  	resolveReflectType(field.Type.common()) // install in runtime
  2618  	f := structField{
  2619  		Name:   newName(field.Name, string(field.Tag), field.IsExported(), field.Anonymous),
  2620  		Typ:    field.Type.common(),
  2621  		Offset: 0,
  2622  	}
  2623  	return f, field.PkgPath
  2624  }
  2625  
  2626  // typeptrdata returns the length in bytes of the prefix of t
  2627  // containing pointer data. Anything after this offset is scalar data.
  2628  // keep in sync with ../cmd/compile/internal/reflectdata/reflect.go
  2629  func typeptrdata(t *abi.Type) uintptr {
  2630  	switch t.Kind() {
  2631  	case abi.Struct:
  2632  		st := (*structType)(unsafe.Pointer(t))
  2633  		// find the last field that has pointers.
  2634  		field := -1
  2635  		for i := range st.Fields {
  2636  			ft := st.Fields[i].Typ
  2637  			if ft.Pointers() {
  2638  				field = i
  2639  			}
  2640  		}
  2641  		if field == -1 {
  2642  			return 0
  2643  		}
  2644  		f := st.Fields[field]
  2645  		return f.Offset + f.Typ.PtrBytes
  2646  
  2647  	default:
  2648  		panic("reflect.typeptrdata: unexpected type, " + stringFor(t))
  2649  	}
  2650  }
  2651  
  2652  // ArrayOf returns the array type with the given length and element type.
  2653  // For example, if t represents int, ArrayOf(5, t) represents [5]int.
  2654  //
  2655  // If the resulting type would be larger than the available address space,
  2656  // ArrayOf panics.
  2657  func ArrayOf(length int, elem Type) Type {
  2658  	if length < 0 {
  2659  		panic("reflect: negative length passed to ArrayOf")
  2660  	}
  2661  
  2662  	typ := elem.common()
  2663  
  2664  	// Look in cache.
  2665  	ckey := cacheKey{Array, typ, nil, uintptr(length)}
  2666  	if array, ok := lookupCache.Load(ckey); ok {
  2667  		return array.(Type)
  2668  	}
  2669  
  2670  	// Look in known types.
  2671  	s := "[" + strconv.Itoa(length) + "]" + stringFor(typ)
  2672  	for _, tt := range typesByString(s) {
  2673  		array := (*arrayType)(unsafe.Pointer(tt))
  2674  		if array.Elem == typ {
  2675  			ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt))
  2676  			return ti.(Type)
  2677  		}
  2678  	}
  2679  
  2680  	// Make an array type.
  2681  	var iarray any = [1]unsafe.Pointer{}
  2682  	prototype := *(**arrayType)(unsafe.Pointer(&iarray))
  2683  	array := *prototype
  2684  	array.TFlag = typ.TFlag & abi.TFlagRegularMemory
  2685  	array.Str = resolveReflectName(newName(s, "", false, false))
  2686  	array.Hash = fnv1(typ.Hash, '[')
  2687  	for n := uint32(length); n > 0; n >>= 8 {
  2688  		array.Hash = fnv1(array.Hash, byte(n))
  2689  	}
  2690  	array.Hash = fnv1(array.Hash, ']')
  2691  	array.Elem = typ
  2692  	array.PtrToThis = 0
  2693  	if typ.Size_ > 0 {
  2694  		max := ^uintptr(0) / typ.Size_
  2695  		if uintptr(length) > max {
  2696  			panic("reflect.ArrayOf: array size would exceed virtual address space")
  2697  		}
  2698  	}
  2699  	array.Size_ = typ.Size_ * uintptr(length)
  2700  	if length > 0 && typ.Pointers() {
  2701  		array.PtrBytes = typ.Size_*uintptr(length-1) + typ.PtrBytes
  2702  	} else {
  2703  		array.PtrBytes = 0
  2704  	}
  2705  	array.Align_ = typ.Align_
  2706  	array.FieldAlign_ = typ.FieldAlign_
  2707  	array.Len = uintptr(length)
  2708  	array.Slice = &(SliceOf(elem).(*rtype).t)
  2709  
  2710  	switch {
  2711  	case array.PtrBytes == 0:
  2712  		// No pointers.
  2713  		array.GCData = nil
  2714  
  2715  	case length == 1:
  2716  		// In memory, 1-element array looks just like the element.
  2717  		// We share the bitmask with the element type.
  2718  		array.TFlag |= typ.TFlag & abi.TFlagGCMaskOnDemand
  2719  		array.GCData = typ.GCData
  2720  
  2721  	case array.PtrBytes <= abi.MaxPtrmaskBytes*8*goarch.PtrSize:
  2722  		// Create pointer mask by repeating the element bitmask Len times.
  2723  		n := (array.PtrBytes/goarch.PtrSize + 7) / 8
  2724  		// Runtime needs pointer masks to be a multiple of uintptr in size.
  2725  		n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
  2726  		mask := make([]byte, n)
  2727  		emitGCMask(mask, 0, typ, array.Len)
  2728  		array.GCData = &mask[0]
  2729  
  2730  	default:
  2731  		// Runtime will build the mask if needed. We just need to allocate
  2732  		// space to store it.
  2733  		array.TFlag |= abi.TFlagGCMaskOnDemand
  2734  		array.GCData = (*byte)(unsafe.Pointer(new(uintptr)))
  2735  		if runtime.GOOS == "aix" {
  2736  			array.GCData = adjustAIXGCData(array.GCData)
  2737  		}
  2738  	}
  2739  
  2740  	etyp := typ
  2741  	esize := etyp.Size()
  2742  
  2743  	array.Equal = nil
  2744  	if eequal := etyp.Equal; eequal != nil {
  2745  		array.Equal = func(p, q unsafe.Pointer) bool {
  2746  			for i := 0; i < length; i++ {
  2747  				pi := arrayAt(p, i, esize, "i < length")
  2748  				qi := arrayAt(q, i, esize, "i < length")
  2749  				if !eequal(pi, qi) {
  2750  					return false
  2751  				}
  2752  
  2753  			}
  2754  			return true
  2755  		}
  2756  	}
  2757  
  2758  	switch {
  2759  	case array.Size_ == goarch.PtrSize && array.PtrBytes == goarch.PtrSize:
  2760  		array.TFlag |= abi.TFlagDirectIface
  2761  	default:
  2762  		array.TFlag &^= abi.TFlagDirectIface
  2763  	}
  2764  
  2765  	ti, _ := lookupCache.LoadOrStore(ckey, toRType(&array.Type))
  2766  	return ti.(Type)
  2767  }
  2768  
  2769  // adjustAIXGCData adjusts the GCData field pointer for AIX.
  2770  // See runtime.getGCMaskOnDemand.
  2771  func adjustAIXGCData(addr *byte) *byte {
  2772  	adjusted := adjustAIXGCDataForRuntime(addr)
  2773  	if adjusted != addr {
  2774  		pinAIXGCDataMu.Lock()
  2775  		pinAIXGCData = append(pinAIXGCData, addr)
  2776  		pinAIXGCDataMu.Unlock()
  2777  	}
  2778  	return adjusted
  2779  }
  2780  
  2781  // adjustAIXGCDataForRuntime adjusts the GCData field pointer
  2782  // as the runtime requires for AIX. See runtime.getGCMaskOnDemand.
  2783  //
  2784  //go:linkname adjustAIXGCDataForRuntime
  2785  //go:noescape
  2786  func adjustAIXGCDataForRuntime(*byte) *byte
  2787  
  2788  // pinAIXGCDataMu proects pinAIXGCData.
  2789  var pinAIXGCDataMu sync.Mutex
  2790  
  2791  // pinAIXGCData keeps the actual GCData pointer alive on AIX.
  2792  // On AIX we need to use adjustAIXGCData to convert the GC pointer
  2793  // to the value that the runtime expects. That means that the rtype
  2794  // no longer refers to the original pointer. This slice keeps it alive.
  2795  var pinAIXGCData []*byte
  2796  
  2797  func appendVarint(x []byte, v uintptr) []byte {
  2798  	for ; v >= 0x80; v >>= 7 {
  2799  		x = append(x, byte(v|0x80))
  2800  	}
  2801  	x = append(x, byte(v))
  2802  	return x
  2803  }
  2804  
  2805  // toType converts from a *rtype to a Type that can be returned
  2806  // to the client of package reflect. In gc, the only concern is that
  2807  // a nil *rtype must be replaced by a nil Type, but in gccgo this
  2808  // function takes care of ensuring that multiple *rtype for the same
  2809  // type are coalesced into a single Type.
  2810  //
  2811  // toType should be an internal detail,
  2812  // but widely used packages access it using linkname.
  2813  // Notable members of the hall of shame include:
  2814  //   - fortio.org/log
  2815  //   - github.com/goccy/go-json
  2816  //   - github.com/goccy/go-reflect
  2817  //   - github.com/sohaha/zlsgo
  2818  //
  2819  // Do not remove or change the type signature.
  2820  // See go.dev/issue/67401.
  2821  //
  2822  //go:linkname toType
  2823  func toType(t *abi.Type) Type {
  2824  	if t == nil {
  2825  		return nil
  2826  	}
  2827  	return toRType(t)
  2828  }
  2829  
  2830  type layoutKey struct {
  2831  	ftyp *funcType // function signature
  2832  	rcvr *abi.Type // receiver type, or nil if none
  2833  }
  2834  
  2835  type layoutType struct {
  2836  	t         *abi.Type
  2837  	framePool *sync.Pool
  2838  	abid      abiDesc
  2839  }
  2840  
  2841  var layoutCache sync.Map // map[layoutKey]layoutType
  2842  
  2843  // funcLayout computes a struct type representing the layout of the
  2844  // stack-assigned function arguments and return values for the function
  2845  // type t.
  2846  // If rcvr != nil, rcvr specifies the type of the receiver.
  2847  // The returned type exists only for GC, so we only fill out GC relevant info.
  2848  // Currently, that's just size and the GC program. We also fill in
  2849  // the name for possible debugging use.
  2850  func funcLayout(t *funcType, rcvr *abi.Type) (frametype *abi.Type, framePool *sync.Pool, abid abiDesc) {
  2851  	if t.Kind() != abi.Func {
  2852  		panic("reflect: funcLayout of non-func type " + stringFor(&t.Type))
  2853  	}
  2854  	if rcvr != nil && rcvr.Kind() == abi.Interface {
  2855  		panic("reflect: funcLayout with interface receiver " + stringFor(rcvr))
  2856  	}
  2857  	k := layoutKey{t, rcvr}
  2858  	if lti, ok := layoutCache.Load(k); ok {
  2859  		lt := lti.(layoutType)
  2860  		return lt.t, lt.framePool, lt.abid
  2861  	}
  2862  
  2863  	// Compute the ABI layout.
  2864  	abid = newAbiDesc(t, rcvr)
  2865  
  2866  	// build dummy rtype holding gc program
  2867  	x := &abi.Type{
  2868  		Align_: goarch.PtrSize,
  2869  		// Don't add spill space here; it's only necessary in
  2870  		// reflectcall's frame, not in the allocated frame.
  2871  		// TODO(mknyszek): Remove this comment when register
  2872  		// spill space in the frame is no longer required.
  2873  		Size_:    align(abid.retOffset+abid.ret.stackBytes, goarch.PtrSize),
  2874  		PtrBytes: uintptr(abid.stackPtrs.n) * goarch.PtrSize,
  2875  	}
  2876  	if abid.stackPtrs.n > 0 {
  2877  		x.GCData = &abid.stackPtrs.data[0]
  2878  	}
  2879  
  2880  	var s string
  2881  	if rcvr != nil {
  2882  		s = "methodargs(" + stringFor(rcvr) + ")(" + stringFor(&t.Type) + ")"
  2883  	} else {
  2884  		s = "funcargs(" + stringFor(&t.Type) + ")"
  2885  	}
  2886  	x.Str = resolveReflectName(newName(s, "", false, false))
  2887  
  2888  	// cache result for future callers
  2889  	framePool = &sync.Pool{New: func() any {
  2890  		return unsafe_New(x)
  2891  	}}
  2892  	lti, _ := layoutCache.LoadOrStore(k, layoutType{
  2893  		t:         x,
  2894  		framePool: framePool,
  2895  		abid:      abid,
  2896  	})
  2897  	lt := lti.(layoutType)
  2898  	return lt.t, lt.framePool, lt.abid
  2899  }
  2900  
  2901  // Note: this type must agree with runtime.bitvector.
  2902  type bitVector struct {
  2903  	n    uint32 // number of bits
  2904  	data []byte
  2905  }
  2906  
  2907  // append a bit to the bitmap.
  2908  func (bv *bitVector) append(bit uint8) {
  2909  	if bv.n%(8*goarch.PtrSize) == 0 {
  2910  		// Runtime needs pointer masks to be a multiple of uintptr in size.
  2911  		// Since reflect passes bv.data directly to the runtime as a pointer mask,
  2912  		// we append a full uintptr of zeros at a time.
  2913  		for i := 0; i < goarch.PtrSize; i++ {
  2914  			bv.data = append(bv.data, 0)
  2915  		}
  2916  	}
  2917  	bv.data[bv.n/8] |= bit << (bv.n % 8)
  2918  	bv.n++
  2919  }
  2920  
  2921  func addTypeBits(bv *bitVector, offset uintptr, t *abi.Type) {
  2922  	if !t.Pointers() {
  2923  		return
  2924  	}
  2925  
  2926  	switch Kind(t.Kind()) {
  2927  	case Chan, Func, Map, Pointer, Slice, String, UnsafePointer:
  2928  		// 1 pointer at start of representation
  2929  		for bv.n < uint32(offset/goarch.PtrSize) {
  2930  			bv.append(0)
  2931  		}
  2932  		bv.append(1)
  2933  
  2934  	case Interface:
  2935  		// 2 pointers
  2936  		for bv.n < uint32(offset/goarch.PtrSize) {
  2937  			bv.append(0)
  2938  		}
  2939  		bv.append(1)
  2940  		bv.append(1)
  2941  
  2942  	case Array:
  2943  		// repeat inner type
  2944  		tt := (*arrayType)(unsafe.Pointer(t))
  2945  		for i := 0; i < int(tt.Len); i++ {
  2946  			addTypeBits(bv, offset+uintptr(i)*tt.Elem.Size_, tt.Elem)
  2947  		}
  2948  
  2949  	case Struct:
  2950  		// apply fields
  2951  		tt := (*structType)(unsafe.Pointer(t))
  2952  		for i := range tt.Fields {
  2953  			f := &tt.Fields[i]
  2954  			addTypeBits(bv, offset+f.Offset, f.Typ)
  2955  		}
  2956  	}
  2957  }
  2958  

View as plain text