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