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

View as plain text