github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/internal/abi/type.go (about)

     1  // Copyright 2023 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 abi
     6  
     7  import (
     8  	"github.com/shogo82148/std/unsafe"
     9  )
    10  
    11  // Type is the runtime representation of a Go type.
    12  //
    13  // Be careful about accessing this type at build time, as the version
    14  // of this type in the compiler/linker may not have the same layout
    15  // as the version in the target binary, due to pointer width
    16  // differences and any experiments. Use cmd/compile/internal/rttype
    17  // or the functions in compiletype.go to access this type instead.
    18  // (TODO: this admonition applies to every type in this package.
    19  // Put it in some shared location?)
    20  type Type struct {
    21  	Size_       uintptr
    22  	PtrBytes    uintptr
    23  	Hash        uint32
    24  	TFlag       TFlag
    25  	Align_      uint8
    26  	FieldAlign_ uint8
    27  	Kind_       uint8
    28  	// function for comparing objects of this type
    29  	// (ptr to object A, ptr to object B) -> ==?
    30  	Equal func(unsafe.Pointer, unsafe.Pointer) bool
    31  	// GCData stores the GC type data for the garbage collector.
    32  	// If the KindGCProg bit is set in kind, GCData is a GC program.
    33  	// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
    34  	GCData    *byte
    35  	Str       NameOff
    36  	PtrToThis TypeOff
    37  }
    38  
    39  // A Kind represents the specific kind of type that a Type represents.
    40  // The zero Kind is not a valid kind.
    41  type Kind uint
    42  
    43  const (
    44  	Invalid Kind = iota
    45  	Bool
    46  	Int
    47  	Int8
    48  	Int16
    49  	Int32
    50  	Int64
    51  	Uint
    52  	Uint8
    53  	Uint16
    54  	Uint32
    55  	Uint64
    56  	Uintptr
    57  	Float32
    58  	Float64
    59  	Complex64
    60  	Complex128
    61  	Array
    62  	Chan
    63  	Func
    64  	Interface
    65  	Map
    66  	Pointer
    67  	Slice
    68  	String
    69  	Struct
    70  	UnsafePointer
    71  )
    72  
    73  const (
    74  	// TODO (khr, drchase) why aren't these in TFlag?  Investigate, fix if possible.
    75  	KindDirectIface = 1 << 5
    76  	KindGCProg      = 1 << 6
    77  	KindMask        = (1 << 5) - 1
    78  )
    79  
    80  // TFlag is used by a Type to signal what extra type information is
    81  // available in the memory directly following the Type value.
    82  type TFlag uint8
    83  
    84  const (
    85  	// TFlagUncommon means that there is a data with a type, UncommonType,
    86  	// just beyond the shared-per-type common data.  That is, the data
    87  	// for struct types will store their UncommonType at one offset, the
    88  	// data for interface types will store their UncommonType at a different
    89  	// offset.  UncommonType is always accessed via a pointer that is computed
    90  	// using trust-us-we-are-the-implementors pointer arithmetic.
    91  	//
    92  	// For example, if t.Kind() == Struct and t.tflag&TFlagUncommon != 0,
    93  	// then t has UncommonType data and it can be accessed as:
    94  	//
    95  	//	type structTypeUncommon struct {
    96  	//		structType
    97  	//		u UncommonType
    98  	//	}
    99  	//	u := &(*structTypeUncommon)(unsafe.Pointer(t)).u
   100  	TFlagUncommon TFlag = 1 << 0
   101  
   102  	// TFlagExtraStar means the name in the str field has an
   103  	// extraneous '*' prefix. This is because for most types T in
   104  	// a program, the type *T also exists and reusing the str data
   105  	// saves binary size.
   106  	TFlagExtraStar TFlag = 1 << 1
   107  
   108  	// TFlagNamed means the type has a name.
   109  	TFlagNamed TFlag = 1 << 2
   110  
   111  	// TFlagRegularMemory means that equal and hash functions can treat
   112  	// this type as a single region of t.size bytes.
   113  	TFlagRegularMemory TFlag = 1 << 3
   114  
   115  	// TFlagUnrolledBitmap marks special types that are unrolled-bitmap
   116  	// versions of types with GC programs.
   117  	// These types need to be deallocated when the underlying object
   118  	// is freed.
   119  	TFlagUnrolledBitmap TFlag = 1 << 4
   120  )
   121  
   122  // NameOff is the offset to a name from moduledata.types.  See resolveNameOff in runtime.
   123  type NameOff int32
   124  
   125  // TypeOff is the offset to a type from moduledata.types.  See resolveTypeOff in runtime.
   126  type TypeOff int32
   127  
   128  // TextOff is an offset from the top of a text section.  See (rtype).textOff in runtime.
   129  type TextOff int32
   130  
   131  // String returns the name of k.
   132  func (k Kind) String() string
   133  
   134  func (t *Type) Kind() Kind
   135  
   136  func (t *Type) HasName() bool
   137  
   138  // Pointers reports whether t contains pointers.
   139  func (t *Type) Pointers() bool
   140  
   141  // IfaceIndir reports whether t is stored indirectly in an interface value.
   142  func (t *Type) IfaceIndir() bool
   143  
   144  // isDirectIface reports whether t is stored directly in an interface value.
   145  func (t *Type) IsDirectIface() bool
   146  
   147  func (t *Type) GcSlice(begin, end uintptr) []byte
   148  
   149  // Method on non-interface type
   150  type Method struct {
   151  	Name NameOff
   152  	Mtyp TypeOff
   153  	Ifn  TextOff
   154  	Tfn  TextOff
   155  }
   156  
   157  // UncommonType is present only for defined types or types with methods
   158  // (if T is a defined type, the uncommonTypes for T and *T have methods).
   159  // Using a pointer to this struct reduces the overall size required
   160  // to describe a non-defined type with no methods.
   161  type UncommonType struct {
   162  	PkgPath NameOff
   163  	Mcount  uint16
   164  	Xcount  uint16
   165  	Moff    uint32
   166  	_       uint32
   167  }
   168  
   169  func (t *UncommonType) Methods() []Method
   170  
   171  func (t *UncommonType) ExportedMethods() []Method
   172  
   173  // Imethod represents a method on an interface type
   174  type Imethod struct {
   175  	Name NameOff
   176  	Typ  TypeOff
   177  }
   178  
   179  // ArrayType represents a fixed array type.
   180  type ArrayType struct {
   181  	Type
   182  	Elem  *Type
   183  	Slice *Type
   184  	Len   uintptr
   185  }
   186  
   187  // Len returns the length of t if t is an array type, otherwise 0
   188  func (t *Type) Len() int
   189  
   190  func (t *Type) Common() *Type
   191  
   192  type ChanDir int
   193  
   194  const (
   195  	RecvDir ChanDir = 1 << iota
   196  	SendDir
   197  	BothDir            = RecvDir | SendDir
   198  	InvalidDir ChanDir = 0
   199  )
   200  
   201  // ChanType represents a channel type
   202  type ChanType struct {
   203  	Type
   204  	Elem *Type
   205  	Dir  ChanDir
   206  }
   207  
   208  // ChanDir returns the direction of t if t is a channel type, otherwise InvalidDir (0).
   209  func (t *Type) ChanDir() ChanDir
   210  
   211  // Uncommon returns a pointer to T's "uncommon" data if there is any, otherwise nil
   212  func (t *Type) Uncommon() *UncommonType
   213  
   214  // Elem returns the element type for t if t is an array, channel, map, pointer, or slice, otherwise nil.
   215  func (t *Type) Elem() *Type
   216  
   217  // StructType returns t cast to a *StructType, or nil if its tag does not match.
   218  func (t *Type) StructType() *StructType
   219  
   220  // MapType returns t cast to a *MapType, or nil if its tag does not match.
   221  func (t *Type) MapType() *MapType
   222  
   223  // ArrayType returns t cast to a *ArrayType, or nil if its tag does not match.
   224  func (t *Type) ArrayType() *ArrayType
   225  
   226  // FuncType returns t cast to a *FuncType, or nil if its tag does not match.
   227  func (t *Type) FuncType() *FuncType
   228  
   229  // InterfaceType returns t cast to a *InterfaceType, or nil if its tag does not match.
   230  func (t *Type) InterfaceType() *InterfaceType
   231  
   232  // Size returns the size of data with type t.
   233  func (t *Type) Size() uintptr
   234  
   235  // Align returns the alignment of data with type t.
   236  func (t *Type) Align() int
   237  
   238  func (t *Type) FieldAlign() int
   239  
   240  type InterfaceType struct {
   241  	Type
   242  	PkgPath Name
   243  	Methods []Imethod
   244  }
   245  
   246  func (t *Type) ExportedMethods() []Method
   247  
   248  func (t *Type) NumMethod() int
   249  
   250  // NumMethod returns the number of interface methods in the type's method set.
   251  func (t *InterfaceType) NumMethod() int
   252  
   253  type MapType struct {
   254  	Type
   255  	Key    *Type
   256  	Elem   *Type
   257  	Bucket *Type
   258  	// function for hashing keys (ptr to key, seed) -> hash
   259  	Hasher     func(unsafe.Pointer, uintptr) uintptr
   260  	KeySize    uint8
   261  	ValueSize  uint8
   262  	BucketSize uint16
   263  	Flags      uint32
   264  }
   265  
   266  // Note: flag values must match those used in the TMAP case
   267  // in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
   268  func (mt *MapType) IndirectKey() bool
   269  
   270  func (mt *MapType) IndirectElem() bool
   271  
   272  func (mt *MapType) ReflexiveKey() bool
   273  
   274  func (mt *MapType) NeedKeyUpdate() bool
   275  
   276  func (mt *MapType) HashMightPanic() bool
   277  
   278  func (t *Type) Key() *Type
   279  
   280  type SliceType struct {
   281  	Type
   282  	Elem *Type
   283  }
   284  
   285  // funcType represents a function type.
   286  //
   287  // A *Type for each in and out parameter is stored in an array that
   288  // directly follows the funcType (and possibly its uncommonType). So
   289  // a function type with one method, one input, and one output is:
   290  //
   291  //	struct {
   292  //		funcType
   293  //		uncommonType
   294  //		[2]*rtype    // [0] is in, [1] is out
   295  //	}
   296  type FuncType struct {
   297  	Type
   298  	InCount  uint16
   299  	OutCount uint16
   300  }
   301  
   302  func (t *FuncType) In(i int) *Type
   303  
   304  func (t *FuncType) NumIn() int
   305  
   306  func (t *FuncType) NumOut() int
   307  
   308  func (t *FuncType) Out(i int) *Type
   309  
   310  func (t *FuncType) InSlice() []*Type
   311  
   312  func (t *FuncType) OutSlice() []*Type
   313  
   314  func (t *FuncType) IsVariadic() bool
   315  
   316  type PtrType struct {
   317  	Type
   318  	Elem *Type
   319  }
   320  
   321  type StructField struct {
   322  	Name   Name
   323  	Typ    *Type
   324  	Offset uintptr
   325  }
   326  
   327  func (f *StructField) Embedded() bool
   328  
   329  type StructType struct {
   330  	Type
   331  	PkgPath Name
   332  	Fields  []StructField
   333  }
   334  
   335  type Name struct {
   336  	Bytes *byte
   337  }
   338  
   339  // DataChecked does pointer arithmetic on n's Bytes, and that arithmetic is asserted to
   340  // be safe for the reason in whySafe (which can appear in a backtrace, etc.)
   341  func (n Name) DataChecked(off int, whySafe string) *byte
   342  
   343  // Data does pointer arithmetic on n's Bytes, and that arithmetic is asserted to
   344  // be safe because the runtime made the call (other packages use DataChecked)
   345  func (n Name) Data(off int) *byte
   346  
   347  // IsExported returns "is n exported?"
   348  func (n Name) IsExported() bool
   349  
   350  // HasTag returns true iff there is tag data following this name
   351  func (n Name) HasTag() bool
   352  
   353  // IsEmbedded returns true iff n is embedded (an anonymous field).
   354  func (n Name) IsEmbedded() bool
   355  
   356  // ReadVarint parses a varint as encoded by encoding/binary.
   357  // It returns the number of encoded bytes and the encoded value.
   358  func (n Name) ReadVarint(off int) (int, int)
   359  
   360  // IsBlank indicates whether n is "_".
   361  func (n Name) IsBlank() bool
   362  
   363  // Name returns the tag string for n, or empty if there is none.
   364  func (n Name) Name() string
   365  
   366  // Tag returns the tag string for n, or empty if there is none.
   367  func (n Name) Tag() string
   368  
   369  func NewName(n, tag string, exported, embedded bool) Name
   370  
   371  const (
   372  	TraceArgsLimit    = 10
   373  	TraceArgsMaxDepth = 5
   374  
   375  	// maxLen is a (conservative) upper bound of the byte stream length. For
   376  	// each arg/component, it has no more than 2 bytes of data (size, offset),
   377  	// and no more than one {, }, ... at each level (it cannot have both the
   378  	// data and ... unless it is the last one, just be conservative). Plus 1
   379  	// for _endSeq.
   380  	TraceArgsMaxLen = (TraceArgsMaxDepth*3+2)*TraceArgsLimit + 1
   381  )
   382  
   383  // Populate the data.
   384  // The data is a stream of bytes, which contains the offsets and sizes of the
   385  // non-aggregate arguments or non-aggregate fields/elements of aggregate-typed
   386  // arguments, along with special "operators". Specifically,
   387  //   - for each non-aggregate arg/field/element, its offset from FP (1 byte) and
   388  //     size (1 byte)
   389  //   - special operators:
   390  //   - 0xff - end of sequence
   391  //   - 0xfe - print { (at the start of an aggregate-typed argument)
   392  //   - 0xfd - print } (at the end of an aggregate-typed argument)
   393  //   - 0xfc - print ... (more args/fields/elements)
   394  //   - 0xfb - print _ (offset too large)
   395  const (
   396  	TraceArgsEndSeq         = 0xff
   397  	TraceArgsStartAgg       = 0xfe
   398  	TraceArgsEndAgg         = 0xfd
   399  	TraceArgsDotdotdot      = 0xfc
   400  	TraceArgsOffsetTooLarge = 0xfb
   401  	TraceArgsSpecial        = 0xf0
   402  )
   403  
   404  // MaxPtrmaskBytes is the maximum length of a GC ptrmask bitmap,
   405  // which holds 1-bit entries describing where pointers are in a given type.
   406  // Above this length, the GC information is recorded as a GC program,
   407  // which can express repetition compactly. In either form, the
   408  // information is used by the runtime to initialize the heap bitmap,
   409  // and for large types (like 128 or more words), they are roughly the
   410  // same speed. GC programs are never much larger and often more
   411  // compact. (If large arrays are involved, they can be arbitrarily
   412  // more compact.)
   413  //
   414  // The cutoff must be large enough that any allocation large enough to
   415  // use a GC program is large enough that it does not share heap bitmap
   416  // bytes with any other objects, allowing the GC program execution to
   417  // assume an aligned start and not use atomic operations. In the current
   418  // runtime, this means all malloc size classes larger than the cutoff must
   419  // be multiples of four words. On 32-bit systems that's 16 bytes, and
   420  // all size classes >= 16 bytes are 16-byte aligned, so no real constraint.
   421  // On 64-bit systems, that's 32 bytes, and 32-byte alignment is guaranteed
   422  // for size classes >= 256 bytes. On a 64-bit system, 256 bytes allocated
   423  // is 32 pointers, the bits for which fit in 4 bytes. So MaxPtrmaskBytes
   424  // must be >= 4.
   425  //
   426  // We used to use 16 because the GC programs do have some constant overhead
   427  // to get started, and processing 128 pointers seems to be enough to
   428  // amortize that overhead well.
   429  //
   430  // To make sure that the runtime's chansend can call typeBitsBulkBarrier,
   431  // we raised the limit to 2048, so that even 32-bit systems are guaranteed to
   432  // use bitmaps for objects up to 64 kB in size.
   433  const MaxPtrmaskBytes = 2048