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