github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/not-internal/reflectlite/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 reflectlite implements lightweight version of reflect, not using
     6  // any package except for "runtime" and "unsafe".
     7  package reflectlite
     8  
     9  import (
    10  	"unsafe"
    11  )
    12  
    13  // Type is the representation of a Go type.
    14  //
    15  // Not all methods apply to all kinds of types. Restrictions,
    16  // if any, are noted in the documentation for each method.
    17  // Use the Kind method to find out the kind of type before
    18  // calling kind-specific methods. Calling a method
    19  // inappropriate to the kind of type causes a run-time panic.
    20  //
    21  // Type values are comparable, such as with the == operator,
    22  // so they can be used as map keys.
    23  // Two Type values are equal if they represent identical types.
    24  type Type interface {
    25  	// Methods applicable to all types.
    26  
    27  	// Name returns the type's name within its package for a defined type.
    28  	// For other (non-defined) types it returns the empty string.
    29  	Name() string
    30  
    31  	// PkgPath returns a defined type's package path, that is, the import path
    32  	// that uniquely identifies the package, such as "encoding/base64".
    33  	// If the type was predeclared (string, error) or not defined (*T, struct{},
    34  	// []int, or A where A is an alias for a non-defined type), the package path
    35  	// will be the empty string.
    36  	PkgPath() string
    37  
    38  	// Size returns the number of bytes needed to store
    39  	// a value of the given type; it is analogous to unsafe.Sizeof.
    40  	Size() uintptr
    41  
    42  	// Kind returns the specific kind of this type.
    43  	Kind() Kind
    44  
    45  	// Implements reports whether the type implements the interface type u.
    46  	Implements(u Type) bool
    47  
    48  	// AssignableTo reports whether a value of the type is assignable to type u.
    49  	AssignableTo(u Type) bool
    50  
    51  	// Comparable reports whether values of this type are comparable.
    52  	Comparable() bool
    53  
    54  	// String returns a string representation of the type.
    55  	// The string representation may use shortened package names
    56  	// (e.g., base64 instead of "encoding/base64") and is not
    57  	// guaranteed to be unique among types. To test for type identity,
    58  	// compare the Types directly.
    59  	String() string
    60  
    61  	// Elem returns a type's element type.
    62  	// It panics if the type's Kind is not Ptr.
    63  	Elem() Type
    64  
    65  	common() *rtype
    66  	uncommon() *uncommonType
    67  }
    68  
    69  /*
    70   * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
    71   * A few are known to ../runtime/type.go to convey to debuggers.
    72   * They are also known to ../runtime/type.go.
    73   */
    74  
    75  // A Kind represents the specific kind of type that a Type represents.
    76  // The zero Kind is not a valid kind.
    77  type Kind uint
    78  
    79  const (
    80  	Invalid Kind = iota
    81  	Bool
    82  	Int
    83  	Int8
    84  	Int16
    85  	Int32
    86  	Int64
    87  	Uint
    88  	Uint8
    89  	Uint16
    90  	Uint32
    91  	Uint64
    92  	Uintptr
    93  	Float32
    94  	Float64
    95  	Complex64
    96  	Complex128
    97  	Array
    98  	Chan
    99  	Func
   100  	Interface
   101  	Map
   102  	Ptr
   103  	Slice
   104  	String
   105  	Struct
   106  	UnsafePointer
   107  )
   108  
   109  // tflag is used by an rtype to signal what extra type information is
   110  // available in the memory directly following the rtype value.
   111  //
   112  // tflag values must be kept in sync with copies in:
   113  //	cmd/compile/internal/gc/reflect.go
   114  //	cmd/link/internal/ld/decodesym.go
   115  //	runtime/type.go
   116  type tflag uint8
   117  
   118  const (
   119  	// tflagUncommon means that there is a pointer, *uncommonType,
   120  	// just beyond the outer type structure.
   121  	//
   122  	// For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0,
   123  	// then t has uncommonType data and it can be accessed as:
   124  	//
   125  	//	type tUncommon struct {
   126  	//		structType
   127  	//		u uncommonType
   128  	//	}
   129  	//	u := &(*tUncommon)(unsafe.Pointer(t)).u
   130  	tflagUncommon tflag = 1 << 0
   131  
   132  	// tflagExtraStar means the name in the str field has an
   133  	// extraneous '*' prefix. This is because for most types T in
   134  	// a program, the type *T also exists and reusing the str data
   135  	// saves binary size.
   136  	tflagExtraStar tflag = 1 << 1
   137  
   138  	// tflagNamed means the type has a name.
   139  	tflagNamed tflag = 1 << 2
   140  
   141  	// tflagRegularMemory means that equal and hash functions can treat
   142  	// this type as a single region of t.size bytes.
   143  	tflagRegularMemory tflag = 1 << 3
   144  )
   145  
   146  // rtype is the common implementation of most values.
   147  // It is embedded in other struct types.
   148  //
   149  // rtype must be kept in sync with ../runtime/type.go:/^type._type.
   150  type rtype struct {
   151  	size       uintptr
   152  	ptrdata    uintptr // number of bytes in the type that can contain pointers
   153  	hash       uint32  // hash of type; avoids computation in hash tables
   154  	tflag      tflag   // extra type information flags
   155  	align      uint8   // alignment of variable with this type
   156  	fieldAlign uint8   // alignment of struct field with this type
   157  	kind       uint8   // enumeration for C
   158  	// function for comparing objects of this type
   159  	// (ptr to object A, ptr to object B) -> ==?
   160  	equal     func(unsafe.Pointer, unsafe.Pointer) bool
   161  	gcdata    *byte   // garbage collection data
   162  	str       nameOff // string form
   163  	ptrToThis typeOff // type for pointer to this type, may be zero
   164  }
   165  
   166  // Method on non-interface type
   167  type method struct {
   168  	name nameOff // name of method
   169  	mtyp typeOff // method type (without receiver)
   170  	ifn  textOff // fn used in interface call (one-word receiver)
   171  	tfn  textOff // fn used for normal method call
   172  }
   173  
   174  // uncommonType is present only for defined types or types with methods
   175  // (if T is a defined type, the uncommonTypes for T and *T have methods).
   176  // Using a pointer to this struct reduces the overall size required
   177  // to describe a non-defined type with no methods.
   178  type uncommonType struct {
   179  	pkgPath nameOff // import path; empty for built-in types like int, string
   180  	mcount  uint16  // number of methods
   181  	xcount  uint16  // number of exported methods
   182  	moff    uint32  // offset from this uncommontype to [mcount]method
   183  	_       uint32  // unused
   184  }
   185  
   186  // chanDir represents a channel type's direction.
   187  type chanDir int
   188  
   189  const (
   190  	recvDir chanDir             = 1 << iota // <-chan
   191  	sendDir                                 // chan<-
   192  	bothDir = recvDir | sendDir             // chan
   193  )
   194  
   195  // arrayType represents a fixed array type.
   196  type arrayType struct {
   197  	rtype
   198  	elem  *rtype // array element type
   199  	slice *rtype // slice type
   200  	len   uintptr
   201  }
   202  
   203  // chanType represents a channel type.
   204  type chanType struct {
   205  	rtype
   206  	elem *rtype  // channel element type
   207  	dir  uintptr // channel direction (chanDir)
   208  }
   209  
   210  // funcType represents a function type.
   211  //
   212  // A *rtype for each in and out parameter is stored in an array that
   213  // directly follows the funcType (and possibly its uncommonType). So
   214  // a function type with one method, one input, and one output is:
   215  //
   216  //	struct {
   217  //		funcType
   218  //		uncommonType
   219  //		[2]*rtype    // [0] is in, [1] is out
   220  //	}
   221  type funcType struct {
   222  	rtype
   223  	inCount  uint16
   224  	outCount uint16 // top bit is set if last input parameter is ...
   225  }
   226  
   227  // imethod represents a method on an interface type
   228  type imethod struct {
   229  	name nameOff // name of method
   230  	typ  typeOff // .(*FuncType) underneath
   231  }
   232  
   233  // interfaceType represents an interface type.
   234  type interfaceType struct {
   235  	rtype
   236  	pkgPath name      // import path
   237  	methods []imethod // sorted by hash
   238  }
   239  
   240  // mapType represents a map type.
   241  type mapType struct {
   242  	rtype
   243  	key    *rtype // map key type
   244  	elem   *rtype // map element (value) type
   245  	bucket *rtype // internal bucket structure
   246  	// function for hashing keys (ptr to key, seed) -> hash
   247  	hasher     func(unsafe.Pointer, uintptr) uintptr
   248  	keysize    uint8  // size of key slot
   249  	valuesize  uint8  // size of value slot
   250  	bucketsize uint16 // size of bucket
   251  	flags      uint32
   252  }
   253  
   254  // ptrType represents a pointer type.
   255  type ptrType struct {
   256  	rtype
   257  	elem *rtype // pointer element (pointed at) type
   258  }
   259  
   260  // sliceType represents a slice type.
   261  type sliceType struct {
   262  	rtype
   263  	elem *rtype // slice element type
   264  }
   265  
   266  // Struct field
   267  type structField struct {
   268  	name        name    // name is always non-empty
   269  	typ         *rtype  // type of field
   270  	offsetEmbed uintptr // byte offset of field<<1 | isEmbedded
   271  }
   272  
   273  func (f *structField) offset() uintptr {
   274  	return f.offsetEmbed >> 1
   275  }
   276  
   277  func (f *structField) embedded() bool {
   278  	return f.offsetEmbed&1 != 0
   279  }
   280  
   281  // structType represents a struct type.
   282  type structType struct {
   283  	rtype
   284  	pkgPath name
   285  	fields  []structField // sorted by offset
   286  }
   287  
   288  // name is an encoded type name with optional extra data.
   289  //
   290  // The first byte is a bit field containing:
   291  //
   292  //	1<<0 the name is exported
   293  //	1<<1 tag data follows the name
   294  //	1<<2 pkgPath nameOff follows the name and tag
   295  //
   296  // The next two bytes are the data length:
   297  //
   298  //	 l := uint16(data[1])<<8 | uint16(data[2])
   299  //
   300  // Bytes [3:3+l] are the string data.
   301  //
   302  // If tag data follows then bytes 3+l and 3+l+1 are the tag length,
   303  // with the data following.
   304  //
   305  // If the import path follows, then 4 bytes at the end of
   306  // the data form a nameOff. The import path is only set for concrete
   307  // methods that are defined in a different package than their type.
   308  //
   309  // If a name starts with "*", then the exported bit represents
   310  // whether the pointed to type is exported.
   311  type name struct {
   312  	bytes *byte
   313  }
   314  
   315  func (n name) data(off int, whySafe string) *byte {
   316  	return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe))
   317  }
   318  
   319  func (n name) isExported() bool {
   320  	return (*n.bytes)&(1<<0) != 0
   321  }
   322  
   323  func (n name) nameLen() int {
   324  	return int(uint16(*n.data(1, "name len field"))<<8 | uint16(*n.data(2, "name len field")))
   325  }
   326  
   327  func (n name) tagLen() int {
   328  	if *n.data(0, "name flag field")&(1<<1) == 0 {
   329  		return 0
   330  	}
   331  	off := 3 + n.nameLen()
   332  	return int(uint16(*n.data(off, "name taglen field"))<<8 | uint16(*n.data(off+1, "name taglen field")))
   333  }
   334  
   335  func (n name) name() (s string) {
   336  	if n.bytes == nil {
   337  		return
   338  	}
   339  	b := (*[4]byte)(unsafe.Pointer(n.bytes))
   340  
   341  	hdr := (*stringHeader)(unsafe.Pointer(&s))
   342  	hdr.Data = unsafe.Pointer(&b[3])
   343  	hdr.Len = int(b[1])<<8 | int(b[2])
   344  	return s
   345  }
   346  
   347  func (n name) tag() (s string) {
   348  	tl := n.tagLen()
   349  	if tl == 0 {
   350  		return ""
   351  	}
   352  	nl := n.nameLen()
   353  	hdr := (*stringHeader)(unsafe.Pointer(&s))
   354  	hdr.Data = unsafe.Pointer(n.data(3+nl+2, "non-empty string"))
   355  	hdr.Len = tl
   356  	return s
   357  }
   358  
   359  func (n name) pkgPath() string {
   360  	if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
   361  		return ""
   362  	}
   363  	off := 3 + n.nameLen()
   364  	if tl := n.tagLen(); tl > 0 {
   365  		off += 2 + tl
   366  	}
   367  	var nameOff int32
   368  	// Note that this field may not be aligned in memory,
   369  	// so we cannot use a direct int32 assignment here.
   370  	copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:])
   371  	pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))}
   372  	return pkgPathName.name()
   373  }
   374  
   375  /*
   376   * The compiler knows the exact layout of all the data structures above.
   377   * The compiler does not know about the data structures and methods below.
   378   */
   379  
   380  const (
   381  	kindDirectIface = 1 << 5
   382  	kindGCProg      = 1 << 6 // Type.gc points to GC program
   383  	kindMask        = (1 << 5) - 1
   384  )
   385  
   386  func (t *uncommonType) methods() []method {
   387  	if t.mcount == 0 {
   388  		return nil
   389  	}
   390  	return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount]
   391  }
   392  
   393  func (t *uncommonType) exportedMethods() []method {
   394  	if t.xcount == 0 {
   395  		return nil
   396  	}
   397  	return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount]
   398  }
   399  
   400  // resolveNameOff resolves a name offset from a base pointer.
   401  // The (*rtype).nameOff method is a convenience wrapper for this function.
   402  // Implemented in the runtime package.
   403  func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
   404  
   405  // resolveTypeOff resolves an *rtype offset from a base type.
   406  // The (*rtype).typeOff method is a convenience wrapper for this function.
   407  // Implemented in the runtime package.
   408  func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
   409  
   410  type nameOff int32 // offset to a name
   411  type typeOff int32 // offset to an *rtype
   412  type textOff int32 // offset from top of text section
   413  
   414  func (t *rtype) nameOff(off nameOff) name {
   415  	return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
   416  }
   417  
   418  func (t *rtype) typeOff(off typeOff) *rtype {
   419  	return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
   420  }
   421  
   422  func (t *rtype) uncommon() *uncommonType {
   423  	if t.tflag&tflagUncommon == 0 {
   424  		return nil
   425  	}
   426  	switch t.Kind() {
   427  	case Struct:
   428  		return &(*structTypeUncommon)(unsafe.Pointer(t)).u
   429  	case Ptr:
   430  		type u struct {
   431  			ptrType
   432  			u uncommonType
   433  		}
   434  		return &(*u)(unsafe.Pointer(t)).u
   435  	case Func:
   436  		type u struct {
   437  			funcType
   438  			u uncommonType
   439  		}
   440  		return &(*u)(unsafe.Pointer(t)).u
   441  	case Slice:
   442  		type u struct {
   443  			sliceType
   444  			u uncommonType
   445  		}
   446  		return &(*u)(unsafe.Pointer(t)).u
   447  	case Array:
   448  		type u struct {
   449  			arrayType
   450  			u uncommonType
   451  		}
   452  		return &(*u)(unsafe.Pointer(t)).u
   453  	case Chan:
   454  		type u struct {
   455  			chanType
   456  			u uncommonType
   457  		}
   458  		return &(*u)(unsafe.Pointer(t)).u
   459  	case Map:
   460  		type u struct {
   461  			mapType
   462  			u uncommonType
   463  		}
   464  		return &(*u)(unsafe.Pointer(t)).u
   465  	case Interface:
   466  		type u struct {
   467  			interfaceType
   468  			u uncommonType
   469  		}
   470  		return &(*u)(unsafe.Pointer(t)).u
   471  	default:
   472  		type u struct {
   473  			rtype
   474  			u uncommonType
   475  		}
   476  		return &(*u)(unsafe.Pointer(t)).u
   477  	}
   478  }
   479  
   480  func (t *rtype) String() string {
   481  	s := t.nameOff(t.str).name()
   482  	if t.tflag&tflagExtraStar != 0 {
   483  		return s[1:]
   484  	}
   485  	return s
   486  }
   487  
   488  func (t *rtype) Size() uintptr { return t.size }
   489  
   490  func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
   491  
   492  func (t *rtype) pointers() bool { return t.ptrdata != 0 }
   493  
   494  func (t *rtype) common() *rtype { return t }
   495  
   496  func (t *rtype) exportedMethods() []method {
   497  	ut := t.uncommon()
   498  	if ut == nil {
   499  		return nil
   500  	}
   501  	return ut.exportedMethods()
   502  }
   503  
   504  func (t *rtype) NumMethod() int {
   505  	if t.Kind() == Interface {
   506  		tt := (*interfaceType)(unsafe.Pointer(t))
   507  		return tt.NumMethod()
   508  	}
   509  	return len(t.exportedMethods())
   510  }
   511  
   512  func (t *rtype) PkgPath() string {
   513  	if t.tflag&tflagNamed == 0 {
   514  		return ""
   515  	}
   516  	ut := t.uncommon()
   517  	if ut == nil {
   518  		return ""
   519  	}
   520  	return t.nameOff(ut.pkgPath).name()
   521  }
   522  
   523  func (t *rtype) hasName() bool {
   524  	return t.tflag&tflagNamed != 0
   525  }
   526  
   527  func (t *rtype) Name() string {
   528  	if !t.hasName() {
   529  		return ""
   530  	}
   531  	s := t.String()
   532  	i := len(s) - 1
   533  	for i >= 0 && s[i] != '.' {
   534  		i--
   535  	}
   536  	return s[i+1:]
   537  }
   538  
   539  func (t *rtype) chanDir() chanDir {
   540  	if t.Kind() != Chan {
   541  		panic("reflect: chanDir of non-chan type")
   542  	}
   543  	tt := (*chanType)(unsafe.Pointer(t))
   544  	return chanDir(tt.dir)
   545  }
   546  
   547  func (t *rtype) Elem() Type {
   548  	switch t.Kind() {
   549  	case Array:
   550  		tt := (*arrayType)(unsafe.Pointer(t))
   551  		return toType(tt.elem)
   552  	case Chan:
   553  		tt := (*chanType)(unsafe.Pointer(t))
   554  		return toType(tt.elem)
   555  	case Map:
   556  		tt := (*mapType)(unsafe.Pointer(t))
   557  		return toType(tt.elem)
   558  	case Ptr:
   559  		tt := (*ptrType)(unsafe.Pointer(t))
   560  		return toType(tt.elem)
   561  	case Slice:
   562  		tt := (*sliceType)(unsafe.Pointer(t))
   563  		return toType(tt.elem)
   564  	}
   565  	panic("reflect: Elem of invalid type")
   566  }
   567  
   568  func (t *rtype) In(i int) Type {
   569  	if t.Kind() != Func {
   570  		panic("reflect: In of non-func type")
   571  	}
   572  	tt := (*funcType)(unsafe.Pointer(t))
   573  	return toType(tt.in()[i])
   574  }
   575  
   576  func (t *rtype) Key() Type {
   577  	if t.Kind() != Map {
   578  		panic("reflect: Key of non-map type")
   579  	}
   580  	tt := (*mapType)(unsafe.Pointer(t))
   581  	return toType(tt.key)
   582  }
   583  
   584  func (t *rtype) Len() int {
   585  	if t.Kind() != Array {
   586  		panic("reflect: Len of non-array type")
   587  	}
   588  	tt := (*arrayType)(unsafe.Pointer(t))
   589  	return int(tt.len)
   590  }
   591  
   592  func (t *rtype) NumField() int {
   593  	if t.Kind() != Struct {
   594  		panic("reflect: NumField of non-struct type")
   595  	}
   596  	tt := (*structType)(unsafe.Pointer(t))
   597  	return len(tt.fields)
   598  }
   599  
   600  func (t *rtype) NumIn() int {
   601  	if t.Kind() != Func {
   602  		panic("reflect: NumIn of non-func type")
   603  	}
   604  	tt := (*funcType)(unsafe.Pointer(t))
   605  	return int(tt.inCount)
   606  }
   607  
   608  func (t *rtype) NumOut() int {
   609  	if t.Kind() != Func {
   610  		panic("reflect: NumOut of non-func type")
   611  	}
   612  	tt := (*funcType)(unsafe.Pointer(t))
   613  	return len(tt.out())
   614  }
   615  
   616  func (t *rtype) Out(i int) Type {
   617  	if t.Kind() != Func {
   618  		panic("reflect: Out of non-func type")
   619  	}
   620  	tt := (*funcType)(unsafe.Pointer(t))
   621  	return toType(tt.out()[i])
   622  }
   623  
   624  func (t *funcType) in() []*rtype {
   625  	uadd := unsafe.Sizeof(*t)
   626  	if t.tflag&tflagUncommon != 0 {
   627  		uadd += unsafe.Sizeof(uncommonType{})
   628  	}
   629  	if t.inCount == 0 {
   630  		return nil
   631  	}
   632  	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount]
   633  }
   634  
   635  func (t *funcType) out() []*rtype {
   636  	uadd := unsafe.Sizeof(*t)
   637  	if t.tflag&tflagUncommon != 0 {
   638  		uadd += unsafe.Sizeof(uncommonType{})
   639  	}
   640  	outCount := t.outCount & (1<<15 - 1)
   641  	if outCount == 0 {
   642  		return nil
   643  	}
   644  	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount]
   645  }
   646  
   647  // add returns p+x.
   648  //
   649  // The whySafe string is ignored, so that the function still inlines
   650  // as efficiently as p+x, but all call sites should use the string to
   651  // record why the addition is safe, which is to say why the addition
   652  // does not cause x to advance to the very end of p's allocation
   653  // and therefore point incorrectly at the next block in memory.
   654  func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
   655  	return unsafe.Pointer(uintptr(p) + x)
   656  }
   657  
   658  // NumMethod returns the number of interface methods in the type's method set.
   659  func (t *interfaceType) NumMethod() int { return len(t.methods) }
   660  
   661  // TypeOf returns the reflection Type that represents the dynamic type of i.
   662  // If i is a nil interface value, TypeOf returns nil.
   663  func TypeOf(i interface{}) Type {
   664  	eface := *(*emptyInterface)(unsafe.Pointer(&i))
   665  	return toType(eface.typ)
   666  }
   667  
   668  func (t *rtype) Implements(u Type) bool {
   669  	if u == nil {
   670  		panic("reflect: nil type passed to Type.Implements")
   671  	}
   672  	if u.Kind() != Interface {
   673  		panic("reflect: non-interface type passed to Type.Implements")
   674  	}
   675  	return implements(u.(*rtype), t)
   676  }
   677  
   678  func (t *rtype) AssignableTo(u Type) bool {
   679  	if u == nil {
   680  		panic("reflect: nil type passed to Type.AssignableTo")
   681  	}
   682  	uu := u.(*rtype)
   683  	return directlyAssignable(uu, t) || implements(uu, t)
   684  }
   685  
   686  func (t *rtype) Comparable() bool {
   687  	return t.equal != nil
   688  }
   689  
   690  // implements reports whether the type V implements the interface type T.
   691  func implements(T, V *rtype) bool {
   692  	if T.Kind() != Interface {
   693  		return false
   694  	}
   695  	t := (*interfaceType)(unsafe.Pointer(T))
   696  	if len(t.methods) == 0 {
   697  		return true
   698  	}
   699  
   700  	// The same algorithm applies in both cases, but the
   701  	// method tables for an interface type and a concrete type
   702  	// are different, so the code is duplicated.
   703  	// In both cases the algorithm is a linear scan over the two
   704  	// lists - T's methods and V's methods - simultaneously.
   705  	// Since method tables are stored in a unique sorted order
   706  	// (alphabetical, with no duplicate method names), the scan
   707  	// through V's methods must hit a match for each of T's
   708  	// methods along the way, or else V does not implement T.
   709  	// This lets us run the scan in overall linear time instead of
   710  	// the quadratic time  a naive search would require.
   711  	// See also ../runtime/iface.go.
   712  	if V.Kind() == Interface {
   713  		v := (*interfaceType)(unsafe.Pointer(V))
   714  		i := 0
   715  		for j := 0; j < len(v.methods); j++ {
   716  			tm := &t.methods[i]
   717  			tmName := t.nameOff(tm.name)
   718  			vm := &v.methods[j]
   719  			vmName := V.nameOff(vm.name)
   720  			if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) {
   721  				if !tmName.isExported() {
   722  					tmPkgPath := tmName.pkgPath()
   723  					if tmPkgPath == "" {
   724  						tmPkgPath = t.pkgPath.name()
   725  					}
   726  					vmPkgPath := vmName.pkgPath()
   727  					if vmPkgPath == "" {
   728  						vmPkgPath = v.pkgPath.name()
   729  					}
   730  					if tmPkgPath != vmPkgPath {
   731  						continue
   732  					}
   733  				}
   734  				if i++; i >= len(t.methods) {
   735  					return true
   736  				}
   737  			}
   738  		}
   739  		return false
   740  	}
   741  
   742  	v := V.uncommon()
   743  	if v == nil {
   744  		return false
   745  	}
   746  	i := 0
   747  	vmethods := v.methods()
   748  	for j := 0; j < int(v.mcount); j++ {
   749  		tm := &t.methods[i]
   750  		tmName := t.nameOff(tm.name)
   751  		vm := vmethods[j]
   752  		vmName := V.nameOff(vm.name)
   753  		if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) {
   754  			if !tmName.isExported() {
   755  				tmPkgPath := tmName.pkgPath()
   756  				if tmPkgPath == "" {
   757  					tmPkgPath = t.pkgPath.name()
   758  				}
   759  				vmPkgPath := vmName.pkgPath()
   760  				if vmPkgPath == "" {
   761  					vmPkgPath = V.nameOff(v.pkgPath).name()
   762  				}
   763  				if tmPkgPath != vmPkgPath {
   764  					continue
   765  				}
   766  			}
   767  			if i++; i >= len(t.methods) {
   768  				return true
   769  			}
   770  		}
   771  	}
   772  	return false
   773  }
   774  
   775  // directlyAssignable reports whether a value x of type V can be directly
   776  // assigned (using memmove) to a value of type T.
   777  // https://golang.org/doc/go_spec.html#Assignability
   778  // Ignoring the interface rules (implemented elsewhere)
   779  // and the ideal constant rules (no ideal constants at run time).
   780  func directlyAssignable(T, V *rtype) bool {
   781  	// x's type V is identical to T?
   782  	if T == V {
   783  		return true
   784  	}
   785  
   786  	// Otherwise at least one of T and V must not be defined
   787  	// and they must have the same kind.
   788  	if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
   789  		return false
   790  	}
   791  
   792  	// x's type T and V must  have identical underlying types.
   793  	return haveIdenticalUnderlyingType(T, V, true)
   794  }
   795  
   796  func haveIdenticalType(T, V Type, cmpTags bool) bool {
   797  	if cmpTags {
   798  		return T == V
   799  	}
   800  
   801  	if T.Name() != V.Name() || T.Kind() != V.Kind() {
   802  		return false
   803  	}
   804  
   805  	return haveIdenticalUnderlyingType(T.common(), V.common(), false)
   806  }
   807  
   808  func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
   809  	if T == V {
   810  		return true
   811  	}
   812  
   813  	kind := T.Kind()
   814  	if kind != V.Kind() {
   815  		return false
   816  	}
   817  
   818  	// Non-composite types of equal kind have same underlying type
   819  	// (the predefined instance of the type).
   820  	if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
   821  		return true
   822  	}
   823  
   824  	// Composite types.
   825  	switch kind {
   826  	case Array:
   827  		return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   828  
   829  	case Chan:
   830  		// Special case:
   831  		// x is a bidirectional channel value, T is a channel type,
   832  		// and x's type V and T have identical element types.
   833  		if V.chanDir() == bothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) {
   834  			return true
   835  		}
   836  
   837  		// Otherwise continue test for identical underlying type.
   838  		return V.chanDir() == T.chanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   839  
   840  	case Func:
   841  		t := (*funcType)(unsafe.Pointer(T))
   842  		v := (*funcType)(unsafe.Pointer(V))
   843  		if t.outCount != v.outCount || t.inCount != v.inCount {
   844  			return false
   845  		}
   846  		for i := 0; i < t.NumIn(); i++ {
   847  			if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
   848  				return false
   849  			}
   850  		}
   851  		for i := 0; i < t.NumOut(); i++ {
   852  			if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
   853  				return false
   854  			}
   855  		}
   856  		return true
   857  
   858  	case Interface:
   859  		t := (*interfaceType)(unsafe.Pointer(T))
   860  		v := (*interfaceType)(unsafe.Pointer(V))
   861  		if len(t.methods) == 0 && len(v.methods) == 0 {
   862  			return true
   863  		}
   864  		// Might have the same methods but still
   865  		// need a run time conversion.
   866  		return false
   867  
   868  	case Map:
   869  		return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   870  
   871  	case Ptr, Slice:
   872  		return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   873  
   874  	case Struct:
   875  		t := (*structType)(unsafe.Pointer(T))
   876  		v := (*structType)(unsafe.Pointer(V))
   877  		if len(t.fields) != len(v.fields) {
   878  			return false
   879  		}
   880  		if t.pkgPath.name() != v.pkgPath.name() {
   881  			return false
   882  		}
   883  		for i := range t.fields {
   884  			tf := &t.fields[i]
   885  			vf := &v.fields[i]
   886  			if tf.name.name() != vf.name.name() {
   887  				return false
   888  			}
   889  			if !haveIdenticalType(tf.typ, vf.typ, cmpTags) {
   890  				return false
   891  			}
   892  			if cmpTags && tf.name.tag() != vf.name.tag() {
   893  				return false
   894  			}
   895  			if tf.offsetEmbed != vf.offsetEmbed {
   896  				return false
   897  			}
   898  		}
   899  		return true
   900  	}
   901  
   902  	return false
   903  }
   904  
   905  type structTypeUncommon struct {
   906  	structType
   907  	u uncommonType
   908  }
   909  
   910  // toType converts from a *rtype to a Type that can be returned
   911  // to the client of package reflect. In gc, the only concern is that
   912  // a nil *rtype must be replaced by a nil Type, but in gccgo this
   913  // function takes care of ensuring that multiple *rtype for the same
   914  // type are coalesced into a single Type.
   915  func toType(t *rtype) Type {
   916  	if t == nil {
   917  		return nil
   918  	}
   919  	return t
   920  }
   921  
   922  // ifaceIndir reports whether t is stored indirectly in an interface value.
   923  func ifaceIndir(t *rtype) bool {
   924  	return t.kind&kindDirectIface == 0
   925  }