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