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

View as plain text