...

Source file src/reflect/type.go

Documentation: reflect

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package reflect implements run-time reflection, allowing a program to
     6  // manipulate objects with arbitrary types. The typical use is to take a value
     7  // with static type interface{} and extract its dynamic type information by
     8  // calling TypeOf, which returns a Type.
     9  //
    10  // A call to ValueOf returns a Value representing the run-time data.
    11  // Zero takes a Type and returns a Value representing a zero value
    12  // for that type.
    13  //
    14  // See "The Laws of Reflection" for an introduction to reflection in Go:
    15  // https://golang.org/doc/articles/laws_of_reflection.html
    16  package reflect
    17  
    18  import (
    19  	"internal/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  	// TODO(mdempsky): Binary search.
   896  	for i, p := range ut.exportedMethods() {
   897  		if t.nameOff(p.name).name() == name {
   898  			return t.Method(i), true
   899  		}
   900  	}
   901  	return Method{}, false
   902  }
   903  
   904  func (t *rtype) PkgPath() string {
   905  	if t.tflag&tflagNamed == 0 {
   906  		return ""
   907  	}
   908  	ut := t.uncommon()
   909  	if ut == nil {
   910  		return ""
   911  	}
   912  	return t.nameOff(ut.pkgPath).name()
   913  }
   914  
   915  func (t *rtype) hasName() bool {
   916  	return t.tflag&tflagNamed != 0
   917  }
   918  
   919  func (t *rtype) Name() string {
   920  	if !t.hasName() {
   921  		return ""
   922  	}
   923  	s := t.String()
   924  	i := len(s) - 1
   925  	sqBrackets := 0
   926  	for i >= 0 && (s[i] != '.' || sqBrackets != 0) {
   927  		switch s[i] {
   928  		case ']':
   929  			sqBrackets++
   930  		case '[':
   931  			sqBrackets--
   932  		}
   933  		i--
   934  	}
   935  	return s[i+1:]
   936  }
   937  
   938  func (t *rtype) ChanDir() ChanDir {
   939  	if t.Kind() != Chan {
   940  		panic("reflect: ChanDir of non-chan type " + t.String())
   941  	}
   942  	tt := (*chanType)(unsafe.Pointer(t))
   943  	return ChanDir(tt.dir)
   944  }
   945  
   946  func (t *rtype) IsVariadic() bool {
   947  	if t.Kind() != Func {
   948  		panic("reflect: IsVariadic of non-func type " + t.String())
   949  	}
   950  	tt := (*funcType)(unsafe.Pointer(t))
   951  	return tt.outCount&(1<<15) != 0
   952  }
   953  
   954  func (t *rtype) Elem() Type {
   955  	switch t.Kind() {
   956  	case Array:
   957  		tt := (*arrayType)(unsafe.Pointer(t))
   958  		return toType(tt.elem)
   959  	case Chan:
   960  		tt := (*chanType)(unsafe.Pointer(t))
   961  		return toType(tt.elem)
   962  	case Map:
   963  		tt := (*mapType)(unsafe.Pointer(t))
   964  		return toType(tt.elem)
   965  	case Pointer:
   966  		tt := (*ptrType)(unsafe.Pointer(t))
   967  		return toType(tt.elem)
   968  	case Slice:
   969  		tt := (*sliceType)(unsafe.Pointer(t))
   970  		return toType(tt.elem)
   971  	}
   972  	panic("reflect: Elem of invalid type " + t.String())
   973  }
   974  
   975  func (t *rtype) Field(i int) StructField {
   976  	if t.Kind() != Struct {
   977  		panic("reflect: Field of non-struct type " + t.String())
   978  	}
   979  	tt := (*structType)(unsafe.Pointer(t))
   980  	return tt.Field(i)
   981  }
   982  
   983  func (t *rtype) FieldByIndex(index []int) StructField {
   984  	if t.Kind() != Struct {
   985  		panic("reflect: FieldByIndex of non-struct type " + t.String())
   986  	}
   987  	tt := (*structType)(unsafe.Pointer(t))
   988  	return tt.FieldByIndex(index)
   989  }
   990  
   991  func (t *rtype) FieldByName(name string) (StructField, bool) {
   992  	if t.Kind() != Struct {
   993  		panic("reflect: FieldByName of non-struct type " + t.String())
   994  	}
   995  	tt := (*structType)(unsafe.Pointer(t))
   996  	return tt.FieldByName(name)
   997  }
   998  
   999  func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
  1000  	if t.Kind() != Struct {
  1001  		panic("reflect: FieldByNameFunc of non-struct type " + t.String())
  1002  	}
  1003  	tt := (*structType)(unsafe.Pointer(t))
  1004  	return tt.FieldByNameFunc(match)
  1005  }
  1006  
  1007  func (t *rtype) In(i int) Type {
  1008  	if t.Kind() != Func {
  1009  		panic("reflect: In of non-func type " + t.String())
  1010  	}
  1011  	tt := (*funcType)(unsafe.Pointer(t))
  1012  	return toType(tt.in()[i])
  1013  }
  1014  
  1015  func (t *rtype) Key() Type {
  1016  	if t.Kind() != Map {
  1017  		panic("reflect: Key of non-map type " + t.String())
  1018  	}
  1019  	tt := (*mapType)(unsafe.Pointer(t))
  1020  	return toType(tt.key)
  1021  }
  1022  
  1023  func (t *rtype) Len() int {
  1024  	if t.Kind() != Array {
  1025  		panic("reflect: Len of non-array type " + t.String())
  1026  	}
  1027  	tt := (*arrayType)(unsafe.Pointer(t))
  1028  	return int(tt.len)
  1029  }
  1030  
  1031  func (t *rtype) NumField() int {
  1032  	if t.Kind() != Struct {
  1033  		panic("reflect: NumField of non-struct type " + t.String())
  1034  	}
  1035  	tt := (*structType)(unsafe.Pointer(t))
  1036  	return len(tt.fields)
  1037  }
  1038  
  1039  func (t *rtype) NumIn() int {
  1040  	if t.Kind() != Func {
  1041  		panic("reflect: NumIn of non-func type " + t.String())
  1042  	}
  1043  	tt := (*funcType)(unsafe.Pointer(t))
  1044  	return int(tt.inCount)
  1045  }
  1046  
  1047  func (t *rtype) NumOut() int {
  1048  	if t.Kind() != Func {
  1049  		panic("reflect: NumOut of non-func type " + t.String())
  1050  	}
  1051  	tt := (*funcType)(unsafe.Pointer(t))
  1052  	return len(tt.out())
  1053  }
  1054  
  1055  func (t *rtype) Out(i int) Type {
  1056  	if t.Kind() != Func {
  1057  		panic("reflect: Out of non-func type " + t.String())
  1058  	}
  1059  	tt := (*funcType)(unsafe.Pointer(t))
  1060  	return toType(tt.out()[i])
  1061  }
  1062  
  1063  func (t *funcType) in() []*rtype {
  1064  	uadd := unsafe.Sizeof(*t)
  1065  	if t.tflag&tflagUncommon != 0 {
  1066  		uadd += unsafe.Sizeof(uncommonType{})
  1067  	}
  1068  	if t.inCount == 0 {
  1069  		return nil
  1070  	}
  1071  	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount]
  1072  }
  1073  
  1074  func (t *funcType) out() []*rtype {
  1075  	uadd := unsafe.Sizeof(*t)
  1076  	if t.tflag&tflagUncommon != 0 {
  1077  		uadd += unsafe.Sizeof(uncommonType{})
  1078  	}
  1079  	outCount := t.outCount & (1<<15 - 1)
  1080  	if outCount == 0 {
  1081  		return nil
  1082  	}
  1083  	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount]
  1084  }
  1085  
  1086  // add returns p+x.
  1087  //
  1088  // The whySafe string is ignored, so that the function still inlines
  1089  // as efficiently as p+x, but all call sites should use the string to
  1090  // record why the addition is safe, which is to say why the addition
  1091  // does not cause x to advance to the very end of p's allocation
  1092  // and therefore point incorrectly at the next block in memory.
  1093  func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
  1094  	return unsafe.Pointer(uintptr(p) + x)
  1095  }
  1096  
  1097  func (d ChanDir) String() string {
  1098  	switch d {
  1099  	case SendDir:
  1100  		return "chan<-"
  1101  	case RecvDir:
  1102  		return "<-chan"
  1103  	case BothDir:
  1104  		return "chan"
  1105  	}
  1106  	return "ChanDir" + strconv.Itoa(int(d))
  1107  }
  1108  
  1109  // Method returns the i'th method in the type's method set.
  1110  func (t *interfaceType) Method(i int) (m Method) {
  1111  	if i < 0 || i >= len(t.methods) {
  1112  		return
  1113  	}
  1114  	p := &t.methods[i]
  1115  	pname := t.nameOff(p.name)
  1116  	m.Name = pname.name()
  1117  	if !pname.isExported() {
  1118  		m.PkgPath = pname.pkgPath()
  1119  		if m.PkgPath == "" {
  1120  			m.PkgPath = t.pkgPath.name()
  1121  		}
  1122  	}
  1123  	m.Type = toType(t.typeOff(p.typ))
  1124  	m.Index = i
  1125  	return
  1126  }
  1127  
  1128  // NumMethod returns the number of interface methods in the type's method set.
  1129  func (t *interfaceType) NumMethod() int { return len(t.methods) }
  1130  
  1131  // MethodByName method with the given name in the type's method set.
  1132  func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
  1133  	if t == nil {
  1134  		return
  1135  	}
  1136  	var p *imethod
  1137  	for i := range t.methods {
  1138  		p = &t.methods[i]
  1139  		if t.nameOff(p.name).name() == name {
  1140  			return t.Method(i), true
  1141  		}
  1142  	}
  1143  	return
  1144  }
  1145  
  1146  // A StructField describes a single field in a struct.
  1147  type StructField struct {
  1148  	// Name is the field name.
  1149  	Name string
  1150  
  1151  	// PkgPath is the package path that qualifies a lower case (unexported)
  1152  	// field name. It is empty for upper case (exported) field names.
  1153  	// See https://golang.org/ref/spec#Uniqueness_of_identifiers
  1154  	PkgPath string
  1155  
  1156  	Type      Type      // field type
  1157  	Tag       StructTag // field tag string
  1158  	Offset    uintptr   // offset within struct, in bytes
  1159  	Index     []int     // index sequence for Type.FieldByIndex
  1160  	Anonymous bool      // is an embedded field
  1161  }
  1162  
  1163  // IsExported reports whether the field is exported.
  1164  func (f StructField) IsExported() bool {
  1165  	return f.PkgPath == ""
  1166  }
  1167  
  1168  // A StructTag is the tag string in a struct field.
  1169  //
  1170  // By convention, tag strings are a concatenation of
  1171  // optionally space-separated key:"value" pairs.
  1172  // Each key is a non-empty string consisting of non-control
  1173  // characters other than space (U+0020 ' '), quote (U+0022 '"'),
  1174  // and colon (U+003A ':').  Each value is quoted using U+0022 '"'
  1175  // characters and Go string literal syntax.
  1176  type StructTag string
  1177  
  1178  // Get returns the value associated with key in the tag string.
  1179  // If there is no such key in the tag, Get returns the empty string.
  1180  // If the tag does not have the conventional format, the value
  1181  // returned by Get is unspecified. To determine whether a tag is
  1182  // explicitly set to the empty string, use Lookup.
  1183  func (tag StructTag) Get(key string) string {
  1184  	v, _ := tag.Lookup(key)
  1185  	return v
  1186  }
  1187  
  1188  // Lookup returns the value associated with key in the tag string.
  1189  // If the key is present in the tag the value (which may be empty)
  1190  // is returned. Otherwise the returned value will be the empty string.
  1191  // The ok return value reports whether the value was explicitly set in
  1192  // the tag string. If the tag does not have the conventional format,
  1193  // the value returned by Lookup is unspecified.
  1194  func (tag StructTag) Lookup(key string) (value string, ok bool) {
  1195  	// When modifying this code, also update the validateStructTag code
  1196  	// in cmd/vet/structtag.go.
  1197  
  1198  	for tag != "" {
  1199  		// Skip leading space.
  1200  		i := 0
  1201  		for i < len(tag) && tag[i] == ' ' {
  1202  			i++
  1203  		}
  1204  		tag = tag[i:]
  1205  		if tag == "" {
  1206  			break
  1207  		}
  1208  
  1209  		// Scan to colon. A space, a quote or a control character is a syntax error.
  1210  		// Strictly speaking, control chars include the range [0x7f, 0x9f], not just
  1211  		// [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
  1212  		// as it is simpler to inspect the tag's bytes than the tag's runes.
  1213  		i = 0
  1214  		for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
  1215  			i++
  1216  		}
  1217  		if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
  1218  			break
  1219  		}
  1220  		name := string(tag[:i])
  1221  		tag = tag[i+1:]
  1222  
  1223  		// Scan quoted string to find value.
  1224  		i = 1
  1225  		for i < len(tag) && tag[i] != '"' {
  1226  			if tag[i] == '\\' {
  1227  				i++
  1228  			}
  1229  			i++
  1230  		}
  1231  		if i >= len(tag) {
  1232  			break
  1233  		}
  1234  		qvalue := string(tag[:i+1])
  1235  		tag = tag[i+1:]
  1236  
  1237  		if key == name {
  1238  			value, err := strconv.Unquote(qvalue)
  1239  			if err != nil {
  1240  				break
  1241  			}
  1242  			return value, true
  1243  		}
  1244  	}
  1245  	return "", false
  1246  }
  1247  
  1248  // Field returns the i'th struct field.
  1249  func (t *structType) Field(i int) (f StructField) {
  1250  	if i < 0 || i >= len(t.fields) {
  1251  		panic("reflect: Field index out of bounds")
  1252  	}
  1253  	p := &t.fields[i]
  1254  	f.Type = toType(p.typ)
  1255  	f.Name = p.name.name()
  1256  	f.Anonymous = p.embedded()
  1257  	if !p.name.isExported() {
  1258  		f.PkgPath = t.pkgPath.name()
  1259  	}
  1260  	if tag := p.name.tag(); tag != "" {
  1261  		f.Tag = StructTag(tag)
  1262  	}
  1263  	f.Offset = p.offset
  1264  
  1265  	// NOTE(rsc): This is the only allocation in the interface
  1266  	// presented by a reflect.Type. It would be nice to avoid,
  1267  	// at least in the common cases, but we need to make sure
  1268  	// that misbehaving clients of reflect cannot affect other
  1269  	// uses of reflect. One possibility is CL 5371098, but we
  1270  	// postponed that ugliness until there is a demonstrated
  1271  	// need for the performance. This is issue 2320.
  1272  	f.Index = []int{i}
  1273  	return
  1274  }
  1275  
  1276  // TODO(gri): Should there be an error/bool indicator if the index
  1277  // is wrong for FieldByIndex?
  1278  
  1279  // FieldByIndex returns the nested field corresponding to index.
  1280  func (t *structType) FieldByIndex(index []int) (f StructField) {
  1281  	f.Type = toType(&t.rtype)
  1282  	for i, x := range index {
  1283  		if i > 0 {
  1284  			ft := f.Type
  1285  			if ft.Kind() == Pointer && ft.Elem().Kind() == Struct {
  1286  				ft = ft.Elem()
  1287  			}
  1288  			f.Type = ft
  1289  		}
  1290  		f = f.Type.Field(x)
  1291  	}
  1292  	return
  1293  }
  1294  
  1295  // A fieldScan represents an item on the fieldByNameFunc scan work list.
  1296  type fieldScan struct {
  1297  	typ   *structType
  1298  	index []int
  1299  }
  1300  
  1301  // FieldByNameFunc returns the struct field with a name that satisfies the
  1302  // match function and a boolean to indicate if the field was found.
  1303  func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) {
  1304  	// This uses the same condition that the Go language does: there must be a unique instance
  1305  	// of the match at a given depth level. If there are multiple instances of a match at the
  1306  	// same depth, they annihilate each other and inhibit any possible match at a lower level.
  1307  	// The algorithm is breadth first search, one depth level at a time.
  1308  
  1309  	// The current and next slices are work queues:
  1310  	// current lists the fields to visit on this depth level,
  1311  	// and next lists the fields on the next lower level.
  1312  	current := []fieldScan{}
  1313  	next := []fieldScan{{typ: t}}
  1314  
  1315  	// nextCount records the number of times an embedded type has been
  1316  	// encountered and considered for queueing in the 'next' slice.
  1317  	// We only queue the first one, but we increment the count on each.
  1318  	// If a struct type T can be reached more than once at a given depth level,
  1319  	// then it annihilates itself and need not be considered at all when we
  1320  	// process that next depth level.
  1321  	var nextCount map[*structType]int
  1322  
  1323  	// visited records the structs that have been considered already.
  1324  	// Embedded pointer fields can create cycles in the graph of
  1325  	// reachable embedded types; visited avoids following those cycles.
  1326  	// It also avoids duplicated effort: if we didn't find the field in an
  1327  	// embedded type T at level 2, we won't find it in one at level 4 either.
  1328  	visited := map[*structType]bool{}
  1329  
  1330  	for len(next) > 0 {
  1331  		current, next = next, current[:0]
  1332  		count := nextCount
  1333  		nextCount = nil
  1334  
  1335  		// Process all the fields at this depth, now listed in 'current'.
  1336  		// The loop queues embedded fields found in 'next', for processing during the next
  1337  		// iteration. The multiplicity of the 'current' field counts is recorded
  1338  		// in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
  1339  		for _, scan := range current {
  1340  			t := scan.typ
  1341  			if visited[t] {
  1342  				// We've looked through this type before, at a higher level.
  1343  				// That higher level would shadow the lower level we're now at,
  1344  				// so this one can't be useful to us. Ignore it.
  1345  				continue
  1346  			}
  1347  			visited[t] = true
  1348  			for i := range t.fields {
  1349  				f := &t.fields[i]
  1350  				// Find name and (for embedded field) type for field f.
  1351  				fname := f.name.name()
  1352  				var ntyp *rtype
  1353  				if f.embedded() {
  1354  					// Embedded field of type T or *T.
  1355  					ntyp = f.typ
  1356  					if ntyp.Kind() == Pointer {
  1357  						ntyp = ntyp.Elem().common()
  1358  					}
  1359  				}
  1360  
  1361  				// Does it match?
  1362  				if match(fname) {
  1363  					// Potential match
  1364  					if count[t] > 1 || ok {
  1365  						// Name appeared multiple times at this level: annihilate.
  1366  						return StructField{}, false
  1367  					}
  1368  					result = t.Field(i)
  1369  					result.Index = nil
  1370  					result.Index = append(result.Index, scan.index...)
  1371  					result.Index = append(result.Index, i)
  1372  					ok = true
  1373  					continue
  1374  				}
  1375  
  1376  				// Queue embedded struct fields for processing with next level,
  1377  				// but only if we haven't seen a match yet at this level and only
  1378  				// if the embedded types haven't already been queued.
  1379  				if ok || ntyp == nil || ntyp.Kind() != Struct {
  1380  					continue
  1381  				}
  1382  				styp := (*structType)(unsafe.Pointer(ntyp))
  1383  				if nextCount[styp] > 0 {
  1384  					nextCount[styp] = 2 // exact multiple doesn't matter
  1385  					continue
  1386  				}
  1387  				if nextCount == nil {
  1388  					nextCount = map[*structType]int{}
  1389  				}
  1390  				nextCount[styp] = 1
  1391  				if count[t] > 1 {
  1392  					nextCount[styp] = 2 // exact multiple doesn't matter
  1393  				}
  1394  				var index []int
  1395  				index = append(index, scan.index...)
  1396  				index = append(index, i)
  1397  				next = append(next, fieldScan{styp, index})
  1398  			}
  1399  		}
  1400  		if ok {
  1401  			break
  1402  		}
  1403  	}
  1404  	return
  1405  }
  1406  
  1407  // FieldByName returns the struct field with the given name
  1408  // and a boolean to indicate if the field was found.
  1409  func (t *structType) FieldByName(name string) (f StructField, present bool) {
  1410  	// Quick check for top-level name, or struct without embedded fields.
  1411  	hasEmbeds := false
  1412  	if name != "" {
  1413  		for i := range t.fields {
  1414  			tf := &t.fields[i]
  1415  			if tf.name.name() == name {
  1416  				return t.Field(i), true
  1417  			}
  1418  			if tf.embedded() {
  1419  				hasEmbeds = true
  1420  			}
  1421  		}
  1422  	}
  1423  	if !hasEmbeds {
  1424  		return
  1425  	}
  1426  	return t.FieldByNameFunc(func(s string) bool { return s == name })
  1427  }
  1428  
  1429  // TypeOf returns the reflection Type that represents the dynamic type of i.
  1430  // If i is a nil interface value, TypeOf returns nil.
  1431  func TypeOf(i any) Type {
  1432  	eface := *(*emptyInterface)(unsafe.Pointer(&i))
  1433  	return toType(eface.typ)
  1434  }
  1435  
  1436  // ptrMap is the cache for PointerTo.
  1437  var ptrMap sync.Map // map[*rtype]*ptrType
  1438  
  1439  // PtrTo returns the pointer type with element t.
  1440  // For example, if t represents type Foo, PtrTo(t) represents *Foo.
  1441  //
  1442  // PtrTo is the old spelling of PointerTo.
  1443  // The two functions behave identically.
  1444  func PtrTo(t Type) Type { return PointerTo(t) }
  1445  
  1446  // PointerTo returns the pointer type with element t.
  1447  // For example, if t represents type Foo, PointerTo(t) represents *Foo.
  1448  func PointerTo(t Type) Type {
  1449  	return t.(*rtype).ptrTo()
  1450  }
  1451  
  1452  func (t *rtype) ptrTo() *rtype {
  1453  	if t.ptrToThis != 0 {
  1454  		return t.typeOff(t.ptrToThis)
  1455  	}
  1456  
  1457  	// Check the cache.
  1458  	if pi, ok := ptrMap.Load(t); ok {
  1459  		return &pi.(*ptrType).rtype
  1460  	}
  1461  
  1462  	// Look in known types.
  1463  	s := "*" + t.String()
  1464  	for _, tt := range typesByString(s) {
  1465  		p := (*ptrType)(unsafe.Pointer(tt))
  1466  		if p.elem != t {
  1467  			continue
  1468  		}
  1469  		pi, _ := ptrMap.LoadOrStore(t, p)
  1470  		return &pi.(*ptrType).rtype
  1471  	}
  1472  
  1473  	// Create a new ptrType starting with the description
  1474  	// of an *unsafe.Pointer.
  1475  	var iptr any = (*unsafe.Pointer)(nil)
  1476  	prototype := *(**ptrType)(unsafe.Pointer(&iptr))
  1477  	pp := *prototype
  1478  
  1479  	pp.str = resolveReflectName(newName(s, "", false, false))
  1480  	pp.ptrToThis = 0
  1481  
  1482  	// For the type structures linked into the binary, the
  1483  	// compiler provides a good hash of the string.
  1484  	// Create a good hash for the new string by using
  1485  	// the FNV-1 hash's mixing function to combine the
  1486  	// old hash and the new "*".
  1487  	pp.hash = fnv1(t.hash, '*')
  1488  
  1489  	pp.elem = t
  1490  
  1491  	pi, _ := ptrMap.LoadOrStore(t, &pp)
  1492  	return &pi.(*ptrType).rtype
  1493  }
  1494  
  1495  // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
  1496  func fnv1(x uint32, list ...byte) uint32 {
  1497  	for _, b := range list {
  1498  		x = x*16777619 ^ uint32(b)
  1499  	}
  1500  	return x
  1501  }
  1502  
  1503  func (t *rtype) Implements(u Type) bool {
  1504  	if u == nil {
  1505  		panic("reflect: nil type passed to Type.Implements")
  1506  	}
  1507  	if u.Kind() != Interface {
  1508  		panic("reflect: non-interface type passed to Type.Implements")
  1509  	}
  1510  	return implements(u.(*rtype), t)
  1511  }
  1512  
  1513  func (t *rtype) AssignableTo(u Type) bool {
  1514  	if u == nil {
  1515  		panic("reflect: nil type passed to Type.AssignableTo")
  1516  	}
  1517  	uu := u.(*rtype)
  1518  	return directlyAssignable(uu, t) || implements(uu, t)
  1519  }
  1520  
  1521  func (t *rtype) ConvertibleTo(u Type) bool {
  1522  	if u == nil {
  1523  		panic("reflect: nil type passed to Type.ConvertibleTo")
  1524  	}
  1525  	uu := u.(*rtype)
  1526  	return convertOp(uu, t) != nil
  1527  }
  1528  
  1529  func (t *rtype) Comparable() bool {
  1530  	return t.equal != nil
  1531  }
  1532  
  1533  // implements reports whether the type V implements the interface type T.
  1534  func implements(T, V *rtype) bool {
  1535  	if T.Kind() != Interface {
  1536  		return false
  1537  	}
  1538  	t := (*interfaceType)(unsafe.Pointer(T))
  1539  	if len(t.methods) == 0 {
  1540  		return true
  1541  	}
  1542  
  1543  	// The same algorithm applies in both cases, but the
  1544  	// method tables for an interface type and a concrete type
  1545  	// are different, so the code is duplicated.
  1546  	// In both cases the algorithm is a linear scan over the two
  1547  	// lists - T's methods and V's methods - simultaneously.
  1548  	// Since method tables are stored in a unique sorted order
  1549  	// (alphabetical, with no duplicate method names), the scan
  1550  	// through V's methods must hit a match for each of T's
  1551  	// methods along the way, or else V does not implement T.
  1552  	// This lets us run the scan in overall linear time instead of
  1553  	// the quadratic time  a naive search would require.
  1554  	// See also ../runtime/iface.go.
  1555  	if V.Kind() == Interface {
  1556  		v := (*interfaceType)(unsafe.Pointer(V))
  1557  		i := 0
  1558  		for j := 0; j < len(v.methods); j++ {
  1559  			tm := &t.methods[i]
  1560  			tmName := t.nameOff(tm.name)
  1561  			vm := &v.methods[j]
  1562  			vmName := V.nameOff(vm.name)
  1563  			if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) {
  1564  				if !tmName.isExported() {
  1565  					tmPkgPath := tmName.pkgPath()
  1566  					if tmPkgPath == "" {
  1567  						tmPkgPath = t.pkgPath.name()
  1568  					}
  1569  					vmPkgPath := vmName.pkgPath()
  1570  					if vmPkgPath == "" {
  1571  						vmPkgPath = v.pkgPath.name()
  1572  					}
  1573  					if tmPkgPath != vmPkgPath {
  1574  						continue
  1575  					}
  1576  				}
  1577  				if i++; i >= len(t.methods) {
  1578  					return true
  1579  				}
  1580  			}
  1581  		}
  1582  		return false
  1583  	}
  1584  
  1585  	v := V.uncommon()
  1586  	if v == nil {
  1587  		return false
  1588  	}
  1589  	i := 0
  1590  	vmethods := v.methods()
  1591  	for j := 0; j < int(v.mcount); j++ {
  1592  		tm := &t.methods[i]
  1593  		tmName := t.nameOff(tm.name)
  1594  		vm := vmethods[j]
  1595  		vmName := V.nameOff(vm.name)
  1596  		if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) {
  1597  			if !tmName.isExported() {
  1598  				tmPkgPath := tmName.pkgPath()
  1599  				if tmPkgPath == "" {
  1600  					tmPkgPath = t.pkgPath.name()
  1601  				}
  1602  				vmPkgPath := vmName.pkgPath()
  1603  				if vmPkgPath == "" {
  1604  					vmPkgPath = V.nameOff(v.pkgPath).name()
  1605  				}
  1606  				if tmPkgPath != vmPkgPath {
  1607  					continue
  1608  				}
  1609  			}
  1610  			if i++; i >= len(t.methods) {
  1611  				return true
  1612  			}
  1613  		}
  1614  	}
  1615  	return false
  1616  }
  1617  
  1618  // specialChannelAssignability reports whether a value x of channel type V
  1619  // can be directly assigned (using memmove) to another channel type T.
  1620  // https://golang.org/doc/go_spec.html#Assignability
  1621  // T and V must be both of Chan kind.
  1622  func specialChannelAssignability(T, V *rtype) bool {
  1623  	// Special case:
  1624  	// x is a bidirectional channel value, T is a channel type,
  1625  	// x's type V and T have identical element types,
  1626  	// and at least one of V or T is not a defined type.
  1627  	return V.ChanDir() == BothDir && (T.Name() == "" || V.Name() == "") && haveIdenticalType(T.Elem(), V.Elem(), true)
  1628  }
  1629  
  1630  // directlyAssignable reports whether a value x of type V can be directly
  1631  // assigned (using memmove) to a value of type T.
  1632  // https://golang.org/doc/go_spec.html#Assignability
  1633  // Ignoring the interface rules (implemented elsewhere)
  1634  // and the ideal constant rules (no ideal constants at run time).
  1635  func directlyAssignable(T, V *rtype) bool {
  1636  	// x's type V is identical to T?
  1637  	if T == V {
  1638  		return true
  1639  	}
  1640  
  1641  	// Otherwise at least one of T and V must not be defined
  1642  	// and they must have the same kind.
  1643  	if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
  1644  		return false
  1645  	}
  1646  
  1647  	if T.Kind() == Chan && specialChannelAssignability(T, V) {
  1648  		return true
  1649  	}
  1650  
  1651  	// x's type T and V must have identical underlying types.
  1652  	return haveIdenticalUnderlyingType(T, V, true)
  1653  }
  1654  
  1655  func haveIdenticalType(T, V Type, cmpTags bool) bool {
  1656  	if cmpTags {
  1657  		return T == V
  1658  	}
  1659  
  1660  	if T.Name() != V.Name() || T.Kind() != V.Kind() || T.PkgPath() != V.PkgPath() {
  1661  		return false
  1662  	}
  1663  
  1664  	return haveIdenticalUnderlyingType(T.common(), V.common(), false)
  1665  }
  1666  
  1667  func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
  1668  	if T == V {
  1669  		return true
  1670  	}
  1671  
  1672  	kind := T.Kind()
  1673  	if kind != V.Kind() {
  1674  		return false
  1675  	}
  1676  
  1677  	// Non-composite types of equal kind have same underlying type
  1678  	// (the predefined instance of the type).
  1679  	if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
  1680  		return true
  1681  	}
  1682  
  1683  	// Composite types.
  1684  	switch kind {
  1685  	case Array:
  1686  		return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
  1687  
  1688  	case Chan:
  1689  		return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
  1690  
  1691  	case Func:
  1692  		t := (*funcType)(unsafe.Pointer(T))
  1693  		v := (*funcType)(unsafe.Pointer(V))
  1694  		if t.outCount != v.outCount || t.inCount != v.inCount {
  1695  			return false
  1696  		}
  1697  		for i := 0; i < t.NumIn(); i++ {
  1698  			if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
  1699  				return false
  1700  			}
  1701  		}
  1702  		for i := 0; i < t.NumOut(); i++ {
  1703  			if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
  1704  				return false
  1705  			}
  1706  		}
  1707  		return true
  1708  
  1709  	case Interface:
  1710  		t := (*interfaceType)(unsafe.Pointer(T))
  1711  		v := (*interfaceType)(unsafe.Pointer(V))
  1712  		if len(t.methods) == 0 && len(v.methods) == 0 {
  1713  			return true
  1714  		}
  1715  		// Might have the same methods but still
  1716  		// need a run time conversion.
  1717  		return false
  1718  
  1719  	case Map:
  1720  		return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
  1721  
  1722  	case Pointer, Slice:
  1723  		return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
  1724  
  1725  	case Struct:
  1726  		t := (*structType)(unsafe.Pointer(T))
  1727  		v := (*structType)(unsafe.Pointer(V))
  1728  		if len(t.fields) != len(v.fields) {
  1729  			return false
  1730  		}
  1731  		if t.pkgPath.name() != v.pkgPath.name() {
  1732  			return false
  1733  		}
  1734  		for i := range t.fields {
  1735  			tf := &t.fields[i]
  1736  			vf := &v.fields[i]
  1737  			if tf.name.name() != vf.name.name() {
  1738  				return false
  1739  			}
  1740  			if !haveIdenticalType(tf.typ, vf.typ, cmpTags) {
  1741  				return false
  1742  			}
  1743  			if cmpTags && tf.name.tag() != vf.name.tag() {
  1744  				return false
  1745  			}
  1746  			if tf.offset != vf.offset {
  1747  				return false
  1748  			}
  1749  			if tf.embedded() != vf.embedded() {
  1750  				return false
  1751  			}
  1752  		}
  1753  		return true
  1754  	}
  1755  
  1756  	return false
  1757  }
  1758  
  1759  // typelinks is implemented in package runtime.
  1760  // It returns a slice of the sections in each module,
  1761  // and a slice of *rtype offsets in each module.
  1762  //
  1763  // The types in each module are sorted by string. That is, the first
  1764  // two linked types of the first module are:
  1765  //
  1766  //	d0 := sections[0]
  1767  //	t1 := (*rtype)(add(d0, offset[0][0]))
  1768  //	t2 := (*rtype)(add(d0, offset[0][1]))
  1769  //
  1770  // and
  1771  //
  1772  //	t1.String() < t2.String()
  1773  //
  1774  // Note that strings are not unique identifiers for types:
  1775  // there can be more than one with a given string.
  1776  // Only types we might want to look up are included:
  1777  // pointers, channels, maps, slices, and arrays.
  1778  func typelinks() (sections []unsafe.Pointer, offset [][]int32)
  1779  
  1780  func rtypeOff(section unsafe.Pointer, off int32) *rtype {
  1781  	return (*rtype)(add(section, uintptr(off), "sizeof(rtype) > 0"))
  1782  }
  1783  
  1784  // typesByString returns the subslice of typelinks() whose elements have
  1785  // the given string representation.
  1786  // It may be empty (no known types with that string) or may have
  1787  // multiple elements (multiple types with that string).
  1788  func typesByString(s string) []*rtype {
  1789  	sections, offset := typelinks()
  1790  	var ret []*rtype
  1791  
  1792  	for offsI, offs := range offset {
  1793  		section := sections[offsI]
  1794  
  1795  		// We are looking for the first index i where the string becomes >= s.
  1796  		// This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s).
  1797  		i, j := 0, len(offs)
  1798  		for i < j {
  1799  			h := i + (j-i)>>1 // avoid overflow when computing h
  1800  			// i ≤ h < j
  1801  			if !(rtypeOff(section, offs[h]).String() >= s) {
  1802  				i = h + 1 // preserves f(i-1) == false
  1803  			} else {
  1804  				j = h // preserves f(j) == true
  1805  			}
  1806  		}
  1807  		// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
  1808  
  1809  		// Having found the first, linear scan forward to find the last.
  1810  		// We could do a second binary search, but the caller is going
  1811  		// to do a linear scan anyway.
  1812  		for j := i; j < len(offs); j++ {
  1813  			typ := rtypeOff(section, offs[j])
  1814  			if typ.String() != s {
  1815  				break
  1816  			}
  1817  			ret = append(ret, typ)
  1818  		}
  1819  	}
  1820  	return ret
  1821  }
  1822  
  1823  // The lookupCache caches ArrayOf, ChanOf, MapOf and SliceOf lookups.
  1824  var lookupCache sync.Map // map[cacheKey]*rtype
  1825  
  1826  // A cacheKey is the key for use in the lookupCache.
  1827  // Four values describe any of the types we are looking for:
  1828  // type kind, one or two subtypes, and an extra integer.
  1829  type cacheKey struct {
  1830  	kind  Kind
  1831  	t1    *rtype
  1832  	t2    *rtype
  1833  	extra uintptr
  1834  }
  1835  
  1836  // The funcLookupCache caches FuncOf lookups.
  1837  // FuncOf does not share the common lookupCache since cacheKey is not
  1838  // sufficient to represent functions unambiguously.
  1839  var funcLookupCache struct {
  1840  	sync.Mutex // Guards stores (but not loads) on m.
  1841  
  1842  	// m is a map[uint32][]*rtype keyed by the hash calculated in FuncOf.
  1843  	// Elements of m are append-only and thus safe for concurrent reading.
  1844  	m sync.Map
  1845  }
  1846  
  1847  // ChanOf returns the channel type with the given direction and element type.
  1848  // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
  1849  //
  1850  // The gc runtime imposes a limit of 64 kB on channel element types.
  1851  // If t's size is equal to or exceeds this limit, ChanOf panics.
  1852  func ChanOf(dir ChanDir, t Type) Type {
  1853  	typ := t.(*rtype)
  1854  
  1855  	// Look in cache.
  1856  	ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
  1857  	if ch, ok := lookupCache.Load(ckey); ok {
  1858  		return ch.(*rtype)
  1859  	}
  1860  
  1861  	// This restriction is imposed by the gc compiler and the runtime.
  1862  	if typ.size >= 1<<16 {
  1863  		panic("reflect.ChanOf: element size too large")
  1864  	}
  1865  
  1866  	// Look in known types.
  1867  	var s string
  1868  	switch dir {
  1869  	default:
  1870  		panic("reflect.ChanOf: invalid dir")
  1871  	case SendDir:
  1872  		s = "chan<- " + typ.String()
  1873  	case RecvDir:
  1874  		s = "<-chan " + typ.String()
  1875  	case BothDir:
  1876  		typeStr := typ.String()
  1877  		if typeStr[0] == '<' {
  1878  			// typ is recv chan, need parentheses as "<-" associates with leftmost
  1879  			// chan possible, see:
  1880  			// * https://golang.org/ref/spec#Channel_types
  1881  			// * https://github.com/golang/go/issues/39897
  1882  			s = "chan (" + typeStr + ")"
  1883  		} else {
  1884  			s = "chan " + typeStr
  1885  		}
  1886  	}
  1887  	for _, tt := range typesByString(s) {
  1888  		ch := (*chanType)(unsafe.Pointer(tt))
  1889  		if ch.elem == typ && ch.dir == uintptr(dir) {
  1890  			ti, _ := lookupCache.LoadOrStore(ckey, tt)
  1891  			return ti.(Type)
  1892  		}
  1893  	}
  1894  
  1895  	// Make a channel type.
  1896  	var ichan any = (chan unsafe.Pointer)(nil)
  1897  	prototype := *(**chanType)(unsafe.Pointer(&ichan))
  1898  	ch := *prototype
  1899  	ch.tflag = tflagRegularMemory
  1900  	ch.dir = uintptr(dir)
  1901  	ch.str = resolveReflectName(newName(s, "", false, false))
  1902  	ch.hash = fnv1(typ.hash, 'c', byte(dir))
  1903  	ch.elem = typ
  1904  
  1905  	ti, _ := lookupCache.LoadOrStore(ckey, &ch.rtype)
  1906  	return ti.(Type)
  1907  }
  1908  
  1909  // MapOf returns the map type with the given key and element types.
  1910  // For example, if k represents int and e represents string,
  1911  // MapOf(k, e) represents map[int]string.
  1912  //
  1913  // If the key type is not a valid map key type (that is, if it does
  1914  // not implement Go's == operator), MapOf panics.
  1915  func MapOf(key, elem Type) Type {
  1916  	ktyp := key.(*rtype)
  1917  	etyp := elem.(*rtype)
  1918  
  1919  	if ktyp.equal == nil {
  1920  		panic("reflect.MapOf: invalid key type " + ktyp.String())
  1921  	}
  1922  
  1923  	// Look in cache.
  1924  	ckey := cacheKey{Map, ktyp, etyp, 0}
  1925  	if mt, ok := lookupCache.Load(ckey); ok {
  1926  		return mt.(Type)
  1927  	}
  1928  
  1929  	// Look in known types.
  1930  	s := "map[" + ktyp.String() + "]" + etyp.String()
  1931  	for _, tt := range typesByString(s) {
  1932  		mt := (*mapType)(unsafe.Pointer(tt))
  1933  		if mt.key == ktyp && mt.elem == etyp {
  1934  			ti, _ := lookupCache.LoadOrStore(ckey, tt)
  1935  			return ti.(Type)
  1936  		}
  1937  	}
  1938  
  1939  	// Make a map type.
  1940  	// Note: flag values must match those used in the TMAP case
  1941  	// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
  1942  	var imap any = (map[unsafe.Pointer]unsafe.Pointer)(nil)
  1943  	mt := **(**mapType)(unsafe.Pointer(&imap))
  1944  	mt.str = resolveReflectName(newName(s, "", false, false))
  1945  	mt.tflag = 0
  1946  	mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
  1947  	mt.key = ktyp
  1948  	mt.elem = etyp
  1949  	mt.bucket = bucketOf(ktyp, etyp)
  1950  	mt.hasher = func(p unsafe.Pointer, seed uintptr) uintptr {
  1951  		return typehash(ktyp, p, seed)
  1952  	}
  1953  	mt.flags = 0
  1954  	if ktyp.size > maxKeySize {
  1955  		mt.keysize = uint8(goarch.PtrSize)
  1956  		mt.flags |= 1 // indirect key
  1957  	} else {
  1958  		mt.keysize = uint8(ktyp.size)
  1959  	}
  1960  	if etyp.size > maxValSize {
  1961  		mt.valuesize = uint8(goarch.PtrSize)
  1962  		mt.flags |= 2 // indirect value
  1963  	} else {
  1964  		mt.valuesize = uint8(etyp.size)
  1965  	}
  1966  	mt.bucketsize = uint16(mt.bucket.size)
  1967  	if isReflexive(ktyp) {
  1968  		mt.flags |= 4
  1969  	}
  1970  	if needKeyUpdate(ktyp) {
  1971  		mt.flags |= 8
  1972  	}
  1973  	if hashMightPanic(ktyp) {
  1974  		mt.flags |= 16
  1975  	}
  1976  	mt.ptrToThis = 0
  1977  
  1978  	ti, _ := lookupCache.LoadOrStore(ckey, &mt.rtype)
  1979  	return ti.(Type)
  1980  }
  1981  
  1982  // TODO(crawshaw): as these funcTypeFixedN structs have no methods,
  1983  // they could be defined at runtime using the StructOf function.
  1984  type funcTypeFixed4 struct {
  1985  	funcType
  1986  	args [4]*rtype
  1987  }
  1988  type funcTypeFixed8 struct {
  1989  	funcType
  1990  	args [8]*rtype
  1991  }
  1992  type funcTypeFixed16 struct {
  1993  	funcType
  1994  	args [16]*rtype
  1995  }
  1996  type funcTypeFixed32 struct {
  1997  	funcType
  1998  	args [32]*rtype
  1999  }
  2000  type funcTypeFixed64 struct {
  2001  	funcType
  2002  	args [64]*rtype
  2003  }
  2004  type funcTypeFixed128 struct {
  2005  	funcType
  2006  	args [128]*rtype
  2007  }
  2008  
  2009  // FuncOf returns the function type with the given argument and result types.
  2010  // For example if k represents int and e represents string,
  2011  // FuncOf([]Type{k}, []Type{e}, false) represents func(int) string.
  2012  //
  2013  // The variadic argument controls whether the function is variadic. FuncOf
  2014  // panics if the in[len(in)-1] does not represent a slice and variadic is
  2015  // true.
  2016  func FuncOf(in, out []Type, variadic bool) Type {
  2017  	if variadic && (len(in) == 0 || in[len(in)-1].Kind() != Slice) {
  2018  		panic("reflect.FuncOf: last arg of variadic func must be slice")
  2019  	}
  2020  
  2021  	// Make a func type.
  2022  	var ifunc any = (func())(nil)
  2023  	prototype := *(**funcType)(unsafe.Pointer(&ifunc))
  2024  	n := len(in) + len(out)
  2025  
  2026  	var ft *funcType
  2027  	var args []*rtype
  2028  	switch {
  2029  	case n <= 4:
  2030  		fixed := new(funcTypeFixed4)
  2031  		args = fixed.args[:0:len(fixed.args)]
  2032  		ft = &fixed.funcType
  2033  	case n <= 8:
  2034  		fixed := new(funcTypeFixed8)
  2035  		args = fixed.args[:0:len(fixed.args)]
  2036  		ft = &fixed.funcType
  2037  	case n <= 16:
  2038  		fixed := new(funcTypeFixed16)
  2039  		args = fixed.args[:0:len(fixed.args)]
  2040  		ft = &fixed.funcType
  2041  	case n <= 32:
  2042  		fixed := new(funcTypeFixed32)
  2043  		args = fixed.args[:0:len(fixed.args)]
  2044  		ft = &fixed.funcType
  2045  	case n <= 64:
  2046  		fixed := new(funcTypeFixed64)
  2047  		args = fixed.args[:0:len(fixed.args)]
  2048  		ft = &fixed.funcType
  2049  	case n <= 128:
  2050  		fixed := new(funcTypeFixed128)
  2051  		args = fixed.args[:0:len(fixed.args)]
  2052  		ft = &fixed.funcType
  2053  	default:
  2054  		panic("reflect.FuncOf: too many arguments")
  2055  	}
  2056  	*ft = *prototype
  2057  
  2058  	// Build a hash and minimally populate ft.
  2059  	var hash uint32
  2060  	for _, in := range in {
  2061  		t := in.(*rtype)
  2062  		args = append(args, t)
  2063  		hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash))
  2064  	}
  2065  	if variadic {
  2066  		hash = fnv1(hash, 'v')
  2067  	}
  2068  	hash = fnv1(hash, '.')
  2069  	for _, out := range out {
  2070  		t := out.(*rtype)
  2071  		args = append(args, t)
  2072  		hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash))
  2073  	}
  2074  	if len(args) > 50 {
  2075  		panic("reflect.FuncOf does not support more than 50 arguments")
  2076  	}
  2077  	ft.tflag = 0
  2078  	ft.hash = hash
  2079  	ft.inCount = uint16(len(in))
  2080  	ft.outCount = uint16(len(out))
  2081  	if variadic {
  2082  		ft.outCount |= 1 << 15
  2083  	}
  2084  
  2085  	// Look in cache.
  2086  	if ts, ok := funcLookupCache.m.Load(hash); ok {
  2087  		for _, t := range ts.([]*rtype) {
  2088  			if haveIdenticalUnderlyingType(&ft.rtype, t, true) {
  2089  				return t
  2090  			}
  2091  		}
  2092  	}
  2093  
  2094  	// Not in cache, lock and retry.
  2095  	funcLookupCache.Lock()
  2096  	defer funcLookupCache.Unlock()
  2097  	if ts, ok := funcLookupCache.m.Load(hash); ok {
  2098  		for _, t := range ts.([]*rtype) {
  2099  			if haveIdenticalUnderlyingType(&ft.rtype, t, true) {
  2100  				return t
  2101  			}
  2102  		}
  2103  	}
  2104  
  2105  	addToCache := func(tt *rtype) Type {
  2106  		var rts []*rtype
  2107  		if rti, ok := funcLookupCache.m.Load(hash); ok {
  2108  			rts = rti.([]*rtype)
  2109  		}
  2110  		funcLookupCache.m.Store(hash, append(rts, tt))
  2111  		return tt
  2112  	}
  2113  
  2114  	// Look in known types for the same string representation.
  2115  	str := funcStr(ft)
  2116  	for _, tt := range typesByString(str) {
  2117  		if haveIdenticalUnderlyingType(&ft.rtype, tt, true) {
  2118  			return addToCache(tt)
  2119  		}
  2120  	}
  2121  
  2122  	// Populate the remaining fields of ft and store in cache.
  2123  	ft.str = resolveReflectName(newName(str, "", false, false))
  2124  	ft.ptrToThis = 0
  2125  	return addToCache(&ft.rtype)
  2126  }
  2127  
  2128  // funcStr builds a string representation of a funcType.
  2129  func funcStr(ft *funcType) string {
  2130  	repr := make([]byte, 0, 64)
  2131  	repr = append(repr, "func("...)
  2132  	for i, t := range ft.in() {
  2133  		if i > 0 {
  2134  			repr = append(repr, ", "...)
  2135  		}
  2136  		if ft.IsVariadic() && i == int(ft.inCount)-1 {
  2137  			repr = append(repr, "..."...)
  2138  			repr = append(repr, (*sliceType)(unsafe.Pointer(t)).elem.String()...)
  2139  		} else {
  2140  			repr = append(repr, t.String()...)
  2141  		}
  2142  	}
  2143  	repr = append(repr, ')')
  2144  	out := ft.out()
  2145  	if len(out) == 1 {
  2146  		repr = append(repr, ' ')
  2147  	} else if len(out) > 1 {
  2148  		repr = append(repr, " ("...)
  2149  	}
  2150  	for i, t := range out {
  2151  		if i > 0 {
  2152  			repr = append(repr, ", "...)
  2153  		}
  2154  		repr = append(repr, t.String()...)
  2155  	}
  2156  	if len(out) > 1 {
  2157  		repr = append(repr, ')')
  2158  	}
  2159  	return string(repr)
  2160  }
  2161  
  2162  // isReflexive reports whether the == operation on the type is reflexive.
  2163  // That is, x == x for all values x of type t.
  2164  func isReflexive(t *rtype) bool {
  2165  	switch t.Kind() {
  2166  	case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, String, UnsafePointer:
  2167  		return true
  2168  	case Float32, Float64, Complex64, Complex128, Interface:
  2169  		return false
  2170  	case Array:
  2171  		tt := (*arrayType)(unsafe.Pointer(t))
  2172  		return isReflexive(tt.elem)
  2173  	case Struct:
  2174  		tt := (*structType)(unsafe.Pointer(t))
  2175  		for _, f := range tt.fields {
  2176  			if !isReflexive(f.typ) {
  2177  				return false
  2178  			}
  2179  		}
  2180  		return true
  2181  	default:
  2182  		// Func, Map, Slice, Invalid
  2183  		panic("isReflexive called on non-key type " + t.String())
  2184  	}
  2185  }
  2186  
  2187  // needKeyUpdate reports whether map overwrites require the key to be copied.
  2188  func needKeyUpdate(t *rtype) bool {
  2189  	switch t.Kind() {
  2190  	case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, UnsafePointer:
  2191  		return false
  2192  	case Float32, Float64, Complex64, Complex128, Interface, String:
  2193  		// Float keys can be updated from +0 to -0.
  2194  		// String keys can be updated to use a smaller backing store.
  2195  		// Interfaces might have floats of strings in them.
  2196  		return true
  2197  	case Array:
  2198  		tt := (*arrayType)(unsafe.Pointer(t))
  2199  		return needKeyUpdate(tt.elem)
  2200  	case Struct:
  2201  		tt := (*structType)(unsafe.Pointer(t))
  2202  		for _, f := range tt.fields {
  2203  			if needKeyUpdate(f.typ) {
  2204  				return true
  2205  			}
  2206  		}
  2207  		return false
  2208  	default:
  2209  		// Func, Map, Slice, Invalid
  2210  		panic("needKeyUpdate called on non-key type " + t.String())
  2211  	}
  2212  }
  2213  
  2214  // hashMightPanic reports whether the hash of a map key of type t might panic.
  2215  func hashMightPanic(t *rtype) bool {
  2216  	switch t.Kind() {
  2217  	case Interface:
  2218  		return true
  2219  	case Array:
  2220  		tt := (*arrayType)(unsafe.Pointer(t))
  2221  		return hashMightPanic(tt.elem)
  2222  	case Struct:
  2223  		tt := (*structType)(unsafe.Pointer(t))
  2224  		for _, f := range tt.fields {
  2225  			if hashMightPanic(f.typ) {
  2226  				return true
  2227  			}
  2228  		}
  2229  		return false
  2230  	default:
  2231  		return false
  2232  	}
  2233  }
  2234  
  2235  // Make sure these routines stay in sync with ../runtime/map.go!
  2236  // These types exist only for GC, so we only fill out GC relevant info.
  2237  // Currently, that's just size and the GC program. We also fill in string
  2238  // for possible debugging use.
  2239  const (
  2240  	bucketSize uintptr = 8
  2241  	maxKeySize uintptr = 128
  2242  	maxValSize uintptr = 128
  2243  )
  2244  
  2245  func bucketOf(ktyp, etyp *rtype) *rtype {
  2246  	if ktyp.size > maxKeySize {
  2247  		ktyp = PointerTo(ktyp).(*rtype)
  2248  	}
  2249  	if etyp.size > maxValSize {
  2250  		etyp = PointerTo(etyp).(*rtype)
  2251  	}
  2252  
  2253  	// Prepare GC data if any.
  2254  	// A bucket is at most bucketSize*(1+maxKeySize+maxValSize)+ptrSize bytes,
  2255  	// or 2064 bytes, or 258 pointer-size words, or 33 bytes of pointer bitmap.
  2256  	// Note that since the key and value are known to be <= 128 bytes,
  2257  	// they're guaranteed to have bitmaps instead of GC programs.
  2258  	var gcdata *byte
  2259  	var ptrdata uintptr
  2260  
  2261  	size := bucketSize*(1+ktyp.size+etyp.size) + goarch.PtrSize
  2262  	if size&uintptr(ktyp.align-1) != 0 || size&uintptr(etyp.align-1) != 0 {
  2263  		panic("reflect: bad size computation in MapOf")
  2264  	}
  2265  
  2266  	if ktyp.ptrdata != 0 || etyp.ptrdata != 0 {
  2267  		nptr := (bucketSize*(1+ktyp.size+etyp.size) + goarch.PtrSize) / goarch.PtrSize
  2268  		mask := make([]byte, (nptr+7)/8)
  2269  		base := bucketSize / goarch.PtrSize
  2270  
  2271  		if ktyp.ptrdata != 0 {
  2272  			emitGCMask(mask, base, ktyp, bucketSize)
  2273  		}
  2274  		base += bucketSize * ktyp.size / goarch.PtrSize
  2275  
  2276  		if etyp.ptrdata != 0 {
  2277  			emitGCMask(mask, base, etyp, bucketSize)
  2278  		}
  2279  		base += bucketSize * etyp.size / goarch.PtrSize
  2280  
  2281  		word := base
  2282  		mask[word/8] |= 1 << (word % 8)
  2283  		gcdata = &mask[0]
  2284  		ptrdata = (word + 1) * goarch.PtrSize
  2285  
  2286  		// overflow word must be last
  2287  		if ptrdata != size {
  2288  			panic("reflect: bad layout computation in MapOf")
  2289  		}
  2290  	}
  2291  
  2292  	b := &rtype{
  2293  		align:   goarch.PtrSize,
  2294  		size:    size,
  2295  		kind:    uint8(Struct),
  2296  		ptrdata: ptrdata,
  2297  		gcdata:  gcdata,
  2298  	}
  2299  	s := "bucket(" + ktyp.String() + "," + etyp.String() + ")"
  2300  	b.str = resolveReflectName(newName(s, "", false, false))
  2301  	return b
  2302  }
  2303  
  2304  func (t *rtype) gcSlice(begin, end uintptr) []byte {
  2305  	return (*[1 << 30]byte)(unsafe.Pointer(t.gcdata))[begin:end:end]
  2306  }
  2307  
  2308  // emitGCMask writes the GC mask for [n]typ into out, starting at bit
  2309  // offset base.
  2310  func emitGCMask(out []byte, base uintptr, typ *rtype, n uintptr) {
  2311  	if typ.kind&kindGCProg != 0 {
  2312  		panic("reflect: unexpected GC program")
  2313  	}
  2314  	ptrs := typ.ptrdata / goarch.PtrSize
  2315  	words := typ.size / goarch.PtrSize
  2316  	mask := typ.gcSlice(0, (ptrs+7)/8)
  2317  	for j := uintptr(0); j < ptrs; j++ {
  2318  		if (mask[j/8]>>(j%8))&1 != 0 {
  2319  			for i := uintptr(0); i < n; i++ {
  2320  				k := base + i*words + j
  2321  				out[k/8] |= 1 << (k % 8)
  2322  			}
  2323  		}
  2324  	}
  2325  }
  2326  
  2327  // appendGCProg appends the GC program for the first ptrdata bytes of
  2328  // typ to dst and returns the extended slice.
  2329  func appendGCProg(dst []byte, typ *rtype) []byte {
  2330  	if typ.kind&kindGCProg != 0 {
  2331  		// Element has GC program; emit one element.
  2332  		n := uintptr(*(*uint32)(unsafe.Pointer(typ.gcdata)))
  2333  		prog := typ.gcSlice(4, 4+n-1)
  2334  		return append(dst, prog...)
  2335  	}
  2336  
  2337  	// Element is small with pointer mask; use as literal bits.
  2338  	ptrs := typ.ptrdata / goarch.PtrSize
  2339  	mask := typ.gcSlice(0, (ptrs+7)/8)
  2340  
  2341  	// Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes).
  2342  	for ; ptrs > 120; ptrs -= 120 {
  2343  		dst = append(dst, 120)
  2344  		dst = append(dst, mask[:15]...)
  2345  		mask = mask[15:]
  2346  	}
  2347  
  2348  	dst = append(dst, byte(ptrs))
  2349  	dst = append(dst, mask...)
  2350  	return dst
  2351  }
  2352  
  2353  // SliceOf returns the slice type with element type t.
  2354  // For example, if t represents int, SliceOf(t) represents []int.
  2355  func SliceOf(t Type) Type {
  2356  	typ := t.(*rtype)
  2357  
  2358  	// Look in cache.
  2359  	ckey := cacheKey{Slice, typ, nil, 0}
  2360  	if slice, ok := lookupCache.Load(ckey); ok {
  2361  		return slice.(Type)
  2362  	}
  2363  
  2364  	// Look in known types.
  2365  	s := "[]" + typ.String()
  2366  	for _, tt := range typesByString(s) {
  2367  		slice := (*sliceType)(unsafe.Pointer(tt))
  2368  		if slice.elem == typ {
  2369  			ti, _ := lookupCache.LoadOrStore(ckey, tt)
  2370  			return ti.(Type)
  2371  		}
  2372  	}
  2373  
  2374  	// Make a slice type.
  2375  	var islice any = ([]unsafe.Pointer)(nil)
  2376  	prototype := *(**sliceType)(unsafe.Pointer(&islice))
  2377  	slice := *prototype
  2378  	slice.tflag = 0
  2379  	slice.str = resolveReflectName(newName(s, "", false, false))
  2380  	slice.hash = fnv1(typ.hash, '[')
  2381  	slice.elem = typ
  2382  	slice.ptrToThis = 0
  2383  
  2384  	ti, _ := lookupCache.LoadOrStore(ckey, &slice.rtype)
  2385  	return ti.(Type)
  2386  }
  2387  
  2388  // The structLookupCache caches StructOf lookups.
  2389  // StructOf does not share the common lookupCache since we need to pin
  2390  // the memory associated with *structTypeFixedN.
  2391  var structLookupCache struct {
  2392  	sync.Mutex // Guards stores (but not loads) on m.
  2393  
  2394  	// m is a map[uint32][]Type keyed by the hash calculated in StructOf.
  2395  	// Elements in m are append-only and thus safe for concurrent reading.
  2396  	m sync.Map
  2397  }
  2398  
  2399  type structTypeUncommon struct {
  2400  	structType
  2401  	u uncommonType
  2402  }
  2403  
  2404  // isLetter reports whether a given 'rune' is classified as a Letter.
  2405  func isLetter(ch rune) bool {
  2406  	return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
  2407  }
  2408  
  2409  // isValidFieldName checks if a string is a valid (struct) field name or not.
  2410  //
  2411  // According to the language spec, a field name should be an identifier.
  2412  //
  2413  // identifier = letter { letter | unicode_digit } .
  2414  // letter = unicode_letter | "_" .
  2415  func isValidFieldName(fieldName string) bool {
  2416  	for i, c := range fieldName {
  2417  		if i == 0 && !isLetter(c) {
  2418  			return false
  2419  		}
  2420  
  2421  		if !(isLetter(c) || unicode.IsDigit(c)) {
  2422  			return false
  2423  		}
  2424  	}
  2425  
  2426  	return len(fieldName) > 0
  2427  }
  2428  
  2429  // StructOf returns the struct type containing fields.
  2430  // The Offset and Index fields are ignored and computed as they would be
  2431  // by the compiler.
  2432  //
  2433  // StructOf currently does not generate wrapper methods for embedded
  2434  // fields and panics if passed unexported StructFields.
  2435  // These limitations may be lifted in a future version.
  2436  func StructOf(fields []StructField) Type {
  2437  	var (
  2438  		hash       = fnv1(0, []byte("struct {")...)
  2439  		size       uintptr
  2440  		typalign   uint8
  2441  		comparable = true
  2442  		methods    []method
  2443  
  2444  		fs   = make([]structField, len(fields))
  2445  		repr = make([]byte, 0, 64)
  2446  		fset = map[string]struct{}{} // fields' names
  2447  
  2448  		hasGCProg = false // records whether a struct-field type has a GCProg
  2449  	)
  2450  
  2451  	lastzero := uintptr(0)
  2452  	repr = append(repr, "struct {"...)
  2453  	pkgpath := ""
  2454  	for i, field := range fields {
  2455  		if field.Name == "" {
  2456  			panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no name")
  2457  		}
  2458  		if !isValidFieldName(field.Name) {
  2459  			panic("reflect.StructOf: field " + strconv.Itoa(i) + " has invalid name")
  2460  		}
  2461  		if field.Type == nil {
  2462  			panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no type")
  2463  		}
  2464  		f, fpkgpath := runtimeStructField(field)
  2465  		ft := f.typ
  2466  		if ft.kind&kindGCProg != 0 {
  2467  			hasGCProg = true
  2468  		}
  2469  		if fpkgpath != "" {
  2470  			if pkgpath == "" {
  2471  				pkgpath = fpkgpath
  2472  			} else if pkgpath != fpkgpath {
  2473  				panic("reflect.Struct: fields with different PkgPath " + pkgpath + " and " + fpkgpath)
  2474  			}
  2475  		}
  2476  
  2477  		// Update string and hash
  2478  		name := f.name.name()
  2479  		hash = fnv1(hash, []byte(name)...)
  2480  		repr = append(repr, (" " + name)...)
  2481  		if f.embedded() {
  2482  			// Embedded field
  2483  			if f.typ.Kind() == Pointer {
  2484  				// Embedded ** and *interface{} are illegal
  2485  				elem := ft.Elem()
  2486  				if k := elem.Kind(); k == Pointer || k == Interface {
  2487  					panic("reflect.StructOf: illegal embedded field type " + ft.String())
  2488  				}
  2489  			}
  2490  
  2491  			switch f.typ.Kind() {
  2492  			case Interface:
  2493  				ift := (*interfaceType)(unsafe.Pointer(ft))
  2494  				for im, m := range ift.methods {
  2495  					if ift.nameOff(m.name).pkgPath() != "" {
  2496  						// TODO(sbinet).  Issue 15924.
  2497  						panic("reflect: embedded interface with unexported method(s) not implemented")
  2498  					}
  2499  
  2500  					var (
  2501  						mtyp    = ift.typeOff(m.typ)
  2502  						ifield  = i
  2503  						imethod = im
  2504  						ifn     Value
  2505  						tfn     Value
  2506  					)
  2507  
  2508  					if ft.kind&kindDirectIface != 0 {
  2509  						tfn = MakeFunc(mtyp, func(in []Value) []Value {
  2510  							var args []Value
  2511  							var recv = in[0]
  2512  							if len(in) > 1 {
  2513  								args = in[1:]
  2514  							}
  2515  							return recv.Field(ifield).Method(imethod).Call(args)
  2516  						})
  2517  						ifn = MakeFunc(mtyp, func(in []Value) []Value {
  2518  							var args []Value
  2519  							var recv = in[0]
  2520  							if len(in) > 1 {
  2521  								args = in[1:]
  2522  							}
  2523  							return recv.Field(ifield).Method(imethod).Call(args)
  2524  						})
  2525  					} else {
  2526  						tfn = MakeFunc(mtyp, func(in []Value) []Value {
  2527  							var args []Value
  2528  							var recv = in[0]
  2529  							if len(in) > 1 {
  2530  								args = in[1:]
  2531  							}
  2532  							return recv.Field(ifield).Method(imethod).Call(args)
  2533  						})
  2534  						ifn = MakeFunc(mtyp, func(in []Value) []Value {
  2535  							var args []Value
  2536  							var recv = Indirect(in[0])
  2537  							if len(in) > 1 {
  2538  								args = in[1:]
  2539  							}
  2540  							return recv.Field(ifield).Method(imethod).Call(args)
  2541  						})
  2542  					}
  2543  
  2544  					methods = append(methods, method{
  2545  						name: resolveReflectName(ift.nameOff(m.name)),
  2546  						mtyp: resolveReflectType(mtyp),
  2547  						ifn:  resolveReflectText(unsafe.Pointer(&ifn)),
  2548  						tfn:  resolveReflectText(unsafe.Pointer(&tfn)),
  2549  					})
  2550  				}
  2551  			case Pointer:
  2552  				ptr := (*ptrType)(unsafe.Pointer(ft))
  2553  				if unt := ptr.uncommon(); unt != nil {
  2554  					if i > 0 && unt.mcount > 0 {
  2555  						// Issue 15924.
  2556  						panic("reflect: embedded type with methods not implemented if type is not first field")
  2557  					}
  2558  					if len(fields) > 1 {
  2559  						panic("reflect: embedded type with methods not implemented if there is more than one field")
  2560  					}
  2561  					for _, m := range unt.methods() {
  2562  						mname := ptr.nameOff(m.name)
  2563  						if mname.pkgPath() != "" {
  2564  							// TODO(sbinet).
  2565  							// Issue 15924.
  2566  							panic("reflect: embedded interface with unexported method(s) not implemented")
  2567  						}
  2568  						methods = append(methods, method{
  2569  							name: resolveReflectName(mname),
  2570  							mtyp: resolveReflectType(ptr.typeOff(m.mtyp)),
  2571  							ifn:  resolveReflectText(ptr.textOff(m.ifn)),
  2572  							tfn:  resolveReflectText(ptr.textOff(m.tfn)),
  2573  						})
  2574  					}
  2575  				}
  2576  				if unt := ptr.elem.uncommon(); unt != nil {
  2577  					for _, m := range unt.methods() {
  2578  						mname := ptr.nameOff(m.name)
  2579  						if mname.pkgPath() != "" {
  2580  							// TODO(sbinet)
  2581  							// Issue 15924.
  2582  							panic("reflect: embedded interface with unexported method(s) not implemented")
  2583  						}
  2584  						methods = append(methods, method{
  2585  							name: resolveReflectName(mname),
  2586  							mtyp: resolveReflectType(ptr.elem.typeOff(m.mtyp)),
  2587  							ifn:  resolveReflectText(ptr.elem.textOff(m.ifn)),
  2588  							tfn:  resolveReflectText(ptr.elem.textOff(m.tfn)),
  2589  						})
  2590  					}
  2591  				}
  2592  			default:
  2593  				if unt := ft.uncommon(); unt != nil {
  2594  					if i > 0 && unt.mcount > 0 {
  2595  						// Issue 15924.
  2596  						panic("reflect: embedded type with methods not implemented if type is not first field")
  2597  					}
  2598  					if len(fields) > 1 && ft.kind&kindDirectIface != 0 {
  2599  						panic("reflect: embedded type with methods not implemented for non-pointer type")
  2600  					}
  2601  					for _, m := range unt.methods() {
  2602  						mname := ft.nameOff(m.name)
  2603  						if mname.pkgPath() != "" {
  2604  							// TODO(sbinet)
  2605  							// Issue 15924.
  2606  							panic("reflect: embedded interface with unexported method(s) not implemented")
  2607  						}
  2608  						methods = append(methods, method{
  2609  							name: resolveReflectName(mname),
  2610  							mtyp: resolveReflectType(ft.typeOff(m.mtyp)),
  2611  							ifn:  resolveReflectText(ft.textOff(m.ifn)),
  2612  							tfn:  resolveReflectText(ft.textOff(m.tfn)),
  2613  						})
  2614  
  2615  					}
  2616  				}
  2617  			}
  2618  		}
  2619  		if _, dup := fset[name]; dup && name != "_" {
  2620  			panic("reflect.StructOf: duplicate field " + name)
  2621  		}
  2622  		fset[name] = struct{}{}
  2623  
  2624  		hash = fnv1(hash, byte(ft.hash>>24), byte(ft.hash>>16), byte(ft.hash>>8), byte(ft.hash))
  2625  
  2626  		repr = append(repr, (" " + ft.String())...)
  2627  		if f.name.hasTag() {
  2628  			hash = fnv1(hash, []byte(f.name.tag())...)
  2629  			repr = append(repr, (" " + strconv.Quote(f.name.tag()))...)
  2630  		}
  2631  		if i < len(fields)-1 {
  2632  			repr = append(repr, ';')
  2633  		}
  2634  
  2635  		comparable = comparable && (ft.equal != nil)
  2636  
  2637  		offset := align(size, uintptr(ft.align))
  2638  		if offset < size {
  2639  			panic("reflect.StructOf: struct size would exceed virtual address space")
  2640  		}
  2641  		if ft.align > typalign {
  2642  			typalign = ft.align
  2643  		}
  2644  		size = offset + ft.size
  2645  		if size < offset {
  2646  			panic("reflect.StructOf: struct size would exceed virtual address space")
  2647  		}
  2648  		f.offset = offset
  2649  
  2650  		if ft.size == 0 {
  2651  			lastzero = size
  2652  		}
  2653  
  2654  		fs[i] = f
  2655  	}
  2656  
  2657  	if size > 0 && lastzero == size {
  2658  		// This is a non-zero sized struct that ends in a
  2659  		// zero-sized field. We add an extra byte of padding,
  2660  		// to ensure that taking the address of the final
  2661  		// zero-sized field can't manufacture a pointer to the
  2662  		// next object in the heap. See issue 9401.
  2663  		size++
  2664  		if size == 0 {
  2665  			panic("reflect.StructOf: struct size would exceed virtual address space")
  2666  		}
  2667  	}
  2668  
  2669  	var typ *structType
  2670  	var ut *uncommonType
  2671  
  2672  	if len(methods) == 0 {
  2673  		t := new(structTypeUncommon)
  2674  		typ = &t.structType
  2675  		ut = &t.u
  2676  	} else {
  2677  		// A *rtype representing a struct is followed directly in memory by an
  2678  		// array of method objects representing the methods attached to the
  2679  		// struct. To get the same layout for a run time generated type, we
  2680  		// need an array directly following the uncommonType memory.
  2681  		// A similar strategy is used for funcTypeFixed4, ...funcTypeFixedN.
  2682  		tt := New(StructOf([]StructField{
  2683  			{Name: "S", Type: TypeOf(structType{})},
  2684  			{Name: "U", Type: TypeOf(uncommonType{})},
  2685  			{Name: "M", Type: ArrayOf(len(methods), TypeOf(methods[0]))},
  2686  		}))
  2687  
  2688  		typ = (*structType)(tt.Elem().Field(0).Addr().UnsafePointer())
  2689  		ut = (*uncommonType)(tt.Elem().Field(1).Addr().UnsafePointer())
  2690  
  2691  		copy(tt.Elem().Field(2).Slice(0, len(methods)).Interface().([]method), methods)
  2692  	}
  2693  	// TODO(sbinet): Once we allow embedding multiple types,
  2694  	// methods will need to be sorted like the compiler does.
  2695  	// TODO(sbinet): Once we allow non-exported methods, we will
  2696  	// need to compute xcount as the number of exported methods.
  2697  	ut.mcount = uint16(len(methods))
  2698  	ut.xcount = ut.mcount
  2699  	ut.moff = uint32(unsafe.Sizeof(uncommonType{}))
  2700  
  2701  	if len(fs) > 0 {
  2702  		repr = append(repr, ' ')
  2703  	}
  2704  	repr = append(repr, '}')
  2705  	hash = fnv1(hash, '}')
  2706  	str := string(repr)
  2707  
  2708  	// Round the size up to be a multiple of the alignment.
  2709  	s := align(size, uintptr(typalign))
  2710  	if s < size {
  2711  		panic("reflect.StructOf: struct size would exceed virtual address space")
  2712  	}
  2713  	size = s
  2714  
  2715  	// Make the struct type.
  2716  	var istruct any = struct{}{}
  2717  	prototype := *(**structType)(unsafe.Pointer(&istruct))
  2718  	*typ = *prototype
  2719  	typ.fields = fs
  2720  	if pkgpath != "" {
  2721  		typ.pkgPath = newName(pkgpath, "", false, false)
  2722  	}
  2723  
  2724  	// Look in cache.
  2725  	if ts, ok := structLookupCache.m.Load(hash); ok {
  2726  		for _, st := range ts.([]Type) {
  2727  			t := st.common()
  2728  			if haveIdenticalUnderlyingType(&typ.rtype, t, true) {
  2729  				return t
  2730  			}
  2731  		}
  2732  	}
  2733  
  2734  	// Not in cache, lock and retry.
  2735  	structLookupCache.Lock()
  2736  	defer structLookupCache.Unlock()
  2737  	if ts, ok := structLookupCache.m.Load(hash); ok {
  2738  		for _, st := range ts.([]Type) {
  2739  			t := st.common()
  2740  			if haveIdenticalUnderlyingType(&typ.rtype, t, true) {
  2741  				return t
  2742  			}
  2743  		}
  2744  	}
  2745  
  2746  	addToCache := func(t Type) Type {
  2747  		var ts []Type
  2748  		if ti, ok := structLookupCache.m.Load(hash); ok {
  2749  			ts = ti.([]Type)
  2750  		}
  2751  		structLookupCache.m.Store(hash, append(ts, t))
  2752  		return t
  2753  	}
  2754  
  2755  	// Look in known types.
  2756  	for _, t := range typesByString(str) {
  2757  		if haveIdenticalUnderlyingType(&typ.rtype, t, true) {
  2758  			// even if 't' wasn't a structType with methods, we should be ok
  2759  			// as the 'u uncommonType' field won't be accessed except when
  2760  			// tflag&tflagUncommon is set.
  2761  			return addToCache(t)
  2762  		}
  2763  	}
  2764  
  2765  	typ.str = resolveReflectName(newName(str, "", false, false))
  2766  	typ.tflag = 0 // TODO: set tflagRegularMemory
  2767  	typ.hash = hash
  2768  	typ.size = size
  2769  	typ.ptrdata = typeptrdata(typ.common())
  2770  	typ.align = typalign
  2771  	typ.fieldAlign = typalign
  2772  	typ.ptrToThis = 0
  2773  	if len(methods) > 0 {
  2774  		typ.tflag |= tflagUncommon
  2775  	}
  2776  
  2777  	if hasGCProg {
  2778  		lastPtrField := 0
  2779  		for i, ft := range fs {
  2780  			if ft.typ.pointers() {
  2781  				lastPtrField = i
  2782  			}
  2783  		}
  2784  		prog := []byte{0, 0, 0, 0} // will be length of prog
  2785  		var off uintptr
  2786  		for i, ft := range fs {
  2787  			if i > lastPtrField {
  2788  				// gcprog should not include anything for any field after
  2789  				// the last field that contains pointer data
  2790  				break
  2791  			}
  2792  			if !ft.typ.pointers() {
  2793  				// Ignore pointerless fields.
  2794  				continue
  2795  			}
  2796  			// Pad to start of this field with zeros.
  2797  			if ft.offset > off {
  2798  				n := (ft.offset - off) / goarch.PtrSize
  2799  				prog = append(prog, 0x01, 0x00) // emit a 0 bit
  2800  				if n > 1 {
  2801  					prog = append(prog, 0x81)      // repeat previous bit
  2802  					prog = appendVarint(prog, n-1) // n-1 times
  2803  				}
  2804  				off = ft.offset
  2805  			}
  2806  
  2807  			prog = appendGCProg(prog, ft.typ)
  2808  			off += ft.typ.ptrdata
  2809  		}
  2810  		prog = append(prog, 0)
  2811  		*(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4)
  2812  		typ.kind |= kindGCProg
  2813  		typ.gcdata = &prog[0]
  2814  	} else {
  2815  		typ.kind &^= kindGCProg
  2816  		bv := new(bitVector)
  2817  		addTypeBits(bv, 0, typ.common())
  2818  		if len(bv.data) > 0 {
  2819  			typ.gcdata = &bv.data[0]
  2820  		}
  2821  	}
  2822  	typ.equal = nil
  2823  	if comparable {
  2824  		typ.equal = func(p, q unsafe.Pointer) bool {
  2825  			for _, ft := range typ.fields {
  2826  				pi := add(p, ft.offset, "&x.field safe")
  2827  				qi := add(q, ft.offset, "&x.field safe")
  2828  				if !ft.typ.equal(pi, qi) {
  2829  					return false
  2830  				}
  2831  			}
  2832  			return true
  2833  		}
  2834  	}
  2835  
  2836  	switch {
  2837  	case len(fs) == 1 && !ifaceIndir(fs[0].typ):
  2838  		// structs of 1 direct iface type can be direct
  2839  		typ.kind |= kindDirectIface
  2840  	default:
  2841  		typ.kind &^= kindDirectIface
  2842  	}
  2843  
  2844  	return addToCache(&typ.rtype)
  2845  }
  2846  
  2847  // runtimeStructField takes a StructField value passed to StructOf and
  2848  // returns both the corresponding internal representation, of type
  2849  // structField, and the pkgpath value to use for this field.
  2850  func runtimeStructField(field StructField) (structField, string) {
  2851  	if field.Anonymous && field.PkgPath != "" {
  2852  		panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
  2853  	}
  2854  
  2855  	if field.IsExported() {
  2856  		// Best-effort check for misuse.
  2857  		// Since this field will be treated as exported, not much harm done if Unicode lowercase slips through.
  2858  		c := field.Name[0]
  2859  		if 'a' <= c && c <= 'z' || c == '_' {
  2860  			panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath")
  2861  		}
  2862  	}
  2863  
  2864  	resolveReflectType(field.Type.common()) // install in runtime
  2865  	f := structField{
  2866  		name:   newName(field.Name, string(field.Tag), field.IsExported(), field.Anonymous),
  2867  		typ:    field.Type.common(),
  2868  		offset: 0,
  2869  	}
  2870  	return f, field.PkgPath
  2871  }
  2872  
  2873  // typeptrdata returns the length in bytes of the prefix of t
  2874  // containing pointer data. Anything after this offset is scalar data.
  2875  // keep in sync with ../cmd/compile/internal/reflectdata/reflect.go
  2876  func typeptrdata(t *rtype) uintptr {
  2877  	switch t.Kind() {
  2878  	case Struct:
  2879  		st := (*structType)(unsafe.Pointer(t))
  2880  		// find the last field that has pointers.
  2881  		field := -1
  2882  		for i := range st.fields {
  2883  			ft := st.fields[i].typ
  2884  			if ft.pointers() {
  2885  				field = i
  2886  			}
  2887  		}
  2888  		if field == -1 {
  2889  			return 0
  2890  		}
  2891  		f := st.fields[field]
  2892  		return f.offset + f.typ.ptrdata
  2893  
  2894  	default:
  2895  		panic("reflect.typeptrdata: unexpected type, " + t.String())
  2896  	}
  2897  }
  2898  
  2899  // See cmd/compile/internal/reflectdata/reflect.go for derivation of constant.
  2900  const maxPtrmaskBytes = 2048
  2901  
  2902  // ArrayOf returns the array type with the given length and element type.
  2903  // For example, if t represents int, ArrayOf(5, t) represents [5]int.
  2904  //
  2905  // If the resulting type would be larger than the available address space,
  2906  // ArrayOf panics.
  2907  func ArrayOf(length int, elem Type) Type {
  2908  	if length < 0 {
  2909  		panic("reflect: negative length passed to ArrayOf")
  2910  	}
  2911  
  2912  	typ := elem.(*rtype)
  2913  
  2914  	// Look in cache.
  2915  	ckey := cacheKey{Array, typ, nil, uintptr(length)}
  2916  	if array, ok := lookupCache.Load(ckey); ok {
  2917  		return array.(Type)
  2918  	}
  2919  
  2920  	// Look in known types.
  2921  	s := "[" + strconv.Itoa(length) + "]" + typ.String()
  2922  	for _, tt := range typesByString(s) {
  2923  		array := (*arrayType)(unsafe.Pointer(tt))
  2924  		if array.elem == typ {
  2925  			ti, _ := lookupCache.LoadOrStore(ckey, tt)
  2926  			return ti.(Type)
  2927  		}
  2928  	}
  2929  
  2930  	// Make an array type.
  2931  	var iarray any = [1]unsafe.Pointer{}
  2932  	prototype := *(**arrayType)(unsafe.Pointer(&iarray))
  2933  	array := *prototype
  2934  	array.tflag = typ.tflag & tflagRegularMemory
  2935  	array.str = resolveReflectName(newName(s, "", false, false))
  2936  	array.hash = fnv1(typ.hash, '[')
  2937  	for n := uint32(length); n > 0; n >>= 8 {
  2938  		array.hash = fnv1(array.hash, byte(n))
  2939  	}
  2940  	array.hash = fnv1(array.hash, ']')
  2941  	array.elem = typ
  2942  	array.ptrToThis = 0
  2943  	if typ.size > 0 {
  2944  		max := ^uintptr(0) / typ.size
  2945  		if uintptr(length) > max {
  2946  			panic("reflect.ArrayOf: array size would exceed virtual address space")
  2947  		}
  2948  	}
  2949  	array.size = typ.size * uintptr(length)
  2950  	if length > 0 && typ.ptrdata != 0 {
  2951  		array.ptrdata = typ.size*uintptr(length-1) + typ.ptrdata
  2952  	}
  2953  	array.align = typ.align
  2954  	array.fieldAlign = typ.fieldAlign
  2955  	array.len = uintptr(length)
  2956  	array.slice = SliceOf(elem).(*rtype)
  2957  
  2958  	switch {
  2959  	case typ.ptrdata == 0 || array.size == 0:
  2960  		// No pointers.
  2961  		array.gcdata = nil
  2962  		array.ptrdata = 0
  2963  
  2964  	case length == 1:
  2965  		// In memory, 1-element array looks just like the element.
  2966  		array.kind |= typ.kind & kindGCProg
  2967  		array.gcdata = typ.gcdata
  2968  		array.ptrdata = typ.ptrdata
  2969  
  2970  	case typ.kind&kindGCProg == 0 && array.size <= maxPtrmaskBytes*8*goarch.PtrSize:
  2971  		// Element is small with pointer mask; array is still small.
  2972  		// Create direct pointer mask by turning each 1 bit in elem
  2973  		// into length 1 bits in larger mask.
  2974  		mask := make([]byte, (array.ptrdata/goarch.PtrSize+7)/8)
  2975  		emitGCMask(mask, 0, typ, array.len)
  2976  		array.gcdata = &mask[0]
  2977  
  2978  	default:
  2979  		// Create program that emits one element
  2980  		// and then repeats to make the array.
  2981  		prog := []byte{0, 0, 0, 0} // will be length of prog
  2982  		prog = appendGCProg(prog, typ)
  2983  		// Pad from ptrdata to size.
  2984  		elemPtrs := typ.ptrdata / goarch.PtrSize
  2985  		elemWords := typ.size / goarch.PtrSize
  2986  		if elemPtrs < elemWords {
  2987  			// Emit literal 0 bit, then repeat as needed.
  2988  			prog = append(prog, 0x01, 0x00)
  2989  			if elemPtrs+1 < elemWords {
  2990  				prog = append(prog, 0x81)
  2991  				prog = appendVarint(prog, elemWords-elemPtrs-1)
  2992  			}
  2993  		}
  2994  		// Repeat length-1 times.
  2995  		if elemWords < 0x80 {
  2996  			prog = append(prog, byte(elemWords|0x80))
  2997  		} else {
  2998  			prog = append(prog, 0x80)
  2999  			prog = appendVarint(prog, elemWords)
  3000  		}
  3001  		prog = appendVarint(prog, uintptr(length)-1)
  3002  		prog = append(prog, 0)
  3003  		*(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4)
  3004  		array.kind |= kindGCProg
  3005  		array.gcdata = &prog[0]
  3006  		array.ptrdata = array.size // overestimate but ok; must match program
  3007  	}
  3008  
  3009  	etyp := typ.common()
  3010  	esize := etyp.Size()
  3011  
  3012  	array.equal = nil
  3013  	if eequal := etyp.equal; eequal != nil {
  3014  		array.equal = func(p, q unsafe.Pointer) bool {
  3015  			for i := 0; i < length; i++ {
  3016  				pi := arrayAt(p, i, esize, "i < length")
  3017  				qi := arrayAt(q, i, esize, "i < length")
  3018  				if !eequal(pi, qi) {
  3019  					return false
  3020  				}
  3021  
  3022  			}
  3023  			return true
  3024  		}
  3025  	}
  3026  
  3027  	switch {
  3028  	case length == 1 && !ifaceIndir(typ):
  3029  		// array of 1 direct iface type can be direct
  3030  		array.kind |= kindDirectIface
  3031  	default:
  3032  		array.kind &^= kindDirectIface
  3033  	}
  3034  
  3035  	ti, _ := lookupCache.LoadOrStore(ckey, &array.rtype)
  3036  	return ti.(Type)
  3037  }
  3038  
  3039  func appendVarint(x []byte, v uintptr) []byte {
  3040  	for ; v >= 0x80; v >>= 7 {
  3041  		x = append(x, byte(v|0x80))
  3042  	}
  3043  	x = append(x, byte(v))
  3044  	return x
  3045  }
  3046  
  3047  // toType converts from a *rtype to a Type that can be returned
  3048  // to the client of package reflect. In gc, the only concern is that
  3049  // a nil *rtype must be replaced by a nil Type, but in gccgo this
  3050  // function takes care of ensuring that multiple *rtype for the same
  3051  // type are coalesced into a single Type.
  3052  func toType(t *rtype) Type {
  3053  	if t == nil {
  3054  		return nil
  3055  	}
  3056  	return t
  3057  }
  3058  
  3059  type layoutKey struct {
  3060  	ftyp *funcType // function signature
  3061  	rcvr *rtype    // receiver type, or nil if none
  3062  }
  3063  
  3064  type layoutType struct {
  3065  	t         *rtype
  3066  	framePool *sync.Pool
  3067  	abid      abiDesc
  3068  }
  3069  
  3070  var layoutCache sync.Map // map[layoutKey]layoutType
  3071  
  3072  // funcLayout computes a struct type representing the layout of the
  3073  // stack-assigned function arguments and return values for the function
  3074  // type t.
  3075  // If rcvr != nil, rcvr specifies the type of the receiver.
  3076  // The returned type exists only for GC, so we only fill out GC relevant info.
  3077  // Currently, that's just size and the GC program. We also fill in
  3078  // the name for possible debugging use.
  3079  func funcLayout(t *funcType, rcvr *rtype) (frametype *rtype, framePool *sync.Pool, abid abiDesc) {
  3080  	if t.Kind() != Func {
  3081  		panic("reflect: funcLayout of non-func type " + t.String())
  3082  	}
  3083  	if rcvr != nil && rcvr.Kind() == Interface {
  3084  		panic("reflect: funcLayout with interface receiver " + rcvr.String())
  3085  	}
  3086  	k := layoutKey{t, rcvr}
  3087  	if lti, ok := layoutCache.Load(k); ok {
  3088  		lt := lti.(layoutType)
  3089  		return lt.t, lt.framePool, lt.abid
  3090  	}
  3091  
  3092  	// Compute the ABI layout.
  3093  	abid = newAbiDesc(t, rcvr)
  3094  
  3095  	// build dummy rtype holding gc program
  3096  	x := &rtype{
  3097  		align: goarch.PtrSize,
  3098  		// Don't add spill space here; it's only necessary in
  3099  		// reflectcall's frame, not in the allocated frame.
  3100  		// TODO(mknyszek): Remove this comment when register
  3101  		// spill space in the frame is no longer required.
  3102  		size:    align(abid.retOffset+abid.ret.stackBytes, goarch.PtrSize),
  3103  		ptrdata: uintptr(abid.stackPtrs.n) * goarch.PtrSize,
  3104  	}
  3105  	if abid.stackPtrs.n > 0 {
  3106  		x.gcdata = &abid.stackPtrs.data[0]
  3107  	}
  3108  
  3109  	var s string
  3110  	if rcvr != nil {
  3111  		s = "methodargs(" + rcvr.String() + ")(" + t.String() + ")"
  3112  	} else {
  3113  		s = "funcargs(" + t.String() + ")"
  3114  	}
  3115  	x.str = resolveReflectName(newName(s, "", false, false))
  3116  
  3117  	// cache result for future callers
  3118  	framePool = &sync.Pool{New: func() any {
  3119  		return unsafe_New(x)
  3120  	}}
  3121  	lti, _ := layoutCache.LoadOrStore(k, layoutType{
  3122  		t:         x,
  3123  		framePool: framePool,
  3124  		abid:      abid,
  3125  	})
  3126  	lt := lti.(layoutType)
  3127  	return lt.t, lt.framePool, lt.abid
  3128  }
  3129  
  3130  // ifaceIndir reports whether t is stored indirectly in an interface value.
  3131  func ifaceIndir(t *rtype) bool {
  3132  	return t.kind&kindDirectIface == 0
  3133  }
  3134  
  3135  // Note: this type must agree with runtime.bitvector.
  3136  type bitVector struct {
  3137  	n    uint32 // number of bits
  3138  	data []byte
  3139  }
  3140  
  3141  // append a bit to the bitmap.
  3142  func (bv *bitVector) append(bit uint8) {
  3143  	if bv.n%8 == 0 {
  3144  		bv.data = append(bv.data, 0)
  3145  	}
  3146  	bv.data[bv.n/8] |= bit << (bv.n % 8)
  3147  	bv.n++
  3148  }
  3149  
  3150  func addTypeBits(bv *bitVector, offset uintptr, t *rtype) {
  3151  	if t.ptrdata == 0 {
  3152  		return
  3153  	}
  3154  
  3155  	switch Kind(t.kind & kindMask) {
  3156  	case Chan, Func, Map, Pointer, Slice, String, UnsafePointer:
  3157  		// 1 pointer at start of representation
  3158  		for bv.n < uint32(offset/uintptr(goarch.PtrSize)) {
  3159  			bv.append(0)
  3160  		}
  3161  		bv.append(1)
  3162  
  3163  	case Interface:
  3164  		// 2 pointers
  3165  		for bv.n < uint32(offset/uintptr(goarch.PtrSize)) {
  3166  			bv.append(0)
  3167  		}
  3168  		bv.append(1)
  3169  		bv.append(1)
  3170  
  3171  	case Array:
  3172  		// repeat inner type
  3173  		tt := (*arrayType)(unsafe.Pointer(t))
  3174  		for i := 0; i < int(tt.len); i++ {
  3175  			addTypeBits(bv, offset+uintptr(i)*tt.elem.size, tt.elem)
  3176  		}
  3177  
  3178  	case Struct:
  3179  		// apply fields
  3180  		tt := (*structType)(unsafe.Pointer(t))
  3181  		for i := range tt.fields {
  3182  			f := &tt.fields[i]
  3183  			addTypeBits(bv, offset+f.offset, f.typ)
  3184  		}
  3185  	}
  3186  }
  3187  

View as plain text