Black Lives Matter. Support the Equal Justice Initiative.

Source file src/internal/reflectlite/type.go

Documentation: internal/reflectlite

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

View as plain text