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

View as plain text