github.com/reiver/go@v0.0.0-20150109200633-1d0c7792f172/src/reflect/type.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package reflect implements run-time reflection, allowing a program to
     6  // manipulate objects with arbitrary types.  The typical use is to take a value
     7  // with static type interface{} and extract its dynamic type information by
     8  // calling TypeOf, which returns a Type.
     9  //
    10  // A call to ValueOf returns a Value representing the run-time data.
    11  // Zero takes a Type and returns a Value representing a zero value
    12  // for that type.
    13  //
    14  // See "The Laws of Reflection" for an introduction to reflection in Go:
    15  // http://golang.org/doc/articles/laws_of_reflection.html
    16  package reflect
    17  
    18  import (
    19  	"runtime"
    20  	"strconv"
    21  	"sync"
    22  	"unsafe"
    23  )
    24  
    25  // Type is the representation of a Go type.
    26  //
    27  // Not all methods apply to all kinds of types.  Restrictions,
    28  // if any, are noted in the documentation for each method.
    29  // Use the Kind method to find out the kind of type before
    30  // calling kind-specific methods.  Calling a method
    31  // inappropriate to the kind of type causes a run-time panic.
    32  type Type interface {
    33  	// Methods applicable to all types.
    34  
    35  	// Align returns the alignment in bytes of a value of
    36  	// this type when allocated in memory.
    37  	Align() int
    38  
    39  	// FieldAlign returns the alignment in bytes of a value of
    40  	// this type when used as a field in a struct.
    41  	FieldAlign() int
    42  
    43  	// Method returns the i'th method in the type's method set.
    44  	// It panics if i is not in the range [0, NumMethod()).
    45  	//
    46  	// For a non-interface type T or *T, the returned Method's Type and Func
    47  	// fields describe a function whose first argument is the receiver.
    48  	//
    49  	// For an interface type, the returned Method's Type field gives the
    50  	// method signature, without a receiver, and the Func field is nil.
    51  	Method(int) Method
    52  
    53  	// MethodByName returns the method with that name in the type's
    54  	// method set and a boolean indicating if the method was found.
    55  	//
    56  	// For a non-interface type T or *T, the returned Method's Type and Func
    57  	// fields describe a function whose first argument is the receiver.
    58  	//
    59  	// For an interface type, the returned Method's Type field gives the
    60  	// method signature, without a receiver, and the Func field is nil.
    61  	MethodByName(string) (Method, bool)
    62  
    63  	// NumMethod returns the number of methods in the type's method set.
    64  	NumMethod() int
    65  
    66  	// Name returns the type's name within its package.
    67  	// It returns an empty string for unnamed types.
    68  	Name() string
    69  
    70  	// PkgPath returns a named type's package path, that is, the import path
    71  	// that uniquely identifies the package, such as "encoding/base64".
    72  	// If the type was predeclared (string, error) or unnamed (*T, struct{}, []int),
    73  	// the package path will be the empty string.
    74  	PkgPath() string
    75  
    76  	// Size returns the number of bytes needed to store
    77  	// a value of the given type; it is analogous to unsafe.Sizeof.
    78  	Size() uintptr
    79  
    80  	// String returns a string representation of the type.
    81  	// The string representation may use shortened package names
    82  	// (e.g., base64 instead of "encoding/base64") and is not
    83  	// guaranteed to be unique among types.  To test for equality,
    84  	// compare the Types directly.
    85  	String() string
    86  
    87  	// Kind returns the specific kind of this type.
    88  	Kind() Kind
    89  
    90  	// Implements returns true if the type implements the interface type u.
    91  	Implements(u Type) bool
    92  
    93  	// AssignableTo returns true if a value of the type is assignable to type u.
    94  	AssignableTo(u Type) bool
    95  
    96  	// ConvertibleTo returns true if a value of the type is convertible to type u.
    97  	ConvertibleTo(u Type) bool
    98  
    99  	// Comparable returns true if values of this type are comparable.
   100  	Comparable() bool
   101  
   102  	// Methods applicable only to some types, depending on Kind.
   103  	// The methods allowed for each kind are:
   104  	//
   105  	//	Int*, Uint*, Float*, Complex*: Bits
   106  	//	Array: Elem, Len
   107  	//	Chan: ChanDir, Elem
   108  	//	Func: In, NumIn, Out, NumOut, IsVariadic.
   109  	//	Map: Key, Elem
   110  	//	Ptr: Elem
   111  	//	Slice: Elem
   112  	//	Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
   113  
   114  	// Bits returns the size of the type in bits.
   115  	// It panics if the type's Kind is not one of the
   116  	// sized or unsized Int, Uint, Float, or Complex kinds.
   117  	Bits() int
   118  
   119  	// ChanDir returns a channel type's direction.
   120  	// It panics if the type's Kind is not Chan.
   121  	ChanDir() ChanDir
   122  
   123  	// IsVariadic returns true if a function type's final input parameter
   124  	// is a "..." parameter.  If so, t.In(t.NumIn() - 1) returns the parameter's
   125  	// implicit actual type []T.
   126  	//
   127  	// For concreteness, if t represents func(x int, y ... float64), then
   128  	//
   129  	//	t.NumIn() == 2
   130  	//	t.In(0) is the reflect.Type for "int"
   131  	//	t.In(1) is the reflect.Type for "[]float64"
   132  	//	t.IsVariadic() == true
   133  	//
   134  	// IsVariadic panics if the type's Kind is not Func.
   135  	IsVariadic() bool
   136  
   137  	// Elem returns a type's element type.
   138  	// It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
   139  	Elem() Type
   140  
   141  	// Field returns a struct type's i'th field.
   142  	// It panics if the type's Kind is not Struct.
   143  	// It panics if i is not in the range [0, NumField()).
   144  	Field(i int) StructField
   145  
   146  	// FieldByIndex returns the nested field corresponding
   147  	// to the index sequence.  It is equivalent to calling Field
   148  	// successively for each index i.
   149  	// It panics if the type's Kind is not Struct.
   150  	FieldByIndex(index []int) StructField
   151  
   152  	// FieldByName returns the struct field with the given name
   153  	// and a boolean indicating if the field was found.
   154  	FieldByName(name string) (StructField, bool)
   155  
   156  	// FieldByNameFunc returns the first struct field with a name
   157  	// that satisfies the match function and a boolean indicating if
   158  	// the field was found.
   159  	FieldByNameFunc(match func(string) bool) (StructField, bool)
   160  
   161  	// In returns the type of a function type's i'th input parameter.
   162  	// It panics if the type's Kind is not Func.
   163  	// It panics if i is not in the range [0, NumIn()).
   164  	In(i int) Type
   165  
   166  	// Key returns a map type's key type.
   167  	// It panics if the type's Kind is not Map.
   168  	Key() Type
   169  
   170  	// Len returns an array type's length.
   171  	// It panics if the type's Kind is not Array.
   172  	Len() int
   173  
   174  	// NumField returns a struct type's field count.
   175  	// It panics if the type's Kind is not Struct.
   176  	NumField() int
   177  
   178  	// NumIn returns a function type's input parameter count.
   179  	// It panics if the type's Kind is not Func.
   180  	NumIn() int
   181  
   182  	// NumOut returns a function type's output parameter count.
   183  	// It panics if the type's Kind is not Func.
   184  	NumOut() int
   185  
   186  	// Out returns the type of a function type's i'th output parameter.
   187  	// It panics if the type's Kind is not Func.
   188  	// It panics if i is not in the range [0, NumOut()).
   189  	Out(i int) Type
   190  
   191  	common() *rtype
   192  	uncommon() *uncommonType
   193  }
   194  
   195  // BUG(rsc): FieldByName and related functions consider struct field names to be equal
   196  // if the names are equal, even if they are unexported names originating
   197  // in different packages. The practical effect of this is that the result of
   198  // t.FieldByName("x") is not well defined if the struct type t contains
   199  // multiple fields named x (embedded from different packages).
   200  // FieldByName may return one of the fields named x or may report that there are none.
   201  // See golang.org/issue/4876 for more details.
   202  
   203  /*
   204   * These data structures are known to the compiler (../../cmd/gc/reflect.c).
   205   * A few are known to ../runtime/type.go to convey to debuggers.
   206   * They are also known to ../runtime/type.h.
   207   */
   208  
   209  // A Kind represents the specific kind of type that a Type represents.
   210  // The zero Kind is not a valid kind.
   211  type Kind uint
   212  
   213  const (
   214  	Invalid Kind = iota
   215  	Bool
   216  	Int
   217  	Int8
   218  	Int16
   219  	Int32
   220  	Int64
   221  	Uint
   222  	Uint8
   223  	Uint16
   224  	Uint32
   225  	Uint64
   226  	Uintptr
   227  	Float32
   228  	Float64
   229  	Complex64
   230  	Complex128
   231  	Array
   232  	Chan
   233  	Func
   234  	Interface
   235  	Map
   236  	Ptr
   237  	Slice
   238  	String
   239  	Struct
   240  	UnsafePointer
   241  )
   242  
   243  // rtype is the common implementation of most values.
   244  // It is embedded in other, public struct types, but always
   245  // with a unique tag like `reflect:"array"` or `reflect:"ptr"`
   246  // so that code cannot convert from, say, *arrayType to *ptrType.
   247  type rtype struct {
   248  	size          uintptr
   249  	hash          uint32            // hash of type; avoids computation in hash tables
   250  	_             uint8             // unused/padding
   251  	align         uint8             // alignment of variable with this type
   252  	fieldAlign    uint8             // alignment of struct field with this type
   253  	kind          uint8             // enumeration for C
   254  	alg           *typeAlg          // algorithm table
   255  	gc            [2]unsafe.Pointer // garbage collection data
   256  	string        *string           // string form; unnecessary but undeniably useful
   257  	*uncommonType                   // (relatively) uncommon fields
   258  	ptrToThis     *rtype            // type for pointer to this type, if used in binary or has methods
   259  	zero          unsafe.Pointer    // pointer to zero value
   260  }
   261  
   262  // a copy of runtime.typeAlg
   263  type typeAlg struct {
   264  	// function for hashing objects of this type
   265  	// (ptr to object, size, seed) -> hash
   266  	hash func(unsafe.Pointer, uintptr, uintptr) uintptr
   267  	// function for comparing objects of this type
   268  	// (ptr to object A, ptr to object B, size) -> ==?
   269  	equal func(unsafe.Pointer, unsafe.Pointer, uintptr) bool
   270  }
   271  
   272  // Method on non-interface type
   273  type method struct {
   274  	name    *string        // name of method
   275  	pkgPath *string        // nil for exported Names; otherwise import path
   276  	mtyp    *rtype         // method type (without receiver)
   277  	typ     *rtype         // .(*FuncType) underneath (with receiver)
   278  	ifn     unsafe.Pointer // fn used in interface call (one-word receiver)
   279  	tfn     unsafe.Pointer // fn used for normal method call
   280  }
   281  
   282  // uncommonType is present only for types with names or methods
   283  // (if T is a named type, the uncommonTypes for T and *T have methods).
   284  // Using a pointer to this struct reduces the overall size required
   285  // to describe an unnamed type with no methods.
   286  type uncommonType struct {
   287  	name    *string  // name of type
   288  	pkgPath *string  // import path; nil for built-in types like int, string
   289  	methods []method // methods associated with type
   290  }
   291  
   292  // ChanDir represents a channel type's direction.
   293  type ChanDir int
   294  
   295  const (
   296  	RecvDir ChanDir             = 1 << iota // <-chan
   297  	SendDir                                 // chan<-
   298  	BothDir = RecvDir | SendDir             // chan
   299  )
   300  
   301  // arrayType represents a fixed array type.
   302  type arrayType struct {
   303  	rtype `reflect:"array"`
   304  	elem  *rtype // array element type
   305  	slice *rtype // slice type
   306  	len   uintptr
   307  }
   308  
   309  // chanType represents a channel type.
   310  type chanType struct {
   311  	rtype `reflect:"chan"`
   312  	elem  *rtype  // channel element type
   313  	dir   uintptr // channel direction (ChanDir)
   314  }
   315  
   316  // funcType represents a function type.
   317  type funcType struct {
   318  	rtype     `reflect:"func"`
   319  	dotdotdot bool     // last input parameter is ...
   320  	in        []*rtype // input parameter types
   321  	out       []*rtype // output parameter types
   322  }
   323  
   324  // imethod represents a method on an interface type
   325  type imethod struct {
   326  	name    *string // name of method
   327  	pkgPath *string // nil for exported Names; otherwise import path
   328  	typ     *rtype  // .(*FuncType) underneath
   329  }
   330  
   331  // interfaceType represents an interface type.
   332  type interfaceType struct {
   333  	rtype   `reflect:"interface"`
   334  	methods []imethod // sorted by hash
   335  }
   336  
   337  // mapType represents a map type.
   338  type mapType struct {
   339  	rtype         `reflect:"map"`
   340  	key           *rtype // map key type
   341  	elem          *rtype // map element (value) type
   342  	bucket        *rtype // internal bucket structure
   343  	hmap          *rtype // internal map header
   344  	keysize       uint8  // size of key slot
   345  	indirectkey   uint8  // store ptr to key instead of key itself
   346  	valuesize     uint8  // size of value slot
   347  	indirectvalue uint8  // store ptr to value instead of value itself
   348  	bucketsize    uint16 // size of bucket
   349  	reflexivekey  bool   // true if k==k for all keys
   350  }
   351  
   352  // ptrType represents a pointer type.
   353  type ptrType struct {
   354  	rtype `reflect:"ptr"`
   355  	elem  *rtype // pointer element (pointed at) type
   356  }
   357  
   358  // sliceType represents a slice type.
   359  type sliceType struct {
   360  	rtype `reflect:"slice"`
   361  	elem  *rtype // slice element type
   362  }
   363  
   364  // Struct field
   365  type structField struct {
   366  	name    *string // nil for embedded fields
   367  	pkgPath *string // nil for exported Names; otherwise import path
   368  	typ     *rtype  // type of field
   369  	tag     *string // nil if no tag
   370  	offset  uintptr // byte offset of field within struct
   371  }
   372  
   373  // structType represents a struct type.
   374  type structType struct {
   375  	rtype  `reflect:"struct"`
   376  	fields []structField // sorted by offset
   377  }
   378  
   379  /*
   380   * The compiler knows the exact layout of all the data structures above.
   381   * The compiler does not know about the data structures and methods below.
   382   */
   383  
   384  // Method represents a single method.
   385  type Method struct {
   386  	// Name is the method name.
   387  	// PkgPath is the package path that qualifies a lower case (unexported)
   388  	// method name.  It is empty for upper case (exported) method names.
   389  	// The combination of PkgPath and Name uniquely identifies a method
   390  	// in a method set.
   391  	// See http://golang.org/ref/spec#Uniqueness_of_identifiers
   392  	Name    string
   393  	PkgPath string
   394  
   395  	Type  Type  // method type
   396  	Func  Value // func with receiver as first argument
   397  	Index int   // index for Type.Method
   398  }
   399  
   400  const (
   401  	kindDirectIface = 1 << 5
   402  	kindGCProg      = 1 << 6 // Type.gc points to GC program
   403  	kindNoPointers  = 1 << 7
   404  	kindMask        = (1 << 5) - 1
   405  )
   406  
   407  func (k Kind) String() string {
   408  	if int(k) < len(kindNames) {
   409  		return kindNames[k]
   410  	}
   411  	return "kind" + strconv.Itoa(int(k))
   412  }
   413  
   414  var kindNames = []string{
   415  	Invalid:       "invalid",
   416  	Bool:          "bool",
   417  	Int:           "int",
   418  	Int8:          "int8",
   419  	Int16:         "int16",
   420  	Int32:         "int32",
   421  	Int64:         "int64",
   422  	Uint:          "uint",
   423  	Uint8:         "uint8",
   424  	Uint16:        "uint16",
   425  	Uint32:        "uint32",
   426  	Uint64:        "uint64",
   427  	Uintptr:       "uintptr",
   428  	Float32:       "float32",
   429  	Float64:       "float64",
   430  	Complex64:     "complex64",
   431  	Complex128:    "complex128",
   432  	Array:         "array",
   433  	Chan:          "chan",
   434  	Func:          "func",
   435  	Interface:     "interface",
   436  	Map:           "map",
   437  	Ptr:           "ptr",
   438  	Slice:         "slice",
   439  	String:        "string",
   440  	Struct:        "struct",
   441  	UnsafePointer: "unsafe.Pointer",
   442  }
   443  
   444  func (t *uncommonType) uncommon() *uncommonType {
   445  	return t
   446  }
   447  
   448  func (t *uncommonType) PkgPath() string {
   449  	if t == nil || t.pkgPath == nil {
   450  		return ""
   451  	}
   452  	return *t.pkgPath
   453  }
   454  
   455  func (t *uncommonType) Name() string {
   456  	if t == nil || t.name == nil {
   457  		return ""
   458  	}
   459  	return *t.name
   460  }
   461  
   462  func (t *rtype) String() string { return *t.string }
   463  
   464  func (t *rtype) Size() uintptr { return t.size }
   465  
   466  func (t *rtype) Bits() int {
   467  	if t == nil {
   468  		panic("reflect: Bits of nil Type")
   469  	}
   470  	k := t.Kind()
   471  	if k < Int || k > Complex128 {
   472  		panic("reflect: Bits of non-arithmetic Type " + t.String())
   473  	}
   474  	return int(t.size) * 8
   475  }
   476  
   477  func (t *rtype) Align() int { return int(t.align) }
   478  
   479  func (t *rtype) FieldAlign() int { return int(t.fieldAlign) }
   480  
   481  func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
   482  
   483  func (t *rtype) pointers() bool { return t.kind&kindNoPointers == 0 }
   484  
   485  func (t *rtype) common() *rtype { return t }
   486  
   487  func (t *uncommonType) Method(i int) (m Method) {
   488  	if t == nil || i < 0 || i >= len(t.methods) {
   489  		panic("reflect: Method index out of range")
   490  	}
   491  	p := &t.methods[i]
   492  	if p.name != nil {
   493  		m.Name = *p.name
   494  	}
   495  	fl := flag(Func)
   496  	if p.pkgPath != nil {
   497  		m.PkgPath = *p.pkgPath
   498  		fl |= flagRO
   499  	}
   500  	mt := p.typ
   501  	m.Type = mt
   502  	fn := unsafe.Pointer(&p.tfn)
   503  	m.Func = Value{mt, fn, fl}
   504  	m.Index = i
   505  	return
   506  }
   507  
   508  func (t *uncommonType) NumMethod() int {
   509  	if t == nil {
   510  		return 0
   511  	}
   512  	return len(t.methods)
   513  }
   514  
   515  func (t *uncommonType) MethodByName(name string) (m Method, ok bool) {
   516  	if t == nil {
   517  		return
   518  	}
   519  	var p *method
   520  	for i := range t.methods {
   521  		p = &t.methods[i]
   522  		if p.name != nil && *p.name == name {
   523  			return t.Method(i), true
   524  		}
   525  	}
   526  	return
   527  }
   528  
   529  // TODO(rsc): 6g supplies these, but they are not
   530  // as efficient as they could be: they have commonType
   531  // as the receiver instead of *rtype.
   532  func (t *rtype) NumMethod() int {
   533  	if t.Kind() == Interface {
   534  		tt := (*interfaceType)(unsafe.Pointer(t))
   535  		return tt.NumMethod()
   536  	}
   537  	return t.uncommonType.NumMethod()
   538  }
   539  
   540  func (t *rtype) Method(i int) (m Method) {
   541  	if t.Kind() == Interface {
   542  		tt := (*interfaceType)(unsafe.Pointer(t))
   543  		return tt.Method(i)
   544  	}
   545  	return t.uncommonType.Method(i)
   546  }
   547  
   548  func (t *rtype) MethodByName(name string) (m Method, ok bool) {
   549  	if t.Kind() == Interface {
   550  		tt := (*interfaceType)(unsafe.Pointer(t))
   551  		return tt.MethodByName(name)
   552  	}
   553  	return t.uncommonType.MethodByName(name)
   554  }
   555  
   556  func (t *rtype) PkgPath() string {
   557  	return t.uncommonType.PkgPath()
   558  }
   559  
   560  func (t *rtype) Name() string {
   561  	return t.uncommonType.Name()
   562  }
   563  
   564  func (t *rtype) ChanDir() ChanDir {
   565  	if t.Kind() != Chan {
   566  		panic("reflect: ChanDir of non-chan type")
   567  	}
   568  	tt := (*chanType)(unsafe.Pointer(t))
   569  	return ChanDir(tt.dir)
   570  }
   571  
   572  func (t *rtype) IsVariadic() bool {
   573  	if t.Kind() != Func {
   574  		panic("reflect: IsVariadic of non-func type")
   575  	}
   576  	tt := (*funcType)(unsafe.Pointer(t))
   577  	return tt.dotdotdot
   578  }
   579  
   580  func (t *rtype) Elem() Type {
   581  	switch t.Kind() {
   582  	case Array:
   583  		tt := (*arrayType)(unsafe.Pointer(t))
   584  		return toType(tt.elem)
   585  	case Chan:
   586  		tt := (*chanType)(unsafe.Pointer(t))
   587  		return toType(tt.elem)
   588  	case Map:
   589  		tt := (*mapType)(unsafe.Pointer(t))
   590  		return toType(tt.elem)
   591  	case Ptr:
   592  		tt := (*ptrType)(unsafe.Pointer(t))
   593  		return toType(tt.elem)
   594  	case Slice:
   595  		tt := (*sliceType)(unsafe.Pointer(t))
   596  		return toType(tt.elem)
   597  	}
   598  	panic("reflect: Elem of invalid type")
   599  }
   600  
   601  func (t *rtype) Field(i int) StructField {
   602  	if t.Kind() != Struct {
   603  		panic("reflect: Field of non-struct type")
   604  	}
   605  	tt := (*structType)(unsafe.Pointer(t))
   606  	return tt.Field(i)
   607  }
   608  
   609  func (t *rtype) FieldByIndex(index []int) StructField {
   610  	if t.Kind() != Struct {
   611  		panic("reflect: FieldByIndex of non-struct type")
   612  	}
   613  	tt := (*structType)(unsafe.Pointer(t))
   614  	return tt.FieldByIndex(index)
   615  }
   616  
   617  func (t *rtype) FieldByName(name string) (StructField, bool) {
   618  	if t.Kind() != Struct {
   619  		panic("reflect: FieldByName of non-struct type")
   620  	}
   621  	tt := (*structType)(unsafe.Pointer(t))
   622  	return tt.FieldByName(name)
   623  }
   624  
   625  func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
   626  	if t.Kind() != Struct {
   627  		panic("reflect: FieldByNameFunc of non-struct type")
   628  	}
   629  	tt := (*structType)(unsafe.Pointer(t))
   630  	return tt.FieldByNameFunc(match)
   631  }
   632  
   633  func (t *rtype) In(i int) Type {
   634  	if t.Kind() != Func {
   635  		panic("reflect: In of non-func type")
   636  	}
   637  	tt := (*funcType)(unsafe.Pointer(t))
   638  	return toType(tt.in[i])
   639  }
   640  
   641  func (t *rtype) Key() Type {
   642  	if t.Kind() != Map {
   643  		panic("reflect: Key of non-map type")
   644  	}
   645  	tt := (*mapType)(unsafe.Pointer(t))
   646  	return toType(tt.key)
   647  }
   648  
   649  func (t *rtype) Len() int {
   650  	if t.Kind() != Array {
   651  		panic("reflect: Len of non-array type")
   652  	}
   653  	tt := (*arrayType)(unsafe.Pointer(t))
   654  	return int(tt.len)
   655  }
   656  
   657  func (t *rtype) NumField() int {
   658  	if t.Kind() != Struct {
   659  		panic("reflect: NumField of non-struct type")
   660  	}
   661  	tt := (*structType)(unsafe.Pointer(t))
   662  	return len(tt.fields)
   663  }
   664  
   665  func (t *rtype) NumIn() int {
   666  	if t.Kind() != Func {
   667  		panic("reflect: NumIn of non-func type")
   668  	}
   669  	tt := (*funcType)(unsafe.Pointer(t))
   670  	return len(tt.in)
   671  }
   672  
   673  func (t *rtype) NumOut() int {
   674  	if t.Kind() != Func {
   675  		panic("reflect: NumOut of non-func type")
   676  	}
   677  	tt := (*funcType)(unsafe.Pointer(t))
   678  	return len(tt.out)
   679  }
   680  
   681  func (t *rtype) Out(i int) Type {
   682  	if t.Kind() != Func {
   683  		panic("reflect: Out of non-func type")
   684  	}
   685  	tt := (*funcType)(unsafe.Pointer(t))
   686  	return toType(tt.out[i])
   687  }
   688  
   689  func (d ChanDir) String() string {
   690  	switch d {
   691  	case SendDir:
   692  		return "chan<-"
   693  	case RecvDir:
   694  		return "<-chan"
   695  	case BothDir:
   696  		return "chan"
   697  	}
   698  	return "ChanDir" + strconv.Itoa(int(d))
   699  }
   700  
   701  // Method returns the i'th method in the type's method set.
   702  func (t *interfaceType) Method(i int) (m Method) {
   703  	if i < 0 || i >= len(t.methods) {
   704  		return
   705  	}
   706  	p := &t.methods[i]
   707  	m.Name = *p.name
   708  	if p.pkgPath != nil {
   709  		m.PkgPath = *p.pkgPath
   710  	}
   711  	m.Type = toType(p.typ)
   712  	m.Index = i
   713  	return
   714  }
   715  
   716  // NumMethod returns the number of interface methods in the type's method set.
   717  func (t *interfaceType) NumMethod() int { return len(t.methods) }
   718  
   719  // MethodByName method with the given name in the type's method set.
   720  func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
   721  	if t == nil {
   722  		return
   723  	}
   724  	var p *imethod
   725  	for i := range t.methods {
   726  		p = &t.methods[i]
   727  		if *p.name == name {
   728  			return t.Method(i), true
   729  		}
   730  	}
   731  	return
   732  }
   733  
   734  // A StructField describes a single field in a struct.
   735  type StructField struct {
   736  	// Name is the field name.
   737  	// PkgPath is the package path that qualifies a lower case (unexported)
   738  	// field name.  It is empty for upper case (exported) field names.
   739  	// See http://golang.org/ref/spec#Uniqueness_of_identifiers
   740  	Name    string
   741  	PkgPath string
   742  
   743  	Type      Type      // field type
   744  	Tag       StructTag // field tag string
   745  	Offset    uintptr   // offset within struct, in bytes
   746  	Index     []int     // index sequence for Type.FieldByIndex
   747  	Anonymous bool      // is an embedded field
   748  }
   749  
   750  // A StructTag is the tag string in a struct field.
   751  //
   752  // By convention, tag strings are a concatenation of
   753  // optionally space-separated key:"value" pairs.
   754  // Each key is a non-empty string consisting of non-control
   755  // characters other than space (U+0020 ' '), quote (U+0022 '"'),
   756  // and colon (U+003A ':').  Each value is quoted using U+0022 '"'
   757  // characters and Go string literal syntax.
   758  type StructTag string
   759  
   760  // Get returns the value associated with key in the tag string.
   761  // If there is no such key in the tag, Get returns the empty string.
   762  // If the tag does not have the conventional format, the value
   763  // returned by Get is unspecified.
   764  func (tag StructTag) Get(key string) string {
   765  	for tag != "" {
   766  		// skip leading space
   767  		i := 0
   768  		for i < len(tag) && tag[i] == ' ' {
   769  			i++
   770  		}
   771  		tag = tag[i:]
   772  		if tag == "" {
   773  			break
   774  		}
   775  
   776  		// scan to colon.
   777  		// a space or a quote is a syntax error
   778  		i = 0
   779  		for i < len(tag) && tag[i] != ' ' && tag[i] != ':' && tag[i] != '"' {
   780  			i++
   781  		}
   782  		if i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
   783  			break
   784  		}
   785  		name := string(tag[:i])
   786  		tag = tag[i+1:]
   787  
   788  		// scan quoted string to find value
   789  		i = 1
   790  		for i < len(tag) && tag[i] != '"' {
   791  			if tag[i] == '\\' {
   792  				i++
   793  			}
   794  			i++
   795  		}
   796  		if i >= len(tag) {
   797  			break
   798  		}
   799  		qvalue := string(tag[:i+1])
   800  		tag = tag[i+1:]
   801  
   802  		if key == name {
   803  			value, _ := strconv.Unquote(qvalue)
   804  			return value
   805  		}
   806  	}
   807  	return ""
   808  }
   809  
   810  // Field returns the i'th struct field.
   811  func (t *structType) Field(i int) (f StructField) {
   812  	if i < 0 || i >= len(t.fields) {
   813  		return
   814  	}
   815  	p := &t.fields[i]
   816  	f.Type = toType(p.typ)
   817  	if p.name != nil {
   818  		f.Name = *p.name
   819  	} else {
   820  		t := f.Type
   821  		if t.Kind() == Ptr {
   822  			t = t.Elem()
   823  		}
   824  		f.Name = t.Name()
   825  		f.Anonymous = true
   826  	}
   827  	if p.pkgPath != nil {
   828  		f.PkgPath = *p.pkgPath
   829  	}
   830  	if p.tag != nil {
   831  		f.Tag = StructTag(*p.tag)
   832  	}
   833  	f.Offset = p.offset
   834  
   835  	// NOTE(rsc): This is the only allocation in the interface
   836  	// presented by a reflect.Type.  It would be nice to avoid,
   837  	// at least in the common cases, but we need to make sure
   838  	// that misbehaving clients of reflect cannot affect other
   839  	// uses of reflect.  One possibility is CL 5371098, but we
   840  	// postponed that ugliness until there is a demonstrated
   841  	// need for the performance.  This is issue 2320.
   842  	f.Index = []int{i}
   843  	return
   844  }
   845  
   846  // TODO(gri): Should there be an error/bool indicator if the index
   847  //            is wrong for FieldByIndex?
   848  
   849  // FieldByIndex returns the nested field corresponding to index.
   850  func (t *structType) FieldByIndex(index []int) (f StructField) {
   851  	f.Type = toType(&t.rtype)
   852  	for i, x := range index {
   853  		if i > 0 {
   854  			ft := f.Type
   855  			if ft.Kind() == Ptr && ft.Elem().Kind() == Struct {
   856  				ft = ft.Elem()
   857  			}
   858  			f.Type = ft
   859  		}
   860  		f = f.Type.Field(x)
   861  	}
   862  	return
   863  }
   864  
   865  // A fieldScan represents an item on the fieldByNameFunc scan work list.
   866  type fieldScan struct {
   867  	typ   *structType
   868  	index []int
   869  }
   870  
   871  // FieldByNameFunc returns the struct field with a name that satisfies the
   872  // match function and a boolean to indicate if the field was found.
   873  func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) {
   874  	// This uses the same condition that the Go language does: there must be a unique instance
   875  	// of the match at a given depth level. If there are multiple instances of a match at the
   876  	// same depth, they annihilate each other and inhibit any possible match at a lower level.
   877  	// The algorithm is breadth first search, one depth level at a time.
   878  
   879  	// The current and next slices are work queues:
   880  	// current lists the fields to visit on this depth level,
   881  	// and next lists the fields on the next lower level.
   882  	current := []fieldScan{}
   883  	next := []fieldScan{{typ: t}}
   884  
   885  	// nextCount records the number of times an embedded type has been
   886  	// encountered and considered for queueing in the 'next' slice.
   887  	// We only queue the first one, but we increment the count on each.
   888  	// If a struct type T can be reached more than once at a given depth level,
   889  	// then it annihilates itself and need not be considered at all when we
   890  	// process that next depth level.
   891  	var nextCount map[*structType]int
   892  
   893  	// visited records the structs that have been considered already.
   894  	// Embedded pointer fields can create cycles in the graph of
   895  	// reachable embedded types; visited avoids following those cycles.
   896  	// It also avoids duplicated effort: if we didn't find the field in an
   897  	// embedded type T at level 2, we won't find it in one at level 4 either.
   898  	visited := map[*structType]bool{}
   899  
   900  	for len(next) > 0 {
   901  		current, next = next, current[:0]
   902  		count := nextCount
   903  		nextCount = nil
   904  
   905  		// Process all the fields at this depth, now listed in 'current'.
   906  		// The loop queues embedded fields found in 'next', for processing during the next
   907  		// iteration. The multiplicity of the 'current' field counts is recorded
   908  		// in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
   909  		for _, scan := range current {
   910  			t := scan.typ
   911  			if visited[t] {
   912  				// We've looked through this type before, at a higher level.
   913  				// That higher level would shadow the lower level we're now at,
   914  				// so this one can't be useful to us. Ignore it.
   915  				continue
   916  			}
   917  			visited[t] = true
   918  			for i := range t.fields {
   919  				f := &t.fields[i]
   920  				// Find name and type for field f.
   921  				var fname string
   922  				var ntyp *rtype
   923  				if f.name != nil {
   924  					fname = *f.name
   925  				} else {
   926  					// Anonymous field of type T or *T.
   927  					// Name taken from type.
   928  					ntyp = f.typ
   929  					if ntyp.Kind() == Ptr {
   930  						ntyp = ntyp.Elem().common()
   931  					}
   932  					fname = ntyp.Name()
   933  				}
   934  
   935  				// Does it match?
   936  				if match(fname) {
   937  					// Potential match
   938  					if count[t] > 1 || ok {
   939  						// Name appeared multiple times at this level: annihilate.
   940  						return StructField{}, false
   941  					}
   942  					result = t.Field(i)
   943  					result.Index = nil
   944  					result.Index = append(result.Index, scan.index...)
   945  					result.Index = append(result.Index, i)
   946  					ok = true
   947  					continue
   948  				}
   949  
   950  				// Queue embedded struct fields for processing with next level,
   951  				// but only if we haven't seen a match yet at this level and only
   952  				// if the embedded types haven't already been queued.
   953  				if ok || ntyp == nil || ntyp.Kind() != Struct {
   954  					continue
   955  				}
   956  				styp := (*structType)(unsafe.Pointer(ntyp))
   957  				if nextCount[styp] > 0 {
   958  					nextCount[styp] = 2 // exact multiple doesn't matter
   959  					continue
   960  				}
   961  				if nextCount == nil {
   962  					nextCount = map[*structType]int{}
   963  				}
   964  				nextCount[styp] = 1
   965  				if count[t] > 1 {
   966  					nextCount[styp] = 2 // exact multiple doesn't matter
   967  				}
   968  				var index []int
   969  				index = append(index, scan.index...)
   970  				index = append(index, i)
   971  				next = append(next, fieldScan{styp, index})
   972  			}
   973  		}
   974  		if ok {
   975  			break
   976  		}
   977  	}
   978  	return
   979  }
   980  
   981  // FieldByName returns the struct field with the given name
   982  // and a boolean to indicate if the field was found.
   983  func (t *structType) FieldByName(name string) (f StructField, present bool) {
   984  	// Quick check for top-level name, or struct without anonymous fields.
   985  	hasAnon := false
   986  	if name != "" {
   987  		for i := range t.fields {
   988  			tf := &t.fields[i]
   989  			if tf.name == nil {
   990  				hasAnon = true
   991  				continue
   992  			}
   993  			if *tf.name == name {
   994  				return t.Field(i), true
   995  			}
   996  		}
   997  	}
   998  	if !hasAnon {
   999  		return
  1000  	}
  1001  	return t.FieldByNameFunc(func(s string) bool { return s == name })
  1002  }
  1003  
  1004  // TypeOf returns the reflection Type of the value in the interface{}.
  1005  // TypeOf(nil) returns nil.
  1006  func TypeOf(i interface{}) Type {
  1007  	eface := *(*emptyInterface)(unsafe.Pointer(&i))
  1008  	return toType(eface.typ)
  1009  }
  1010  
  1011  // ptrMap is the cache for PtrTo.
  1012  var ptrMap struct {
  1013  	sync.RWMutex
  1014  	m map[*rtype]*ptrType
  1015  }
  1016  
  1017  // PtrTo returns the pointer type with element t.
  1018  // For example, if t represents type Foo, PtrTo(t) represents *Foo.
  1019  func PtrTo(t Type) Type {
  1020  	return t.(*rtype).ptrTo()
  1021  }
  1022  
  1023  func (t *rtype) ptrTo() *rtype {
  1024  	if p := t.ptrToThis; p != nil {
  1025  		return p
  1026  	}
  1027  
  1028  	// Otherwise, synthesize one.
  1029  	// This only happens for pointers with no methods.
  1030  	// We keep the mapping in a map on the side, because
  1031  	// this operation is rare and a separate map lets us keep
  1032  	// the type structures in read-only memory.
  1033  	ptrMap.RLock()
  1034  	if m := ptrMap.m; m != nil {
  1035  		if p := m[t]; p != nil {
  1036  			ptrMap.RUnlock()
  1037  			return &p.rtype
  1038  		}
  1039  	}
  1040  	ptrMap.RUnlock()
  1041  	ptrMap.Lock()
  1042  	if ptrMap.m == nil {
  1043  		ptrMap.m = make(map[*rtype]*ptrType)
  1044  	}
  1045  	p := ptrMap.m[t]
  1046  	if p != nil {
  1047  		// some other goroutine won the race and created it
  1048  		ptrMap.Unlock()
  1049  		return &p.rtype
  1050  	}
  1051  
  1052  	// Create a new ptrType starting with the description
  1053  	// of an *unsafe.Pointer.
  1054  	p = new(ptrType)
  1055  	var iptr interface{} = (*unsafe.Pointer)(nil)
  1056  	prototype := *(**ptrType)(unsafe.Pointer(&iptr))
  1057  	*p = *prototype
  1058  
  1059  	s := "*" + *t.string
  1060  	p.string = &s
  1061  
  1062  	// For the type structures linked into the binary, the
  1063  	// compiler provides a good hash of the string.
  1064  	// Create a good hash for the new string by using
  1065  	// the FNV-1 hash's mixing function to combine the
  1066  	// old hash and the new "*".
  1067  	p.hash = fnv1(t.hash, '*')
  1068  
  1069  	p.uncommonType = nil
  1070  	p.ptrToThis = nil
  1071  	p.zero = unsafe.Pointer(&make([]byte, p.size)[0])
  1072  	p.elem = t
  1073  
  1074  	ptrMap.m[t] = p
  1075  	ptrMap.Unlock()
  1076  	return &p.rtype
  1077  }
  1078  
  1079  // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
  1080  func fnv1(x uint32, list ...byte) uint32 {
  1081  	for _, b := range list {
  1082  		x = x*16777619 ^ uint32(b)
  1083  	}
  1084  	return x
  1085  }
  1086  
  1087  func (t *rtype) Implements(u Type) bool {
  1088  	if u == nil {
  1089  		panic("reflect: nil type passed to Type.Implements")
  1090  	}
  1091  	if u.Kind() != Interface {
  1092  		panic("reflect: non-interface type passed to Type.Implements")
  1093  	}
  1094  	return implements(u.(*rtype), t)
  1095  }
  1096  
  1097  func (t *rtype) AssignableTo(u Type) bool {
  1098  	if u == nil {
  1099  		panic("reflect: nil type passed to Type.AssignableTo")
  1100  	}
  1101  	uu := u.(*rtype)
  1102  	return directlyAssignable(uu, t) || implements(uu, t)
  1103  }
  1104  
  1105  func (t *rtype) ConvertibleTo(u Type) bool {
  1106  	if u == nil {
  1107  		panic("reflect: nil type passed to Type.ConvertibleTo")
  1108  	}
  1109  	uu := u.(*rtype)
  1110  	return convertOp(uu, t) != nil
  1111  }
  1112  
  1113  func (t *rtype) Comparable() bool {
  1114  	return t.alg != nil && t.alg.equal != nil
  1115  }
  1116  
  1117  // implements returns true if the type V implements the interface type T.
  1118  func implements(T, V *rtype) bool {
  1119  	if T.Kind() != Interface {
  1120  		return false
  1121  	}
  1122  	t := (*interfaceType)(unsafe.Pointer(T))
  1123  	if len(t.methods) == 0 {
  1124  		return true
  1125  	}
  1126  
  1127  	// The same algorithm applies in both cases, but the
  1128  	// method tables for an interface type and a concrete type
  1129  	// are different, so the code is duplicated.
  1130  	// In both cases the algorithm is a linear scan over the two
  1131  	// lists - T's methods and V's methods - simultaneously.
  1132  	// Since method tables are stored in a unique sorted order
  1133  	// (alphabetical, with no duplicate method names), the scan
  1134  	// through V's methods must hit a match for each of T's
  1135  	// methods along the way, or else V does not implement T.
  1136  	// This lets us run the scan in overall linear time instead of
  1137  	// the quadratic time  a naive search would require.
  1138  	// See also ../runtime/iface.c.
  1139  	if V.Kind() == Interface {
  1140  		v := (*interfaceType)(unsafe.Pointer(V))
  1141  		i := 0
  1142  		for j := 0; j < len(v.methods); j++ {
  1143  			tm := &t.methods[i]
  1144  			vm := &v.methods[j]
  1145  			if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.typ == tm.typ {
  1146  				if i++; i >= len(t.methods) {
  1147  					return true
  1148  				}
  1149  			}
  1150  		}
  1151  		return false
  1152  	}
  1153  
  1154  	v := V.uncommon()
  1155  	if v == nil {
  1156  		return false
  1157  	}
  1158  	i := 0
  1159  	for j := 0; j < len(v.methods); j++ {
  1160  		tm := &t.methods[i]
  1161  		vm := &v.methods[j]
  1162  		if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.mtyp == tm.typ {
  1163  			if i++; i >= len(t.methods) {
  1164  				return true
  1165  			}
  1166  		}
  1167  	}
  1168  	return false
  1169  }
  1170  
  1171  // directlyAssignable returns true if a value x of type V can be directly
  1172  // assigned (using memmove) to a value of type T.
  1173  // http://golang.org/doc/go_spec.html#Assignability
  1174  // Ignoring the interface rules (implemented elsewhere)
  1175  // and the ideal constant rules (no ideal constants at run time).
  1176  func directlyAssignable(T, V *rtype) bool {
  1177  	// x's type V is identical to T?
  1178  	if T == V {
  1179  		return true
  1180  	}
  1181  
  1182  	// Otherwise at least one of T and V must be unnamed
  1183  	// and they must have the same kind.
  1184  	if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() {
  1185  		return false
  1186  	}
  1187  
  1188  	// x's type T and V must  have identical underlying types.
  1189  	return haveIdenticalUnderlyingType(T, V)
  1190  }
  1191  
  1192  func haveIdenticalUnderlyingType(T, V *rtype) bool {
  1193  	if T == V {
  1194  		return true
  1195  	}
  1196  
  1197  	kind := T.Kind()
  1198  	if kind != V.Kind() {
  1199  		return false
  1200  	}
  1201  
  1202  	// Non-composite types of equal kind have same underlying type
  1203  	// (the predefined instance of the type).
  1204  	if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
  1205  		return true
  1206  	}
  1207  
  1208  	// Composite types.
  1209  	switch kind {
  1210  	case Array:
  1211  		return T.Elem() == V.Elem() && T.Len() == V.Len()
  1212  
  1213  	case Chan:
  1214  		// Special case:
  1215  		// x is a bidirectional channel value, T is a channel type,
  1216  		// and x's type V and T have identical element types.
  1217  		if V.ChanDir() == BothDir && T.Elem() == V.Elem() {
  1218  			return true
  1219  		}
  1220  
  1221  		// Otherwise continue test for identical underlying type.
  1222  		return V.ChanDir() == T.ChanDir() && T.Elem() == V.Elem()
  1223  
  1224  	case Func:
  1225  		t := (*funcType)(unsafe.Pointer(T))
  1226  		v := (*funcType)(unsafe.Pointer(V))
  1227  		if t.dotdotdot != v.dotdotdot || len(t.in) != len(v.in) || len(t.out) != len(v.out) {
  1228  			return false
  1229  		}
  1230  		for i, typ := range t.in {
  1231  			if typ != v.in[i] {
  1232  				return false
  1233  			}
  1234  		}
  1235  		for i, typ := range t.out {
  1236  			if typ != v.out[i] {
  1237  				return false
  1238  			}
  1239  		}
  1240  		return true
  1241  
  1242  	case Interface:
  1243  		t := (*interfaceType)(unsafe.Pointer(T))
  1244  		v := (*interfaceType)(unsafe.Pointer(V))
  1245  		if len(t.methods) == 0 && len(v.methods) == 0 {
  1246  			return true
  1247  		}
  1248  		// Might have the same methods but still
  1249  		// need a run time conversion.
  1250  		return false
  1251  
  1252  	case Map:
  1253  		return T.Key() == V.Key() && T.Elem() == V.Elem()
  1254  
  1255  	case Ptr, Slice:
  1256  		return T.Elem() == V.Elem()
  1257  
  1258  	case Struct:
  1259  		t := (*structType)(unsafe.Pointer(T))
  1260  		v := (*structType)(unsafe.Pointer(V))
  1261  		if len(t.fields) != len(v.fields) {
  1262  			return false
  1263  		}
  1264  		for i := range t.fields {
  1265  			tf := &t.fields[i]
  1266  			vf := &v.fields[i]
  1267  			if tf.name != vf.name && (tf.name == nil || vf.name == nil || *tf.name != *vf.name) {
  1268  				return false
  1269  			}
  1270  			if tf.pkgPath != vf.pkgPath && (tf.pkgPath == nil || vf.pkgPath == nil || *tf.pkgPath != *vf.pkgPath) {
  1271  				return false
  1272  			}
  1273  			if tf.typ != vf.typ {
  1274  				return false
  1275  			}
  1276  			if tf.tag != vf.tag && (tf.tag == nil || vf.tag == nil || *tf.tag != *vf.tag) {
  1277  				return false
  1278  			}
  1279  			if tf.offset != vf.offset {
  1280  				return false
  1281  			}
  1282  		}
  1283  		return true
  1284  	}
  1285  
  1286  	return false
  1287  }
  1288  
  1289  // typelinks is implemented in package runtime.
  1290  // It returns a slice of all the 'typelink' information in the binary,
  1291  // which is to say a slice of known types, sorted by string.
  1292  // Note that strings are not unique identifiers for types:
  1293  // there can be more than one with a given string.
  1294  // Only types we might want to look up are included:
  1295  // channels, maps, slices, and arrays.
  1296  func typelinks() []*rtype
  1297  
  1298  // typesByString returns the subslice of typelinks() whose elements have
  1299  // the given string representation.
  1300  // It may be empty (no known types with that string) or may have
  1301  // multiple elements (multiple types with that string).
  1302  func typesByString(s string) []*rtype {
  1303  	typ := typelinks()
  1304  
  1305  	// We are looking for the first index i where the string becomes >= s.
  1306  	// This is a copy of sort.Search, with f(h) replaced by (*typ[h].string >= s).
  1307  	i, j := 0, len(typ)
  1308  	for i < j {
  1309  		h := i + (j-i)/2 // avoid overflow when computing h
  1310  		// i ≤ h < j
  1311  		if !(*typ[h].string >= s) {
  1312  			i = h + 1 // preserves f(i-1) == false
  1313  		} else {
  1314  			j = h // preserves f(j) == true
  1315  		}
  1316  	}
  1317  	// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
  1318  
  1319  	// Having found the first, linear scan forward to find the last.
  1320  	// We could do a second binary search, but the caller is going
  1321  	// to do a linear scan anyway.
  1322  	j = i
  1323  	for j < len(typ) && *typ[j].string == s {
  1324  		j++
  1325  	}
  1326  
  1327  	// This slice will be empty if the string is not found.
  1328  	return typ[i:j]
  1329  }
  1330  
  1331  // The lookupCache caches ChanOf, MapOf, and SliceOf lookups.
  1332  var lookupCache struct {
  1333  	sync.RWMutex
  1334  	m map[cacheKey]*rtype
  1335  }
  1336  
  1337  // A cacheKey is the key for use in the lookupCache.
  1338  // Four values describe any of the types we are looking for:
  1339  // type kind, one or two subtypes, and an extra integer.
  1340  type cacheKey struct {
  1341  	kind  Kind
  1342  	t1    *rtype
  1343  	t2    *rtype
  1344  	extra uintptr
  1345  }
  1346  
  1347  // cacheGet looks for a type under the key k in the lookupCache.
  1348  // If it finds one, it returns that type.
  1349  // If not, it returns nil with the cache locked.
  1350  // The caller is expected to use cachePut to unlock the cache.
  1351  func cacheGet(k cacheKey) Type {
  1352  	lookupCache.RLock()
  1353  	t := lookupCache.m[k]
  1354  	lookupCache.RUnlock()
  1355  	if t != nil {
  1356  		return t
  1357  	}
  1358  
  1359  	lookupCache.Lock()
  1360  	t = lookupCache.m[k]
  1361  	if t != nil {
  1362  		lookupCache.Unlock()
  1363  		return t
  1364  	}
  1365  
  1366  	if lookupCache.m == nil {
  1367  		lookupCache.m = make(map[cacheKey]*rtype)
  1368  	}
  1369  
  1370  	return nil
  1371  }
  1372  
  1373  // cachePut stores the given type in the cache, unlocks the cache,
  1374  // and returns the type. It is expected that the cache is locked
  1375  // because cacheGet returned nil.
  1376  func cachePut(k cacheKey, t *rtype) Type {
  1377  	lookupCache.m[k] = t
  1378  	lookupCache.Unlock()
  1379  	return t
  1380  }
  1381  
  1382  // ChanOf returns the channel type with the given direction and element type.
  1383  // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
  1384  //
  1385  // The gc runtime imposes a limit of 64 kB on channel element types.
  1386  // If t's size is equal to or exceeds this limit, ChanOf panics.
  1387  func ChanOf(dir ChanDir, t Type) Type {
  1388  	typ := t.(*rtype)
  1389  
  1390  	// Look in cache.
  1391  	ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
  1392  	if ch := cacheGet(ckey); ch != nil {
  1393  		return ch
  1394  	}
  1395  
  1396  	// This restriction is imposed by the gc compiler and the runtime.
  1397  	if typ.size >= 1<<16 {
  1398  		lookupCache.Unlock()
  1399  		panic("reflect.ChanOf: element size too large")
  1400  	}
  1401  
  1402  	// Look in known types.
  1403  	// TODO: Precedence when constructing string.
  1404  	var s string
  1405  	switch dir {
  1406  	default:
  1407  		lookupCache.Unlock()
  1408  		panic("reflect.ChanOf: invalid dir")
  1409  	case SendDir:
  1410  		s = "chan<- " + *typ.string
  1411  	case RecvDir:
  1412  		s = "<-chan " + *typ.string
  1413  	case BothDir:
  1414  		s = "chan " + *typ.string
  1415  	}
  1416  	for _, tt := range typesByString(s) {
  1417  		ch := (*chanType)(unsafe.Pointer(tt))
  1418  		if ch.elem == typ && ch.dir == uintptr(dir) {
  1419  			return cachePut(ckey, tt)
  1420  		}
  1421  	}
  1422  
  1423  	// Make a channel type.
  1424  	var ichan interface{} = (chan unsafe.Pointer)(nil)
  1425  	prototype := *(**chanType)(unsafe.Pointer(&ichan))
  1426  	ch := new(chanType)
  1427  	*ch = *prototype
  1428  	ch.dir = uintptr(dir)
  1429  	ch.string = &s
  1430  	ch.hash = fnv1(typ.hash, 'c', byte(dir))
  1431  	ch.elem = typ
  1432  	ch.uncommonType = nil
  1433  	ch.ptrToThis = nil
  1434  	ch.zero = unsafe.Pointer(&make([]byte, ch.size)[0])
  1435  
  1436  	return cachePut(ckey, &ch.rtype)
  1437  }
  1438  
  1439  func ismapkey(*rtype) bool // implemented in runtime
  1440  
  1441  // MapOf returns the map type with the given key and element types.
  1442  // For example, if k represents int and e represents string,
  1443  // MapOf(k, e) represents map[int]string.
  1444  //
  1445  // If the key type is not a valid map key type (that is, if it does
  1446  // not implement Go's == operator), MapOf panics.
  1447  func MapOf(key, elem Type) Type {
  1448  	ktyp := key.(*rtype)
  1449  	etyp := elem.(*rtype)
  1450  
  1451  	if !ismapkey(ktyp) {
  1452  		panic("reflect.MapOf: invalid key type " + ktyp.String())
  1453  	}
  1454  
  1455  	// Look in cache.
  1456  	ckey := cacheKey{Map, ktyp, etyp, 0}
  1457  	if mt := cacheGet(ckey); mt != nil {
  1458  		return mt
  1459  	}
  1460  
  1461  	// Look in known types.
  1462  	s := "map[" + *ktyp.string + "]" + *etyp.string
  1463  	for _, tt := range typesByString(s) {
  1464  		mt := (*mapType)(unsafe.Pointer(tt))
  1465  		if mt.key == ktyp && mt.elem == etyp {
  1466  			return cachePut(ckey, tt)
  1467  		}
  1468  	}
  1469  
  1470  	// Make a map type.
  1471  	var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
  1472  	prototype := *(**mapType)(unsafe.Pointer(&imap))
  1473  	mt := new(mapType)
  1474  	*mt = *prototype
  1475  	mt.string = &s
  1476  	mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
  1477  	mt.key = ktyp
  1478  	mt.elem = etyp
  1479  	mt.bucket = bucketOf(ktyp, etyp)
  1480  	if ktyp.size > maxKeySize {
  1481  		mt.keysize = uint8(ptrSize)
  1482  		mt.indirectkey = 1
  1483  	} else {
  1484  		mt.keysize = uint8(ktyp.size)
  1485  		mt.indirectkey = 0
  1486  	}
  1487  	if etyp.size > maxValSize {
  1488  		mt.valuesize = uint8(ptrSize)
  1489  		mt.indirectvalue = 1
  1490  	} else {
  1491  		mt.valuesize = uint8(etyp.size)
  1492  		mt.indirectvalue = 0
  1493  	}
  1494  	mt.bucketsize = uint16(mt.bucket.size)
  1495  	mt.reflexivekey = isReflexive(ktyp)
  1496  	mt.uncommonType = nil
  1497  	mt.ptrToThis = nil
  1498  	mt.zero = unsafe.Pointer(&make([]byte, mt.size)[0])
  1499  
  1500  	return cachePut(ckey, &mt.rtype)
  1501  }
  1502  
  1503  // isReflexive reports whether the == operation on the type is reflexive.
  1504  // That is, x == x for all values x of type t.
  1505  func isReflexive(t *rtype) bool {
  1506  	switch t.Kind() {
  1507  	case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Ptr, String, UnsafePointer:
  1508  		return true
  1509  	case Float32, Float64, Complex64, Complex128, Interface:
  1510  		return false
  1511  	case Array:
  1512  		tt := (*arrayType)(unsafe.Pointer(t))
  1513  		return isReflexive(tt.elem)
  1514  	case Struct:
  1515  		tt := (*structType)(unsafe.Pointer(t))
  1516  		for _, f := range tt.fields {
  1517  			if !isReflexive(f.typ) {
  1518  				return false
  1519  			}
  1520  		}
  1521  		return true
  1522  	default:
  1523  		// Func, Map, Slice, Invalid
  1524  		panic("isReflexive called on non-key type " + t.String())
  1525  	}
  1526  }
  1527  
  1528  // gcProg is a helper type for generatation of GC pointer info.
  1529  type gcProg struct {
  1530  	gc       []byte
  1531  	size     uintptr // size of type in bytes
  1532  	hasPtr   bool
  1533  	lastZero uintptr // largest offset of a zero-byte field
  1534  }
  1535  
  1536  func (gc *gcProg) append(v byte) {
  1537  	gc.align(unsafe.Sizeof(uintptr(0)))
  1538  	gc.appendWord(v)
  1539  }
  1540  
  1541  // Appends t's type info to the current program.
  1542  func (gc *gcProg) appendProg(t *rtype) {
  1543  	gc.align(uintptr(t.align))
  1544  	if !t.pointers() {
  1545  		gc.size += t.size
  1546  		if t.size == 0 {
  1547  			gc.lastZero = gc.size
  1548  		}
  1549  		return
  1550  	}
  1551  	switch t.Kind() {
  1552  	default:
  1553  		panic("reflect: non-pointer type marked as having pointers")
  1554  	case Ptr, UnsafePointer, Chan, Func, Map:
  1555  		gc.appendWord(bitsPointer)
  1556  	case Slice:
  1557  		gc.appendWord(bitsPointer)
  1558  		gc.appendWord(bitsScalar)
  1559  		gc.appendWord(bitsScalar)
  1560  	case String:
  1561  		gc.appendWord(bitsPointer)
  1562  		gc.appendWord(bitsScalar)
  1563  	case Array:
  1564  		c := t.Len()
  1565  		e := t.Elem().common()
  1566  		for i := 0; i < c; i++ {
  1567  			gc.appendProg(e)
  1568  		}
  1569  	case Interface:
  1570  		gc.appendWord(bitsPointer)
  1571  		gc.appendWord(bitsPointer)
  1572  	case Struct:
  1573  		oldsize := gc.size
  1574  		c := t.NumField()
  1575  		for i := 0; i < c; i++ {
  1576  			gc.appendProg(t.Field(i).Type.common())
  1577  		}
  1578  		if gc.size > oldsize + t.size {
  1579  			panic("reflect: struct components are larger than the struct itself")
  1580  		}
  1581  		gc.size = oldsize + t.size
  1582  	}
  1583  }
  1584  
  1585  func (gc *gcProg) appendWord(v byte) {
  1586  	ptrsize := unsafe.Sizeof(uintptr(0))
  1587  	if gc.size%ptrsize != 0 {
  1588  		panic("reflect: unaligned GC program")
  1589  	}
  1590  	nptr := gc.size / ptrsize
  1591  	for uintptr(len(gc.gc)) < nptr/2+1 {
  1592  		gc.gc = append(gc.gc, 0x44) // BitsScalar
  1593  	}
  1594  	gc.gc[nptr/2] &= ^(3 << ((nptr%2)*4 + 2))
  1595  	gc.gc[nptr/2] |= v << ((nptr%2)*4 + 2)
  1596  	gc.size += ptrsize
  1597  	if v == bitsPointer {
  1598  		gc.hasPtr = true
  1599  	}
  1600  }
  1601  
  1602  func (gc *gcProg) finalize() (unsafe.Pointer, bool) {
  1603  	if gc.size == 0 {
  1604  		return nil, false
  1605  	}
  1606  	if gc.lastZero == gc.size {
  1607  		gc.size++
  1608  	}
  1609  	ptrsize := unsafe.Sizeof(uintptr(0))
  1610  	gc.align(ptrsize)
  1611  	nptr := gc.size / ptrsize
  1612  	for uintptr(len(gc.gc)) < nptr/2+1 {
  1613  		gc.gc = append(gc.gc, 0x44) // BitsScalar
  1614  	}
  1615  	// If number of words is odd, repeat the mask twice.
  1616  	// Compiler does the same.
  1617  	if nptr%2 != 0 {
  1618  		for i := uintptr(0); i < nptr; i++ {
  1619  			gc.appendWord(extractGCWord(gc.gc, i))
  1620  		}
  1621  	}
  1622  	return unsafe.Pointer(&gc.gc[0]), gc.hasPtr
  1623  }
  1624  
  1625  func extractGCWord(gc []byte, i uintptr) byte {
  1626  	return (gc[i/2] >> ((i%2)*4 + 2)) & 3
  1627  }
  1628  
  1629  func (gc *gcProg) align(a uintptr) {
  1630  	gc.size = align(gc.size, a)
  1631  }
  1632  
  1633  // These constants must stay in sync with ../runtime/mgc0.h.
  1634  const (
  1635  	bitsScalar  = 1
  1636  	bitsPointer = 2
  1637  
  1638  	bitsIface = 2
  1639  	bitsEface = 3
  1640  )
  1641  
  1642  // Make sure these routines stay in sync with ../../runtime/hashmap.go!
  1643  // These types exist only for GC, so we only fill out GC relevant info.
  1644  // Currently, that's just size and the GC program.  We also fill in string
  1645  // for possible debugging use.
  1646  const (
  1647  	bucketSize = 8
  1648  	maxKeySize = 128
  1649  	maxValSize = 128
  1650  )
  1651  
  1652  func bucketOf(ktyp, etyp *rtype) *rtype {
  1653  	if ktyp.size > maxKeySize {
  1654  		ktyp = PtrTo(ktyp).(*rtype)
  1655  	}
  1656  	if etyp.size > maxValSize {
  1657  		etyp = PtrTo(etyp).(*rtype)
  1658  	}
  1659  	ptrsize := unsafe.Sizeof(uintptr(0))
  1660  
  1661  	var gc gcProg
  1662  	// topbits
  1663  	for i := 0; i < int(bucketSize*unsafe.Sizeof(uint8(0))/ptrsize); i++ {
  1664  		gc.append(bitsScalar)
  1665  	}
  1666  	// keys
  1667  	for i := 0; i < bucketSize; i++ {
  1668  		gc.appendProg(ktyp)
  1669  	}
  1670  	// values
  1671  	for i := 0; i < bucketSize; i++ {
  1672  		gc.appendProg(etyp)
  1673  	}
  1674  	// overflow
  1675  	gc.append(bitsPointer)
  1676  	if runtime.GOARCH == "amd64p32" {
  1677  		gc.append(bitsScalar)
  1678  	}
  1679  
  1680  	b := new(rtype)
  1681  	b.size = gc.size
  1682  	b.gc[0], _ = gc.finalize()
  1683  	s := "bucket(" + *ktyp.string + "," + *etyp.string + ")"
  1684  	b.string = &s
  1685  	return b
  1686  }
  1687  
  1688  // SliceOf returns the slice type with element type t.
  1689  // For example, if t represents int, SliceOf(t) represents []int.
  1690  func SliceOf(t Type) Type {
  1691  	typ := t.(*rtype)
  1692  
  1693  	// Look in cache.
  1694  	ckey := cacheKey{Slice, typ, nil, 0}
  1695  	if slice := cacheGet(ckey); slice != nil {
  1696  		return slice
  1697  	}
  1698  
  1699  	// Look in known types.
  1700  	s := "[]" + *typ.string
  1701  	for _, tt := range typesByString(s) {
  1702  		slice := (*sliceType)(unsafe.Pointer(tt))
  1703  		if slice.elem == typ {
  1704  			return cachePut(ckey, tt)
  1705  		}
  1706  	}
  1707  
  1708  	// Make a slice type.
  1709  	var islice interface{} = ([]unsafe.Pointer)(nil)
  1710  	prototype := *(**sliceType)(unsafe.Pointer(&islice))
  1711  	slice := new(sliceType)
  1712  	*slice = *prototype
  1713  	slice.string = &s
  1714  	slice.hash = fnv1(typ.hash, '[')
  1715  	slice.elem = typ
  1716  	slice.uncommonType = nil
  1717  	slice.ptrToThis = nil
  1718  	slice.zero = unsafe.Pointer(&make([]byte, slice.size)[0])
  1719  
  1720  	return cachePut(ckey, &slice.rtype)
  1721  }
  1722  
  1723  // ArrayOf returns the array type with the given count and element type.
  1724  // For example, if t represents int, ArrayOf(5, t) represents [5]int.
  1725  //
  1726  // If the resulting type would be larger than the available address space,
  1727  // ArrayOf panics.
  1728  //
  1729  // TODO(rsc): Unexported for now. Export once the alg field is set correctly
  1730  // for the type. This may require significant work.
  1731  //
  1732  // TODO(rsc): TestArrayOf is also disabled. Re-enable.
  1733  func arrayOf(count int, elem Type) Type {
  1734  	typ := elem.(*rtype)
  1735  	slice := SliceOf(elem)
  1736  
  1737  	// Look in cache.
  1738  	ckey := cacheKey{Array, typ, nil, uintptr(count)}
  1739  	if slice := cacheGet(ckey); slice != nil {
  1740  		return slice
  1741  	}
  1742  
  1743  	// Look in known types.
  1744  	s := "[" + strconv.Itoa(count) + "]" + *typ.string
  1745  	for _, tt := range typesByString(s) {
  1746  		slice := (*sliceType)(unsafe.Pointer(tt))
  1747  		if slice.elem == typ {
  1748  			return cachePut(ckey, tt)
  1749  		}
  1750  	}
  1751  
  1752  	// Make an array type.
  1753  	var iarray interface{} = [1]unsafe.Pointer{}
  1754  	prototype := *(**arrayType)(unsafe.Pointer(&iarray))
  1755  	array := new(arrayType)
  1756  	*array = *prototype
  1757  	// TODO: Set extra kind bits correctly.
  1758  	array.string = &s
  1759  	array.hash = fnv1(typ.hash, '[')
  1760  	for n := uint32(count); n > 0; n >>= 8 {
  1761  		array.hash = fnv1(array.hash, byte(n))
  1762  	}
  1763  	array.hash = fnv1(array.hash, ']')
  1764  	array.elem = typ
  1765  	max := ^uintptr(0) / typ.size
  1766  	if uintptr(count) > max {
  1767  		panic("reflect.ArrayOf: array size would exceed virtual address space")
  1768  	}
  1769  	array.size = typ.size * uintptr(count)
  1770  	array.align = typ.align
  1771  	array.fieldAlign = typ.fieldAlign
  1772  	// TODO: array.alg
  1773  	// TODO: array.gc
  1774  	// TODO:
  1775  	array.uncommonType = nil
  1776  	array.ptrToThis = nil
  1777  	array.zero = unsafe.Pointer(&make([]byte, array.size)[0])
  1778  	array.len = uintptr(count)
  1779  	array.slice = slice.(*rtype)
  1780  
  1781  	return cachePut(ckey, &array.rtype)
  1782  }
  1783  
  1784  // toType converts from a *rtype to a Type that can be returned
  1785  // to the client of package reflect. In gc, the only concern is that
  1786  // a nil *rtype must be replaced by a nil Type, but in gccgo this
  1787  // function takes care of ensuring that multiple *rtype for the same
  1788  // type are coalesced into a single Type.
  1789  func toType(t *rtype) Type {
  1790  	if t == nil {
  1791  		return nil
  1792  	}
  1793  	return t
  1794  }
  1795  
  1796  type layoutKey struct {
  1797  	t    *rtype // function signature
  1798  	rcvr *rtype // receiver type, or nil if none
  1799  }
  1800  
  1801  type layoutType struct {
  1802  	t         *rtype
  1803  	argSize   uintptr // size of arguments
  1804  	retOffset uintptr // offset of return values.
  1805  	stack     *bitVector
  1806  }
  1807  
  1808  var layoutCache struct {
  1809  	sync.RWMutex
  1810  	m map[layoutKey]layoutType
  1811  }
  1812  
  1813  // funcLayout computes a struct type representing the layout of the
  1814  // function arguments and return values for the function type t.
  1815  // If rcvr != nil, rcvr specifies the type of the receiver.
  1816  // The returned type exists only for GC, so we only fill out GC relevant info.
  1817  // Currently, that's just size and the GC program.  We also fill in
  1818  // the name for possible debugging use.
  1819  func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uintptr, stack *bitVector) {
  1820  	if t.Kind() != Func {
  1821  		panic("reflect: funcLayout of non-func type")
  1822  	}
  1823  	if rcvr != nil && rcvr.Kind() == Interface {
  1824  		panic("reflect: funcLayout with interface receiver " + rcvr.String())
  1825  	}
  1826  	k := layoutKey{t, rcvr}
  1827  	layoutCache.RLock()
  1828  	if x := layoutCache.m[k]; x.t != nil {
  1829  		layoutCache.RUnlock()
  1830  		return x.t, x.argSize, x.retOffset, x.stack
  1831  	}
  1832  	layoutCache.RUnlock()
  1833  	layoutCache.Lock()
  1834  	if x := layoutCache.m[k]; x.t != nil {
  1835  		layoutCache.Unlock()
  1836  		return x.t, x.argSize, x.retOffset, x.stack
  1837  	}
  1838  
  1839  	tt := (*funcType)(unsafe.Pointer(t))
  1840  
  1841  	// compute gc program & stack bitmap for arguments
  1842  	stack = new(bitVector)
  1843  	var gc gcProg
  1844  	var offset uintptr
  1845  	if rcvr != nil {
  1846  		// Reflect uses the "interface" calling convention for
  1847  		// methods, where receivers take one word of argument
  1848  		// space no matter how big they actually are.
  1849  		if ifaceIndir(rcvr) {
  1850  			// we pass a pointer to the receiver.
  1851  			gc.append(bitsPointer)
  1852  			stack.append2(bitsPointer)
  1853  		} else if rcvr.pointers() {
  1854  			// rcvr is a one-word pointer object.  Its gc program
  1855  			// is just what we need here.
  1856  			gc.append(bitsPointer)
  1857  			stack.append2(bitsPointer)
  1858  		} else {
  1859  			gc.append(bitsScalar)
  1860  			stack.append2(bitsScalar)
  1861  		}
  1862  		offset += ptrSize
  1863  	}
  1864  	for _, arg := range tt.in {
  1865  		gc.appendProg(arg)
  1866  		addTypeBits(stack, &offset, arg)
  1867  	}
  1868  	argSize = gc.size
  1869  	if runtime.GOARCH == "amd64p32" {
  1870  		gc.align(8)
  1871  	}
  1872  	gc.align(ptrSize)
  1873  	retOffset = gc.size
  1874  	for _, res := range tt.out {
  1875  		gc.appendProg(res)
  1876  		// stack map does not need result bits
  1877  	}
  1878  	gc.align(ptrSize)
  1879  
  1880  	// build dummy rtype holding gc program
  1881  	x := new(rtype)
  1882  	x.size = gc.size
  1883  	var hasPtr bool
  1884  	x.gc[0], hasPtr = gc.finalize()
  1885  	if !hasPtr {
  1886  		x.kind |= kindNoPointers
  1887  	}
  1888  	var s string
  1889  	if rcvr != nil {
  1890  		s = "methodargs(" + *rcvr.string + ")(" + *t.string + ")"
  1891  	} else {
  1892  		s = "funcargs(" + *t.string + ")"
  1893  	}
  1894  	x.string = &s
  1895  
  1896  	// cache result for future callers
  1897  	if layoutCache.m == nil {
  1898  		layoutCache.m = make(map[layoutKey]layoutType)
  1899  	}
  1900  	layoutCache.m[k] = layoutType{
  1901  		t:         x,
  1902  		argSize:   argSize,
  1903  		retOffset: retOffset,
  1904  		stack:     stack,
  1905  	}
  1906  	layoutCache.Unlock()
  1907  	return x, argSize, retOffset, stack
  1908  }
  1909  
  1910  // ifaceIndir reports whether t is stored indirectly in an interface value.
  1911  func ifaceIndir(t *rtype) bool {
  1912  	return t.kind&kindDirectIface == 0
  1913  }
  1914  
  1915  // Layout matches runtime.BitVector (well enough).
  1916  type bitVector struct {
  1917  	n    uint32 // number of bits
  1918  	data []byte
  1919  }
  1920  
  1921  // append a bit pair to the bitmap.
  1922  func (bv *bitVector) append2(bits uint8) {
  1923  	// assume bv.n is a multiple of 2, since append2 is the only operation.
  1924  	if bv.n%8 == 0 {
  1925  		bv.data = append(bv.data, 0)
  1926  	}
  1927  	bv.data[bv.n/8] |= bits << (bv.n % 8)
  1928  	bv.n += 2
  1929  }
  1930  
  1931  func addTypeBits(bv *bitVector, offset *uintptr, t *rtype) {
  1932  	*offset = align(*offset, uintptr(t.align))
  1933  	if !t.pointers() {
  1934  		*offset += t.size
  1935  		return
  1936  	}
  1937  
  1938  	switch Kind(t.kind & kindMask) {
  1939  	case Chan, Func, Map, Ptr, Slice, String, UnsafePointer:
  1940  		// 1 pointer at start of representation
  1941  		for bv.n < 2*uint32(*offset/uintptr(ptrSize)) {
  1942  			bv.append2(bitsScalar)
  1943  		}
  1944  		bv.append2(bitsPointer)
  1945  
  1946  	case Interface:
  1947  		// 2 pointers
  1948  		for bv.n < 2*uint32(*offset/uintptr(ptrSize)) {
  1949  			bv.append2(bitsScalar)
  1950  		}
  1951  		bv.append2(bitsPointer)
  1952  		bv.append2(bitsPointer)
  1953  
  1954  	case Array:
  1955  		// repeat inner type
  1956  		tt := (*arrayType)(unsafe.Pointer(t))
  1957  		for i := 0; i < int(tt.len); i++ {
  1958  			addTypeBits(bv, offset, tt.elem)
  1959  		}
  1960  
  1961  	case Struct:
  1962  		// apply fields
  1963  		tt := (*structType)(unsafe.Pointer(t))
  1964  		start := *offset
  1965  		for i := range tt.fields {
  1966  			f := &tt.fields[i]
  1967  			off := start + f.offset
  1968  			addTypeBits(bv, &off, f.typ)
  1969  		}
  1970  	}
  1971  
  1972  	*offset += t.size
  1973  }