| // 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. |
| |
| /* |
| The Unified IR (UIR) format for primitive types is implicitly defined by the |
| package pkgbits. |
| |
| The most basic primitives are laid out as below. |
| |
| Bool = [ Sync ] byte . |
| Int64 = [ Sync ] zvarint . |
| Uint64 = [ Sync ] uvarint . |
| |
| zvarint = (* a zig-zag encoded signed variable-width integer *) . |
| uvarint = (* an unsigned variable-width integer *) . |
| |
| # References |
| References specify the location of a value. While the representation here is |
| fixed, the interpretation of a reference is left to other packages. |
| |
| Ref[T] = [ Sync ] Uint64 . // points to a value of type T |
| |
| # Markers |
| Markers provide a mechanism for asserting that encoders and decoders |
| are synchronized. If an unexpected marker is found, decoding panics. |
| |
| Sync = uvarint // indicates what should follow if synchronized |
| WriterPCs |
| . |
| |
| A marker also records a configurable number of program counters (PCs) during |
| encoding to assist with debugging. |
| |
| WriterPCs = uvarint // the number of PCs that follow |
| { uvarint } // the PCs |
| . |
| |
| Note that markers are always defined using terminals — they never contain a |
| marker themselves. |
| |
| # Strings |
| A string is a series of bytes. |
| |
| // TODO(markfreeman): Does this need a marker? |
| String = { byte } . |
| |
| Strings are typically not encoded directly. Rather, they are deduplicated |
| during encoding and referenced where needed; this process is called interning. |
| |
| StringRef = [ Sync ] Ref[String] . |
| |
| Note that StringRef is *not* equivalent to Ref[String] due to the extra marker. |
| |
| # Slices |
| Slices are a convenience for encoding a series of values of the same type. |
| |
| // TODO(markfreeman): Does this need a marker? |
| Slice[T] = Uint64 // the number of values in the slice |
| { T } // the values |
| . |
| |
| # Constants |
| Constants appear as defined via the package constant. |
| |
| Constant = [ Sync ] |
| Bool // whether the constant is a complex number |
| Scalar // the real part |
| [ Scalar ] // if complex, the imaginary part |
| . |
| |
| A scalar represents a value using one of several potential formats. The exact |
| format and interpretation is distinguished by a code preceding the value. |
| |
| Scalar = [ Sync ] |
| Uint64 // the code indicating the type of Val |
| Val |
| . |
| |
| Val = Bool |
| | Int64 |
| | StringRef |
| | Term // big integer |
| | Term Term // big ratio, numerator / denominator |
| | BigBytes // big float, precision 512 |
| . |
| |
| Term = BigBytes |
| Bool // whether the term is negative |
| . |
| |
| BigBytes = StringRef . // bytes of a big value |
| */ |
| |
| // Package pkgbits implements low-level coding abstractions for Unified IR's |
| // (UIR) binary export data format. |
| // |
| // At a low-level, the exported objects of a package are encoded as a byte |
| // array. This array contains byte representations of primitive, potentially |
| // variable-length values, such as integers, booleans, strings, and constants. |
| // |
| // Additionally, the array may contain values which denote indices in the byte |
| // array itself. These are termed "relocations" and allow for references. |
| // |
| // The details of mapping high-level Go constructs to primitives are left to |
| // other packages. |
| package pkgbits |