Documentation
¶
Overview ¶
Package export reads the export data gc writes, so that nanogo can compile a package that imports one gc compiled.
The reader is a port of cmd/compile/internal/importer, which is the types2-shaped half of the pair whose other half is go/internal/gcimporter. See README.md for the upstream revision and for every place this copy diverges from it.
Index ¶
- Constants
- func Definition(header string, main bool, payload []byte) ([]byte, error)
- func Payload(archive []byte) ([]byte, error)
- func ReadPackage(ctxt *types2.Context, imports map[string]*types2.Package, ...) *types2.Package
- func SymName(fn *types2.Func) (string, bool)
- func Write(pkg *types2.Package, hasInit bool, src *Source) (data []byte, fingerprint [8]byte, err error)
- type AssertExpr
- type AssignKind
- type AssignOpStmt
- type AssignStmt
- type Assignee
- type BinaryExpr
- type BlockStmt
- type Body
- type BodyError
- type BodySource
- type BranchStmt
- type CallExpr
- type CallStmt
- type CapturedVar
- type CaseClause
- type CommClause
- type CompLitExpr
- type ConstExpr
- type ConvRTTI
- type ConvertExpr
- type Dict
- func (d *Dict) Derive(typ types2.Type) (int, bool, error)
- func (d *Dict) Generic() bool
- func (d *Dict) ItabIndex(typ, iface TypeUse) int
- func (d *Dict) MethodExprIndex(tp int, sel Selector) int
- func (d *Dict) RTypeIndex(t TypeUse) int
- func (d *Dict) SubdictIndex(use ObjUse) int
- func (d *Dict) TypeParamIndex(tp *types2.TypeParam) (int, bool)
- type Expr
- type ExprKind
- type ExprStmt
- type ExprType
- type FieldValExpr
- type ForStmt
- type FuncBody
- type FuncInst
- type FuncInstExpr
- type FuncLitExpr
- type GlobalExpr
- type IfStmt
- type Import
- type IncDecStmt
- type IndexExpr
- type InlineFunc
- type ItabSlot
- type LabelStmt
- type LitElem
- type Local
- type LocalExpr
- type MakeExpr
- type MethodCall
- type MethodExprExpr
- type MethodExprSlot
- type MethodRef
- type MethodValExpr
- type MultiExpr
- type MultiResult
- type NewExpr
- type ObjUse
- type OffsetofExpr
- type Op
- type Param
- type Pos
- type RType
- type RangeClause
- type Reader
- type RecvExpr
- type ReturnStmt
- type RuntimeBuiltinExpr
- type SelectStmt
- type Selector
- type SendStmt
- type SizeExpr
- type SliceExpr
- type Source
- type Stmt
- type StmtKind
- type SwitchStmt
- type TypeSwitchGuard
- type TypeUse
- type UnaryExpr
- type UnsupportedError
- type ZeroExpr
Constants ¶
const MaxInlineCost = 80
MaxInlineCost is the price nanogo offers an exported body at.
It is cmd/compile/internal/inline.inlineMaxBudget, which is the cost of the largest body gc's default budget accepts. gc reads the field as the budget the body spends and uses it twice: to decide whether to inline a call to this function, and to charge a function that calls this one when deciding whether that one can be inlined in turn.
nanogo runs no inliner and measures no hairiness (specs/024-inlining-and-devirtualization.md), so the number is a policy and not a measurement, and the policy is the conservative end of both uses. A caller is charged the most gc's budget allows, so no caller is made inlinable by an understated price. And a big caller, whose budget is 20, inlines nothing nanogo exported, which is where gc is most careful with its own bodies too.
const Version = pkgbits.V4
Version is the unified IR version nanogo writes.
It is cmd/compile/internal/noder.uirVersion, not the newest version the container knows. A reader refuses a stream newer than itself, so the version is a property of the release nanogo is pinned to (specs/000-decisions.md decision 10) and not of this package.
Variables ¶
This section is empty.
Functions ¶
func Definition ¶
Definition returns the body of an archive's __.PKGDEF member.
It is [read.go]'s container from the other side: the object header line, then the header lines the compiler adds, then the export data section. The blank line ends the headers, "$$B" says the section is binary and 'u' says it is the unified format.
header is the "go object ..." line the installed toolchain writes, with its newline; obj.VerifyToolchain reports it. main says the package is a main package, which is the one fact the linker reads out of the header lines.
func Payload ¶
Payload returns the unified export data one gc archive carries.
It is Definition from the other side, and it is what a reader that wants the bytes rather than the package needs: pkgbits.NewPkgDecoder takes exactly this, and ReadBodies takes the decoder.
func ReadPackage ¶
func ReadPackage(ctxt *types2.Context, imports map[string]*types2.Package, input pkgbits.PkgDecoder) *types2.Package
ReadPackage decodes one package from an already opened container.
imports is shared across every archive one compilation reads, because an archive names the packages its declarations mention and materialises them as a side effect. Only the package the archive is for is marked complete.
Most callers want Reader.Read, which opens the archive and turns a stream it cannot decode into an error.
func SymName ¶
SymName returns the name gc's linker gives a function or a method, which is the name the private root's body list names a body by.
A method is "T.M" for a value receiver and "(*T).M" for a pointer one. The second result is false for a method whose receiver is not a defined type, which no declaration has.
func Write ¶
func Write(pkg *types2.Package, hasInit bool, src *Source) (data []byte, fingerprint [8]byte, err error)
Write encodes pkg's exported surface as gc's unified export data and returns the payload and its fingerprint.
The payload is what goes between the "$$B\nu" and "\n$$\n" markers of an archive's __.PKGDEF member; Definition wraps it. The fingerprint has to reach the object nanogo writes for the same package: an importing object records it in its Autolib entry and the linker refuses a build whose two copies disagree.
What is written is the linked form, which is the only form that reaches a file. gc writes a stub form first, in which a declaration of another package is a name with no definition, and its linker resolves every stub by copying the definition out of the archive it came from. nanogo has no such two-step, so a declaration of another package that the exported surface reaches is written out in full here. Only the universe and unsafe stay stubs, which is what every reader of the format expects.
hasInit says the object carries the package's initialisation record. An importer reads it and orders its own record after this one, so a package that has a record and says it has none is a package whose initialisation never runs, and a package that says it has one and has none is a link failure. driver/inittask.go decides it.
src is what the package's own source adds to what the checker recorded: the positions of the declarations and the function bodies an importer can inline. It is nil for a package written without either, and then every position is absent and no body reaches the file. A body the writer cannot allocate every element of is left out rather than guessed at: see [writableBodies].
Types ¶
type AssertExpr ¶
type AssertExpr struct {
X Expr
Pos Pos
Type ExprType
Src RType
// contains filtered or unexported fields
}
An AssertExpr is x.(T).
type AssignKind ¶
type AssignKind int
An AssignKind names one assignment destination encoding.
const ( AssignBlank AssignKind = iota AssignDef AssignExpr )
The assignment destination encodings, in the format's order.
func (AssignKind) Marker ¶
func (c AssignKind) Marker() pkgbits.SyncMarker
func (AssignKind) String ¶
func (c AssignKind) String() string
func (AssignKind) Value ¶
func (c AssignKind) Value() int
type AssignOpStmt ¶
An AssignOpStmt is an assignment that applies an operator, such as x += y.
type AssignStmt ¶
An AssignStmt is an assignment, a short variable declaration, or a var declaration inside a function.
type Assignee ¶
type Assignee struct {
Kind AssignKind
// Kind == AssignDef: the variable the assignment declares.
Pos Pos
Name string
Pkg *types2.Package
Type TypeUse
Local Local
// Kind == AssignExpr.
Expr Expr
}
An Assignee is one destination of an assignment.
type BinaryExpr ¶
A BinaryExpr is a binary operation.
type BlockStmt ¶
A BlockStmt is a block, with the positions of the braces that open and close its scope.
type Body ¶
type Body struct {
// Params is one entry per receiver, parameter and result, in that
// order. They are the first locals, and a local is referred to by its
// index in declaration order.
Params []Local
// HasBlock is false for a declaration with no body, which is a function
// implemented in assembly or by a linkname.
HasBlock bool
// Stmts is the body, and Rbrace is its closing brace.
Stmts []Stmt
Rbrace Pos
// Dict is the object dictionary the declaration this body belongs to
// needs, which [BodySource.BuildBody] fills while it builds the body.
// It is nil for a body read from an archive, which names the slots of a
// dictionary that archive already holds.
Dict *Dict
}
A Body is one function body, decoded from one element of SectionBody.
The element does not say how many parameters the declaration has, so it cannot be decoded on its own: Params is as long as the receiver plus the parameters plus the results of the signature that names the body. See [ReadBody].
type BodyError ¶
type BodyError struct {
Package string // the package the body was read from or written for
Name string // the declaration the body belongs to
Reason string // what the reader cannot decode or the encoder cannot write
// Writing is true for a body the encoder refused. The two halves refuse
// different things, and a message that names one about the other sends a
// user to the wrong side of the format.
Writing bool
}
BodyError reports a body the reader cannot decode.
The declaration is named, because it is what a user has to work around and what specs/015-export-data.md's census counts.
type BodySource ¶
type BodySource struct {
// contains filtered or unexported fields
}
A BodySource is the checker's record of one package, which is everything a body is built from.
It holds no state of its own between bodies: two calls of BuildBody are independent, because a body's locals are numbered inside the body and nothing outside it can name one.
func NewBodySource ¶
NewBodySource returns the source of bodies for one checked package.
info must carry Types, Defs, Uses, Implicits, Selections and Instances: the builder reads a node's type, the object a name denotes, the field or method a selector resolves to, and the type arguments an inferred instantiation got, and none of the four is recoverable from syntax.
func (*BodySource) BuildBody ¶
func (s *BodySource) BuildBody(name string, sig *types2.Signature, block *syntax.BlockStmt) (body *Body, err error)
BuildBody builds the tree of one function body.
name is the declaration the body belongs to and is what a refusal reports. sig is its signature, which is what numbers the first locals. block is nil for a declaration with no body, which is a function implemented in assembly or by a linkname.
type BranchStmt ¶
A BranchStmt is break, continue, goto or fallthrough.
type CallExpr ¶
type CallExpr struct {
// Method is set for a call through a method selection.
Method *MethodCall
// Inst is set for a call of an instantiated generic function.
Inst *FuncInst
InstPos Pos
// Fun is the callee for every other call.
Fun Expr
Pos Pos
Args MultiExpr
Dots bool
// RType is the descriptor append, copy, delete and unsafe.Slice need,
// and is nil for every other callee.
RType *RType
// contains filtered or unexported fields
}
A CallExpr is a call.
type CallStmt ¶
type CallStmt struct {
Pos Pos
Op Op
Call Expr
// DeferAt is the defer record a defer statement runs in, and is nil for
// a defer that uses the frame's own record and for go.
DeferAt Expr
}
A CallStmt is go or defer.
type CapturedVar ¶
A CapturedVar is one variable a function literal captures.
type CaseClause ¶
type CaseClause struct {
// ScopeClose is the position that closes the previous clause's scope
// and is only set for a clause after the first.
ScopeClose *Pos
ScopeOpen Pos
Pos Pos
// Types is set for a type switch, one entry per case. A nil Type is the
// case nil.
Types []*ExprType
// Exprs is set for an expression switch.
Exprs []Expr
// Var is the variable a named type switch guard declares for this
// clause.
Var *Local
VarPos Pos
VarType TypeUse
Body []Stmt
}
A CaseClause is one clause of a switch.
type CommClause ¶
A CommClause is one clause of a select.
type CompLitExpr ¶
type CompLitExpr struct {
Pos Pos
Type TypeUse
// MapRType is the descriptor of the map being built, and is nil for
// every other kind of literal.
MapRType *RType
// Keyed is false when no element has a key, which is the compact form
// the format's version V3 added.
Keyed bool
Elems []LitElem
// contains filtered or unexported fields
}
A CompLitExpr is a composite literal.
type ConstExpr ¶
type ConstExpr struct {
Pos Pos
Type TypeUse
Value constant.Value
// contains filtered or unexported fields
}
A ConstExpr is a constant. gc folds a constant expression before it writes it, so the source's operators are not here.
type ConvRTTI ¶
type ConvRTTI struct {
Src RType
Dst RType
Derived bool
DictIdx int // the itab dictionary slot, when Derived
}
A ConvRTTI is the pair of descriptors a conversion from one type to another needs at run time.
type ConvertExpr ¶
type ConvertExpr struct {
// Implicit is true for a conversion the source did not spell, which the
// assignability rules of the specification require.
Implicit bool
Type TypeUse
Pos Pos
Conv ConvRTTI
// TypeParam is true when the destination is a type parameter, and
// Identical is true when the two types are identical, which happens for
// an explicit conversion that changes nothing.
TypeParam bool
Identical bool
X Expr
// contains filtered or unexported fields
}
A ConvertExpr is a conversion.
type Dict ¶
type Dict struct {
// Implicits are the type parameters of an enclosing declaration, which
// only a type declared inside a generic function has. Receivers are the
// receiver's type parameters, which only a generic method has, and
// TypeParams are the declaration's own.
//
// The three are one numbering, in that order, which is what a reference
// to a type parameter is written in. See [Dict.TypeParamIndex].
Implicits []*types2.TypeParam
Receivers []*types2.TypeParam
TypeParams []*types2.TypeParam
// Derived is every type the declaration names whose identity depends on
// a type parameter, in allocation order.
Derived []types2.Type
// MethodExprs, Subdicts, RTypes and Itabs are the runtime lists, in
// allocation order. Each is a slot of the dictionary an instantiation
// is passed.
MethodExprs []MethodExprSlot
Subdicts []ObjUse
RTypes []TypeUse
Itabs []ItabSlot
// Pkg is the package the declaration belongs to. It is what tells a type
// declared inside the declaration from one declared elsewhere.
Pkg *types2.Package
// contains filtered or unexported fields
}
The object dictionary of one declaration.
A generic declaration's body names types whose identity depends on the enclosing type parameters, and it names runtime values that only exist once the type arguments are known. Neither can be an element of the package, because there is one element per type and there is one such type per instantiation. The format puts them in a dictionary instead: the body names a slot, and the reader resolves the slot against the type arguments the instantiation supplied.
This is cmd/compile/internal/noder.writerDict, with the elements left out. gc allocates a slot while it writes the bitstream, so the slot numbers are a property of the order gc's writer walks a declaration in. A slot the builder numbers differently is a slot gc reads as another type, and gc reads it without complaint, so the numbering is the whole of the problem.
The five lists are what gc's objDict writes and what the four call sites the body encoder has fill:
rtype and varDictIndex -> RTypes itab, which convRTTI is a use of -> Itabs a call of an instantiated function or method -> Subdicts a method expression on a type parameter -> MethodExprs
Derived is not a runtime list. It is the type section of the dictionary: every type the declaration names whose identity depends on a type parameter, in the order gc writes their elements.
func (*Dict) Derive ¶
Derive returns the dictionary slot a type is named by, and false when the type's identity does not depend on a type parameter.
This is cmd/compile/internal/noder.pkgWriter.typIdx with the elements left out. gc allocates the slot of a type after it has written the element of every type that type names, so a composite type's slot follows the slots of its components, and the walk below is the order of gc's encoding rather than an order of this package's choosing. A slot numbered otherwise is a slot gc reads as a different type, and gc reads it without complaint.
One allocator answers the body builder and the export data writer, so that the slot a body names and the slot the dictionary holds cannot disagree. The error is what neither can encode, and each reports it in its own shape.
func (*Dict) Generic ¶
Generic reports whether the declaration the dictionary belongs to has any type parameter, which is the only case in which a slot can be named.
func (*Dict) ItabIndex ¶
ItabIndex returns the slot holding the method table for typ as iface, adding it if it is new.
func (*Dict) MethodExprIndex ¶
MethodExprIndex returns the slot holding the method a type parameter's method expression resolves to, adding it if it is new.
func (*Dict) RTypeIndex ¶
RTypeIndex returns the slot holding t's runtime type descriptor, adding it if it is new.
func (*Dict) SubdictIndex ¶
SubdictIndex returns the slot holding the dictionary of one instantiation, adding it if it is new.
func (*Dict) TypeParamIndex ¶
TypeParamIndex returns the index a reference to tp is written as.
The enclosing declaration's type parameters come first, then the receiver's, and the declaration's own follow at the position they were declared in. A type parameter that is none of the three cannot be named by this declaration, and the index is then out of range for its dictionary, which is why it is a refusal rather than a fallthrough.
type Expr ¶
type Expr interface {
// Reshape is the reshape node the format wrote in front of the
// expression, and is nil where it wrote none.
Reshape() *TypeUse
// ExprType is the type of the value the expression produces, and is nil
// where the stream did not carry one. It is nil for an expression of a
// tuple type, for a reference to a builtin, and for a use of a local.
ExprType() types2.Type
// contains filtered or unexported methods
}
An Expr is one expression of a body.
Every expression that has a type in the checker's record is preceded in the stream by its type, because gc writes a reshape node in front of it. The decoder attaches that type to the expression it wraps, so Expr.ExprType answers for nearly every node without the tree being type checked again.
type ExprKind ¶
type ExprKind int
An ExprKind names one expression encoding.
const ( ExprConst ExprKind = iota ExprLocal ExprGlobal ExprCompLit ExprFuncLit ExprFieldVal ExprMethodVal ExprMethodExpr ExprIndex ExprSlice ExprAssert ExprUnaryOp ExprBinaryOp ExprCall ExprConvert ExprNew ExprMake ExprSizeof ExprAlignof ExprOffsetof ExprZero ExprFuncInst ExprRecv ExprReshape ExprRuntimeBuiltin )
The expression encodings, in the format's order.
func (ExprKind) Marker ¶
func (c ExprKind) Marker() pkgbits.SyncMarker
type ExprStmt ¶
type ExprStmt struct{ X Expr }
An ExprStmt is an expression evaluated for its effect.
type ExprType ¶
type ExprType struct {
Pos Pos
// Itab is set when the type is being matched against a non-empty
// interface, and RType is set otherwise.
Itab *ConvRTTI
RType *RType
Derived bool
}
An ExprType is a type written where an expression is expected, which is a type assertion's type, a type switch case, and make's and new's first argument.
type FieldValExpr ¶
A FieldValExpr is x.f, where f is a field.
type ForStmt ¶
type ForStmt struct {
Open Pos
Range *RangeClause
Pos Pos
Init []Stmt
Cond Expr
Post []Stmt
Body *BlockStmt
// DistinctVars says the loop declares its variables anew on every
// iteration, which is the Go 1.22 rule.
DistinctVars bool
}
A ForStmt is a for statement. Range is set for a range clause and the three-clause fields are set otherwise.
type FuncBody ¶
type FuncBody struct {
// Path and Name are the declaration, as the export data names it. Name
// is gc's linker symbol name, so a method is "T.M" or "(*T).M".
Path string
Name string
// Generic is true for a body reached through the declaration's
// extension data, which is the shape a generic declaration has and the
// one an importer needs in order to instantiate it
// (specs/013-generics.md). It is false for a body reached through the
// private root, which is an inlinable body.
Generic bool
// Idx is the SectionBody element, and Body is it decoded.
Idx pkgbits.Index
Body *Body
// Nested is the number of function literal bodies inside this one,
// each of which is an element of its own that was decoded with it.
Nested int
}
A FuncBody is one function body with the declaration it belongs to.
func ReadBodies ¶
func ReadBodies(ctxt *types2.Context, imports map[string]*types2.Package, input pkgbits.PkgDecoder) (*types2.Package, []*FuncBody, error)
ReadBodies reads a package's declarations and then every function body its export data carries.
The package is returned whether or not a body could be read, because the declarations are what an importer needs first and a body that cannot be read is a refusal about one declaration rather than about the package. A refusal is a *BodyError naming the declaration.
type FuncInst ¶
type FuncInst struct {
// Derived is true when a type argument depends on the enclosing
// declaration's type parameters, and DictIdx is then the subdictionary
// slot the call takes its dictionary from.
Derived bool
DictIdx int
Obj ObjUse
}
A FuncInst is a reference to an instantiated generic function.
type FuncInstExpr ¶
A FuncInstExpr is a reference to an instantiated generic function that is not immediately called.
type FuncLitExpr ¶
type FuncLitExpr struct {
Pos Pos
// Params and Results are the literal's signature. A literal has no
// receiver, so the two together are as long as its body's Params.
Params []Param
Results []Param
Variadic bool
// RangeFuncBody is true for the closure gc builds out of the body of a
// range over a function.
RangeFuncBody bool
// Captured is one entry per variable the literal captures, naming it in
// the enclosing body's numbering.
Captured []CapturedVar
// Body is the index of the SectionBody element holding the literal's
// body, and Decoded is that body once it has been read.
Body pkgbits.Index
Decoded *Body
// contains filtered or unexported fields
}
A FuncLitExpr is a function literal.
type GlobalExpr ¶
type GlobalExpr struct {
Obj ObjUse
// contains filtered or unexported fields
}
A GlobalExpr is a use of a package-scope declaration, of a builtin, or of an unsafe intrinsic.
type IfStmt ¶
type IfStmt struct {
Open Pos
Pos Pos
Init []Stmt
Cond Expr
Static int
Then *BlockStmt
ThenClose Pos
Else []Stmt
}
An IfStmt is an if statement.
Static is the constant value of the condition, if it has one: 1 for a condition that is always true, -1 for one that is always false, and 0 for one that is not constant. gc omits the branch it proved unreachable, so Then is nil when Static is negative and Else is nil when Static is positive.
type Import ¶
type Import struct {
// Path is the import path the export data was read under, after any
// importmap rename.
Path string
// File is the archive it came from.
File string
// Fingerprint identifies the export data. The linker compares it with
// the one in the imported package's own object and refuses a build
// whose two copies disagree.
Fingerprint [8]byte
}
Import is one package this compilation read export data for.
type IndexExpr ¶
type IndexExpr struct {
X Expr
Pos Pos
Index Expr
// MapRType is the descriptor of the map being indexed, and is nil when
// x is not a map.
MapRType *RType
// contains filtered or unexported fields
}
An IndexExpr is x[i].
type InlineFunc ¶
type InlineFunc struct {
// Obj is the declaration. It is what pairs the body with the extension
// data that says the declaration has one.
Obj *types2.Func
// Name is gc's linker symbol name for the declaration: "F" for a
// function, "T.M" or "(*T).M" for a method. gc looks a body up in the
// private root's list by this name and the package path.
Name string
// Cost is the inlining budget the body spends, in gc's units. gc reads
// it and inlines the call when the cost is inside the budget of the
// function it would inline into.
Cost int
// Body is the tree [BodySource.BuildBody] built.
Body *Body
}
An InlineFunc is one declaration whose body gc can inline.
type LabelStmt ¶
A LabelStmt is a label. The statement it labels is the next statement of the same list, because gc writes the two flat.
type LitElem ¶
type LitElem struct {
// Pos is the position of the key, or of the element for a struct
// literal with no key.
Pos Pos
// Key is set for an element of an array, slice or map literal written
// with a key.
Key Expr
// Field is the field index of an element of a struct literal, and
// Embedded is the path to it through embedded fields when the key names
// a promoted field.
Field int
Embedded []int
Value Expr
}
A LitElem is one element of a composite literal.
type Local ¶
type Local struct {
// DictRType is the runtime type slot of a local whose type is derived
// from the enclosing declaration's type parameters, and -1 for a local
// whose type is known without a dictionary.
DictRType int
}
A Local is one local variable's declaration in a body.
The variable has no name and no object here. gc numbers locals in declaration order and refers to one by its number, so a body carries its own local numbering and nothing outside the body can name a local.
type LocalExpr ¶
type LocalExpr struct {
// Captured is true when Index names a captured variable rather than a
// local of this body.
Captured bool
Index int
// contains filtered or unexported fields
}
A LocalExpr is a use of a local variable or of a variable captured by a function literal.
type MakeExpr ¶
type MakeExpr struct {
Pos Pos
Type ExprType
Args []Expr
RType RType
// contains filtered or unexported fields
}
A MakeExpr is make(T, ...).
type MethodCall ¶
A MethodCall is the callee of a call through a method selection.
type MethodExprExpr ¶
type MethodExprExpr struct {
Recv TypeUse
// Implicits is the path of embedded fields the selection goes through.
Implicits []int
// Deref and Addr say whether the receiver needs one before the method
// is applied.
Deref bool
Addr bool
Pos Pos
Method MethodRef
// contains filtered or unexported fields
}
A MethodExprExpr is T.m, where the result is a function whose first parameter is the receiver.
type MethodExprSlot ¶
type MethodExprSlot struct {
// TypeParam is the type parameter's index in the dictionary's own
// numbering, which [Dict.TypeParamIndex] gives.
TypeParam int
Sel Selector
}
A MethodExprSlot is a method named on a type parameter, which the body reaches through the dictionary because the receiver's method is not known until the type argument is.
type MethodRef ¶
type MethodRef struct {
Recv TypeUse
// Generic is true for a method that declares type parameters of its
// own, and Sig is the method's signature otherwise.
Generic bool
Sig TypeUse
Pos Pos
Sel Selector
// TypeParam is set when the receiver is a type parameter, so that the
// call goes through the dictionary at DictIdx.
TypeParam bool
DictIdx int
// Subdict is set when the type arguments are not all known statically,
// and StaticDict is set when they are and the method needs one.
Subdict bool
SubdictIdx int
StaticDict bool
Dict ObjUse
}
A MethodRef is a reference to the method a selection names.
type MethodValExpr ¶
type MethodValExpr struct {
Recv Expr
Pos Pos
Method MethodRef
// contains filtered or unexported fields
}
A MethodValExpr is x.m, where m is a method and the result is a bound method value.
type MultiExpr ¶
type MultiExpr struct {
// Single is set for the one-expression form. Values are then the
// results, in order, each with the type it is converted to.
Single bool
Pos Pos
Expr Expr
Results []MultiResult
// Exprs is the one-expression-per-value form.
Exprs []Expr
}
A MultiExpr is a list of values, which is either one expression per value or one multi-valued expression spread over all of them.
type MultiResult ¶
A MultiResult is one result of a multi-valued expression.
type NewExpr ¶
type NewExpr struct {
Pos Pos
// Value is set for new(x), which Go 1.26 added, and Type is set for
// new(T).
Value Expr
Type *ExprType
// contains filtered or unexported fields
}
A NewExpr is new(T) or new(x).
type ObjUse ¶
type ObjUse struct {
Idx pkgbits.Index
Pkg *types2.Package // nil for the universe
Name string
Obj types2.Object // nil for a declaration the scope has no object for
Targs []TypeUse
}
An ObjUse is a reference to a package-scope declaration from inside a body, with the type arguments it is instantiated with.
type OffsetofExpr ¶
type OffsetofExpr struct {
Pos Pos
Type TypeUse
// Path is the field index at each step of the selection, so a selection
// through an embedded field has more than one entry.
Path []int
// contains filtered or unexported fields
}
An OffsetofExpr is unsafe.Offsetof.
type Op ¶
type Op int
An Op is the operator a body carries on an operation, a branch, or a deferred or concurrent call.
The value is gc's ir.Op ordinal, because that is what reaches the file: noder/writer.go's op writes int(op) and nothing translates it. The ordinals are dense over gc's whole node set, and only the ones below can appear in a body, so an ordinal that is not one of them is a stream this reader refuses rather than a node it guesses at.
const ( OpAdd Op = 6 // x + y OpSub Op = 7 // x - y OpOr Op = 8 // x | y OpXor Op = 9 // x ^ y OpAddr Op = 11 // &x OpAndAnd Op = 12 // x && y OpEq Op = 57 // x == y OpNe Op = 58 // x != y OpLt Op = 59 // x < y OpLe Op = 60 // x <= y OpGe Op = 61 // x >= y OpGt Op = 62 // x > y OpDeref Op = 63 // *x OpMul Op = 74 // x * y OpDiv Op = 75 // x / y OpMod Op = 76 // x % y OpLsh Op = 77 // x << y OpRsh Op = 78 // x >> y OpAnd Op = 79 // x & y OpAndNot Op = 80 // x &^ y OpNot Op = 82 // !x OpBitNot Op = 83 // ^x OpPlus Op = 84 // +x OpNeg Op = 85 // -x OpOrOr Op = 86 // x || y OpRecv Op = 100 // <-x OpBreak Op = 116 // break OpContinue Op = 118 // continue OpDefer Op = 119 // defer OpFall Op = 120 // fallthrough OpGoto Op = 122 // goto OpGo Op = 125 // go )
The operators a body can carry. The names are gc's without its O prefix, and the values are gc's ir.Op ordinals on the pinned release.
type Pos ¶
A Pos is a source position, as the format carries it.
nanogo has no coordinate space for a file of another package (specs/010-scanner-and-positions.md), so a position read from an archive is not turned into a syntax.Pos. Known is false for the absent position.
The base is named twice, and the two names have different owners. Base is the SectionPosBase element of the archive the position was read from, and is meaningless in a position built from syntax. File is the file name that element holds, and is the only name a position built from syntax has: a writer allocates the element from it.
type RType ¶
type RType struct {
Derived bool
DictIdx int // the dictionary slot, when Derived
Type TypeUse // the type, when not Derived
}
An RType is the runtime type descriptor a body needs at run time.
type RangeClause ¶
type RangeClause struct {
Pos Pos
Lhs []Assignee
X Expr
// MapRType is the descriptor of the map being ranged over, and is nil
// when the operand is not a map.
MapRType *RType
// KeyConv and ValueConv convert the key and the value to the type of
// their destination. Each is nil when the clause has no such
// destination or when the destination is blank.
KeyConv *ConvRTTI
ValueConv *ConvRTTI
}
A RangeClause is the range form of a for statement.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader reads the export data of the packages one compilation imports.
One Reader serves a whole compilation, because a package reached through two different archives must be the same types2.Package. gc writes the declarations an archive depends on into that archive, so reading "net/http" materialises "io" as a side effect. A second Reader would produce a second "io" and the checker would report the two io.Writer types as unrelated.
The same reasoning gives the Reader one types2.Context: it is what makes two instantiations of one generic type with the same arguments identical.
func (*Reader) Imports ¶
Imports returns what was read, in the order it was read.
A package is read once, so the order is the order the type checker first asked for each import, which is source order. The slice is what the object writer walks, and walking it rather than a map is what keeps the object's Autolib block identical between runs (specs/053-determinism.md).
func (*Reader) Read ¶
Read returns the package at the import path path, reading it from the archive file.
A package already read is returned only when it is complete. A package that another archive mentioned exists but holds nothing, because ReadPackage marks only the package the archive is for, so an incomplete entry is a package whose own archive has still to be read.
type RecvExpr ¶
type RecvExpr struct {
X Expr
Pos Pos
Implicits []int
Deref bool
Addr bool
// contains filtered or unexported fields
}
A RecvExpr is the operand of a method selection, with the implicit field selections, dereference or address the selection applies.
type RuntimeBuiltinExpr ¶
type RuntimeBuiltinExpr struct {
Name string
// contains filtered or unexported fields
}
A RuntimeBuiltinExpr is a reference to a runtime function that gc's own transformations introduced, such as panicrangeexit. It has no source spelling.
type SelectStmt ¶
type SelectStmt struct {
Pos Pos
Clauses []CommClause
Close Pos
}
A SelectStmt is a select statement.
type SizeExpr ¶
type SizeExpr struct {
Kind ExprKind // ExprSizeof or ExprAlignof
Pos Pos
Type TypeUse
// contains filtered or unexported fields
}
A SizeExpr is unsafe.Sizeof or unsafe.Alignof.
type Source ¶
type Source struct {
// Fset resolves the position of a declaration and of a position a body
// carries. Without it every position the file holds is absent.
Fset *syntax.FileSet
// Funcs is one entry per declaration whose body reaches the file, in
// the order the caller decided. The order the file holds them in is the
// order of the elements they were written to, which is gc's order.
Funcs []InlineFunc
// File maps a position's file name to the name the export data records
// for it. It is nil when the names are recorded as they were parsed.
//
// The driver owns the answer, because it is the same answer the object's
// line table already holds: one compiler must not report two names for
// one file. See [pkgWriter.posBaseIdx].
File func(string) string
}
A Source is what a package's own source adds to what the checker recorded.
It is what the driver assembles: the FileSet that resolves a declaration's position, and the bodies BodySource built. The writer allocates the elements each body names and writes nothing it cannot allocate.
type Stmt ¶
type Stmt interface {
// contains filtered or unexported methods
}
A Stmt is one statement of a body.
type StmtKind ¶
type StmtKind int
A StmtKind names one statement encoding.
const ( StmtEnd StmtKind = iota StmtLabel StmtBlock StmtExpr StmtSend StmtAssign StmtAssignOp StmtIncDec StmtBranch StmtCall StmtReturn StmtIf StmtFor StmtSwitch StmtSelect )
The statement encodings, in the format's order.
func (StmtKind) Marker ¶
func (c StmtKind) Marker() pkgbits.SyncMarker
type SwitchStmt ¶
type SwitchStmt struct {
Open Pos
Pos Pos
Init []Stmt
// Guard is set for a type switch and Tag for an expression switch. Tag
// is nil for a switch with no tag, which is a switch on true.
Guard *TypeSwitchGuard
Tag Expr
Clauses []CaseClause
// ClausesClose is the closing brace as it ends the last clause's scope,
// and Close is the same brace as it ends the switch's own scope. gc
// writes it twice and the second is written even for a switch with no
// clause.
ClausesClose Pos
Close Pos
}
A SwitchStmt is an expression switch or a type switch.
type TypeSwitchGuard ¶
type TypeSwitchGuard struct {
Pos Pos
// Named is true when the guard declares a variable, which each clause
// then declares again with the clause's own type.
Named bool
NamePos Pos
Pkg *types2.Package
Name string
X Expr
}
A TypeSwitchGuard is the x := y.(type) of a type switch.
type TypeUse ¶
A TypeUse is a reference to a type from inside a body.
A derived type is one whose identity depends on the enclosing declaration's type parameters. Idx is then a slot in that declaration's dictionary rather than an index into SectionType.
type UnsupportedError ¶
type UnsupportedError struct {
Package string // the package being written
Name string // the declaration, qualified by its own package
Reason string // what the writer cannot encode about it
}
UnsupportedError reports a declaration the writer cannot encode.
The declaration is named, because the package that holds it is what a user has to remove from the allowlist or work around.
func (*UnsupportedError) Error ¶
func (e *UnsupportedError) Error() string