github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/reflect/type.go (about)

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