1 // Copyright 2022 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 /*
6 The Unified IR (UIR) format for primitive types is implicitly defined by the
7 package pkgbits.
8 9 The most basic primitives are laid out as below.
10 11 Bool = [ Sync ] byte .
12 Int64 = [ Sync ] zvarint .
13 Uint64 = [ Sync ] uvarint .
14 15 zvarint = (* a zig-zag encoded signed variable-width integer *) .
16 uvarint = (* an unsigned variable-width integer *) .
17 18 # References
19 References specify the location of a value. While the representation here is
20 fixed, the interpretation of a reference is left to other packages.
21 22 Ref[T] = [ Sync ] Uint64 . // points to a value of type T
23 24 # Markers
25 Markers provide a mechanism for asserting that encoders and decoders
26 are synchronized. If an unexpected marker is found, decoding panics.
27 28 Sync = uvarint // indicates what should follow if synchronized
29 WriterPCs
30 .
31 32 A marker also records a configurable number of program counters (PCs) during
33 encoding to assist with debugging.
34 35 WriterPCs = uvarint // the number of PCs that follow
36 { uvarint } // the PCs
37 .
38 39 Note that markers are always defined using terminals — they never contain a
40 marker themselves.
41 42 # Strings
43 A string is a series of bytes.
44 45 // TODO(markfreeman): Does this need a marker?
46 String = { byte } .
47 48 Strings are typically not encoded directly. Rather, they are deduplicated
49 during encoding and referenced where needed; this process is called interning.
50 51 StringRef = [ Sync ] Ref[String] .
52 53 Note that StringRef is *not* equivalent to Ref[String] due to the extra marker.
54 55 # Slices
56 Slices are a convenience for encoding a series of values of the same type.
57 58 // TODO(markfreeman): Does this need a marker?
59 Slice[T] = Uint64 // the number of values in the slice
60 { T } // the values
61 .
62 63 # Constants
64 Constants appear as defined via the package constant.
65 66 Constant = [ Sync ]
67 Bool // whether the constant is a complex number
68 Scalar // the real part
69 [ Scalar ] // if complex, the imaginary part
70 .
71 72 A scalar represents a value using one of several potential formats. The exact
73 format and interpretation is distinguished by a code preceding the value.
74 75 Scalar = [ Sync ]
76 Uint64 // the code indicating the type of Val
77 Val
78 .
79 80 Val = Bool
81 | Int64
82 | StringRef
83 | Term // big integer
84 | Term Term // big ratio, numerator / denominator
85 | BigBytes // big float, precision 512
86 .
87 88 Term = BigBytes
89 Bool // whether the term is negative
90 .
91 92 BigBytes = StringRef . // bytes of a big value
93 */
94 95 // Package pkgbits implements low-level coding abstractions for Unified IR's
96 // (UIR) binary export data format.
97 //
98 // At a low-level, the exported objects of a package are encoded as a byte
99 // array. This array contains byte representations of primitive, potentially
100 // variable-length values, such as integers, booleans, strings, and constants.
101 //
102 // Additionally, the array may contain values which denote indices in the byte
103 // array itself. These are termed "relocations" and allow for references.
104 //
105 // The details of mapping high-level Go constructs to primitives are left to
106 // other packages.
107 package pkgbits
108