func (t anyType) Underlying() types2.Type { return t }
func (t anyType) String() string { return "any" }
+// See cmd/compile/internal/noder.derivedInfo.
type derivedInfo struct {
idx int
needed bool
}
+// See cmd/compile/internal/noder.typeInfo.
type typeInfo struct {
idx int
derived bool
itabs []itabInfo
}
+// A derivedInfo represents a reference to an encoded generic Go type.
type derivedInfo struct {
idx int
needed bool
}
+// A typeInfo represents a reference to an encoded Go type.
+//
+// If derived is true, then the typeInfo represents a generic Go type
+// that contains type parameters. In this case, idx is an index into
+// the readerDict.derived{,Types} arrays.
+//
+// Otherwise, the typeInfo represents a non-generic Go type, and idx
+// is an index into the reader.typs array instead.
type typeInfo struct {
idx int
derived bool
func (t anyType) Underlying() types.Type { return t }
func (t anyType) String() string { return "any" }
+// See cmd/compile/internal/noder.derivedInfo.
type derivedInfo struct {
idx int
needed bool
}
+// See cmd/compile/internal/noder.typeInfo.
type typeInfo struct {
idx int
derived bool
"strings"
)
+// A PkgDecoder provides methods for decoding a package's Unified IR
+// export data.
type PkgDecoder struct {
+ // pkgPath is the package path for the package to be decoded.
+ //
+ // TODO(mdempsky): Remove; unneeded since CL 391014.
pkgPath string
+ // elemData is the full data payload of the encoded package.
+ // Elements are densely and contiguously packed together.
+ //
+ // The last 8 bytes of elemData are the package fingerprint.
+ elemData string
+
+ // elemEnds stores the byte-offset end positions of element
+ // bitstreams within elemData.
+ //
+ // For example, element I's bitstream data starts at elemEnds[I-1]
+ // (or 0, if I==0) and ends at elemEnds[I].
+ //
+ // Note: elemEnds is indexed by absolute indices, not
+ // section-relative indices.
+ elemEnds []uint32
+
+ // elemEndsEnds stores the index-offset end positions of relocation
+ // sections within elemEnds.
+ //
+ // For example, section K's end positions start at elemEndsEnds[K-1]
+ // (or 0, if K==0) and end at elemEndsEnds[K].
elemEndsEnds [numRelocs]uint32
- elemEnds []uint32
- elemData string // last 8 bytes are fingerprint
}
func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath }
return pr
}
+// NumElems returns the number of elements in section k.
func (pr *PkgDecoder) NumElems(k RelocKind) int {
count := int(pr.elemEndsEnds[k])
if k > 0 {
return count
}
+// TotalElems returns the total number of elements across all sections.
func (pr *PkgDecoder) TotalElems() int {
return len(pr.elemEnds)
}
+// Fingerprint returns the package fingerprint.
func (pr *PkgDecoder) Fingerprint() [8]byte {
var fp [8]byte
copy(fp[:], pr.elemData[len(pr.elemData)-8:])
return fp
}
+// AbsIdx returns the absolute index for the given (section, index)
+// pair.
func (pr *PkgDecoder) AbsIdx(k RelocKind, idx int) int {
absIdx := idx
if k > 0 {
return absIdx
}
+// DataIdx returns the raw element bitstream for the given (section,
+// index) pair.
func (pr *PkgDecoder) DataIdx(k RelocKind, idx int) string {
absIdx := pr.AbsIdx(k, idx)
return r
}
+// A Decoder provides methods for decoding an individual element's
+// bitstream data.
type Decoder struct {
common *PkgDecoder
--- /dev/null
+// Copyright 2022 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.
+
+// 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).
+package pkgbits
"runtime"
)
+// A PkgEncoder provides methods for encoding a package's Unified IR
+// export data.
type PkgEncoder struct {
+ // elems holds the bitstream for previously encoded elements.
elems [numRelocs][]string
+ // stringsIdx maps previously encoded strings to their index within
+ // the RelocString section, to allow deduplication.
stringsIdx map[string]int
syncFrames int
}
}
+// DumpTo writes the package's encoded data to out0 and returns the
+// package fingerprint.
func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) {
h := md5.New()
out := io.MultiWriter(out0, h)
writeUint32(0) // version
+ // Write elemEndsEnds.
var sum uint32
for _, elems := range &pw.elems {
sum += uint32(len(elems))
writeUint32(sum)
}
+ // Write elemEnds.
sum = 0
for _, elems := range &pw.elems {
for _, elem := range elems {
}
}
+ // Write elemData.
for _, elems := range &pw.elems {
for _, elem := range elems {
_, err := io.WriteString(out, elem)
}
}
+ // Write fingerprint.
copy(fingerprint[:], h.Sum(nil))
_, err := out0.Write(fingerprint[:])
assert(err == nil)
}
}
-// Encoders
-
+// An Encoder provides methods for encoding an individual element's
+// bitstream data.
type Encoder struct {
p *PkgEncoder
Idx int
}
+// Flush finalizes the element's bitstream and returns its Index.
func (w *Encoder) Flush() int {
var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved
// A RelocKind indicates a particular section within a unified IR export.
type RelocKind int
-// A relocEnt (relocation entry) is an entry in an atom's local
+// A relocEnt (relocation entry) is an entry in an element's local
// reference table.
//
// TODO(mdempsky): Rename this too.