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