...

Source file src/reflect/type.go

Documentation: reflect

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

View as plain text