...

Source file src/reflect/type.go

Documentation: reflect

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

View as plain text