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