Source file src/reflect/type.go

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

View as plain text