aboutsummaryrefslogtreecommitdiff
path: root/src/internal/pkgbits/encoder.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2022-05-20 12:48:17 -0700
committerMatthew Dempsky <mdempsky@google.com>2022-05-25 16:15:47 +0000
commit8841699160946263859ea492779bea4aa909f1de (patch)
tree778e072293c551ce771ccb478b6b4159de6d6272 /src/internal/pkgbits/encoder.go
parent7791e934c882fd103357448aee0fd577b20013ce (diff)
downloadgo-8841699160946263859ea492779bea4aa909f1de.tar.xz
internal/pkgbits: finish documentation
This CL adds documentation for all exported pkgbits APIs, and removes its UNREVIEWED comments. Updates #48194. Change-Id: Ifff548cd9f31a5c5cc5f400a6dae5c98c46ec4ca Reviewed-on: https://go-review.googlesource.com/c/go/+/407614 Reviewed-by: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/internal/pkgbits/encoder.go')
-rw-r--r--src/internal/pkgbits/encoder.go77
1 files changed, 64 insertions, 13 deletions
diff --git a/src/internal/pkgbits/encoder.go b/src/internal/pkgbits/encoder.go
index f274e2a676..9fddb58237 100644
--- a/src/internal/pkgbits/encoder.go
+++ b/src/internal/pkgbits/encoder.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
// Copyright 2021 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.
@@ -23,12 +21,19 @@ type PkgEncoder struct {
elems [numRelocs][]string
// stringsIdx maps previously encoded strings to their index within
- // the RelocString section, to allow deduplication.
+ // the RelocString section, to allow deduplication. That is,
+ // elems[RelocString][stringsIdx[s]] == s (if present).
stringsIdx map[string]int
syncFrames int
}
+// 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.
func NewPkgEncoder(syncFrames int) PkgEncoder {
return PkgEncoder{
stringsIdx: make(map[string]int),
@@ -80,6 +85,8 @@ func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) {
return
}
+// StringIdx adds a string value to the strings section, if not
+// already present, and returns its index.
func (pw *PkgEncoder) StringIdx(s string) int {
if idx, ok := pw.stringsIdx[s]; ok {
assert(pw.elems[RelocString][idx] == s)
@@ -92,12 +99,19 @@ func (pw *PkgEncoder) StringIdx(s string) int {
return idx
}
+// 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 (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder {
e := pw.NewEncoderRaw(k)
e.Sync(marker)
return e
}
+// NewEncoderRaw returns an Encoder for a new element within the given
+// section.
+//
+// Most callers should use NewEncoder instead.
func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder {
idx := len(pw.elems[k])
pw.elems[k] = append(pw.elems[k], "") // placeholder
@@ -115,12 +129,12 @@ type Encoder struct {
p *PkgEncoder
Relocs []RelocEnt
- Data bytes.Buffer
+ Data bytes.Buffer // accumulated element bitstream data
encodingRelocHeader bool
k RelocKind
- Idx int
+ Idx int // index within relocation section
}
// Flush finalizes the element's bitstream and returns its Index.
@@ -140,10 +154,10 @@ func (w *Encoder) Flush() int {
w.encodingRelocHeader = true
w.Sync(SyncRelocs)
w.Len(len(w.Relocs))
- for _, rent := range w.Relocs {
+ for _, rEnt := range w.Relocs {
w.Sync(SyncReloc)
- w.Len(int(rent.Kind))
- w.Len(rent.Idx)
+ w.Len(int(rEnt.Kind))
+ w.Len(rEnt.Idx)
}
io.Copy(&sb, &w.Data)
@@ -177,9 +191,9 @@ func (w *Encoder) rawVarint(x int64) {
}
func (w *Encoder) rawReloc(r RelocKind, idx int) int {
- // TODO(mdempsky): Use map for lookup.
- for i, rent := range w.Relocs {
- if rent.Kind == r && rent.Idx == idx {
+ // TODO(mdempsky): Use map for lookup; this takes quadratic time.
+ for i, rEnt := range w.Relocs {
+ if rEnt.Kind == r && rEnt.Idx == idx {
return i
}
}
@@ -214,6 +228,19 @@ func (w *Encoder) Sync(m SyncMarker) {
}
}
+// 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 (w *Encoder) Bool(b bool) bool {
w.Sync(SyncBool)
var x byte
@@ -225,35 +252,57 @@ func (w *Encoder) Bool(b bool) bool {
return b
}
+// Int64 encodes and writes an int64 value into the element bitstream.
func (w *Encoder) Int64(x int64) {
w.Sync(SyncInt64)
w.rawVarint(x)
}
+// Uint64 encodes and writes a uint64 value into the element bitstream.
func (w *Encoder) Uint64(x uint64) {
w.Sync(SyncUint64)
w.rawUvarint(x)
}
-func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) }
-func (w *Encoder) Int(x int) { w.Int64(int64(x)) }
+// Len encodes and writes a non-negative int value into the element bitstream.
+func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) }
+
+// Int encodes and writes an int value into the element bitstream.
+func (w *Encoder) Int(x int) { w.Int64(int64(x)) }
+
+// Len encodes and writes a uint value into the element bitstream.
func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) }
+// 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 (w *Encoder) Reloc(r RelocKind, idx int) {
w.Sync(SyncUseReloc)
w.Len(w.rawReloc(r, idx))
}
+// Code encodes and writes a Code value into the element bitstream.
func (w *Encoder) Code(c Code) {
w.Sync(c.Marker())
w.Len(c.Value())
}
+// 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 (w *Encoder) String(s string) {
w.Sync(SyncString)
w.Reloc(RelocString, w.p.StringIdx(s))
}
+// Strings encodes and writes a variable-length slice of strings into
+// the element bitstream.
func (w *Encoder) Strings(ss []string) {
w.Len(len(ss))
for _, s := range ss {
@@ -261,6 +310,8 @@ func (w *Encoder) Strings(ss []string) {
}
}
+// Value encodes and writes a constant.Value into the element
+// bitstream.
func (w *Encoder) Value(val constant.Value) {
w.Sync(SyncValue)
if w.Bool(val.Kind() == constant.Complex) {