github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/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  	"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 // number of (prefix) bytes in the type that can contain pointers
    23  	Hash        uint32  // hash of type; avoids computation in hash tables
    24  	TFlag       TFlag   // extra type information flags
    25  	Align_      uint8   // alignment of variable with this type
    26  	FieldAlign_ uint8   // alignment of struct field with this type
    27  	Kind_       uint8   // enumeration for C
    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 // string form
    36  	PtrToThis TypeOff // type for pointer to this type, may be zero
    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 // Type.gc points to GC program
    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  	if int(k) < len(kindNames) {
   134  		return kindNames[k]
   135  	}
   136  	return kindNames[0]
   137  }
   138  
   139  var kindNames = []string{
   140  	Invalid:       "invalid",
   141  	Bool:          "bool",
   142  	Int:           "int",
   143  	Int8:          "int8",
   144  	Int16:         "int16",
   145  	Int32:         "int32",
   146  	Int64:         "int64",
   147  	Uint:          "uint",
   148  	Uint8:         "uint8",
   149  	Uint16:        "uint16",
   150  	Uint32:        "uint32",
   151  	Uint64:        "uint64",
   152  	Uintptr:       "uintptr",
   153  	Float32:       "float32",
   154  	Float64:       "float64",
   155  	Complex64:     "complex64",
   156  	Complex128:    "complex128",
   157  	Array:         "array",
   158  	Chan:          "chan",
   159  	Func:          "func",
   160  	Interface:     "interface",
   161  	Map:           "map",
   162  	Pointer:       "ptr",
   163  	Slice:         "slice",
   164  	String:        "string",
   165  	Struct:        "struct",
   166  	UnsafePointer: "unsafe.Pointer",
   167  }
   168  
   169  func (t *Type) Kind() Kind { return Kind(t.Kind_ & KindMask) }
   170  
   171  func (t *Type) HasName() bool {
   172  	return t.TFlag&TFlagNamed != 0
   173  }
   174  
   175  // Pointers reports whether t contains pointers.
   176  func (t *Type) Pointers() bool { return t.PtrBytes != 0 }
   177  
   178  // IfaceIndir reports whether t is stored indirectly in an interface value.
   179  func (t *Type) IfaceIndir() bool {
   180  	return t.Kind_&KindDirectIface == 0
   181  }
   182  
   183  // isDirectIface reports whether t is stored directly in an interface value.
   184  func (t *Type) IsDirectIface() bool {
   185  	return t.Kind_&KindDirectIface != 0
   186  }
   187  
   188  func (t *Type) GcSlice(begin, end uintptr) []byte {
   189  	return unsafe.Slice(t.GCData, int(end))[begin:]
   190  }
   191  
   192  // Method on non-interface type
   193  type Method struct {
   194  	Name NameOff // name of method
   195  	Mtyp TypeOff // method type (without receiver)
   196  	Ifn  TextOff // fn used in interface call (one-word receiver)
   197  	Tfn  TextOff // fn used for normal method call
   198  }
   199  
   200  // UncommonType is present only for defined types or types with methods
   201  // (if T is a defined type, the uncommonTypes for T and *T have methods).
   202  // Using a pointer to this struct reduces the overall size required
   203  // to describe a non-defined type with no methods.
   204  type UncommonType struct {
   205  	PkgPath NameOff // import path; empty for built-in types like int, string
   206  	Mcount  uint16  // number of methods
   207  	Xcount  uint16  // number of exported methods
   208  	Moff    uint32  // offset from this uncommontype to [mcount]Method
   209  	_       uint32  // unused
   210  }
   211  
   212  func (t *UncommonType) Methods() []Method {
   213  	if t.Mcount == 0 {
   214  		return nil
   215  	}
   216  	return (*[1 << 16]Method)(addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.mcount > 0"))[:t.Mcount:t.Mcount]
   217  }
   218  
   219  func (t *UncommonType) ExportedMethods() []Method {
   220  	if t.Xcount == 0 {
   221  		return nil
   222  	}
   223  	return (*[1 << 16]Method)(addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.xcount > 0"))[:t.Xcount:t.Xcount]
   224  }
   225  
   226  // addChecked returns p+x.
   227  //
   228  // The whySafe string is ignored, so that the function still inlines
   229  // as efficiently as p+x, but all call sites should use the string to
   230  // record why the addition is safe, which is to say why the addition
   231  // does not cause x to advance to the very end of p's allocation
   232  // and therefore point incorrectly at the next block in memory.
   233  func addChecked(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
   234  	return unsafe.Pointer(uintptr(p) + x)
   235  }
   236  
   237  // Imethod represents a method on an interface type
   238  type Imethod struct {
   239  	Name NameOff // name of method
   240  	Typ  TypeOff // .(*FuncType) underneath
   241  }
   242  
   243  // ArrayType represents a fixed array type.
   244  type ArrayType struct {
   245  	Type
   246  	Elem  *Type // array element type
   247  	Slice *Type // slice type
   248  	Len   uintptr
   249  }
   250  
   251  // Len returns the length of t if t is an array type, otherwise 0
   252  func (t *Type) Len() int {
   253  	if t.Kind() == Array {
   254  		return int((*ArrayType)(unsafe.Pointer(t)).Len)
   255  	}
   256  	return 0
   257  }
   258  
   259  func (t *Type) Common() *Type {
   260  	return t
   261  }
   262  
   263  type ChanDir int
   264  
   265  const (
   266  	RecvDir    ChanDir = 1 << iota         // <-chan
   267  	SendDir                                // chan<-
   268  	BothDir            = RecvDir | SendDir // chan
   269  	InvalidDir ChanDir = 0
   270  )
   271  
   272  // ChanType represents a channel type
   273  type ChanType struct {
   274  	Type
   275  	Elem *Type
   276  	Dir  ChanDir
   277  }
   278  
   279  type structTypeUncommon struct {
   280  	StructType
   281  	u UncommonType
   282  }
   283  
   284  // ChanDir returns the direction of t if t is a channel type, otherwise InvalidDir (0).
   285  func (t *Type) ChanDir() ChanDir {
   286  	if t.Kind() == Chan {
   287  		ch := (*ChanType)(unsafe.Pointer(t))
   288  		return ch.Dir
   289  	}
   290  	return InvalidDir
   291  }
   292  
   293  // Uncommon returns a pointer to T's "uncommon" data if there is any, otherwise nil
   294  func (t *Type) Uncommon() *UncommonType {
   295  	if t.TFlag&TFlagUncommon == 0 {
   296  		return nil
   297  	}
   298  	switch t.Kind() {
   299  	case Struct:
   300  		return &(*structTypeUncommon)(unsafe.Pointer(t)).u
   301  	case Pointer:
   302  		type u struct {
   303  			PtrType
   304  			u UncommonType
   305  		}
   306  		return &(*u)(unsafe.Pointer(t)).u
   307  	case Func:
   308  		type u struct {
   309  			FuncType
   310  			u UncommonType
   311  		}
   312  		return &(*u)(unsafe.Pointer(t)).u
   313  	case Slice:
   314  		type u struct {
   315  			SliceType
   316  			u UncommonType
   317  		}
   318  		return &(*u)(unsafe.Pointer(t)).u
   319  	case Array:
   320  		type u struct {
   321  			ArrayType
   322  			u UncommonType
   323  		}
   324  		return &(*u)(unsafe.Pointer(t)).u
   325  	case Chan:
   326  		type u struct {
   327  			ChanType
   328  			u UncommonType
   329  		}
   330  		return &(*u)(unsafe.Pointer(t)).u
   331  	case Map:
   332  		type u struct {
   333  			MapType
   334  			u UncommonType
   335  		}
   336  		return &(*u)(unsafe.Pointer(t)).u
   337  	case Interface:
   338  		type u struct {
   339  			InterfaceType
   340  			u UncommonType
   341  		}
   342  		return &(*u)(unsafe.Pointer(t)).u
   343  	default:
   344  		type u struct {
   345  			Type
   346  			u UncommonType
   347  		}
   348  		return &(*u)(unsafe.Pointer(t)).u
   349  	}
   350  }
   351  
   352  // Elem returns the element type for t if t is an array, channel, map, pointer, or slice, otherwise nil.
   353  func (t *Type) Elem() *Type {
   354  	switch t.Kind() {
   355  	case Array:
   356  		tt := (*ArrayType)(unsafe.Pointer(t))
   357  		return tt.Elem
   358  	case Chan:
   359  		tt := (*ChanType)(unsafe.Pointer(t))
   360  		return tt.Elem
   361  	case Map:
   362  		tt := (*MapType)(unsafe.Pointer(t))
   363  		return tt.Elem
   364  	case Pointer:
   365  		tt := (*PtrType)(unsafe.Pointer(t))
   366  		return tt.Elem
   367  	case Slice:
   368  		tt := (*SliceType)(unsafe.Pointer(t))
   369  		return tt.Elem
   370  	}
   371  	return nil
   372  }
   373  
   374  // StructType returns t cast to a *StructType, or nil if its tag does not match.
   375  func (t *Type) StructType() *StructType {
   376  	if t.Kind() != Struct {
   377  		return nil
   378  	}
   379  	return (*StructType)(unsafe.Pointer(t))
   380  }
   381  
   382  // MapType returns t cast to a *MapType, or nil if its tag does not match.
   383  func (t *Type) MapType() *MapType {
   384  	if t.Kind() != Map {
   385  		return nil
   386  	}
   387  	return (*MapType)(unsafe.Pointer(t))
   388  }
   389  
   390  // ArrayType returns t cast to a *ArrayType, or nil if its tag does not match.
   391  func (t *Type) ArrayType() *ArrayType {
   392  	if t.Kind() != Array {
   393  		return nil
   394  	}
   395  	return (*ArrayType)(unsafe.Pointer(t))
   396  }
   397  
   398  // FuncType returns t cast to a *FuncType, or nil if its tag does not match.
   399  func (t *Type) FuncType() *FuncType {
   400  	if t.Kind() != Func {
   401  		return nil
   402  	}
   403  	return (*FuncType)(unsafe.Pointer(t))
   404  }
   405  
   406  // InterfaceType returns t cast to a *InterfaceType, or nil if its tag does not match.
   407  func (t *Type) InterfaceType() *InterfaceType {
   408  	if t.Kind() != Interface {
   409  		return nil
   410  	}
   411  	return (*InterfaceType)(unsafe.Pointer(t))
   412  }
   413  
   414  // Size returns the size of data with type t.
   415  func (t *Type) Size() uintptr { return t.Size_ }
   416  
   417  // Align returns the alignment of data with type t.
   418  func (t *Type) Align() int { return int(t.Align_) }
   419  
   420  func (t *Type) FieldAlign() int { return int(t.FieldAlign_) }
   421  
   422  type InterfaceType struct {
   423  	Type
   424  	PkgPath Name      // import path
   425  	Methods []Imethod // sorted by hash
   426  }
   427  
   428  func (t *Type) ExportedMethods() []Method {
   429  	ut := t.Uncommon()
   430  	if ut == nil {
   431  		return nil
   432  	}
   433  	return ut.ExportedMethods()
   434  }
   435  
   436  func (t *Type) NumMethod() int {
   437  	if t.Kind() == Interface {
   438  		tt := (*InterfaceType)(unsafe.Pointer(t))
   439  		return tt.NumMethod()
   440  	}
   441  	return len(t.ExportedMethods())
   442  }
   443  
   444  // NumMethod returns the number of interface methods in the type's method set.
   445  func (t *InterfaceType) NumMethod() int { return len(t.Methods) }
   446  
   447  type MapType struct {
   448  	Type
   449  	Key    *Type
   450  	Elem   *Type
   451  	Bucket *Type // internal type representing a hash bucket
   452  	// function for hashing keys (ptr to key, seed) -> hash
   453  	Hasher     func(unsafe.Pointer, uintptr) uintptr
   454  	KeySize    uint8  // size of key slot
   455  	ValueSize  uint8  // size of elem slot
   456  	BucketSize uint16 // size of bucket
   457  	Flags      uint32
   458  }
   459  
   460  // Note: flag values must match those used in the TMAP case
   461  // in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
   462  func (mt *MapType) IndirectKey() bool { // store ptr to key instead of key itself
   463  	return mt.Flags&1 != 0
   464  }
   465  func (mt *MapType) IndirectElem() bool { // store ptr to elem instead of elem itself
   466  	return mt.Flags&2 != 0
   467  }
   468  func (mt *MapType) ReflexiveKey() bool { // true if k==k for all keys
   469  	return mt.Flags&4 != 0
   470  }
   471  func (mt *MapType) NeedKeyUpdate() bool { // true if we need to update key on an overwrite
   472  	return mt.Flags&8 != 0
   473  }
   474  func (mt *MapType) HashMightPanic() bool { // true if hash function might panic
   475  	return mt.Flags&16 != 0
   476  }
   477  
   478  func (t *Type) Key() *Type {
   479  	if t.Kind() == Map {
   480  		return (*MapType)(unsafe.Pointer(t)).Key
   481  	}
   482  	return nil
   483  }
   484  
   485  type SliceType struct {
   486  	Type
   487  	Elem *Type // slice element type
   488  }
   489  
   490  // funcType represents a function type.
   491  //
   492  // A *Type for each in and out parameter is stored in an array that
   493  // directly follows the funcType (and possibly its uncommonType). So
   494  // a function type with one method, one input, and one output is:
   495  //
   496  //	struct {
   497  //		funcType
   498  //		uncommonType
   499  //		[2]*rtype    // [0] is in, [1] is out
   500  //	}
   501  type FuncType struct {
   502  	Type
   503  	InCount  uint16
   504  	OutCount uint16 // top bit is set if last input parameter is ...
   505  }
   506  
   507  func (t *FuncType) In(i int) *Type {
   508  	return t.InSlice()[i]
   509  }
   510  
   511  func (t *FuncType) NumIn() int {
   512  	return int(t.InCount)
   513  }
   514  
   515  func (t *FuncType) NumOut() int {
   516  	return int(t.OutCount & (1<<15 - 1))
   517  }
   518  
   519  func (t *FuncType) Out(i int) *Type {
   520  	return (t.OutSlice()[i])
   521  }
   522  
   523  func (t *FuncType) InSlice() []*Type {
   524  	uadd := unsafe.Sizeof(*t)
   525  	if t.TFlag&TFlagUncommon != 0 {
   526  		uadd += unsafe.Sizeof(UncommonType{})
   527  	}
   528  	if t.InCount == 0 {
   529  		return nil
   530  	}
   531  	return (*[1 << 16]*Type)(addChecked(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.InCount:t.InCount]
   532  }
   533  func (t *FuncType) OutSlice() []*Type {
   534  	outCount := uint16(t.NumOut())
   535  	if outCount == 0 {
   536  		return nil
   537  	}
   538  	uadd := unsafe.Sizeof(*t)
   539  	if t.TFlag&TFlagUncommon != 0 {
   540  		uadd += unsafe.Sizeof(UncommonType{})
   541  	}
   542  	return (*[1 << 17]*Type)(addChecked(unsafe.Pointer(t), uadd, "outCount > 0"))[t.InCount : t.InCount+outCount : t.InCount+outCount]
   543  }
   544  
   545  func (t *FuncType) IsVariadic() bool {
   546  	return t.OutCount&(1<<15) != 0
   547  }
   548  
   549  type PtrType struct {
   550  	Type
   551  	Elem *Type // pointer element (pointed at) type
   552  }
   553  
   554  type StructField struct {
   555  	Name   Name    // name is always non-empty
   556  	Typ    *Type   // type of field
   557  	Offset uintptr // byte offset of field
   558  }
   559  
   560  func (f *StructField) Embedded() bool {
   561  	return f.Name.IsEmbedded()
   562  }
   563  
   564  type StructType struct {
   565  	Type
   566  	PkgPath Name
   567  	Fields  []StructField
   568  }
   569  
   570  // Name is an encoded type Name with optional extra data.
   571  //
   572  // The first byte is a bit field containing:
   573  //
   574  //	1<<0 the name is exported
   575  //	1<<1 tag data follows the name
   576  //	1<<2 pkgPath nameOff follows the name and tag
   577  //	1<<3 the name is of an embedded (a.k.a. anonymous) field
   578  //
   579  // Following that, there is a varint-encoded length of the name,
   580  // followed by the name itself.
   581  //
   582  // If tag data is present, it also has a varint-encoded length
   583  // followed by the tag itself.
   584  //
   585  // If the import path follows, then 4 bytes at the end of
   586  // the data form a nameOff. The import path is only set for concrete
   587  // methods that are defined in a different package than their type.
   588  //
   589  // If a name starts with "*", then the exported bit represents
   590  // whether the pointed to type is exported.
   591  //
   592  // Note: this encoding must match here and in:
   593  //   cmd/compile/internal/reflectdata/reflect.go
   594  //   cmd/link/internal/ld/decodesym.go
   595  
   596  type Name struct {
   597  	Bytes *byte
   598  }
   599  
   600  // DataChecked does pointer arithmetic on n's Bytes, and that arithmetic is asserted to
   601  // be safe for the reason in whySafe (which can appear in a backtrace, etc.)
   602  func (n Name) DataChecked(off int, whySafe string) *byte {
   603  	return (*byte)(addChecked(unsafe.Pointer(n.Bytes), uintptr(off), whySafe))
   604  }
   605  
   606  // Data does pointer arithmetic on n's Bytes, and that arithmetic is asserted to
   607  // be safe because the runtime made the call (other packages use DataChecked)
   608  func (n Name) Data(off int) *byte {
   609  	return (*byte)(addChecked(unsafe.Pointer(n.Bytes), uintptr(off), "the runtime doesn't need to give you a reason"))
   610  }
   611  
   612  // IsExported returns "is n exported?"
   613  func (n Name) IsExported() bool {
   614  	return (*n.Bytes)&(1<<0) != 0
   615  }
   616  
   617  // HasTag returns true iff there is tag data following this name
   618  func (n Name) HasTag() bool {
   619  	return (*n.Bytes)&(1<<1) != 0
   620  }
   621  
   622  // IsEmbedded returns true iff n is embedded (an anonymous field).
   623  func (n Name) IsEmbedded() bool {
   624  	return (*n.Bytes)&(1<<3) != 0
   625  }
   626  
   627  // ReadVarint parses a varint as encoded by encoding/binary.
   628  // It returns the number of encoded bytes and the encoded value.
   629  func (n Name) ReadVarint(off int) (int, int) {
   630  	v := 0
   631  	for i := 0; ; i++ {
   632  		x := *n.DataChecked(off+i, "read varint")
   633  		v += int(x&0x7f) << (7 * i)
   634  		if x&0x80 == 0 {
   635  			return i + 1, v
   636  		}
   637  	}
   638  }
   639  
   640  // IsBlank indicates whether n is "_".
   641  func (n Name) IsBlank() bool {
   642  	if n.Bytes == nil {
   643  		return false
   644  	}
   645  	_, l := n.ReadVarint(1)
   646  	return l == 1 && *n.Data(2) == '_'
   647  }
   648  
   649  // writeVarint writes n to buf in varint form. Returns the
   650  // number of bytes written. n must be nonnegative.
   651  // Writes at most 10 bytes.
   652  func writeVarint(buf []byte, n int) int {
   653  	for i := 0; ; i++ {
   654  		b := byte(n & 0x7f)
   655  		n >>= 7
   656  		if n == 0 {
   657  			buf[i] = b
   658  			return i + 1
   659  		}
   660  		buf[i] = b | 0x80
   661  	}
   662  }
   663  
   664  // Name returns the tag string for n, or empty if there is none.
   665  func (n Name) Name() string {
   666  	if n.Bytes == nil {
   667  		return ""
   668  	}
   669  	i, l := n.ReadVarint(1)
   670  	return unsafe.String(n.DataChecked(1+i, "non-empty string"), l)
   671  }
   672  
   673  // Tag returns the tag string for n, or empty if there is none.
   674  func (n Name) Tag() string {
   675  	if !n.HasTag() {
   676  		return ""
   677  	}
   678  	i, l := n.ReadVarint(1)
   679  	i2, l2 := n.ReadVarint(1 + i + l)
   680  	return unsafe.String(n.DataChecked(1+i+l+i2, "non-empty string"), l2)
   681  }
   682  
   683  func NewName(n, tag string, exported, embedded bool) Name {
   684  	if len(n) >= 1<<29 {
   685  		panic("abi.NewName: name too long: " + n[:1024] + "...")
   686  	}
   687  	if len(tag) >= 1<<29 {
   688  		panic("abi.NewName: tag too long: " + tag[:1024] + "...")
   689  	}
   690  	var nameLen [10]byte
   691  	var tagLen [10]byte
   692  	nameLenLen := writeVarint(nameLen[:], len(n))
   693  	tagLenLen := writeVarint(tagLen[:], len(tag))
   694  
   695  	var bits byte
   696  	l := 1 + nameLenLen + len(n)
   697  	if exported {
   698  		bits |= 1 << 0
   699  	}
   700  	if len(tag) > 0 {
   701  		l += tagLenLen + len(tag)
   702  		bits |= 1 << 1
   703  	}
   704  	if embedded {
   705  		bits |= 1 << 3
   706  	}
   707  
   708  	b := make([]byte, l)
   709  	b[0] = bits
   710  	copy(b[1:], nameLen[:nameLenLen])
   711  	copy(b[1+nameLenLen:], n)
   712  	if len(tag) > 0 {
   713  		tb := b[1+nameLenLen+len(n):]
   714  		copy(tb, tagLen[:tagLenLen])
   715  		copy(tb[tagLenLen:], tag)
   716  	}
   717  
   718  	return Name{Bytes: &b[0]}
   719  }
   720  
   721  const (
   722  	TraceArgsLimit    = 10 // print no more than 10 args/components
   723  	TraceArgsMaxDepth = 5  // no more than 5 layers of nesting
   724  
   725  	// maxLen is a (conservative) upper bound of the byte stream length. For
   726  	// each arg/component, it has no more than 2 bytes of data (size, offset),
   727  	// and no more than one {, }, ... at each level (it cannot have both the
   728  	// data and ... unless it is the last one, just be conservative). Plus 1
   729  	// for _endSeq.
   730  	TraceArgsMaxLen = (TraceArgsMaxDepth*3+2)*TraceArgsLimit + 1
   731  )
   732  
   733  // Populate the data.
   734  // The data is a stream of bytes, which contains the offsets and sizes of the
   735  // non-aggregate arguments or non-aggregate fields/elements of aggregate-typed
   736  // arguments, along with special "operators". Specifically,
   737  //   - for each non-aggregate arg/field/element, its offset from FP (1 byte) and
   738  //     size (1 byte)
   739  //   - special operators:
   740  //   - 0xff - end of sequence
   741  //   - 0xfe - print { (at the start of an aggregate-typed argument)
   742  //   - 0xfd - print } (at the end of an aggregate-typed argument)
   743  //   - 0xfc - print ... (more args/fields/elements)
   744  //   - 0xfb - print _ (offset too large)
   745  const (
   746  	TraceArgsEndSeq         = 0xff
   747  	TraceArgsStartAgg       = 0xfe
   748  	TraceArgsEndAgg         = 0xfd
   749  	TraceArgsDotdotdot      = 0xfc
   750  	TraceArgsOffsetTooLarge = 0xfb
   751  	TraceArgsSpecial        = 0xf0 // above this are operators, below this are ordinary offsets
   752  )
   753  
   754  // MaxPtrmaskBytes is the maximum length of a GC ptrmask bitmap,
   755  // which holds 1-bit entries describing where pointers are in a given type.
   756  // Above this length, the GC information is recorded as a GC program,
   757  // which can express repetition compactly. In either form, the
   758  // information is used by the runtime to initialize the heap bitmap,
   759  // and for large types (like 128 or more words), they are roughly the
   760  // same speed. GC programs are never much larger and often more
   761  // compact. (If large arrays are involved, they can be arbitrarily
   762  // more compact.)
   763  //
   764  // The cutoff must be large enough that any allocation large enough to
   765  // use a GC program is large enough that it does not share heap bitmap
   766  // bytes with any other objects, allowing the GC program execution to
   767  // assume an aligned start and not use atomic operations. In the current
   768  // runtime, this means all malloc size classes larger than the cutoff must
   769  // be multiples of four words. On 32-bit systems that's 16 bytes, and
   770  // all size classes >= 16 bytes are 16-byte aligned, so no real constraint.
   771  // On 64-bit systems, that's 32 bytes, and 32-byte alignment is guaranteed
   772  // for size classes >= 256 bytes. On a 64-bit system, 256 bytes allocated
   773  // is 32 pointers, the bits for which fit in 4 bytes. So MaxPtrmaskBytes
   774  // must be >= 4.
   775  //
   776  // We used to use 16 because the GC programs do have some constant overhead
   777  // to get started, and processing 128 pointers seems to be enough to
   778  // amortize that overhead well.
   779  //
   780  // To make sure that the runtime's chansend can call typeBitsBulkBarrier,
   781  // we raised the limit to 2048, so that even 32-bit systems are guaranteed to
   782  // use bitmaps for objects up to 64 kB in size.
   783  const MaxPtrmaskBytes = 2048