File size: 9,551 Bytes
e36aeda | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | // Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
The Unified IR (UIR) format is implicitly defined by the package noder.
At the highest level, a package encoded in UIR follows the grammar
below.
File = Header Payload fingerprint .
Header = version [ flags ] sectionEnds elementEnds .
version = uint32 . // used for backward compatibility
flags = uint32 . // feature flags used across versions
sectionEnds = [10]uint32 . // defines section boundaries
elementEnds = []uint32 . // defines element boundaries
fingerprint = [8]byte . // sha256 fingerprint
The payload is a series of sections. Each section has a kind which
determines its index in the series.
SectionKind = Uint64 .
Payload = SectionString
SectionMeta
SectionPosBase
SectionPkg
SectionName
SectionType
SectionObj
SectionObjExt // TODO(markfreeman) Define.
SectionObjDict // TODO(markfreeman) Define.
SectionBody // TODO(markfreeman) Define.
.
# Sections
A section is a series of elements of a type determined by the section's
kind. Go constructs are mapped onto one or more elements with possibly
different types; in that case, the elements are in different sections.
Elements are accessed using an element index relative to the start of
the section.
RelElemIdx = Uint64 .
## String Section
String values are stored as elements in the string section. Elements
outside the string section access string values by reference.
SectionString = { String } .
Note that despite being an element, a string does not begin with a
reference table.
## Meta Section
The meta section provides fundamental information for a package. It
contains exactly two elements — a public root and a private root.
SectionMeta = PublicRoot
PrivateRoot // TODO(markfreeman): Define.
.
The public root element identifies the package and provides references
for all exported objects it contains.
PublicRoot = RefTable
[ Sync ]
PkgRef
[ HasInit ]
ObjectRefCount // TODO(markfreeman): Define.
{ ObjectRef } // TODO(markfreeman): Define.
.
HasInit = Bool . // Whether the package uses any
// initialization functions.
## PosBase Section
This section provides position information. It is a series of PosBase
elements.
SectionPosBase = { PosBase } .
A base is either a file base or line base (produced by a line
directive). Every base has a position, line, and column; these are
constant for file bases and hence not encoded.
PosBase = RefTable
[ Sync ]
StringRef // the (absolute) file name for the base
Bool // true if a file base, else a line base
// The below is omitted for file bases.
[ Pos
Uint64 // line
Uint64 ] // column
.
A source position Pos represents a file-absolute (line, column) pair
and a PosBase indicating the position Pos is relative to. Positions
without a PosBase have no line or column.
Pos = [ Sync ]
Bool // true if the position has a base
// The below is omitted if the position has no base.
[ Ref[PosBase]
Uint64 // line
Uint64 ] // column
.
## Package Section
The package section holds package information. It is a series of Pkg
elements.
SectionPkg = { Pkg } .
A Pkg element contains a (path, name) pair and a series of imported
packages. The below package paths have special meaning.
+--------------+-----------------------------------+
| package path | indicates |
+--------------+-----------------------------------+
| "" | the current package |
| "builtin" | the fake builtin package |
| "unsafe" | the compiler-known unsafe package |
+--------------+-----------------------------------+
Pkg = RefTable
[ Sync ]
StringRef // path
// The below is omitted for the special package paths
// "builtin" and "unsafe".
[ StringRef // name
Imports ]
.
Imports = Uint64 // the number of declared imports
{ PkgRef } // references to declared imports
.
Note, a PkgRef is *not* equivalent to Ref[Pkg] due to an extra marker.
PkgRef = [ Sync ]
Ref[Pkg]
.
## Type Section
The type section is a series of type definition elements.
SectionType = { TypeDef } .
A type definition can be in one of several formats, which are identified
by their TypeSpec code.
TypeDef = RefTable
[ Sync ]
[ Sync ]
Uint64 // denotes which TypeSpec to use
TypeSpec
.
TypeSpec = TypeSpecBasic // TODO(markfreeman): Define.
| TypeSpecNamed // TODO(markfreeman): Define.
| TypeSpecPointer // TODO(markfreeman): Define.
| TypeSpecSlice // TODO(markfreeman): Define.
| TypeSpecArray // TODO(markfreeman): Define.
| TypeSpecChan // TODO(markfreeman): Define.
| TypeSpecMap // TODO(markfreeman): Define.
| TypeSpecSignature // TODO(markfreeman): Define.
| TypeSpecStruct // TODO(markfreeman): Define.
| TypeSpecInterface // TODO(markfreeman): Define.
| TypeSpecUnion // TODO(markfreeman): Define.
| TypeSpecTypeParam // TODO(markfreeman): Define.
.
// TODO(markfreeman): Document the reader dictionary once we understand it more.
To use a type elsewhere, a TypeUse is encoded.
TypeUse = [ Sync ]
Bool // whether it is a derived type
[ Uint64 ] // if derived, an index into the reader dictionary
[ Ref[TypeDef] ] // else, a reference to the type
.
## Object Sections
Information about an object (e.g. variable, function, type name, etc.)
is split into multiple elements in different sections. Those elements
have the same section-relative element index.
### Name Section
The name section holds a series of names.
SectionName = { Name } .
Names are elements holding qualified identifiers and type information
for objects.
Name = RefTable
[ Sync ]
[ Sync ]
PkgRef // the object's package
StringRef // the object's package-local name
[ Sync ]
Uint64 // the object's type (e.g. Var, Func, etc.)
.
### Definition Section
The definition section holds definitions for objects defined by the target
package; it does not contain definitions for imported objects.
SectionObj = { ObjectDef } .
Object definitions can be in one of several formats. To determine the correct
format, the name section must be referenced; it contains a code indicating
the object's type.
ObjectDef = RefTable
[ Sync ]
ObjectSpec
.
ObjectSpec = ObjectSpecConst // TODO(markfreeman) Define.
| ObjectSpecFunc // TODO(markfreeman) Define.
| ObjectSpecAlias // TODO(markfreeman) Define.
| ObjectSpecNamedType // TODO(markfreeman) Define.
| ObjectSpecVar // TODO(markfreeman) Define.
.
To use an object definition elsewhere, an ObjectUse is encoded.
ObjectUse = [ Sync ]
[ Bool ]
Ref[ObjectDef]
Uint64 // the number of type arguments
{ TypeUse } // references to the type arguments
.
# References
A reference table precedes every element. Each entry in the table
contains a (section, index) pair denoting the location of the
referenced element.
RefTable = [ Sync ]
Uint64 // the number of table entries
{ RefTableEntry }
.
RefTableEntry = [ Sync ]
SectionKind
RelElemIdx
.
Elements encode references to other elements as an index in the
reference table — not the location of the referenced element directly.
RefTableIdx = Uint64 .
To do this, the Ref[T] primitive is used as below; note that this is
the same shape as provided by package pkgbits, just with new
interpretation applied.
Ref[T] = [ Sync ]
RefTableIdx // the Uint64
.
# Primitives
Primitive encoding is handled separately by the pkgbits package. Check
there for definitions of the below productions.
* Bool
* Int64
* Uint64
* String
* Ref[T]
* Sync
*/
package noder
|