github.com/eh-steve/goloader@v0.0.0-20240111193454-90ff3cfdae39/reflectlite/reflectlite1.19/type.go (about)

     1  package reflectlite
     2  
     3  import (
     4  	"github.com/eh-steve/goloader/reflectlite/internal/unsafeheader"
     5  	"strconv"
     6  	"sync"
     7  	"unsafe"
     8  )
     9  
    10  // Type is the representation of a Go type.
    11  //
    12  // Not all methods apply to all kinds of types. Restrictions,
    13  // if any, are noted in the documentation for each method.
    14  // Use the Kind method to find out the kind of type before
    15  // calling kind-specific methods. Calling a method
    16  // inappropriate to the kind of type causes a run-time panic.
    17  //
    18  // Type values are comparable, such as with the == operator,
    19  // so they can be used as map keys.
    20  // Two Type values are equal if they represent identical types.
    21  type Type interface {
    22  
    23  	// NumMethod returns the number of methods accessible using Method.
    24  	//
    25  	// For a non-interface type, it returns the number of exported methods.
    26  	//
    27  	// For an interface type, it returns the number of exported and unexported methods.
    28  	NumMethod() int
    29  
    30  	// Name returns the type's name within its package for a defined type.
    31  	// For other (non-defined) types it returns the empty string.
    32  	Name() string
    33  
    34  	// PkgPath returns a defined type's package path, that is, the import path
    35  	// that uniquely identifies the package, such as "encoding/base64".
    36  	// If the type was predeclared (string, error) or not defined (*T, struct{},
    37  	// []int, or A where A is an alias for a non-defined type), the package path
    38  	// will be the empty string.
    39  	PkgPath() string
    40  
    41  	// String returns a string representation of the type.
    42  	// The string representation may use shortened package names
    43  	// (e.g., base64 instead of "encoding/base64") and is not
    44  	// guaranteed to be unique among types. To test for type identity,
    45  	// compare the Types directly.
    46  	String() string
    47  
    48  	// Kind returns the specific kind of this type.
    49  	Kind() Kind
    50  
    51  	// ConvertibleTo reports whether a value of the type is convertible to type u.
    52  	// Even if ConvertibleTo returns true, the conversion may still panic.
    53  	// For example, a slice of type []T is convertible to *[N]T,
    54  	// but the conversion will panic if its length is less than N.
    55  	ConvertibleTo(u Type) bool
    56  
    57  	ConvertibleToWithInterface(u Type) bool
    58  
    59  	// ChanDir returns a channel type's direction.
    60  	// It panics if the type's Kind is not Chan.
    61  	ChanDir() ChanDir
    62  
    63  	// IsVariadic reports whether a function type's final input parameter
    64  	// is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's
    65  	// implicit actual type []T.
    66  	//
    67  	// For concreteness, if t represents func(x int, y ... float64), then
    68  	//
    69  	//	t.NumIn() == 2
    70  	//	t.In(0) is the reflect.Type for "int"
    71  	//	t.In(1) is the reflect.Type for "[]float64"
    72  	//	t.IsVariadic() == true
    73  	//
    74  	// IsVariadic panics if the type's Kind is not Func.
    75  	IsVariadic() bool
    76  
    77  	// Elem returns a type's element type.
    78  	// It panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice.
    79  	Elem() Type
    80  
    81  	// Field returns a struct type's i'th field.
    82  	// It panics if the type's Kind is not Struct.
    83  	// It panics if i is not in the range [0, NumField()).
    84  	Field(i int) StructField
    85  
    86  	// In returns the type of a function type's i'th input parameter.
    87  	// It panics if the type's Kind is not Func.
    88  	// It panics if i is not in the range [0, NumIn()).
    89  	In(i int) Type
    90  
    91  	// Key returns a map type's key type.
    92  	// It panics if the type's Kind is not Map.
    93  	Key() Type
    94  
    95  	// Len returns an array type's length.
    96  	// It panics if the type's Kind is not Array.
    97  	Len() int
    98  
    99  	// NumField returns a struct type's field count.
   100  	// It panics if the type's Kind is not Struct.
   101  	NumField() int
   102  
   103  	// NumIn returns a function type's input parameter count.
   104  	// It panics if the type's Kind is not Func.
   105  	NumIn() int
   106  
   107  	// NumOut returns a function type's output parameter count.
   108  	// It panics if the type's Kind is not Func.
   109  	NumOut() int
   110  
   111  	// Out returns the type of a function type's i'th output parameter.
   112  	// It panics if the type's Kind is not Func.
   113  	// It panics if i is not in the range [0, NumOut()).
   114  	Out(i int) Type
   115  
   116  	common() *rtype
   117  	uncommon() *uncommonType
   118  }
   119  
   120  var _ Type = (*rtype)(nil)
   121  
   122  // A Kind represents the specific kind of type that a Type represents.
   123  // The zero Kind is not a valid kind.
   124  type Kind uint
   125  
   126  const (
   127  	Invalid Kind = iota
   128  	Bool
   129  	Int
   130  	Int8
   131  	Int16
   132  	Int32
   133  	Int64
   134  	Uint
   135  	Uint8
   136  	Uint16
   137  	Uint32
   138  	Uint64
   139  	Uintptr
   140  	Float32
   141  	Float64
   142  	Complex64
   143  	Complex128
   144  	Array
   145  	Chan
   146  	Func
   147  	Interface
   148  	Map
   149  	Pointer
   150  	Slice
   151  	String
   152  	Struct
   153  	UnsafePointer
   154  )
   155  
   156  // Ptr is the old name for the Pointer kind.
   157  const Ptr = Pointer
   158  
   159  var kindNames = []string{
   160  	Invalid:       "invalid",
   161  	Bool:          "bool",
   162  	Int:           "int",
   163  	Int8:          "int8",
   164  	Int16:         "int16",
   165  	Int32:         "int32",
   166  	Int64:         "int64",
   167  	Uint:          "uint",
   168  	Uint8:         "uint8",
   169  	Uint16:        "uint16",
   170  	Uint32:        "uint32",
   171  	Uint64:        "uint64",
   172  	Uintptr:       "uintptr",
   173  	Float32:       "float32",
   174  	Float64:       "float64",
   175  	Complex64:     "complex64",
   176  	Complex128:    "complex128",
   177  	Array:         "array",
   178  	Chan:          "chan",
   179  	Func:          "func",
   180  	Interface:     "interface",
   181  	Map:           "map",
   182  	Pointer:       "ptr",
   183  	Slice:         "slice",
   184  	String:        "string",
   185  	Struct:        "struct",
   186  	UnsafePointer: "unsafe.Pointer",
   187  }
   188  
   189  // String returns the name of k.
   190  func (k Kind) String() string {
   191  	if uint(k) < uint(len(kindNames)) {
   192  		return kindNames[uint(k)]
   193  	}
   194  	return "kind" + strconv.Itoa(int(k))
   195  }
   196  
   197  // tflag is used by an rtype to signal what extra type information is
   198  // available in the memory directly following the rtype value.
   199  //
   200  // tflag values must be kept in sync with copies in:
   201  //
   202  //	cmd/compile/internal/reflectdata/reflect.go
   203  //	cmd/link/internal/ld/decodesym.go
   204  //	runtime/type.go
   205  type tflag uint8
   206  
   207  const (
   208  	// tflagUncommon means that there is a pointer, *uncommonType,
   209  	// just beyond the outer type structure.
   210  	//
   211  	// For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0,
   212  	// then t has uncommonType data and it can be accessed as:
   213  	//
   214  	//	type tUncommon struct {
   215  	//		structType
   216  	//		u uncommonType
   217  	//	}
   218  	//	u := &(*tUncommon)(unsafe.Pointer(t)).u
   219  	tflagUncommon tflag = 1 << 0
   220  
   221  	// tflagExtraStar means the name in the str field has an
   222  	// extraneous '*' prefix. This is because for most types T in
   223  	// a program, the type *T also exists and reusing the str data
   224  	// saves binary size.
   225  	tflagExtraStar tflag = 1 << 1
   226  
   227  	// tflagNamed means the type has a name.
   228  	tflagNamed tflag = 1 << 2
   229  
   230  	// tflagRegularMemory means that equal and hash functions can treat
   231  	// this type as a single region of t.size bytes.
   232  	tflagRegularMemory tflag = 1 << 3
   233  )
   234  
   235  const (
   236  	kindDirectIface = 1 << 5
   237  	kindGCProg      = 1 << 6 // Type.gc points to GC program
   238  	kindMask        = (1 << 5) - 1
   239  )
   240  
   241  // resolveNameOff resolves a name offset from a base pointer.
   242  // The (*rtype).nameOff method is a convenience wrapper for this function.
   243  // Implemented in the runtime package.
   244  //
   245  //go:linkname resolveNameOff reflect.resolveNameOff
   246  func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
   247  
   248  // resolveTypeOff resolves an *rtype offset from a base type.
   249  // The (*rtype).typeOff method is a convenience wrapper for this function.
   250  // Implemented in the runtime package.
   251  //
   252  //go:linkname resolveTypeOff reflect.resolveTypeOff
   253  func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
   254  
   255  // resolveTextOff resolves a function pointer offset from a base type.
   256  // The (*rtype).textOff method is a convenience wrapper for this function.
   257  // Implemented in the runtime package.
   258  //
   259  //go:linkname resolveTextOff reflect.resolveTextOff
   260  func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
   261  
   262  //go:linkname addReflectOff reflect.addReflectOff
   263  func addReflectOff(ptr unsafe.Pointer) int32
   264  
   265  // resolveReflectName adds a name to the reflection lookup map in the runtime.
   266  // It returns a new nameOff that can be used to refer to the pointer.
   267  func resolveReflectName(n name) nameOff {
   268  	return nameOff(addReflectOff(unsafe.Pointer(n.bytes)))
   269  }
   270  
   271  // resolveReflectType adds a *rtype to the reflection lookup map in the runtime.
   272  // It returns a new typeOff that can be used to refer to the pointer.
   273  func resolveReflectType(t *rtype) typeOff {
   274  	return typeOff(addReflectOff(unsafe.Pointer(t)))
   275  }
   276  
   277  // resolveReflectText adds a function pointer to the reflection lookup map in
   278  // the runtime. It returns a new textOff that can be used to refer to the
   279  // pointer.
   280  func resolveReflectText(ptr unsafe.Pointer) textOff {
   281  	return textOff(addReflectOff(ptr))
   282  }
   283  
   284  type nameOff int32 // offset to a name
   285  type typeOff int32 // offset to an *rtype
   286  type textOff int32 // offset from top of text section
   287  
   288  func (t *rtype) nameOff(off nameOff) name {
   289  	return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
   290  }
   291  
   292  func (t *rtype) typeOff(off typeOff) *rtype {
   293  	return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
   294  }
   295  
   296  func (t *rtype) textOff(off textOff) unsafe.Pointer {
   297  	return resolveTextOff(unsafe.Pointer(t), int32(off))
   298  }
   299  
   300  // rtype is the common implementation of most values.
   301  // It is embedded in other struct types.
   302  //
   303  // rtype must be kept in sync with ../runtime/type.go:/^type._type.
   304  type rtype struct {
   305  	size       uintptr
   306  	ptrdata    uintptr // number of bytes in the type that can contain pointers
   307  	hash       uint32  // hash of type; avoids computation in hash tables
   308  	tflag      tflag   // extra type information flags
   309  	align      uint8   // alignment of variable with this type
   310  	fieldAlign uint8   // alignment of struct field with this type
   311  	kind       uint8   // enumeration for C
   312  	// function for comparing objects of this type
   313  	// (ptr to object A, ptr to object B) -> ==?
   314  	equal     func(unsafe.Pointer, unsafe.Pointer) bool
   315  	gcdata    *byte   // garbage collection data
   316  	str       nameOff // string form
   317  	ptrToThis typeOff // type for pointer to this type, may be zero
   318  }
   319  
   320  type _typePair struct {
   321  	t1 *rtype
   322  	t2 *rtype
   323  }
   324  
   325  func (t *rtype) hasName() bool {
   326  	return t.tflag&tflagNamed != 0
   327  }
   328  
   329  func (t *rtype) Name() string {
   330  	if !t.hasName() {
   331  		return ""
   332  	}
   333  	s := t.String()
   334  	i := len(s) - 1
   335  	sqBrackets := 0
   336  	for i >= 0 && (s[i] != '.' || sqBrackets != 0) {
   337  		switch s[i] {
   338  		case ']':
   339  			sqBrackets++
   340  		case '[':
   341  			sqBrackets--
   342  		}
   343  		i--
   344  	}
   345  	return s[i+1:]
   346  }
   347  
   348  //go:linkname typelinks reflect.typelinks
   349  func typelinks() (sections []unsafe.Pointer, offset [][]int32)
   350  
   351  func rtypeOff(section unsafe.Pointer, off int32) *rtype {
   352  	return (*rtype)(add(section, uintptr(off), "sizeof(rtype) > 0"))
   353  }
   354  
   355  // typesByString returns the subslice of typelinks() whose elements have
   356  // the given string representation.
   357  // It may be empty (no known types with that string) or may have
   358  // multiple elements (multiple types with that string).
   359  func typesByString(s string) []*rtype {
   360  	sections, offset := typelinks()
   361  	var ret []*rtype
   362  
   363  	for offsI, offs := range offset {
   364  		section := sections[offsI]
   365  
   366  		// We are looking for the first index i where the string becomes >= s.
   367  		// This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s).
   368  		i, j := 0, len(offs)
   369  		for i < j {
   370  			h := i + (j-i)>>1 // avoid overflow when computing h
   371  			// i ≤ h < j
   372  			if !(rtypeOff(section, offs[h]).String() >= s) {
   373  				i = h + 1 // preserves f(i-1) == false
   374  			} else {
   375  				j = h // preserves f(j) == true
   376  			}
   377  		}
   378  		// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
   379  
   380  		// Having found the first, linear scan forward to find the last.
   381  		// We could do a second binary search, but the caller is going
   382  		// to do a linear scan anyway.
   383  		for j := i; j < len(offs); j++ {
   384  			typ := rtypeOff(section, offs[j])
   385  			if typ.String() != s {
   386  				break
   387  			}
   388  			ret = append(ret, typ)
   389  		}
   390  	}
   391  	return ret
   392  }
   393  
   394  // TypeOf returns the reflection Type that represents the dynamic type of i.
   395  // If i is a nil interface value, TypeOf returns nil.
   396  func TypeOf(i interface{}) Type {
   397  	eface := *(*emptyInterface)(unsafe.Pointer(&i))
   398  	return toType(eface.typ)
   399  }
   400  
   401  // toType converts from a *rtype to a Type that can be returned
   402  // to the client of package reflect. In gc, the only concern is that
   403  // a nil *rtype must be replaced by a nil Type, but in gccgo this
   404  // function takes care of ensuring that multiple *rtype for the same
   405  // type are coalesced into a single Type.
   406  func toType(t *rtype) Type {
   407  	if t == nil {
   408  		return nil
   409  	}
   410  	return t
   411  }
   412  
   413  // ptrMap is the cache for PointerTo.
   414  var ptrMap sync.Map // map[*rtype]*ptrType
   415  
   416  func (t *rtype) ptrTo() *rtype {
   417  	if t.ptrToThis != 0 {
   418  		return t.typeOff(t.ptrToThis)
   419  	}
   420  
   421  	// Check the cache.
   422  	if pi, ok := ptrMap.Load(t); ok {
   423  		return &pi.(*ptrType).rtype
   424  	}
   425  
   426  	// Look in known types.
   427  	s := "*" + t.String()
   428  	for _, tt := range typesByString(s) {
   429  		p := (*ptrType)(unsafe.Pointer(tt))
   430  		if p.elem != t {
   431  			continue
   432  		}
   433  		pi, _ := ptrMap.LoadOrStore(t, p)
   434  		return &pi.(*ptrType).rtype
   435  	}
   436  
   437  	// Create a new ptrType starting with the description
   438  	// of an *unsafe.Pointer.
   439  	var iptr interface{} = (*unsafe.Pointer)(nil)
   440  	prototype := *(**ptrType)(unsafe.Pointer(&iptr))
   441  	pp := *prototype
   442  
   443  	pp.str = resolveReflectName(newName(s, "", false, false))
   444  	pp.ptrToThis = 0
   445  
   446  	// For the type structures linked into the binary, the
   447  	// compiler provides a good hash of the string.
   448  	// Create a good hash for the new string by using
   449  	// the FNV-1 hash's mixing function to combine the
   450  	// old hash and the new "*".
   451  	pp.hash = fnv1(t.hash, '*')
   452  
   453  	pp.elem = t
   454  
   455  	pi, _ := ptrMap.LoadOrStore(t, &pp)
   456  	return &pi.(*ptrType).rtype
   457  }
   458  
   459  // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
   460  func fnv1(x uint32, list ...byte) uint32 {
   461  	for _, b := range list {
   462  		x = x*16777619 ^ uint32(b)
   463  	}
   464  	return x
   465  }
   466  
   467  func (t *rtype) PkgPath() string {
   468  	if t.tflag&tflagNamed == 0 {
   469  		return ""
   470  	}
   471  	ut := t.uncommon()
   472  	if ut == nil {
   473  		return ""
   474  	}
   475  	return t.nameOff(ut.pkgPath).name()
   476  }
   477  
   478  func (t *rtype) String() string {
   479  	s := t.nameOff(t.str).name()
   480  	if t.tflag&tflagExtraStar != 0 {
   481  		return s[1:]
   482  	}
   483  	return s
   484  }
   485  
   486  func (t *rtype) ConvertibleTo(u Type) bool {
   487  	if u == nil {
   488  		panic("reflect: nil type passed to Type.ConvertibleTo")
   489  	}
   490  	uu := u.(*rtype)
   491  	seen := map[_typePair]struct{}{}
   492  	return convertOp(uu, t, false, seen) != nil
   493  }
   494  
   495  func (t *rtype) ConvertibleToWithInterface(u Type) bool {
   496  	if u == nil {
   497  		panic("reflect: nil type passed to Type.ConvertibleTo")
   498  	}
   499  	uu := u.(*rtype)
   500  	seen := map[_typePair]struct{}{}
   501  	return convertOp(uu, t, true, seen) != nil
   502  }
   503  
   504  // implements reports whether the type V implements the interface type T.
   505  func implements(T, V *rtype, seen map[_typePair]struct{}) bool {
   506  	if T.Kind() != Interface {
   507  		return false
   508  	}
   509  	t := (*interfaceType)(unsafe.Pointer(T))
   510  	if len(t.methods) == 0 {
   511  		return true
   512  	}
   513  
   514  	// The same algorithm applies in both cases, but the
   515  	// method tables for an interface type and a concrete type
   516  	// are different, so the code is duplicated.
   517  	// In both cases the algorithm is a linear scan over the two
   518  	// lists - T's methods and V's methods - simultaneously.
   519  	// Since method tables are stored in a unique sorted order
   520  	// (alphabetical, with no duplicate method names), the scan
   521  	// through V's methods must hit a match for each of T's
   522  	// methods along the way, or else V does not implement T.
   523  	// This lets us run the scan in overall linear time instead of
   524  	// the quadratic time  a naive search would require.
   525  	// See also ../runtime/iface.go.
   526  	if V.Kind() == Interface {
   527  		v := (*interfaceType)(unsafe.Pointer(V))
   528  		i := 0
   529  		for j := 0; j < len(v.methods); j++ {
   530  			tm := &t.methods[i]
   531  			tmName := t.nameOff(tm.name)
   532  			vm := &v.methods[j]
   533  			vmName := V.nameOff(vm.name)
   534  			if vmName.name() == tmName.name() && haveIdenticalUnderlyingType(V.typeOff(vm.typ), t.typeOff(tm.typ), false, true, seen) {
   535  				if !tmName.isExported() {
   536  					tmPkgPath := tmName.pkgPath()
   537  					if tmPkgPath == "" {
   538  						tmPkgPath = t.pkgPath.name()
   539  					}
   540  					vmPkgPath := vmName.pkgPath()
   541  					if vmPkgPath == "" {
   542  						vmPkgPath = v.pkgPath.name()
   543  					}
   544  					if tmPkgPath != vmPkgPath {
   545  						continue
   546  					}
   547  				}
   548  				if i++; i >= len(t.methods) {
   549  					return true
   550  				}
   551  			}
   552  		}
   553  		return false
   554  	}
   555  
   556  	v := V.uncommon()
   557  	if v == nil {
   558  		return false
   559  	}
   560  	i := 0
   561  	vmethods := v.methods()
   562  	for j := 0; j < int(v.mcount); j++ {
   563  		tm := &t.methods[i]
   564  		tmName := t.nameOff(tm.name)
   565  		vm := vmethods[j]
   566  		vmName := V.nameOff(vm.name)
   567  		if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) {
   568  			if !tmName.isExported() {
   569  				tmPkgPath := tmName.pkgPath()
   570  				if tmPkgPath == "" {
   571  					tmPkgPath = t.pkgPath.name()
   572  				}
   573  				vmPkgPath := vmName.pkgPath()
   574  				if vmPkgPath == "" {
   575  					vmPkgPath = V.nameOff(v.pkgPath).name()
   576  				}
   577  				if tmPkgPath != vmPkgPath {
   578  					continue
   579  				}
   580  			}
   581  			if i++; i >= len(t.methods) {
   582  				return true
   583  			}
   584  		}
   585  	}
   586  	return false
   587  }
   588  
   589  // specialChannelAssignability reports whether a value x of channel type V
   590  // can be directly assigned (using memmove) to another channel type T.
   591  // https://golang.org/doc/go_spec.html#Assignability
   592  // T and V must be both of Chan kind.
   593  func specialChannelAssignability(T, V *rtype, seen map[_typePair]struct{}) bool {
   594  	// Special case:
   595  	// x is a bidirectional channel value, T is a channel type,
   596  	// x's type V and T have identical element types,
   597  	// and at least one of V or T is not a defined type.
   598  	return V.ChanDir() == BothDir && (T.Name() == "" || V.Name() == "") && haveIdenticalType(T.Elem(), V.Elem(), true, true, seen)
   599  }
   600  
   601  func (t *rtype) ChanDir() ChanDir {
   602  	if t.Kind() != Chan {
   603  		panic("reflect: ChanDir of non-chan type " + t.String())
   604  	}
   605  	tt := (*chanType)(unsafe.Pointer(t))
   606  	return ChanDir(tt.dir)
   607  }
   608  
   609  func (t *rtype) IsVariadic() bool {
   610  	if t.Kind() != Func {
   611  		panic("reflect: IsVariadic of non-func type " + t.String())
   612  	}
   613  	tt := (*funcType)(unsafe.Pointer(t))
   614  	return tt.outCount&(1<<15) != 0
   615  }
   616  
   617  func (t *rtype) Elem() Type {
   618  	switch t.Kind() {
   619  	case Array:
   620  		tt := (*arrayType)(unsafe.Pointer(t))
   621  		return toType(tt.elem)
   622  	case Chan:
   623  		tt := (*chanType)(unsafe.Pointer(t))
   624  		return toType(tt.elem)
   625  	case Map:
   626  		tt := (*mapType)(unsafe.Pointer(t))
   627  		return toType(tt.elem)
   628  	case Pointer:
   629  		tt := (*ptrType)(unsafe.Pointer(t))
   630  		return toType(tt.elem)
   631  	case Slice:
   632  		tt := (*sliceType)(unsafe.Pointer(t))
   633  		return toType(tt.elem)
   634  	}
   635  	panic("reflect: Elem of invalid type " + t.String())
   636  }
   637  
   638  func (t *rtype) Field(i int) StructField {
   639  	if t.Kind() != Struct {
   640  		panic("reflect: Field of non-struct type " + t.String())
   641  	}
   642  	tt := (*structType)(unsafe.Pointer(t))
   643  	return tt.Field(i)
   644  }
   645  
   646  func (t *rtype) In(i int) Type {
   647  	if t.Kind() != Func {
   648  		panic("reflect: In of non-func type " + t.String())
   649  	}
   650  	tt := (*funcType)(unsafe.Pointer(t))
   651  	return toType(tt.in()[i])
   652  }
   653  
   654  func (t *rtype) Key() Type {
   655  	if t.Kind() != Map {
   656  		panic("reflect: Key of non-map type " + t.String())
   657  	}
   658  	tt := (*mapType)(unsafe.Pointer(t))
   659  	return toType(tt.key)
   660  }
   661  
   662  func (t *rtype) Len() int {
   663  	if t.Kind() != Array {
   664  		panic("reflect: Len of non-array type " + t.String())
   665  	}
   666  	tt := (*arrayType)(unsafe.Pointer(t))
   667  	return int(tt.len)
   668  }
   669  
   670  func (t *rtype) NumField() int {
   671  	if t.Kind() != Struct {
   672  		panic("reflect: NumField of non-struct type " + t.String())
   673  	}
   674  	tt := (*structType)(unsafe.Pointer(t))
   675  	return len(tt.fields)
   676  }
   677  
   678  func (t *rtype) NumIn() int {
   679  	if t.Kind() != Func {
   680  		panic("reflect: NumIn of non-func type " + t.String())
   681  	}
   682  	tt := (*funcType)(unsafe.Pointer(t))
   683  	return int(tt.inCount)
   684  }
   685  
   686  func (t *rtype) NumOut() int {
   687  	if t.Kind() != Func {
   688  		panic("reflect: NumOut of non-func type " + t.String())
   689  	}
   690  	tt := (*funcType)(unsafe.Pointer(t))
   691  	return len(tt.out())
   692  }
   693  
   694  func (t *rtype) Out(i int) Type {
   695  	if t.Kind() != Func {
   696  		panic("reflect: Out of non-func type " + t.String())
   697  	}
   698  	tt := (*funcType)(unsafe.Pointer(t))
   699  	return toType(tt.out()[i])
   700  }
   701  
   702  func (t *funcType) in() []*rtype {
   703  	uadd := unsafe.Sizeof(*t)
   704  	if t.tflag&tflagUncommon != 0 {
   705  		uadd += unsafe.Sizeof(uncommonType{})
   706  	}
   707  	if t.inCount == 0 {
   708  		return nil
   709  	}
   710  	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount]
   711  }
   712  
   713  func (t *funcType) out() []*rtype {
   714  	uadd := unsafe.Sizeof(*t)
   715  	if t.tflag&tflagUncommon != 0 {
   716  		uadd += unsafe.Sizeof(uncommonType{})
   717  	}
   718  	outCount := t.outCount & (1<<15 - 1)
   719  	if outCount == 0 {
   720  		return nil
   721  	}
   722  	return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount]
   723  }
   724  
   725  func (t *rtype) common() *rtype { return t }
   726  
   727  // Method on non-interface type
   728  type method struct {
   729  	name nameOff // name of method
   730  	mtyp typeOff // method type (without receiver)
   731  	ifn  textOff // fn used in interface call (one-word receiver)
   732  	tfn  textOff // fn used for normal method call
   733  }
   734  
   735  // uncommonType is present only for defined types or types with methods
   736  // (if T is a defined type, the uncommonTypes for T and *T have methods).
   737  // Using a pointer to this struct reduces the overall size required
   738  // to describe a non-defined type with no methods.
   739  type uncommonType struct {
   740  	pkgPath nameOff // import path; empty for built-in types like int, string
   741  	mcount  uint16  // number of methods
   742  	xcount  uint16  // number of exported methods
   743  	moff    uint32  // offset from this uncommontype to [mcount]method
   744  	_       uint32  // unused
   745  }
   746  
   747  // ChanDir represents a channel type's direction.
   748  type ChanDir int
   749  
   750  const (
   751  	RecvDir ChanDir             = 1 << iota // <-chan
   752  	SendDir                                 // chan<-
   753  	BothDir = RecvDir | SendDir             // chan
   754  )
   755  
   756  // arrayType represents a fixed array type.
   757  type arrayType struct {
   758  	rtype
   759  	elem  *rtype // array element type
   760  	slice *rtype // slice type
   761  	len   uintptr
   762  }
   763  
   764  // chanType represents a channel type.
   765  type chanType struct {
   766  	rtype
   767  	elem *rtype  // channel element type
   768  	dir  uintptr // channel direction (ChanDir)
   769  }
   770  
   771  // funcType represents a function type.
   772  //
   773  // A *rtype for each in and out parameter is stored in an array that
   774  // directly follows the funcType (and possibly its uncommonType). So
   775  // a function type with one method, one input, and one output is:
   776  //
   777  //	struct {
   778  //		funcType
   779  //		uncommonType
   780  //		[2]*rtype    // [0] is in, [1] is out
   781  //	}
   782  type funcType struct {
   783  	rtype
   784  	inCount  uint16
   785  	outCount uint16 // top bit is set if last input parameter is ...
   786  }
   787  
   788  // imethod represents a method on an interface type
   789  type imethod struct {
   790  	name nameOff // name of method
   791  	typ  typeOff // .(*FuncType) underneath
   792  }
   793  
   794  // interfaceType represents an interface type.
   795  type interfaceType struct {
   796  	rtype
   797  	pkgPath name      // import path
   798  	methods []imethod // sorted by hash
   799  }
   800  
   801  // mapType represents a map type.
   802  type mapType struct {
   803  	rtype
   804  	key    *rtype // map key type
   805  	elem   *rtype // map element (value) type
   806  	bucket *rtype // internal bucket structure
   807  	// function for hashing keys (ptr to key, seed) -> hash
   808  	hasher     func(unsafe.Pointer, uintptr) uintptr
   809  	keysize    uint8  // size of key slot
   810  	valuesize  uint8  // size of value slot
   811  	bucketsize uint16 // size of bucket
   812  	flags      uint32
   813  }
   814  
   815  // ptrType represents a pointer type.
   816  type ptrType struct {
   817  	rtype
   818  	elem *rtype // pointer element (pointed at) type
   819  }
   820  
   821  // sliceType represents a slice type.
   822  type sliceType struct {
   823  	rtype
   824  	elem *rtype // slice element type
   825  }
   826  
   827  // Struct field
   828  type structField struct {
   829  	name   name    // name is always non-empty
   830  	typ    *rtype  // type of field
   831  	offset uintptr // byte offset of field
   832  }
   833  
   834  func (f *structField) embedded() bool {
   835  	return f.name.embedded()
   836  }
   837  
   838  // structType represents a struct type.
   839  type structType struct {
   840  	rtype
   841  	pkgPath name
   842  	fields  []structField // sorted by offset
   843  }
   844  
   845  type structTypeUncommon struct {
   846  	structType
   847  	u uncommonType
   848  }
   849  
   850  // Field returns the i'th struct field.
   851  func (t *structType) Field(i int) (f StructField) {
   852  	if i < 0 || i >= len(t.fields) {
   853  		panic("reflect: Field index out of bounds")
   854  	}
   855  	p := &t.fields[i]
   856  	f.Type = toType(p.typ)
   857  	f.Name = p.name.name()
   858  	f.Anonymous = p.embedded()
   859  	if !p.name.isExported() {
   860  		f.PkgPath = t.pkgPath.name()
   861  	}
   862  	if tag := p.name.tag(); tag != "" {
   863  		f.Tag = StructTag(tag)
   864  	}
   865  	f.Offset = p.offset
   866  
   867  	// NOTE(rsc): This is the only allocation in the interface
   868  	// presented by a reflect.Type. It would be nice to avoid,
   869  	// at least in the common cases, but we need to make sure
   870  	// that misbehaving clients of reflect cannot affect other
   871  	// uses of reflect. One possibility is CL 5371098, but we
   872  	// postponed that ugliness until there is a demonstrated
   873  	// need for the performance. This is issue 2320.
   874  	f.Index = []int{i}
   875  	return
   876  }
   877  
   878  // name is an encoded type name with optional extra data.
   879  //
   880  // The first byte is a bit field containing:
   881  //
   882  //	1<<0 the name is exported
   883  //	1<<1 tag data follows the name
   884  //	1<<2 pkgPath nameOff follows the name and tag
   885  //	1<<3 the name is of an embedded (a.k.a. anonymous) field
   886  //
   887  // Following that, there is a varint-encoded length of the name,
   888  // followed by the name itself.
   889  //
   890  // If tag data is present, it also has a varint-encoded length
   891  // followed by the tag itself.
   892  //
   893  // If the import path follows, then 4 bytes at the end of
   894  // the data form a nameOff. The import path is only set for concrete
   895  // methods that are defined in a different package than their type.
   896  //
   897  // If a name starts with "*", then the exported bit represents
   898  // whether the pointed to type is exported.
   899  //
   900  // Note: this encoding must match here and in:
   901  //   cmd/compile/internal/reflectdata/reflect.go
   902  //   runtime/type.go
   903  //   internal/reflectlite/type.go
   904  //   cmd/link/internal/ld/decodesym.go
   905  
   906  type name struct {
   907  	bytes *byte
   908  }
   909  
   910  func (n name) data(off int, whySafe string) *byte {
   911  	return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe))
   912  }
   913  
   914  func (n name) isExported() bool {
   915  	return (*n.bytes)&(1<<0) != 0
   916  }
   917  
   918  func (n name) hasTag() bool {
   919  	return (*n.bytes)&(1<<1) != 0
   920  }
   921  
   922  func (n name) embedded() bool {
   923  	return (*n.bytes)&(1<<3) != 0
   924  }
   925  
   926  func (n name) name() (s string) {
   927  	if n.bytes == nil {
   928  		return
   929  	}
   930  	i, l := n.readVarint(1)
   931  	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
   932  	hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string"))
   933  	hdr.Len = l
   934  	return
   935  }
   936  
   937  func (n name) tag() (s string) {
   938  	if !n.hasTag() {
   939  		return ""
   940  	}
   941  	i, l := n.readVarint(1)
   942  	i2, l2 := n.readVarint(1 + i + l)
   943  	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
   944  	hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string"))
   945  	hdr.Len = l2
   946  	return
   947  }
   948  
   949  func (n name) pkgPath() string {
   950  	if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
   951  		return ""
   952  	}
   953  	i, l := n.readVarint(1)
   954  	off := 1 + i + l
   955  	if n.hasTag() {
   956  		i2, l2 := n.readVarint(off)
   957  		off += i2 + l2
   958  	}
   959  	var nameOff int32
   960  	// Note that this field may not be aligned in memory,
   961  	// so we cannot use a direct int32 assignment here.
   962  	copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:])
   963  	pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))}
   964  	return pkgPathName.name()
   965  }
   966  
   967  func newName(n, tag string, exported, embedded bool) name {
   968  	if len(n) >= 1<<29 {
   969  		panic("reflect.nameFrom: name too long: " + n[:1024] + "...")
   970  	}
   971  	if len(tag) >= 1<<29 {
   972  		panic("reflect.nameFrom: tag too long: " + tag[:1024] + "...")
   973  	}
   974  	var nameLen [10]byte
   975  	var tagLen [10]byte
   976  	nameLenLen := writeVarint(nameLen[:], len(n))
   977  	tagLenLen := writeVarint(tagLen[:], len(tag))
   978  
   979  	var bits byte
   980  	l := 1 + nameLenLen + len(n)
   981  	if exported {
   982  		bits |= 1 << 0
   983  	}
   984  	if len(tag) > 0 {
   985  		l += tagLenLen + len(tag)
   986  		bits |= 1 << 1
   987  	}
   988  	if embedded {
   989  		bits |= 1 << 3
   990  	}
   991  
   992  	b := make([]byte, l)
   993  	b[0] = bits
   994  	copy(b[1:], nameLen[:nameLenLen])
   995  	copy(b[1+nameLenLen:], n)
   996  	if len(tag) > 0 {
   997  		tb := b[1+nameLenLen+len(n):]
   998  		copy(tb, tagLen[:tagLenLen])
   999  		copy(tb[tagLenLen:], tag)
  1000  	}
  1001  
  1002  	return name{bytes: &b[0]}
  1003  }
  1004  
  1005  type StructTag string
  1006  
  1007  // A StructField describes a single field in a struct.
  1008  type StructField struct {
  1009  	// Name is the field name.
  1010  	Name string
  1011  
  1012  	// PkgPath is the package path that qualifies a lower case (unexported)
  1013  	// field name. It is empty for upper case (exported) field names.
  1014  	// See https://golang.org/ref/spec#Uniqueness_of_identifiers
  1015  	PkgPath string
  1016  
  1017  	Type      Type      // field type
  1018  	Tag       StructTag // field tag string
  1019  	Offset    uintptr   // offset within struct, in bytes
  1020  	Index     []int     // index sequence for Type.FieldByIndex
  1021  	Anonymous bool      // is an embedded field
  1022  }
  1023  
  1024  // readVarint parses a varint as encoded by encoding/binary.
  1025  // It returns the number of encoded bytes and the encoded value.
  1026  func (n name) readVarint(off int) (int, int) {
  1027  	v := 0
  1028  	for i := uint(0); ; i++ {
  1029  		x := *n.data(off+int(i), "read varint")
  1030  		v += int(x&0x7f) << (7 * i)
  1031  		if x&0x80 == 0 {
  1032  			return int(i + 1), v
  1033  		}
  1034  	}
  1035  }
  1036  
  1037  // writeVarint writes n to buf in varint form. Returns the
  1038  // number of bytes written. n must be nonnegative.
  1039  // Writes at most 10 bytes.
  1040  func writeVarint(buf []byte, n int) int {
  1041  	for i := 0; ; i++ {
  1042  		b := byte(n & 0x7f)
  1043  		n >>= 7
  1044  		if n == 0 {
  1045  			buf[i] = b
  1046  			return i + 1
  1047  		}
  1048  		buf[i] = b | 0x80
  1049  	}
  1050  }
  1051  
  1052  // add returns p+x.
  1053  //
  1054  // The whySafe string is ignored, so that the function still inlines
  1055  // as efficiently as p+x, but all call sites should use the string to
  1056  // record why the addition is safe, which is to say why the addition
  1057  // does not cause x to advance to the very end of p's allocation
  1058  // and therefore point incorrectly at the next block in memory.
  1059  func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
  1060  	return unsafe.Pointer(uintptr(p) + x)
  1061  }
  1062  
  1063  func (t *rtype) pointers() bool { return t.ptrdata != 0 }
  1064  
  1065  func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
  1066  
  1067  func (t *rtype) NumMethod() int {
  1068  	if t.Kind() == Interface {
  1069  		tt := (*interfaceType)(unsafe.Pointer(t))
  1070  		return tt.NumMethod()
  1071  	}
  1072  	return len(t.exportedMethods())
  1073  }
  1074  
  1075  func (t *rtype) uncommon() *uncommonType {
  1076  	if t.tflag&tflagUncommon == 0 {
  1077  		return nil
  1078  	}
  1079  	switch t.Kind() {
  1080  	case Struct:
  1081  		return &(*structTypeUncommon)(unsafe.Pointer(t)).u
  1082  	case Pointer:
  1083  		type u struct {
  1084  			ptrType
  1085  			u uncommonType
  1086  		}
  1087  		return &(*u)(unsafe.Pointer(t)).u
  1088  	case Func:
  1089  		type u struct {
  1090  			funcType
  1091  			u uncommonType
  1092  		}
  1093  		return &(*u)(unsafe.Pointer(t)).u
  1094  	case Slice:
  1095  		type u struct {
  1096  			sliceType
  1097  			u uncommonType
  1098  		}
  1099  		return &(*u)(unsafe.Pointer(t)).u
  1100  	case Array:
  1101  		type u struct {
  1102  			arrayType
  1103  			u uncommonType
  1104  		}
  1105  		return &(*u)(unsafe.Pointer(t)).u
  1106  	case Chan:
  1107  		type u struct {
  1108  			chanType
  1109  			u uncommonType
  1110  		}
  1111  		return &(*u)(unsafe.Pointer(t)).u
  1112  	case Map:
  1113  		type u struct {
  1114  			mapType
  1115  			u uncommonType
  1116  		}
  1117  		return &(*u)(unsafe.Pointer(t)).u
  1118  	case Interface:
  1119  		type u struct {
  1120  			interfaceType
  1121  			u uncommonType
  1122  		}
  1123  		return &(*u)(unsafe.Pointer(t)).u
  1124  	default:
  1125  		type u struct {
  1126  			rtype
  1127  			u uncommonType
  1128  		}
  1129  		return &(*u)(unsafe.Pointer(t)).u
  1130  	}
  1131  }
  1132  
  1133  func (t *rtype) exportedMethods() []method {
  1134  	ut := t.uncommon()
  1135  	if ut == nil {
  1136  		return nil
  1137  	}
  1138  	return ut.exportedMethods()
  1139  }
  1140  
  1141  func (t *uncommonType) methods() []method {
  1142  	if t.mcount == 0 {
  1143  		return nil
  1144  	}
  1145  	return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount]
  1146  }
  1147  
  1148  func (t *uncommonType) exportedMethods() []method {
  1149  	if t.xcount == 0 {
  1150  		return nil
  1151  	}
  1152  	return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount]
  1153  }
  1154  
  1155  // NumMethod returns the number of interface methods in the type's method set.
  1156  func (t *interfaceType) NumMethod() int { return len(t.methods) }