github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/reflect/type.go (about)

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