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