github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/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  	"github.com/hxx258456/ccgo/internal/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/reflectdata/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/reflectdata/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) hasTag() bool {
   326  	return (*n.bytes)&(1<<1) != 0
   327  }
   328  
   329  // readVarint parses a varint as encoded by encoding/binary.
   330  // It returns the number of encoded bytes and the encoded value.
   331  func (n name) readVarint(off int) (int, int) {
   332  	v := 0
   333  	for i := 0; ; i++ {
   334  		x := *n.data(off+i, "read varint")
   335  		v += int(x&0x7f) << (7 * i)
   336  		if x&0x80 == 0 {
   337  			return i + 1, v
   338  		}
   339  	}
   340  }
   341  
   342  func (n name) name() (s string) {
   343  	if n.bytes == nil {
   344  		return
   345  	}
   346  	i, l := n.readVarint(1)
   347  	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
   348  	hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string"))
   349  	hdr.Len = l
   350  	return
   351  }
   352  
   353  func (n name) tag() (s string) {
   354  	if !n.hasTag() {
   355  		return ""
   356  	}
   357  	i, l := n.readVarint(1)
   358  	i2, l2 := n.readVarint(1 + i + l)
   359  	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
   360  	hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string"))
   361  	hdr.Len = l2
   362  	return
   363  }
   364  
   365  func (n name) pkgPath() string {
   366  	if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
   367  		return ""
   368  	}
   369  	i, l := n.readVarint(1)
   370  	off := 1 + i + l
   371  	if n.hasTag() {
   372  		i2, l2 := n.readVarint(off)
   373  		off += i2 + l2
   374  	}
   375  	var nameOff int32
   376  	// Note that this field may not be aligned in memory,
   377  	// so we cannot use a direct int32 assignment here.
   378  	copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:])
   379  	pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))}
   380  	return pkgPathName.name()
   381  }
   382  
   383  /*
   384   * The compiler knows the exact layout of all the data structures above.
   385   * The compiler does not know about the data structures and methods below.
   386   */
   387  
   388  const (
   389  	kindDirectIface = 1 << 5
   390  	kindGCProg      = 1 << 6 // Type.gc points to GC program
   391  	kindMask        = (1 << 5) - 1
   392  )
   393  
   394  // String returns the name of k.
   395  func (k Kind) String() string {
   396  	if int(k) < len(kindNames) {
   397  		return kindNames[k]
   398  	}
   399  	return kindNames[0]
   400  }
   401  
   402  var kindNames = []string{
   403  	Invalid:       "invalid",
   404  	Bool:          "bool",
   405  	Int:           "int",
   406  	Int8:          "int8",
   407  	Int16:         "int16",
   408  	Int32:         "int32",
   409  	Int64:         "int64",
   410  	Uint:          "uint",
   411  	Uint8:         "uint8",
   412  	Uint16:        "uint16",
   413  	Uint32:        "uint32",
   414  	Uint64:        "uint64",
   415  	Uintptr:       "uintptr",
   416  	Float32:       "float32",
   417  	Float64:       "float64",
   418  	Complex64:     "complex64",
   419  	Complex128:    "complex128",
   420  	Array:         "array",
   421  	Chan:          "chan",
   422  	Func:          "func",
   423  	Interface:     "interface",
   424  	Map:           "map",
   425  	Ptr:           "ptr",
   426  	Slice:         "slice",
   427  	String:        "string",
   428  	Struct:        "struct",
   429  	UnsafePointer: "unsafe.Pointer",
   430  }
   431  
   432  func (t *uncommonType) methods() []method {
   433  	if t.mcount == 0 {
   434  		return nil
   435  	}
   436  	return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount]
   437  }
   438  
   439  func (t *uncommonType) exportedMethods() []method {
   440  	if t.xcount == 0 {
   441  		return nil
   442  	}
   443  	return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount]
   444  }
   445  
   446  // resolveNameOff resolves a name offset from a base pointer.
   447  // The (*rtype).nameOff method is a convenience wrapper for this function.
   448  // Implemented in the runtime package.
   449  func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
   450  
   451  // resolveTypeOff resolves an *rtype offset from a base type.
   452  // The (*rtype).typeOff method is a convenience wrapper for this function.
   453  // Implemented in the runtime package.
   454  func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
   455  
   456  type nameOff int32 // offset to a name
   457  type typeOff int32 // offset to an *rtype
   458  type textOff int32 // offset from top of text section
   459  
   460  func (t *rtype) nameOff(off nameOff) name {
   461  	return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
   462  }
   463  
   464  func (t *rtype) typeOff(off typeOff) *rtype {
   465  	return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
   466  }
   467  
   468  func (t *rtype) uncommon() *uncommonType {
   469  	if t.tflag&tflagUncommon == 0 {
   470  		return nil
   471  	}
   472  	switch t.Kind() {
   473  	case Struct:
   474  		return &(*structTypeUncommon)(unsafe.Pointer(t)).u
   475  	case Ptr:
   476  		type u struct {
   477  			ptrType
   478  			u uncommonType
   479  		}
   480  		return &(*u)(unsafe.Pointer(t)).u
   481  	case Func:
   482  		type u struct {
   483  			funcType
   484  			u uncommonType
   485  		}
   486  		return &(*u)(unsafe.Pointer(t)).u
   487  	case Slice:
   488  		type u struct {
   489  			sliceType
   490  			u uncommonType
   491  		}
   492  		return &(*u)(unsafe.Pointer(t)).u
   493  	case Array:
   494  		type u struct {
   495  			arrayType
   496  			u uncommonType
   497  		}
   498  		return &(*u)(unsafe.Pointer(t)).u
   499  	case Chan:
   500  		type u struct {
   501  			chanType
   502  			u uncommonType
   503  		}
   504  		return &(*u)(unsafe.Pointer(t)).u
   505  	case Map:
   506  		type u struct {
   507  			mapType
   508  			u uncommonType
   509  		}
   510  		return &(*u)(unsafe.Pointer(t)).u
   511  	case Interface:
   512  		type u struct {
   513  			interfaceType
   514  			u uncommonType
   515  		}
   516  		return &(*u)(unsafe.Pointer(t)).u
   517  	default:
   518  		type u struct {
   519  			rtype
   520  			u uncommonType
   521  		}
   522  		return &(*u)(unsafe.Pointer(t)).u
   523  	}
   524  }
   525  
   526  func (t *rtype) String() string {
   527  	s := t.nameOff(t.str).name()
   528  	if t.tflag&tflagExtraStar != 0 {
   529  		return s[1:]
   530  	}
   531  	return s
   532  }
   533  
   534  func (t *rtype) Size() uintptr { return t.size }
   535  
   536  func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
   537  
   538  func (t *rtype) pointers() bool { return t.ptrdata != 0 }
   539  
   540  func (t *rtype) common() *rtype { return t }
   541  
   542  func (t *rtype) exportedMethods() []method {
   543  	ut := t.uncommon()
   544  	if ut == nil {
   545  		return nil
   546  	}
   547  	return ut.exportedMethods()
   548  }
   549  
   550  func (t *rtype) NumMethod() int {
   551  	if t.Kind() == Interface {
   552  		tt := (*interfaceType)(unsafe.Pointer(t))
   553  		return tt.NumMethod()
   554  	}
   555  	return len(t.exportedMethods())
   556  }
   557  
   558  func (t *rtype) PkgPath() string {
   559  	if t.tflag&tflagNamed == 0 {
   560  		return ""
   561  	}
   562  	ut := t.uncommon()
   563  	if ut == nil {
   564  		return ""
   565  	}
   566  	return t.nameOff(ut.pkgPath).name()
   567  }
   568  
   569  func (t *rtype) hasName() bool {
   570  	return t.tflag&tflagNamed != 0
   571  }
   572  
   573  func (t *rtype) Name() string {
   574  	if !t.hasName() {
   575  		return ""
   576  	}
   577  	s := t.String()
   578  	i := len(s) - 1
   579  	for i >= 0 && s[i] != '.' {
   580  		i--
   581  	}
   582  	return s[i+1:]
   583  }
   584  
   585  func (t *rtype) chanDir() chanDir {
   586  	if t.Kind() != Chan {
   587  		panic("reflect: chanDir of non-chan type")
   588  	}
   589  	tt := (*chanType)(unsafe.Pointer(t))
   590  	return chanDir(tt.dir)
   591  }
   592  
   593  func (t *rtype) Elem() Type {
   594  	switch t.Kind() {
   595  	case Array:
   596  		tt := (*arrayType)(unsafe.Pointer(t))
   597  		return toType(tt.elem)
   598  	case Chan:
   599  		tt := (*chanType)(unsafe.Pointer(t))
   600  		return toType(tt.elem)
   601  	case Map:
   602  		tt := (*mapType)(unsafe.Pointer(t))
   603  		return toType(tt.elem)
   604  	case Ptr:
   605  		tt := (*ptrType)(unsafe.Pointer(t))
   606  		return toType(tt.elem)
   607  	case Slice:
   608  		tt := (*sliceType)(unsafe.Pointer(t))
   609  		return toType(tt.elem)
   610  	}
   611  	panic("reflect: Elem of invalid type")
   612  }
   613  
   614  func (t *rtype) In(i int) Type {
   615  	if t.Kind() != Func {
   616  		panic("reflect: In of non-func type")
   617  	}
   618  	tt := (*funcType)(unsafe.Pointer(t))
   619  	return toType(tt.in()[i])
   620  }
   621  
   622  func (t *rtype) Key() Type {
   623  	if t.Kind() != Map {
   624  		panic("reflect: Key of non-map type")
   625  	}
   626  	tt := (*mapType)(unsafe.Pointer(t))
   627  	return toType(tt.key)
   628  }
   629  
   630  func (t *rtype) Len() int {
   631  	if t.Kind() != Array {
   632  		panic("reflect: Len of non-array type")
   633  	}
   634  	tt := (*arrayType)(unsafe.Pointer(t))
   635  	return int(tt.len)
   636  }
   637  
   638  func (t *rtype) NumField() int {
   639  	if t.Kind() != Struct {
   640  		panic("reflect: NumField of non-struct type")
   641  	}
   642  	tt := (*structType)(unsafe.Pointer(t))
   643  	return len(tt.fields)
   644  }
   645  
   646  func (t *rtype) NumIn() int {
   647  	if t.Kind() != Func {
   648  		panic("reflect: NumIn of non-func type")
   649  	}
   650  	tt := (*funcType)(unsafe.Pointer(t))
   651  	return int(tt.inCount)
   652  }
   653  
   654  func (t *rtype) NumOut() int {
   655  	if t.Kind() != Func {
   656  		panic("reflect: NumOut of non-func type")
   657  	}
   658  	tt := (*funcType)(unsafe.Pointer(t))
   659  	return len(tt.out())
   660  }
   661  
   662  func (t *rtype) Out(i int) Type {
   663  	if t.Kind() != Func {
   664  		panic("reflect: Out of non-func type")
   665  	}
   666  	tt := (*funcType)(unsafe.Pointer(t))
   667  	return toType(tt.out()[i])
   668  }
   669  
   670  func (t *funcType) in() []*rtype {
   671  	uadd := unsafe.Sizeof(*t)
   672  	if t.tflag&tflagUncommon != 0 {
   673  		uadd += unsafe.Sizeof(uncommonType{})
   674  	}
   675  	if t.inCount == 0 {
   676  		return nil
   677  	}
   678  	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount]
   679  }
   680  
   681  func (t *funcType) out() []*rtype {
   682  	uadd := unsafe.Sizeof(*t)
   683  	if t.tflag&tflagUncommon != 0 {
   684  		uadd += unsafe.Sizeof(uncommonType{})
   685  	}
   686  	outCount := t.outCount & (1<<15 - 1)
   687  	if outCount == 0 {
   688  		return nil
   689  	}
   690  	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount]
   691  }
   692  
   693  // add returns p+x.
   694  //
   695  // The whySafe string is ignored, so that the function still inlines
   696  // as efficiently as p+x, but all call sites should use the string to
   697  // record why the addition is safe, which is to say why the addition
   698  // does not cause x to advance to the very end of p's allocation
   699  // and therefore point incorrectly at the next block in memory.
   700  func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
   701  	return unsafe.Pointer(uintptr(p) + x)
   702  }
   703  
   704  // NumMethod returns the number of interface methods in the type's method set.
   705  func (t *interfaceType) NumMethod() int { return len(t.methods) }
   706  
   707  // TypeOf returns the reflection Type that represents the dynamic type of i.
   708  // If i is a nil interface value, TypeOf returns nil.
   709  func TypeOf(i interface{}) Type {
   710  	eface := *(*emptyInterface)(unsafe.Pointer(&i))
   711  	return toType(eface.typ)
   712  }
   713  
   714  func (t *rtype) Implements(u Type) bool {
   715  	if u == nil {
   716  		panic("reflect: nil type passed to Type.Implements")
   717  	}
   718  	if u.Kind() != Interface {
   719  		panic("reflect: non-interface type passed to Type.Implements")
   720  	}
   721  	return implements(u.(*rtype), t)
   722  }
   723  
   724  func (t *rtype) AssignableTo(u Type) bool {
   725  	if u == nil {
   726  		panic("reflect: nil type passed to Type.AssignableTo")
   727  	}
   728  	uu := u.(*rtype)
   729  	return directlyAssignable(uu, t) || implements(uu, t)
   730  }
   731  
   732  func (t *rtype) Comparable() bool {
   733  	return t.equal != nil
   734  }
   735  
   736  // implements reports whether the type V implements the interface type T.
   737  func implements(T, V *rtype) bool {
   738  	if T.Kind() != Interface {
   739  		return false
   740  	}
   741  	t := (*interfaceType)(unsafe.Pointer(T))
   742  	if len(t.methods) == 0 {
   743  		return true
   744  	}
   745  
   746  	// The same algorithm applies in both cases, but the
   747  	// method tables for an interface type and a concrete type
   748  	// are different, so the code is duplicated.
   749  	// In both cases the algorithm is a linear scan over the two
   750  	// lists - T's methods and V's methods - simultaneously.
   751  	// Since method tables are stored in a unique sorted order
   752  	// (alphabetical, with no duplicate method names), the scan
   753  	// through V's methods must hit a match for each of T's
   754  	// methods along the way, or else V does not implement T.
   755  	// This lets us run the scan in overall linear time instead of
   756  	// the quadratic time  a naive search would require.
   757  	// See also ../runtime/iface.go.
   758  	if V.Kind() == Interface {
   759  		v := (*interfaceType)(unsafe.Pointer(V))
   760  		i := 0
   761  		for j := 0; j < len(v.methods); j++ {
   762  			tm := &t.methods[i]
   763  			tmName := t.nameOff(tm.name)
   764  			vm := &v.methods[j]
   765  			vmName := V.nameOff(vm.name)
   766  			if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) {
   767  				if !tmName.isExported() {
   768  					tmPkgPath := tmName.pkgPath()
   769  					if tmPkgPath == "" {
   770  						tmPkgPath = t.pkgPath.name()
   771  					}
   772  					vmPkgPath := vmName.pkgPath()
   773  					if vmPkgPath == "" {
   774  						vmPkgPath = v.pkgPath.name()
   775  					}
   776  					if tmPkgPath != vmPkgPath {
   777  						continue
   778  					}
   779  				}
   780  				if i++; i >= len(t.methods) {
   781  					return true
   782  				}
   783  			}
   784  		}
   785  		return false
   786  	}
   787  
   788  	v := V.uncommon()
   789  	if v == nil {
   790  		return false
   791  	}
   792  	i := 0
   793  	vmethods := v.methods()
   794  	for j := 0; j < int(v.mcount); j++ {
   795  		tm := &t.methods[i]
   796  		tmName := t.nameOff(tm.name)
   797  		vm := vmethods[j]
   798  		vmName := V.nameOff(vm.name)
   799  		if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) {
   800  			if !tmName.isExported() {
   801  				tmPkgPath := tmName.pkgPath()
   802  				if tmPkgPath == "" {
   803  					tmPkgPath = t.pkgPath.name()
   804  				}
   805  				vmPkgPath := vmName.pkgPath()
   806  				if vmPkgPath == "" {
   807  					vmPkgPath = V.nameOff(v.pkgPath).name()
   808  				}
   809  				if tmPkgPath != vmPkgPath {
   810  					continue
   811  				}
   812  			}
   813  			if i++; i >= len(t.methods) {
   814  				return true
   815  			}
   816  		}
   817  	}
   818  	return false
   819  }
   820  
   821  // directlyAssignable reports whether a value x of type V can be directly
   822  // assigned (using memmove) to a value of type T.
   823  // https://golang.org/doc/go_spec.html#Assignability
   824  // Ignoring the interface rules (implemented elsewhere)
   825  // and the ideal constant rules (no ideal constants at run time).
   826  func directlyAssignable(T, V *rtype) bool {
   827  	// x's type V is identical to T?
   828  	if T == V {
   829  		return true
   830  	}
   831  
   832  	// Otherwise at least one of T and V must not be defined
   833  	// and they must have the same kind.
   834  	if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
   835  		return false
   836  	}
   837  
   838  	// x's type T and V must  have identical underlying types.
   839  	return haveIdenticalUnderlyingType(T, V, true)
   840  }
   841  
   842  func haveIdenticalType(T, V Type, cmpTags bool) bool {
   843  	if cmpTags {
   844  		return T == V
   845  	}
   846  
   847  	if T.Name() != V.Name() || T.Kind() != V.Kind() {
   848  		return false
   849  	}
   850  
   851  	return haveIdenticalUnderlyingType(T.common(), V.common(), false)
   852  }
   853  
   854  func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
   855  	if T == V {
   856  		return true
   857  	}
   858  
   859  	kind := T.Kind()
   860  	if kind != V.Kind() {
   861  		return false
   862  	}
   863  
   864  	// Non-composite types of equal kind have same underlying type
   865  	// (the predefined instance of the type).
   866  	if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
   867  		return true
   868  	}
   869  
   870  	// Composite types.
   871  	switch kind {
   872  	case Array:
   873  		return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   874  
   875  	case Chan:
   876  		// Special case:
   877  		// x is a bidirectional channel value, T is a channel type,
   878  		// and x's type V and T have identical element types.
   879  		if V.chanDir() == bothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) {
   880  			return true
   881  		}
   882  
   883  		// Otherwise continue test for identical underlying type.
   884  		return V.chanDir() == T.chanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   885  
   886  	case Func:
   887  		t := (*funcType)(unsafe.Pointer(T))
   888  		v := (*funcType)(unsafe.Pointer(V))
   889  		if t.outCount != v.outCount || t.inCount != v.inCount {
   890  			return false
   891  		}
   892  		for i := 0; i < t.NumIn(); i++ {
   893  			if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
   894  				return false
   895  			}
   896  		}
   897  		for i := 0; i < t.NumOut(); i++ {
   898  			if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
   899  				return false
   900  			}
   901  		}
   902  		return true
   903  
   904  	case Interface:
   905  		t := (*interfaceType)(unsafe.Pointer(T))
   906  		v := (*interfaceType)(unsafe.Pointer(V))
   907  		if len(t.methods) == 0 && len(v.methods) == 0 {
   908  			return true
   909  		}
   910  		// Might have the same methods but still
   911  		// need a run time conversion.
   912  		return false
   913  
   914  	case Map:
   915  		return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   916  
   917  	case Ptr, Slice:
   918  		return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   919  
   920  	case Struct:
   921  		t := (*structType)(unsafe.Pointer(T))
   922  		v := (*structType)(unsafe.Pointer(V))
   923  		if len(t.fields) != len(v.fields) {
   924  			return false
   925  		}
   926  		if t.pkgPath.name() != v.pkgPath.name() {
   927  			return false
   928  		}
   929  		for i := range t.fields {
   930  			tf := &t.fields[i]
   931  			vf := &v.fields[i]
   932  			if tf.name.name() != vf.name.name() {
   933  				return false
   934  			}
   935  			if !haveIdenticalType(tf.typ, vf.typ, cmpTags) {
   936  				return false
   937  			}
   938  			if cmpTags && tf.name.tag() != vf.name.tag() {
   939  				return false
   940  			}
   941  			if tf.offsetEmbed != vf.offsetEmbed {
   942  				return false
   943  			}
   944  		}
   945  		return true
   946  	}
   947  
   948  	return false
   949  }
   950  
   951  type structTypeUncommon struct {
   952  	structType
   953  	u uncommonType
   954  }
   955  
   956  // toType converts from a *rtype to a Type that can be returned
   957  // to the client of package reflect. In gc, the only concern is that
   958  // a nil *rtype must be replaced by a nil Type, but in gccgo this
   959  // function takes care of ensuring that multiple *rtype for the same
   960  // type are coalesced into a single Type.
   961  func toType(t *rtype) Type {
   962  	if t == nil {
   963  		return nil
   964  	}
   965  	return t
   966  }
   967  
   968  // ifaceIndir reports whether t is stored indirectly in an interface value.
   969  func ifaceIndir(t *rtype) bool {
   970  	return t.kind&kindDirectIface == 0
   971  }