package pkgbits

import "internal/pkgbits"

Package pkgbits implements low-level coding abstractions for Unified IR's export data format.

At a low-level, a package is a collection of bitstream elements. Each element has a "kind" and a dense, non-negative index. Elements can be randomly accessed given their kind and index.

Individual elements are sequences of variable-length values (e.g., integers, booleans, strings, go/constant values, cross-references to other elements). Package pkgbits provides APIs for encoding and decoding these low-level values, but the details of mapping higher-level Go constructs into elements is left to higher-level abstractions.

Elements may cross-reference each other with "relocations." For example, an element representing a pointer type has a relocation referring to the element type.

Go constructs may be composed as a constellation of multiple elements. For example, a declared function may have one element to describe the object (e.g., its name, type, position), and a separate element to describe its function body. This allows readers some flexibility in efficiently seeking or re-reading data (e.g., inlining requires re-reading the function body for each inlined call, without needing to re-read the object-level details).

Index

Types

type Code

type Code interface {
	// Marker returns the SyncMarker for the Code's dynamic type.
	Marker() SyncMarker

	// Value returns the Code's ordinal value.
	Value() int
}

A Code is an enum value that can be encoded into bitstreams.

Code types are preferable for enum types, because they allow Decoder to detect desyncs.

type CodeObj

type CodeObj int

A CodeObj distinguishes among go/types.Object encodings.

const (
	ObjAlias CodeObj = iota
	ObjConst
	ObjType
	ObjFunc
	ObjVar
	ObjStub
)

func (CodeObj) Marker

func (c CodeObj) Marker() SyncMarker

func (CodeObj) Value

func (c CodeObj) Value() int

type CodeType

type CodeType int

A CodeType distinguishes among go/types.Type encodings.

const (
	TypeBasic CodeType = iota
	TypeNamed
	TypePointer
	TypeSlice
	TypeArray
	TypeChan
	TypeMap
	TypeSignature
	TypeStruct
	TypeInterface
	TypeUnion
	TypeTypeParam
)

func (CodeType) Marker

func (c CodeType) Marker() SyncMarker

func (CodeType) Value

func (c CodeType) Value() int

type CodeVal

type CodeVal int

A CodeVal distinguishes among go/constant.Value encodings.

const (
	ValBool CodeVal = iota
	ValString
	ValInt64
	ValBigInt
	ValBigRat
	ValBigFloat
)

func (CodeVal) Marker

func (c CodeVal) Marker() SyncMarker

func (CodeVal) Value

func (c CodeVal) Value() int

type Decoder

type Decoder struct {
	Relocs []RelocEnt
	Data   strings.Reader

	Idx Index
	// contains filtered or unexported fields
}

A Decoder provides methods for decoding an individual element's bitstream data.

func (*Decoder) Bool

func (r *Decoder) Bool() bool

Bool decodes and returns a bool value from the element bitstream.

func (*Decoder) Code

func (r *Decoder) Code(mark SyncMarker) int

Code decodes a Code value from the element bitstream and returns its ordinal value. It's the caller's responsibility to convert the result to an appropriate Code type.

TODO(mdempsky): Ideally this method would have signature "Code[T Code] T" instead, but we don't allow generic methods and the compiler can't depend on generics yet anyway.

func (*Decoder) Int

func (r *Decoder) Int() int

Int decodes and returns an int value from the element bitstream.

func (*Decoder) Int64

func (r *Decoder) Int64() int64

Int64 decodes and returns an int64 value from the element bitstream.

func (*Decoder) Len

func (r *Decoder) Len() int

Len decodes and returns a non-negative int value from the element bitstream.

func (*Decoder) Reloc

func (r *Decoder) Reloc(k RelocKind) Index

Reloc decodes a relocation of expected section k from the element bitstream and returns an index to the referenced element.

func (*Decoder) String

func (r *Decoder) String() string

String decodes and returns a string value from the element bitstream.

func (*Decoder) Strings

func (r *Decoder) Strings() []string

Strings decodes and returns a variable-length slice of strings from the element bitstream.

func (*Decoder) Sync

func (r *Decoder) Sync(mWant SyncMarker)

Sync decodes a sync marker from the element bitstream and asserts that it matches the expected marker.

If EnableSync is false, then Sync is a no-op.

func (*Decoder) Uint

func (r *Decoder) Uint() uint

Uint decodes and returns a uint value from the element bitstream.

func (*Decoder) Uint64

func (r *Decoder) Uint64() uint64

Int64 decodes and returns a uint64 value from the element bitstream.

func (*Decoder) Value

func (r *Decoder) Value() constant.Value

Value decodes and returns a constant.Value from the element bitstream.

type Encoder

type Encoder struct {
	Relocs   []RelocEnt
	RelocMap map[RelocEnt]uint32
	Data     bytes.Buffer // accumulated element bitstream data

	Idx Index // index within relocation section
	// contains filtered or unexported fields
}

An Encoder provides methods for encoding an individual element's bitstream data.

func (*Encoder) Bool

func (w *Encoder) Bool(b bool) bool

Bool encodes and writes a bool value into the element bitstream, and then returns the bool value.

For simple, 2-alternative encodings, the idiomatic way to call Bool is something like:

if w.Bool(x != 0) {
	// alternative #1
} else {
	// alternative #2
}

For multi-alternative encodings, use Code instead.

func (*Encoder) Code

func (w *Encoder) Code(c Code)

Code encodes and writes a Code value into the element bitstream.

func (*Encoder) Flush

func (w *Encoder) Flush() Index

Flush finalizes the element's bitstream and returns its Index.

func (*Encoder) Int

func (w *Encoder) Int(x int)

Int encodes and writes an int value into the element bitstream.

func (*Encoder) Int64

func (w *Encoder) Int64(x int64)

Int64 encodes and writes an int64 value into the element bitstream.

func (*Encoder) Len

func (w *Encoder) Len(x int)

Len encodes and writes a non-negative int value into the element bitstream.

func (*Encoder) Reloc

func (w *Encoder) Reloc(r RelocKind, idx Index)

Reloc encodes and writes a relocation for the given (section, index) pair into the element bitstream.

Note: Only the index is formally written into the element bitstream, so bitstream decoders must know from context which section an encoded relocation refers to.

func (*Encoder) String

func (w *Encoder) String(s string)

String encodes and writes a string value into the element bitstream.

Internally, strings are deduplicated by adding them to the strings section (if not already present), and then writing a relocation into the element bitstream.

func (*Encoder) StringRef

func (w *Encoder) StringRef(idx Index)

StringRef writes a reference to the given index, which must be a previously encoded string value.

func (*Encoder) Strings

func (w *Encoder) Strings(ss []string)

Strings encodes and writes a variable-length slice of strings into the element bitstream.

func (*Encoder) Sync

func (w *Encoder) Sync(m SyncMarker)

func (*Encoder) Uint

func (w *Encoder) Uint(x uint)

Len encodes and writes a uint value into the element bitstream.

func (*Encoder) Uint64

func (w *Encoder) Uint64(x uint64)

Uint64 encodes and writes a uint64 value into the element bitstream.

func (*Encoder) Value

func (w *Encoder) Value(val constant.Value)

Value encodes and writes a constant.Value into the element bitstream.

type Index

type Index int32

An Index represents a bitstream element index within a particular section.

const (
	PublicRootIdx  Index = 0
	PrivateRootIdx Index = 1
)

Reserved indices within the meta relocation section.

type PkgDecoder

type PkgDecoder struct {
	// contains filtered or unexported fields
}

A PkgDecoder provides methods for decoding a package's Unified IR export data.

func NewPkgDecoder

func NewPkgDecoder(pkgPath, input string) PkgDecoder

NewPkgDecoder returns a PkgDecoder initialized to read the Unified IR export data from input. pkgPath is the package path for the compilation unit that produced the export data.

TODO(mdempsky): Remove pkgPath parameter; unneeded since CL 391014.

func (*PkgDecoder) AbsIdx

func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int

AbsIdx returns the absolute index for the given (section, index) pair.

func (*PkgDecoder) DataIdx

func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string

DataIdx returns the raw element bitstream for the given (section, index) pair.

func (*PkgDecoder) Fingerprint

func (pr *PkgDecoder) Fingerprint() [8]byte

Fingerprint returns the package fingerprint.

func (*PkgDecoder) NewDecoder

func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder

NewDecoder returns a Decoder for the given (section, index) pair, and decodes the given SyncMarker from the element bitstream.

func (*PkgDecoder) NewDecoderRaw

func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder

NewDecoderRaw returns a Decoder for the given (section, index) pair.

Most callers should use NewDecoder instead.

func (*PkgDecoder) NumElems

func (pr *PkgDecoder) NumElems(k RelocKind) int

NumElems returns the number of elements in section k.

func (*PkgDecoder) PeekObj

func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj)

PeekObj returns the package path, object name, and CodeObj for the specified object index.

func (*PkgDecoder) PeekPkgPath

func (pr *PkgDecoder) PeekPkgPath(idx Index) string

PeekPkgPath returns the package path for the specified package index.

func (*PkgDecoder) PkgPath

func (pr *PkgDecoder) PkgPath() string

PkgPath returns the package path for the package

TODO(mdempsky): Remove; unneeded since CL 391014.

func (*PkgDecoder) RetireDecoder

func (pr *PkgDecoder) RetireDecoder(d *Decoder)

func (*PkgDecoder) StringIdx

func (pr *PkgDecoder) StringIdx(idx Index) string

StringIdx returns the string value for the given string index.

func (*PkgDecoder) SyncMarkers

func (pr *PkgDecoder) SyncMarkers() bool

SyncMarkers reports whether pr uses sync markers.

func (*PkgDecoder) TempDecoder

func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder

TempDecoder returns a Decoder for the given (section, index) pair, and decodes the given SyncMarker from the element bitstream. If possible the Decoder should be RetireDecoder'd when it is no longer needed, this will avoid heap allocations.

func (*PkgDecoder) TempDecoderRaw

func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder

func (*PkgDecoder) TotalElems

func (pr *PkgDecoder) TotalElems() int

TotalElems returns the total number of elements across all sections.

type PkgEncoder

type PkgEncoder struct {
	// contains filtered or unexported fields
}

A PkgEncoder provides methods for encoding a package's Unified IR export data.

func NewPkgEncoder

func NewPkgEncoder(syncFrames int) PkgEncoder

NewPkgEncoder returns an initialized PkgEncoder.

syncFrames is the number of caller frames that should be serialized at Sync points. Serializing additional frames results in larger export data files, but can help diagnosing desync errors in higher-level Unified IR reader/writer code. If syncFrames is negative, then sync markers are omitted entirely.

func (*PkgEncoder) DumpTo

func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte)

DumpTo writes the package's encoded data to out0 and returns the package fingerprint.

func (*PkgEncoder) NewEncoder

func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder

NewEncoder returns an Encoder for a new element within the given section, and encodes the given SyncMarker as the start of the element bitstream.

func (*PkgEncoder) NewEncoderRaw

func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder

NewEncoderRaw returns an Encoder for a new element within the given section.

Most callers should use NewEncoder instead.

func (*PkgEncoder) StringIdx

func (pw *PkgEncoder) StringIdx(s string) Index

StringIdx adds a string value to the strings section, if not already present, and returns its index.

func (*PkgEncoder) SyncMarkers

func (pw *PkgEncoder) SyncMarkers() bool

SyncMarkers reports whether pw uses sync markers.

type RelocEnt

type RelocEnt struct {
	Kind RelocKind
	Idx  Index
}

A relocEnt (relocation entry) is an entry in an element's local reference table.

TODO(mdempsky): Rename this too.

type RelocKind

type RelocKind int32

A RelocKind indicates a particular section within a unified IR export.

const (
	RelocString RelocKind = iota
	RelocMeta
	RelocPosBase
	RelocPkg
	RelocName
	RelocType
	RelocObj
	RelocObjExt
	RelocObjDict
	RelocBody
)

type SyncMarker

type SyncMarker int

SyncMarker is an enum type that represents markers that may be written to export data to ensure the reader and writer stay synchronized.

const (

	// Low-level coding markers.
	SyncEOF SyncMarker
	SyncBool
	SyncInt64
	SyncUint64
	SyncString
	SyncValue
	SyncVal
	SyncRelocs
	SyncReloc
	SyncUseReloc

	// Higher-level object and type markers.
	SyncPublic
	SyncPos
	SyncPosBase
	SyncObject
	SyncObject1
	SyncPkg
	SyncPkgDef
	SyncMethod
	SyncType
	SyncTypeIdx
	SyncTypeParamNames
	SyncSignature
	SyncParams
	SyncParam
	SyncCodeObj
	SyncSym
	SyncLocalIdent
	SyncSelector

	// Private markers (only known to cmd/compile).
	SyncPrivate

	SyncFuncExt
	SyncVarExt
	SyncTypeExt
	SyncPragma

	SyncExprList
	SyncExprs
	SyncExpr
	SyncExprType
	SyncAssign
	SyncOp
	SyncFuncLit
	SyncCompLit

	SyncDecl
	SyncFuncBody
	SyncOpenScope
	SyncCloseScope
	SyncCloseAnotherScope
	SyncDeclNames
	SyncDeclName

	SyncStmts
	SyncBlockStmt
	SyncIfStmt
	SyncForStmt
	SyncSwitchStmt
	SyncRangeStmt
	SyncCaseClause
	SyncCommClause
	SyncSelectStmt
	SyncDecls
	SyncLabeledStmt
	SyncUseObjLocal
	SyncAddLocal
	SyncLinkname
	SyncStmt1
	SyncStmtsEnd
	SyncLabel
	SyncOptLabel

	SyncMultiExpr
	SyncRType
	SyncConvRTTI
)

func (SyncMarker) String

func (i SyncMarker) String() string