github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/reflect/type.go (about)

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