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

View as plain text