Source file src/reflect/type.go

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