From 017313f9d82c4b7b91f06c24d4210eae83a65039 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Fri, 5 Sep 2025 13:58:49 +0000 Subject: [PATCH 01/18] Convert the TVM latex to markdown --- ton/tvm.mdx | 4763 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4763 insertions(+) create mode 100644 ton/tvm.mdx diff --git a/ton/tvm.mdx b/ton/tvm.mdx new file mode 100644 index 00000000..8aaf890a --- /dev/null +++ b/ton/tvm.mdx @@ -0,0 +1,4763 @@ +--- +title: "TVM" +--- + +## Introduction +The primary purpose of the Telegram Open Network Virtual Machine (TON VM or TVM) is to execute smart-contract code in the TON Blockchain. TVM must support all operations required to parse incoming messages and persistent data, and to create new messages and modify persistent data. + +Additionally, TVM must meet the following requirements: +* It must provide for possible future extensions and improvements while retaining backward compatibility and interoperability, because the code of a smart contract, once committed into the blockchain, must continue working in a predictable manner regardless of any future modifications to the VM. +* It must strive to attain high "(virtual) machine code" density, so that the code of a typical smart contract occupies as little persistent blockchain storage as possible. +* It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used.[^1] + +The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM,[^2] the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. + +TVM is not intended to be implemented in hardware (e.g., in a specialized microprocessor chip); rather, it should be implemented in software running on conventional hardware. This consideration lets us incorporate some high-level concepts and operations in TVM that would require convoluted microcode in a hardware implementation but pose no significant problems for a software implementation. Such operations are useful for achieving high code density and minimizing the byte (or storage cell) profile of smart-contract code when deployed in the TON Blockchain. + +--- + +## 1.0 Notation for bitstrings + +The following notation is used for bit strings (or bitstrings)—i.e., finite strings consisting of binary digits (bits), 0 and 1—throughout this document. + +### 1.0.1 Hexadecimal notation for bitstrings + +When the length of a bitstring is a multiple of four, we subdivide it into groups of four bits and represent each group by one of sixteen hexadecimal digits 0–9, A–F in the usual manner: + +* 0₁₆ ↔ 0000 +* 1₁₆ ↔ 0001 +* … +* F₁₆ ↔ 1111 + +The resulting hexadecimal string is our equivalent representation for the original binary string. + +### 1.0.2 Bitstrings of lengths not divisible by four + +If the length of a binary string is not divisible by four, we augment it by one `1` and several (maybe zero) `0`s at the end, so that its length becomes divisible by four, and then transform it into a string of hexadecimal digits as described above. To indicate that such a transformation has taken place, a special **completion tag** `_` is added to the end of the hexadecimal string. + +The reverse transformation (applied if the completion tag is present) consists in first replacing each hexadecimal digit by four corresponding bits, and then removing all trailing zeroes (if any) and the last `1` immediately preceding them (if the resulting bitstring is non-empty at this point). + +Notice that there are several admissible hexadecimal representations for the same bitstring. Among them, the shortest one is **canonical**. It can be deterministically obtained by the above procedure. + +For example: + +* `8A` corresponds to binary string `10001010`. +* `8A_` and `8A0_` both correspond to `100010`. +* An empty bitstring may be represented by either `''`, `8_`, `0_`, `_`, or `00_`. + +### 1.0.3 Emphasizing that a string is a hexadecimal representation of a bitstring + +Sometimes we need to emphasize that a string of hexadecimal digits (with or without a `_` at the end) is the hexadecimal representation of a bitstring. In such cases, we either prepend `x` to the resulting string (e.g., `x8A`), or prepend `x{` and append `}` (e.g., `x{2D9_}`, which is `00101101100`). + +This should not be confused with hexadecimal numbers, usually prepended by `0x` (e.g., `0x2D9` or `0x2d9`, which is the integer 729). + +### 1.0.4 Serializing a bitstring into a sequence of octets + +When a bitstring needs to be represented as a sequence of 8-bit bytes (octets), which take values in integers 0…255, this is achieved essentially in the same fashion as above: we split the bitstring into groups of eight bits and interpret each group as the binary representation of an integer 0…255. + +If the length of the bitstring is not a multiple of eight, the bitstring is augmented by a binary `1` and up to seven binary `0`s before being split into groups. The fact that such a completion has been applied is usually reflected by a **completion tag** bit. + +For instance, `00101101100` corresponds to the sequence of two octets: + +* `(0x2d, 0x90)` in hexadecimal +* `(45, 144)` in decimal + +…along with a completion tag bit equal to `1` (meaning that the completion has been applied), which must be stored separately. + +In some cases, it is more convenient to assume the completion is enabled by default rather than store an additional completion tag bit separately. Under such conventions, `8n`-bit strings are represented by `n + 1` octets, with the last octet always equal to `0x80 = 128`. + +Perfect — I’ll keep the **exact wording** from your excerpt, only formatting it in Markdown for readability (headings, lists, code style for inline values). Numbering stays **exactly as in the source**. + +--- + +# 1.1 TVM is a stack machine + +First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective.³ + +Most operations and user-defined functions take their arguments from the top of the stack, and replace them with their result. For example, the integer addition primitive (built-in operation) `ADD` does not take any arguments describing which registers or immediate values should be added together and where the result should be stored. Instead, the two top values are taken from the stack, they are added together, and their sum is pushed into the stack in their place. + +³ A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. + +--- + +## 1.1.1 TVM values + +The entities that can be stored in the TVM stack will be called **TVM values**, or simply **values** for brevity. They belong to one of several predefined value types. Each value belongs to exactly one value type. The values are always kept on the stack along with tags uniquely determining their types, and all built-in TVM operations (or primitives) only accept values of predefined types. + +For example, the integer addition primitive `ADD` accepts only two integer values, and returns one integer value as a result. One cannot supply `ADD` with two strings instead of two integers expecting it to concatenate these strings or to implicitly transform the strings into their decimal integer values; any attempt to do so will result in a run-time type-checking exception. + +--- + +## 1.1.2 Static typing, dynamic typing, and run-time type checking + +In some respects TVM performs a kind of dynamic typing using run-time type checking. However, this does not make the TVM code a “dynamically typed language” like PHP or Javascript, because all primitives accept values and return results of predefined (value) types, each value belongs to strictly one type, and values are never implicitly converted from one type to another. + +If, on the other hand, one compares the TVM code to the conventional microprocessor machine code, one sees that the TVM mechanism of value tagging prevents, for example, using the address of a string as a number—or, potentially even more disastrously, using a number as the address of a string—thus eliminating the possibility of all sorts of bugs and security vulnerabilities related to invalid memory accesses, usually leading to memory corruption and segmentation faults. + +This property is highly desirable for a VM used to execute smart contracts in a blockchain. In this respect, TVM’s insistence on tagging all values with their appropriate types, instead of reinterpreting the bit sequence in a register depending on the needs of the operation it is used in, is just an additional run-time type-safety mechanism. + +An alternative would be to somehow analyze the smart-contract code for type correctness and type safety before allowing its execution in the VM, or even before allowing it to be uploaded into the blockchain as the code of a smart contract. Such a static analysis of code for a Turing-complete machine appears to be a time-consuming and non-trivial problem (likely to be equivalent to the stopping problem for Turing machines), something we would rather avoid in a blockchain smart-contract context. + +One should bear in mind that one always can implement compilers from statically typed high-level smart-contract languages into the TVM code (and we do expect that most smart contracts for TON will be written in such languages), just as one can compile statically typed languages into conventional machine code (e.g., x86 architecture). If the compiler works correctly, the resulting machine code will never generate any run-time type-checking exceptions. + +All type tags attached to values processed by TVM will always have expected values and may be safely ignored during the analysis of the resulting TVM code, apart from the fact that the run-time generation and verification of these type tags by TVM will slightly slow down the execution of the TVM code. + +--- + +## 1.1.3 Preliminary list of value types + +A preliminary list of value types supported by TVM is as follows: + +* **Integer** — Signed 257-bit integers, representing integer numbers in the range −2²⁵⁶ … 2²⁵⁶−1, as well as a special “not-a-number” value `NaN`. +* **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. \[1, 2.5.14]). +* **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. +* **Null** — A type with exactly one value ⊥, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. +* **Slice** — A TVM cell slice, or slice for short, is a contiguous “sub-cell” of an existing cell, containing some of its bits of data and some of its references. Essentially, a slice is a read-only view for a subcell of a cell. Slices are used for unpacking data previously stored (or serialized) in a cell or a tree of cells. +* **Builder** — A TVM cell builder, or builder for short, is an “incomplete” cell that supports fast operations of appending bitstrings and cell references at its end. Builders are used for packing (or serializing) data from the top of the stack into new cells (e.g., before transferring them to persistent storage). +* **Continuation** — A special value containing TVM code and execution context that can be invoked (executed) later. As such, it generalizes function addresses (i.e., function pointers and references), subroutine return addresses, instruction pointer addresses, exception handler addresses, closures, partial applications, anonymous functions, and so on. + +This list of value types is incomplete and may be extended in future revisions of TVM without breaking the old TVM code, due mostly to the fact that all originally defined primitives accept only values of types known to them and will fail (generate a type-checking exception) if invoked on values of new types. + +Furthermore, existing value types themselves can also be extended in the future: for example, 257-bit `Integer` might become 513-bit `LongInteger`, with originally defined arithmetic primitives failing if either of the arguments or the result does not fit into the original subtype `Integer`. + +Backward compatibility with respect to the introduction of new value types and extension of existing value types will be discussed in more detail later (cf. 5.1.4). + +--- + +## 1.2 Categories of TVM instructions + +TVM instructions, also called **primitives** and sometimes **(built-in) operations**, are the smallest operations atomically performed by TVM that can be present in the TVM code. They fall into several categories, depending on the types of values (cf. 1.1.3) they work on. The most important of these categories are: + +* **Stack (manipulation) primitives** — Rearrange data in the TVM stack, so that the other primitives and user-defined functions can later be called with correct arguments. Unlike most other primitives, they are polymorphic, i.e., work with values of arbitrary types. +* **Tuple (manipulation) primitives** — Construct, modify, and decompose Tuples. Similarly to the stack primitives, they are polymorphic. +* **Constant or literal primitives** — Push into the stack some “constant” or “literal” values embedded into the TVM code itself, thus providing arguments to the other primitives. They are somewhat similar to stack primitives, but are less generic because they work with values of specific types. +* **Arithmetic primitives** — Perform the usual integer arithmetic operations on values of type Integer. +* **Cell (manipulation) primitives** — Create new cells and store data in them (cell creation primitives) or read data from previously created cells (cell parsing primitives). Because all memory and persistent storage of TVM consists of cells, these cell manipulation primitives actually correspond to “memory access instructions” of other architectures. Cell creation primitives usually work with values of type Builder, while cell parsing primitives work with Slices. +* **Continuation and control flow primitives** — Create and modify Continuations, as well as execute existing Continuations in different ways, including conditional and repeated execution. +* **Custom or application-specific primitives** — Efficiently perform specific high-level actions required by the application (in our case, the TON Blockchain), such as computing hash functions, performing elliptic curve cryptography, sending new blockchain messages, creating new smart contracts, and so on. These primitives correspond to standard library functions rather than microprocessor instructions. + +--- + +## 1.3 Control registers + +While TVM is a stack machine, some rarely changed values needed in almost all functions are better passed in certain special registers, and not near the top of the stack. Otherwise, a prohibitive number of stack reordering operations would be required to manage all these values. + +To this end, the TVM model includes, apart from the stack, up to **16 special control registers**, denoted by `c0` to `c15`, or `c(0)` to `c(15)`. The original version of TVM makes use of only some of these registers; the rest may be supported later. + +--- + +### 1.3.1 Values kept in control registers + +The values kept in control registers are of the same types as those kept on the stack. However, some control registers accept only values of specific types, and any attempt to load a value of a different type will lead to an exception. + +--- + +### 1.3.2 List of control registers + +The original version of TVM defines and uses the following control registers: + +* **c0** — Contains the return continuation (similar to the subroutine return address in conventional designs). This value must be a Continuation. +* **c1** — Contains the alternative (return) continuation; this value must be a Continuation. It is used in some (experimental) control flow primitives, allowing TVM to define and call “subroutines with two exit points”. +* **c2** — Contains the exception handler. This value is a Continuation, invoked whenever an exception is triggered. +* **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in 4.6, this value is also a Continuation, not a Cell as one might expect. +* **c4** — Contains the root of persistent data, or simply the data. This value is a Cell. When the code of a smart contract is invoked, `c4` points to the root cell of its persistent data kept in the blockchain state. If the smart contract needs to modify this data, it changes `c4` before returning. +* **c5** — Contains the output actions. It is also a Cell initialized by a reference to an empty cell, but its final value is considered one of the smart contract outputs. For instance, the `SENDMSG` primitive, specific for the TON Blockchain, simply inserts the message into a list stored in the output actions. +* **c7** — Contains the root of temporary data. It is a Tuple, initialized by a reference to an empty Tuple before invoking the smart contract and discarded after its termination.⁴ + +⁴ In the TON Blockchain context, `c7` is initialized with a singleton Tuple, the only component of which is a Tuple containing blockchain-specific data. The smart contract is free to modify `c7` to store its temporary data provided the first component of this Tuple remains intact. + +More control registers may be defined in the future for specific TON Blockchain or high-level programming language purposes, if necessary. + +--- + +## 1.4 Total state of TVM (SCCCG) + +The total state of TVM consists of the following components: + +* **Stack** (cf. 1.1) — Contains zero or more values (cf. 1.1.1), each belonging to one of value types listed in 1.1.3. +* **Control registers `c0–c15`** — Contain some specific values as described in 1.3.2. (Only seven control registers are used in the current version.) +* **Current continuation `cc`** — Contains the current continuation (i.e., the code that would be normally executed after the current primitive is completed). This component is similar to the instruction pointer register (`ip`) in other architectures. +* **Current codepage `cp`** — A special signed 16-bit integer value that selects the way the next TVM opcode will be decoded. For example, future versions of TVM might use different codepages to add new opcodes while preserving backward compatibility. +* **Gas limits `gas`** — Contains four signed 64-bit integers: the current gas limit `gl`, the maximal gas limit `gm`, the remaining gas `gr`, and the gas credit `gc`. Always `0 ≤ gl ≤ gm`, `gc ≥ 0`, and `gr ≤ gl + gc`; `gc` is usually initialized by zero, `gr` is initialized by `gl + gc` and gradually decreases as the TVM runs. When `gr` becomes negative or if the final value of `gr` is less than `gc`, an out of gas exception is triggered. + +Notice that there is no “return stack” containing the return addresses of all previously called but unfinished functions. Instead, only control register `c0` is used. The reason for this will be explained later in 4.1.9. + +Also notice that there are no general-purpose registers, because TVM is a stack machine (cf. 1.1). So the above list, which can be summarized as “stack, control, continuation, codepage, and gas” (**SCCCG**), similarly to the classical SECD machine state (“stack, environment, control, dump”), is indeed the total state of TVM. + +Perfect — here’s the next part, keeping the **exact wording** but properly formatted into Markdown. + +--- + +## 1.5 Integer arithmetic + +All arithmetic primitives of TVM operate on several arguments of type **Integer**, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that Integer represents all integer values in the range `−2²⁵⁶ ≤ x < 2²⁵⁶`, and additionally contains a special value **NaN** (“not-a-number”). + +If one of the results does not fit into the supported range of integers—or if one of the arguments is a NaN—then this result or all of the results are replaced by a NaN, and (by default) an integer overflow exception is generated. However, special “quiet” versions of arithmetic operations will simply produce NaNs and keep going. If these NaNs end up being used in a “non-quiet” arithmetic operation, or in a non-arithmetic operation, an integer overflow exception will occur. + +--- + +### 1.5.1 Absence of automatic conversion of integers + +Notice that TVM Integers are “mathematical” integers, and not 257-bit strings interpreted differently depending on the primitive used, as is common for other machine code designs. For example, TVM has only one multiplication primitive `MUL`, rather than two (`MUL` for unsigned multiplication and `IMUL` for signed multiplication) as occurs, for example, in the popular x86 architecture. + +--- + +### 1.5.2 Automatic overflow checks + +Notice that all TVM arithmetic primitives perform overflow checks of the results. If a result does not fit into the Integer type, it is replaced by a NaN, and (usually) an exception occurs. In particular, the result is not automatically reduced modulo `2²⁵⁶` or `2²⁵⁷`, as is common for most hardware machine code architectures. + +--- + +### 1.5.3 Custom overflow checks + +In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. + +* `FITS n` checks whether the value on the top of the stack is an integer `x` in the range `−2ⁿ⁻¹ ≤ x < 2ⁿ⁻¹`. +* `UFITS n` checks whether the value is in the range `0 ≤ x < 2ⁿ`. + +If the value does not fit, it is replaced with a NaN and (optionally) an integer overflow exception is generated. + +This greatly simplifies the implementation of arbitrary `n`-bit integer types, signed or unsigned: the programmer or the compiler must insert appropriate `FITS` or `UFITS` primitives either after each arithmetic operation (which is more reasonable, but requires more checks) or before storing computed values and returning them from functions. This is important for smart contracts, where unexpected integer overflows happen to be among the most common source of bugs. + +--- + +### 1.5.4 Reduction modulo 2ⁿ + +TVM also has a primitive `MODPOW2 n`, which reduces the integer at the top of the stack modulo `2ⁿ`, with the result ranging from `0` to `2ⁿ − 1`. + +--- + +### 1.5.5 Integer is 257-bit, not 256-bit + +One can understand now why TVM’s Integer is (signed) 257-bit, not 256-bit. The reason is that it is the smallest integer type containing both signed 256-bit integers and unsigned 256-bit integers, which does not require automatic reinterpreting of the same 256-bit string depending on the operation used (cf. 1.5.1). + +--- + +### 1.5.6 Division and rounding + +The most important division primitives are `DIV`, `MOD`, and `DIVMOD`. All of them take two numbers from the stack, `x` and `y` (`y` is taken from the top of the stack, and `x` is originally under it), compute the quotient `q` and remainder `r` of the division of `x` by `y` (i.e., two integers such that `x = yq + r` and `|r| < |y|`), and return either `q`, `r`, or both of them. + +* If `y` is zero, then all of the expected results are replaced by NaNs, and (usually) an integer overflow exception is generated. +* By default, these primitives round to `−∞`, meaning that `q = ⌊x / y⌋`, and `r` has the same sign as `y`. (Most conventional implementations of division use “rounding to zero” instead, meaning that `r` has the same sign as `x`.) + +Apart from this **floor rounding**, two other rounding modes are available: + +* **Ceiling rounding**: `q = ⌈x / y⌉`, and `r` and `y` have opposite signs. +* **Nearest rounding**: `q = ⌊x / y + 1/2⌋` and `|r| ≤ |y| / 2`. + +These rounding modes are selected by using other division primitives, with letters `C` and `R` appended to their mnemonics. For example, `DIVMODR` computes both the quotient and the remainder using rounding to the nearest integer. + +--- + +### 1.5.7 Combined multiply-divide, multiply-shift, and shift-divide operations + +To simplify implementation of fixed-point arithmetic, TVM supports combined multiply-divide, multiply-shift, and shift-divide operations with double-length (i.e., 514-bit) intermediate product. + +For example, `MULDIVMODR` takes three integer arguments from the stack, `a`, `b`, and `c`, first computes `ab` using a 514-bit intermediate result, and then divides `ab` by `c` using rounding to the nearest integer. + +* If `c` is zero or if the quotient does not fit into Integer, either two NaNs are returned, or an integer overflow exception is generated, depending on whether a quiet version of the operation has been used. +* Otherwise, both the quotient and the remainder are pushed into the stack. + +--- + +# 2 The stack + +This chapter contains a general discussion and comparison of register and +stack machines, expanded further in Appendix C, and describes the two +main classes of stack manipulation primitives employed by TVM: the basic +and the compound stack manipulation primitives. An informal explanation of +their sufficiency for all stack reordering required for correctly invoking other +primitives and user-defined functions is also provided. Finally, the problem +of efficiently implementing TVM stack manipulation primitives is discussed +in 2.3. + +## 2.1 Stack calling conventions + +A stack machine, such as TVM, uses the stack—and especially the values +near the top of the stack—to pass arguments to called functions and primitives (such as built-in arithmetic operations) and receive their results. This +section discusses the TVM stack calling conventions, introduces some notation, and compares TVM stack calling conventions with those of certain +register machines. + +### 2.1.1. Notation for “stack registers”. + +Recall that a stack machine, as +opposed to a more conventional register machine, lacks general-purpose registers. However, one can treat the values near the top of the stack as a kind +of “stack registers”. +We denote by s0 or s(0) the value at the top of the stack, by s1 or s(1) +the value immediately under it, and so on. The total number of values in the +stack is called its depth. If the depth of the stack is n, then s(0), s(1), . . . , +s(n − 1) are well-defined, while s(n) and all subsequent s(i) with i > n are +not. Any attempt to use s(i) with i ≥ n should produce a stack underflow +exception. +A compiler, or a human programmer in “TVM code”, would use these +“stack registers” to hold all declared variables and intermediate values, similarly to the way general-purpose registers are used on a register machine. + +### 2.1.2. Pushing and popping values. + +When a value x is pushed into a +stack of depth n, it becomes the new s0; at the same time, the old s0 becomes +the new s1, the old s1—the new s2, and so on. The depth of the resulting +stack is n + 1. +Similarly, when a value x is popped from a stack of depth n ≥ 1, it is the +old value of s0 (i.e., the old value at the top of the stack). After this, it is +removed from the stack, and the old s1 becomes the new s0 (the new value +at the top of the stack), the old s2 becomes the new s1, and so on. The +depth of the resulting stack is n − 1. +If originally n = 0, then the stack is empty, and a value cannot be popped +from it. If a primitive attempts to pop a value from an empty stack, a stack +underflow exception occurs. + +### 2.1.3. Notation for hypothetical general-purpose registers. + +In order +to compare stack machines with sufficiently general register machines, we will +denote the general-purpose registers of a register machine by r0, r1, and so +on, or by r(0), r(1), . . . , r(n − 1), where n is the total number of registers. +When we need a specific value of n, we will use n = 16, corresponding to the +very popular x86-64 architecture. + +### 2.1.4. The top-of-stack register s0 vs. the accumulator register r0. + +Some register machine architectures require one of the arguments for most +arithmetic and logical operations to reside in a special register called the +accumulator. In our comparison, we will assume that the accumulator is +the general-purpose register r0; otherwise we could simply renumber the +registers. In this respect, the accumulator is somewhat similar to the top-ofstack “register” s0 of a stack machine, because virtually all operations of a +stack machine both use s0 as one of their arguments and return their result +as s0. + +### 2.1.5. Register calling conventions. + +When compiled for a register machine, high-level language functions usually receive their arguments in certain +registers in a predefined order. If there are too many arguments, these functions take the remainder from the stack (yes, a register machine usually has +a stack, too!). Some register calling conventions pass no arguments in registers at all, however, and only use the stack (for example, the original calling +conventions used in implementations of Pascal and C, although modern implementations of C use some registers as well). +For simplicity, we will assume that up to m ≤ n function arguments are +passed in registers, and that these registers are r0, r1, . . . , r(m − 1), in that +order (if some other registers are used, we can simply renumber them).6 +6Our inclusion of r0 here creates a minor conflict with our assumption that the ac + +### 2.1.6. Order of function arguments. + +If a function or primitive requires +m arguments x1, . . . , xm, they are pushed by the caller into the stack in the +same order, starting from x1. Therefore, when the function or primitive is +invoked, its first argument x1 is in s(m − 1), its second argument x2 is in +s(m − 2), and so on. The last argument xm is in s0 (i.e., at the top of the +stack). It is the called function or primitive’s responsibility to remove its +arguments from the stack. +In this respect the TVM stack calling conventions—obeyed, at least, by +TMV primitives—match those of Pascal and Forth, and are the opposite of +those of C (in which the arguments are pushed into the stack in the reverse +order, and are removed by the caller after it regains control, not the callee). +Of course, an implementation of a high-level language for TVM might +choose some other calling conventions for its functions, different from the +default ones. This might be useful for certain functions—for instance, if the +total number of arguments depends on the value of the first argument, as +happens for “variadic functions” such as scanf and printf. In such cases, +the first one or several arguments are better passed near the top of the stack, +not somewhere at some unknown location deep in the stack. + +### 2.1.7. Arguments to arithmetic primitives on register machines. + +On a stack machine, built-in arithmetic primitives (such as ADD or DIVMOD) +follow the same calling conventions as user-defined functions. In this respect, +user-defined functions (for example, a function computing the square root of +a number) might be considered as “extensions” or “custom upgrades” of the +stack machine. This is one of the clearest advantages of stack machines +(and of stack programming languages such as Forth) compared to register +machines. + +In contrast, arithmetic instructions (built-in operations) on register machines usually get their parameters from general-purpose registers encoded +in the full opcode. A binary operation, such as SUB, thus requires two arguments, r(i) and r(j), with i and j specified by the instruction. A register +r(k) for storing the result also must be specified. Arithmetic operations can +take several possible forms, depending on whether i, j, and k are allowed to +take arbitrary values: + +* Three-address form — Allows the programmer to arbitrarily choose + not only the two source registers r(i) and r(j), but also a separate + destination register r(k). This form is common for most RISC processors, and for the XMM and AVX SIMD instruction sets in the x86-64 + architecture. +* Two-address form — Uses one of the two operand registers (usually + r(i)) to store the result of an operation, so that k = i is never indicated + explicitly. Only i and j are encoded inside the instruction. This is the + most common form of arithmetic operations on register machines, and + is quite popular on microprocessors (including the x86 family). +* One-address form — Always takes one of the arguments from the accumulator r0, and stores the result in r0 as well; then i = k = 0, and + only j needs to be specified by the instruction. This form is used by + some simpler microprocessors (such as Intel 8080). + +Note that this flexibility is available only for built-in operations, but not for user-defined functions. In this respect, register machines are not as easily “upgradable” as stack machines.7 + +Got it ✅ — you want all the inline code-like things (mnemonics, variables, stack notation, etc.) properly wrapped in backticks (`` ` ``) for Markdown. I’ll take the exact text from Chapter 2 (as we’ve been doing), but ensure things like `s0`, `s(i)`, `XCHG`, `PUSH`, `DIV`, etc. are in backticks so they render as code. + +Here’s the **cleaned version with backticks applied** (continuing from §2.1.8 to the end of Chapter 2): + +--- + +### 2.1.8. Return values of functions. + +In stack machines such as TVM, +when a function or primitive needs to return a result value, it simply pushes +it into the stack (from which all arguments to the function have already been +removed). Therefore, the caller will be able to access the result value through +the top-of-stack “register” `s0`. +This is in complete accordance with Forth calling conventions, but differs slightly from Pascal and C calling conventions, where the accumulator +register `r0` is normally used for the return value. + +### 2.1.9. Returning several values. + +Some functions might want to return +several values `y1, . . . , yk`, with `k` not necessarily equal to one. In these cases, +the `k` return values are pushed into the stack in their natural order, starting +from `y1`. +For example, the “divide with remainder” primitive `DIVMOD` needs to return two values, the quotient `q` and the remainder `r`. Therefore, `DIVMOD` +pushes `q` and `r` into the stack, in that order, so that the quotient is available +thereafter at `s1` and the remainder at `s0`. The net effect of `DIVMOD` is to +divide the original value of `s1` by the original value of `s0`, and return the +quotient in `s1` and the remainder in `s0`. In this particular case the depth +of the stack and the values of all other “stack registers” remain unchanged, +because `DIVMOD` takes two arguments and returns two results. In general, the +values of other “stack registers” that lie in the stack below the arguments +passed and the values returned are shifted according to the change of the +depth of the stack. +In principle, some primitives and user-defined functions might return a +variable number of result values. In this respect, the remarks above about +variadic functions (cf. 2.1.6) apply: the total number of result values and +their types should be determined by the values near the top of the stack. +(For example, one might push the return values `y1, . . . , yk`, and then push +their total number `k` as an integer. The caller would then determine the total +number of returned values by inspecting `s0`.) +In this respect TVM, again, faithfully observes Forth calling conventions. + +### 2.1.10. Stack notation. + +When a stack of depth `n` contains values `z1, . . . , +zn`, in that order, with `z1` the deepest element and `zn` the top of the stack, +the contents of the stack are often represented by a list `z1 z2 . . . zn`, in that +order. When a primitive transforms the original stack state `S0` +into a new +state `S00`, this is often written as `S0 – S00`; this is the so-called stack notation. +For example, the action of the division primitive `DIV` can be described by +`S x y – S ⌊x/y⌋`, where `S` is any list of values. This is usually abbreviated as +`x y – ⌊x/y⌋`, tacitly assuming that all other values deeper in the stack remain +intact. +Alternatively, one can describe `DIV` as a primitive that runs on a stack `S0` +of depth `n ≥ 2`, divides `s1` by `s0`, and returns the floor-rounded quotient as +`s0` of the new stack `S00` of depth `n − 1`. The new value of `s(i)` equals the old +value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but +saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `. . . x y` into `. . . ⌊x/y⌋`, is more +concise. +The stack notation is extensively used throughout Appendix A, where all +currently defined TVM primitives are listed. + +### 2.1.11. Explicitly defining the number of arguments to a function. + +Stack machines usually pass the current stack in its entirety to the invoked +primitive or function. That primitive or function accesses only the several +values near the top of the stack that represent its arguments, and pushes the +return values in their place, by convention leaving all deeper values intact. +Then the resulting stack, again in its entirety, is returned to the caller. +Most TVM primitives behave in this way, and we expect most user-defined +functions to be implemented under such conventions. However, TVM provides mechanisms to specify how many arguments must be passed to a called +function (cf. 4.1.10). When these mechanisms are employed, the specified +number of values are moved from the caller’s stack into the (usually initially +empty) stack of the called function, while deeper values remain in the caller’s +stack and are inaccessible to the callee. The caller can also specify how many +return values it expects from the called function. +Such argument-checking mechanisms might be useful, for example, for a +library function that calls user-provided functions passed as arguments to it. + +--- + +## 2.2 Stack manipulation primitives + +A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, +so that they become located near the top of the stack in correct order. This +section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some +examples of code using these primitives can be found in Appendix C. + +### 2.2.1. Basic stack manipulation primitives. + +The most important stack +manipulation primitives used by TVM are the following: + +* Top-of-stack exchange operation: `XCHG s0,s(i)` or `XCHG s(i)` — Exchanges values of `s0` and `s(i)`. When `i = 1`, operation `XCHG s1` is + traditionally denoted by `SWAP`. When `i = 0`, this is a `NOP` (an operation + that does nothing, at least if the stack is non-empty). + +* Arbitrary exchange operation: `XCHG s(i),s(j)` — Exchanges values of + `s(i)` and `s(j)`. Notice that this operation is not strictly necessary, because it can be simulated by three top-of-stack exchanges: + `XCHG s(i); XCHG s(j); XCHG s(i)`. However, it is useful to have arbitrary exchanges + as primitives, because they are required quite often. + +* Push operation: `PUSH s(i)` — Pushes a copy of the (old) value of `s(i)` + into the stack. Traditionally, `PUSH s0` is also denoted by `DUP` (it duplicates the value at the top of the stack), and `PUSH s1` by `OVER`. + +* Pop operation: `POP s(i)` — Removes the top-of-stack value and puts it + into the (new) `s(i − 1)`, or the old `s(i)`. Traditionally, `POP s0` is also + denoted by `DROP` (it simply drops the top-of-stack value), and `POP s1` + by `NIP`. + +Some other “unsystematic” stack manipulation operations might be also +defined (e.g., `ROT`, with stack notation `a b c – b c a`). While such operations are defined in stack languages like Forth (where `DUP`, `DROP`, `OVER`, `NIP` +and `SWAP` are also present), they are not strictly necessary because the basic +stack manipulation primitives listed above suffice to rearrange stack registers +to allow any arithmetic primitives and user-defined functions to be invoked +correctly. + +Perfect 👍 — let’s continue from **§2.2.2** through the end of Chapter 2, with all mnemonics, variables, and stack notation in backticks for Markdown. + +--- + +### 2.2.2. Basic stack manipulation primitives suffice. + +A compiler or a +human TVM-code programmer might use the basic stack primitives as follows. +Suppose that the function or primitive to be invoked is to be passed, say, +three arguments `x`, `y`, and `z`, currently located in stack registers `s(i)`, `s(j)`, +and `s(k)`. In this circumstance, the compiler (or programmer) might issue +operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) +or `XCHG s(i)` (if it will not be needed afterwards) to put the first argument +`x` into the top of the stack. Then, the compiler (or programmer) could use +either `PUSH s(j0)` or `XCHG s(j0)`, where `j0 = j` or `j + 1`, to put `y` into the new +top of the stack. + +Proceeding in this manner, we see that we can put the original values of +`x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using +a sequence of push and exchange operations (cf. 2.2.4 and 2.2.5 for a more +detailed explanation). In order to generate this sequence, the compiler will +need to know only the three values `i`, `j` and `k`, describing the old locations of +variables or temporary values in question, and some flags describing whether +each value will be needed thereafter or is needed only for this primitive or +function call. The locations of other variables and temporary values will be +affected in the process, but a compiler (or a human programmer) can easily +track their new locations. + +Similarly, if the results returned from a function need to be discarded +or moved to other stack registers, a suitable sequence of exchange and pop +operations will do the job. In the typical case of one return value in `s0`, +this is achieved either by an `XCHG s(i)` or a `POP s(i)` (in most cases, a `DROP`) +operation. + +Rearranging the result value or values before returning from a function is +essentially the same problem as arranging arguments for a function call, and +is achieved similarly. + +### 2.2.3. Compound stack manipulation primitives. + +In order to improve +the density of the TVM code and simplify development of compilers, compound stack manipulation primitives may be defined, each combining up to +four exchange and push or exchange and pop basic primitives. Such compound stack operations might include, for example: + +* `XCHG2 s(i),s(j)` — Equivalent to `XCHG s1,s(i); XCHG s(j)`. +* `PUSH2 s(i),s(j)` — Equivalent to `PUSH s(i); PUSH s(j + 1)`. +* `XCPU s(i),s(j)` — Equivalent to `XCHG s(i); PUSH s(j)`. +* `PUXC s(i),s(j)` — Equivalent to `PUSH s(i); SWAP; XCHG s(j+1)`. When + `j ≠ i` and `j ≠ 0`, it is also equivalent to `XCHG s(j); PUSH s(i); SWAP`. +* `XCHG3 s(i),s(j),s(k)` — Equivalent to `XCHG s2,s(i); XCHG s1,s(j); + XCHG s(k)`. +* `PUSH3 s(i),s(j),s(k)` — Equivalent to `PUSH s(i); PUSH s(j + 1); PUSH + s(k + 2)`. + +Of course, such operations make sense only if they admit a more compact +encoding than the equivalent sequence of basic operations. For example, +if all top-of-stack exchanges, `XCHG s1,s(i)` exchanges, and push and pop +operations admit one-byte encodings, the only compound stack operations +suggested above that might merit inclusion in the set of stack manipulation +primitives are `PUXC`, `XCHG3`, and `PUSH3`. + +Notice that the most common `XCHG s(i)` operation is not really required here if we +do not insist on keeping the same temporary value or variable always in the same stack +location, but rather keep track of its subsequent locations. We will move it to some other +location while preparing the arguments to the next primitive or function call. + +### 2.2.4. Mnemonics of compound stack operations. + +The mnemonics +of compound stack operations, some examples of which have been provided +in 2.2.3, are created as follows. +The `γ ≥ 2` formal arguments `s(i1), . . . , s(iγ)` to such an operation `O` +represent the values in the original stack that will end up in `s(γ − 1), . . . , +s0` after the execution of this compound operation, at least if all `iν, 1 ≤ +ν ≤ γ`, are distinct and at least γ. The mnemonic itself of the operation +`O` is a sequence of γ two-letter strings `PU` and `XC`, with `PU` meaning that +the corresponding argument is to be PUshed (i.e., a copy is to be created), +and `XC` meaning that the value is to be eXChanged (i.e., no other copy of +the original value is created). Sequences of several `PU` or `XC` strings may be +abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, +we write `PUXC2PU` instead of `PUXCXCPU`.) +As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, +so that the compound operation is equivalent to a sequence of `m` `PUSH`es or +`XCHG`s, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. + +### 2.2.5. Semantics of compound stack operations. + +Each compound `γ`- +ary operation `O s(i1),. . . ,s(iγ)` is translated into an equivalent sequence of +basic stack operations by induction in `γ` as follows: + +* As a base of induction, if `γ = 0`, the only nullary compound stack + operation corresponds to an empty sequence of basic stack operations. +* Equivalently, we might begin the induction from `γ = 1`. Then `PU s(i)` + corresponds to the sequence consisting of one basic operation `PUSH + s(i)`, and `XC s(i)` corresponds to the one-element sequence consisting + of `XCHG s(i)`. +* For `γ ≥ 1` (or for `γ ≥ 2`, if we use `γ = 1` as induction base), there are + two subcases: + + 1. `O s(i1), . . . , s(iγ)`, with `O = XCO0`, where `O0` + is a compound operation of arity `γ−1` (i.e., the mnemonic of `O0` + consists of `γ−1` strings + `XC` and `PU`). Let `α` be the total quantity of PUshes in `O`, and `β` be + that of eXChanges, so that `α+β = γ`. Then the original operation + is translated into `XCHG s(β −1),s(i1)`, followed by the translation + of `O0 s(i2), . . . , s(iγ)`, defined by the induction hypothesis. + + 2. `O s(i1), . . . , s(iγ)`, with `O = PUO0`, + where `O0` + is a compound operation of arity `γ − 1`. Then the original operation is translated into + `PUSH s(i1); XCHG s(β)`, followed by the translation of + `O0 s(i2 + 1), . . . , s(iγ + 1)`, defined by the induction hypothesis. + +An alternative, arguably better, translation of +`PUO0 s(i1), . . . , s(iγ)` consists of the +translation of `O0 s(i2), . . . , s(iγ)`, followed by +`PUSH s(i1 + α − 1); XCHG s(γ − 1)`. + +### 2.2.6. Stack manipulation instructions are polymorphic. + +Notice that +the stack manipulation instructions are almost the only “polymorphic” primitives in TVM—i.e., they work with values of arbitrary types (including the +value types that will appear only in future revisions of TVM). For example, `SWAP` always interchanges the two top values of the stack, even if one of +them is an integer and the other is a cell. Almost all other instructions, especially the data processing instructions (including arithmetic instructions), +require each of their arguments to be of some fixed type (possibly different +for different arguments). + +--- + +## 2.3 Efficiency of stack manipulation primitives + +Stack manipulation primitives employed by a stack machine, such as TVM, +have to be implemented very efficiently, because they constitute more than +half of all the instructions used in a typical program. In fact, TVM performs +all these instructions in a (small) constant time, regardless of the values +involved (even if they represent very large integers or very large trees of +cells). + +### 2.3.1. Implementation of stack manipulation primitives: using references for operations instead of objects. + +The efficiency of TVM’s +implementation of stack manipulation primitives results from the fact that a +typical TVM implementation keeps in the stack not the value objects themselves, but only the references (pointers) to such objects. Therefore, a `SWAP` +instruction only needs to interchange the references at `s0` and `s1`, not the +actual objects they refer to. + +### 2.3.2. Efficient implementation of DUP and PUSH instructions using copy-on-write. + +Furthermore, a `DUP` (or, more generally, `PUSH s(i)`) instruction, which appears to make a copy of a potentially large object, also works +in small constant time, because it uses a copy-on-write technique of delayed +copying: it copies only the reference instead of the object itself, but increases +the “reference counter” inside the object, thus sharing the object between the +two references. If an attempt to modify an object with a reference counter +greater than one is detected, a separate copy of the object in question is made +first (incurring a certain “non-uniqueness penalty” or “copying penalty” for +the data manipulation instruction that triggered the creation of a new copy). + +### 2.3.3. Garbage collecting and reference counting. + +When the reference counter of a TVM object becomes zero (for example, because the last +reference to such an object has been consumed by a `DROP` operation or an +arithmetic instruction), it is immediately freed. Because cyclic references +are impossible in TVM data structures, this method of reference counting +provides a fast and convenient way of freeing unused objects, replacing slow +and unpredictable garbage collectors. + +### 2.3.4. Transparency of the implementation: Stack values are “values”, not “references”. + +Regardless of the implementation details just discussed, all stack values are really “values”, not “references”, from the perspective of the TVM programmer, similarly to the values of all types in functional +programming languages. Any attempt to modify an existing object referred +to from any other objects or stack locations will result in a transparent replacement of this object by its perfect copy before the modification is actually +performed. +In other words, the programmer should always act as if the objects themselves were directly manipulated by stack, arithmetic, and other data transformation primitives, and treat the previous discussion only as an explanation +of the high efficiency of the stack manipulation primitives. + +### 2.3.5. Absence of circular references. + +One might attempt to create a +circular reference between two cells, `A` and `B`, as follows: first create `A` and +write some data into it; then create `B` and write some data into it, along +with a reference to previously constructed cell `A`; finally, add a reference to +`B` into `A`. While it may seem that after this sequence of operations we obtain +a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. +In fact, we obtain a new cell `A0`, which contains a copy of the data originally +stored into cell `A` along with a reference to cell `B`, which contains a reference +to (the original) cell `A`. +In this way the transparent copy-on-write mechanism and the “everything +is a value” paradigm enable us to create new cells using only previously +constructed cells, thus forbidding the appearance of circular references. This +property also applies to all other data structures: for instance, the absence +of circular references enables TVM to use reference counting to immediately +free unused memory instead of relying on garbage collectors. Similarly, this +property is crucial for storing data in the TON Blockchain. + +Great — here’s **Chapter 3 (Cells, memory, and persistent storage)** reformatted to Markdown with all mnemonics, variables, and notation in backticks. + +--- + +# 3 Cells, memory, and persistent storage + +This chapter briefly describes TVM cells, used to represent all data structures +inside the TVM memory and its persistent storage, and the basic operations +used to create cells, write (or serialize) data into them, and read (or deserialize) data from them. + +## 3.1 Generalities on cells + +### 3.1.1. TVM memory and persistent storage consist of cells. + +Recall +that the TVM memory and persistent storage consist of (TVM) cells. Each +cell contains up to `1023` bits of data and up to four references to other cells. +Circular references are forbidden and cannot be created by means of TVM +(cf. 2.3.5). In this way, all cells kept in TVM memory and persistent storage +constitute a directed acyclic graph (DAG). + +### 3.1.2. Ordinary and exotic cells. + +Apart from the data and references, +a cell has a cell type, encoded by an integer `−1 ... 255`. A cell of type `−1` +is called ordinary; such cells do not require any special processing. Cells of +other types are called exotic, and may be loaded—automatically replaced by +other cells when an attempt to deserialize them (i.e., to convert them into +a `Slice` by a `CTOS` instruction) is made. They may also exhibit a non-trivial +behavior when their hashes are computed. + +The most common use for exotic cells is to represent some other cells—for +instance, cells present in an external library, or pruned from the original tree +of cells when a Merkle proof has been created. + +The type of an exotic cell is stored as the first eight bits of its data. If an +exotic cell has less than eight data bits, it is invalid. + +### 3.1.3. The level of a cell. + +Every cell `c` has another attribute `Lvl(c)` called +its (de Brujn) level, which currently takes integer values in the range `0...3`. +The level of an ordinary cell is always equal to the maximum of the levels of +all its children `ci`: + +``` +Lvl(c) = max ( Lvl(ci) ) for 1 ≤ i ≤ r +``` + +for an ordinary cell `c` containing `r` references to cells `c1, ..., cr`. +If `r = 0`, then `Lvl(c) = 0`. Exotic cells may have different rules for setting their level. + +A cell’s level affects the number of higher hashes it has. More precisely, +a level `l` cell has `l` higher hashes `Hash1(c), ..., Hashl(c)` in addition to its +representation hash `Hash(c) = Hash∞(c)`. Cells of non-zero level appear +inside Merkle proofs and Merkle updates, after some branches of the tree of +cells representing a value of an abstract data type are pruned. + +### 3.1.4. Standard cell representation. + +When a cell needs to be transferred +by a network protocol or stored in a disk file, it must be serialized. +The standard representation `CellRepr(c) = CellRepr∞(c)` of a cell `c` as an +octet (byte) sequence is constructed as follows: + +1. Two descriptor bytes `d1` and `d2` are serialized first. + + * `d1 = r + 8s + 32l`, where `0 ≤ r ≤ 4` is the number of cell references contained + in the cell, `0 ≤ l ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is `1` for + exotic cells and `0` for ordinary cells. + * `d2 = ⌊b/8⌋ + ⌈b/8⌉`, where `0 ≤ b ≤ 1023` is the number of data bits in `c`. + +2. Then the data bits are serialized as `⌈b/8⌉` 8-bit octets (bytes). + If `b` is not a multiple of eight, a binary `1` and up to six binary `0`s are appended to + the data bits. After that, the data is split into `⌈b/8⌉` eight-bit groups, + and each group is interpreted as an unsigned big-endian integer `0...255` + and stored into an octet. + +3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(ci)` of the cell `ci` referred to. + +In this way, `2 + ⌈b/8⌉ + 32r` bytes of `CellRepr(c)` are obtained. + +### 3.1.5. The representation hash of a cell. + +The 256-bit representation +hash or simply hash `Hash(c)` of a cell `c` is recursively defined as the `sha256` +of the standard representation of the cell `c`: + +``` +Hash(c) := sha256(CellRepr(c)) +``` + +Notice that cyclic cell references are not allowed and cannot be created by +means of the TVM (cf. 2.3.5), so this recursion always ends, and the representation hash of any cell is well-defined. + +### 3.1.6. The higher hashes of a cell. + +Recall that a cell `c` of level `l` has `l` +higher hashes `Hashi(c)`, `1 ≤ i ≤ l`. Exotic cells have their own rules +for computing their higher hashes. Higher hashes `Hashi(c)` of an ordinary +cell `c` are computed similarly to its representation hash, but using the higher +hashes `Hashi(cj)` of its children `cj` instead of their representation hashes +`Hash(cj)`. By convention, we set `Hash∞(c) := Hash(c)`, and `Hashi(c) := Hash(c)` +for all `i > l`. + +Perfect — here’s the continuation of **Chapter 3**, keeping **all text exactly the same** but fully in Markdown, with mnemonics, variables, and formulas wrapped in backticks: + +--- + +### 3.1.7. Types of exotic cells. + +TVM currently supports the following cell +types: + +* **Type −1: Ordinary cell** — Contains up to `1023` bits of data and up to + four cell references. +* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ l ≤ 3`. It + contains exactly `8 + 256l` data bits: first an 8-bit integer equal to `1` + (representing the cell’s type), then its `l` higher hashes `Hash1(c), ..., + Hashl(c)`. The level `l` of a pruned branch cell may be called its *de + Brujn index*, because it determines the outer Merkle proof or Merkle + update during the construction of which the branch has been pruned. + An attempt to load a pruned branch cell usually leads to an exception. +* **Type 2: Library reference cell** — Always has level `0`, and contains `8+256` + data bits, including its 8-bit type integer `2` and the representation hash + `Hash(c0)` of the library cell being referred to. When loaded, a library + reference cell may be transparently replaced by the cell it refers to, if + found in the current library context. +* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c1` and level + `0 ≤ l ≤ 3`, which must be one less than the level of its only child `c1`: + + ``` + Lvl(c) = max(Lvl(c1) − 1, 0) + ``` + + The `8 + 256` data bits of a Merkle proof cell contain its 8-bit type + integer `3`, followed by `Hash1(c1)` (assumed to be equal to `Hash(c1)` if + `Lvl(c1) = 0`). The higher hashes `Hashi(c)` of `c` are computed similarly + to the higher hashes of an ordinary cell, but with `Hashi+1(c1)` used + instead of `Hashi(c1)`. When loaded, a Merkle proof cell is replaced by + `c1`. +* **Type 4: Merkle update cell `c`** — Has two children `c1` and `c2`. Its level + `0 ≤ l ≤ 3` is given by: + + ``` + Lvl(c) = max(Lvl(c1) − 1, Lvl(c2) − 1, 0) + ``` + + A Merkle update behaves like a Merkle proof for both `c1` and `c2`, and + contains `8 + 256 + 256` data bits with `Hash1(c1)` and `Hash1(c2)`. + However, an extra requirement is that all pruned branch cells `c0` that are + descendants of `c2` and are bound by `c` must also be descendants of `c1`. + When a Merkle update cell is loaded, it is replaced by `c2`. + +--- + +### 3.1.8. All values of algebraic data types are trees of cells. + +Arbitrary +values of arbitrary algebraic data types (e.g., all types used in functional +programming languages) can be serialized into trees of cells (of level `0`), and +such representations are used for representing such values within TVM. + +The copy-on-write mechanism (cf. 2.3.2) allows TVM to identify cells containing +the same data and references, and to keep only one copy of such cells. This +actually transforms a tree of cells into a directed acyclic graph (with the +additional property that all its vertices be accessible from a marked vertex +called the “root”). However, this is a storage optimization rather than an +essential property of TVM. From the perspective of a TVM code programmer, +one should think of TVM data structures as trees of cells. + +--- + +### 3.1.9. TVM code is a tree of cells. + +The TVM code itself is also represented by a tree of cells. Indeed, TVM code is simply a value of some +complex algebraic data type, and as such, it can be serialized into a tree of +cells. + +The exact way in which the TVM code (e.g., TVM assembly code) is +transformed into a tree of cells is explained later (cf. 4.1.4 and 5.2), in sections discussing control flow instructions, continuations, and TVM instruction encoding. + +--- + +### 3.1.10. “Everything is a bag of cells” paradigm. + +As described in `[1, +2.5.14]`, all the data used by the TON Blockchain, including the blocks +themselves and the blockchain state, can be represented—and are represented—as +collections, or “bags”, of cells. + +We see that TVM’s structure of data (cf. 3.1.8) +and code (cf. 3.1.9) nicely fits into this “everything is a bag of cells” paradigm. +In this way, TVM can naturally be used to execute smart contracts in the +TON Blockchain, and the TON Blockchain can be used to store the code +and persistent data of these smart contracts between invocations of TVM. + +(Of course, both TVM and the TON Blockchain have been designed so that +this would become possible.) +Got it — here’s the continuation with **3.2 Data manipulation instructions and cells** in proper Markdown, keeping **all text exactly the same** but formatted (mnemonics, values, variables in backticks): + +--- + +## 3.2 Data manipulation instructions and cells + +The next large group of TVM instructions consists of data manipulation +instructions, also known as cell manipulation instructions or simply cell +instructions. They correspond to memory access instructions of other architectures. + +--- + +### 3.2.1. Classes of cell manipulation instructions. + +The TVM cell instructions are naturally subdivided into two principal classes: + +* **Cell creation instructions** or **serialization instructions**, used to construct new cells from values previously kept in the stack and previously + constructed cells. +* **Cell parsing instructions** or **deserialization instructions**, used to extract + data previously stored into cells by cell creation instructions. + +Additionally, there are exotic cell instructions used to create and inspect +exotic cells (cf. 3.1.2), which in particular are used to represent pruned +branches of Merkle proofs and Merkle proofs themselves. + +--- + +### 3.2.2. Builder and Slice values. + +Cell creation instructions usually work +with `Builder` values, which can be kept only in the stack (cf. 1.1.3). Such +values represent partially constructed cells, for which fast operations for appending bitstrings, integers, other cells, and references to other cells can be +defined. Similarly, cell parsing instructions make heavy use of `Slice` values, +which represent either the remainder of a partially parsed cell, or a value +(subcell) residing inside such a cell and extracted from it by a parsing instruction. + +--- + +### 3.2.3. Builder and Slice values exist only as stack values. + +Notice that +`Builder` and `Slice` objects appear only as values in a TVM stack. They cannot +be stored in “memory” (i.e., trees of cells) or “persistent storage” (which is +also a bag of cells). In this sense, there are far more `Cell` objects than `Builder` +or `Slice` objects in a TVM environment, but, somewhat paradoxically, a TVM +program sees `Builder` and `Slice` objects in its stack more often than `Cell`s. + +In fact, a TVM program does not have much use for `Cell` values, because they +are immutable and opaque; all cell manipulation primitives require that a +`Cell` value be transformed into either a `Builder` or a `Slice` first, before it can +be modified or inspected. + +--- + +### 3.2.4. TVM has no separate Bitstring value type. + +Notice that TVM +offers no separate bitstring value type. Instead, bitstrings are represented by +`Slice`s that happen to have no references at all, but can still contain up to +`1023` data bits. + +--- + +### 3.2.5. Cells and cell primitives are bit-oriented, not byte-oriented. + +An important point is that TVM regards data kept in cells as sequences +(strings, streams) of (up to `1023`) bits, not of bytes. In other words, TVM +is a bit-oriented machine, not a byte-oriented machine. If necessary, an +application is free to use, say, `21`-bit integer fields inside records serialized into +TVM cells, thus using fewer persistent storage bytes to represent the same +data. + +--- + +### 3.2.6. Taxonomy of cell creation (serialization) primitives. + +Cell creation primitives usually accept a `Builder` argument and an argument representing the value to be serialized. Additional arguments controlling some +aspects of the serialization process (e.g., how many bits should be used for +serialization) can be also provided, either in the stack or as an immediate +value inside the instruction. + +The result of a cell creation primitive is usually +another `Builder`, representing the concatenation of the original builder and +the serialization of the value provided. + +Therefore, one can suggest a classification of cell serialization primitives +according to the answers to the following questions: + +* Which is the type of values being serialized? +* How many bits are used for serialization? If this is a variable number, + does it come from the stack, or from the instruction itself? +* What happens if the value does not fit into the prescribed number of + bits? Is an exception generated, or is a success flag equal to zero silently + returned in the top of stack? +* What happens if there is insufficient space left in the `Builder`? Is an + exception generated, or is a zero success flag returned along with the + unmodified original `Builder`? + +The mnemonics of cell serialization primitives usually begin with `ST`. Subsequent letters describe the following attributes: + +* The type of values being serialized and the serialization format (e.g., `I` + for signed integers, `U` for unsigned integers). +* The source of the field width in bits to be used (e.g., `X` for integer + serialization instructions means that the bit width `n` is supplied in + the stack; otherwise it has to be embedded into the instruction as an + immediate value). +* The action to be performed if the operation cannot be completed (by + default, an exception is generated; “quiet” versions of serialization instructions are marked by a `Q` letter in their mnemonics). + +This classification scheme is used to create a more complete taxonomy of cell +serialization primitives, which can be found in **A.7.1**. + +--- + +### 3.2.7. Integer serialization primitives. + +Integer serialization primitives +can be classified according to the above taxonomy as well. For example: + +* There are signed and unsigned (big-endian) integer serialization primitives. +* The size `n` of the bit field to be used (`1 ≤ n ≤ 257` for signed integers, + `0 ≤ n ≤ 256` for unsigned integers) can either come from the top of + stack or be embedded into the instruction itself. +* If the integer `x` to be serialized is not in the range `−2^(n−1) ≤ x < 2^(n−1)` + (for signed integer serialization) or `0 ≤ x < 2^n` (for unsigned integer + serialization), a range check exception is usually generated, and if `n` bits + cannot be stored into the provided `Builder`, a cell overflow exception is + generated. +* Quiet versions of serialization instructions do not throw exceptions; + instead, they push `-1` on top of the resulting `Builder` upon success, or + return the original `Builder` with `0` on top of it to indicate failure. + +Integer serialization instructions have mnemonics like `STU 20` (“store an +unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of +variable length provided in the stack”). + +The full list of these instructions— +including their mnemonics, descriptions, and opcodes—is provided in **A.7.1**. + +--- + +### 3.2.8. Integers in cells are big-endian by default. + +Notice that the +default order of bits in `Integer`s serialized into `Cell`s is big-endian, not little- +endian. + +In this respect TVM is a big-endian machine. However, this affects +only the serialization of integers inside cells. The internal representation of +the `Integer` value type is implementation-dependent and irrelevant for the +operation of TVM. + +Besides, there are some special primitives such as `STULE` +for (de)serializing little-endian integers, which must be stored into an integral +number of bytes (otherwise “little-endianness” does not make sense, unless +one is also willing to revert the order of bits inside octets). + +Such primitives are +useful for interfacing with the little-endian world—for instance, for parsing +custom-format messages arriving to a TON Blockchain smart contract from +the outside world. + +--- + +### 3.2.9. Other serialization primitives. + +Other cell creation primitives serialize bitstrings (i.e., cell slices without references), either taken from the stack +or supplied as literal arguments; cell slices (which are concatenated to the +cell builder in an obvious way); other `Builder`s (which are also concatenated); +and cell references (`STREF`). + +--- + +### 3.2.10. Other cell creation primitives. + +In addition to the cell serialization primitives for certain built-in value types described above, there are +simple primitives that create a new empty `Builder` and push it into the stack +(`NEWC`), or transform a `Builder` into a `Cell` (`ENDC`), thus finishing the cell +creation process. + +An `ENDC` can be combined with a `STREF` into a single instruction `ENDCST`, which finishes the creation of a cell and immediately stores +a reference to it in an “outer” `Builder`. + +There are also primitives that obtain +the quantity of data bits or references already stored in a `Builder`, and check how many data bits or references can be stored. + +--- + +### 3.2.11. Taxonomy of cell deserialisation primitives. + +Cell parsing, or +deserialization, primitives can be classified as described in 3.2.6, with the +following modifications: + +* They work with `Slice`s (representing the remainder of the cell being + parsed) instead of `Builder`s. +* They return deserialized values instead of accepting them as arguments. +* They may come in two flavors, depending on whether they remove the + deserialized portion from the `Slice` supplied (“fetch operations”) or leave + it unmodified (“prefetch operations”). +* Their mnemonics usually begin with `LD` (or `PLD` for prefetch operations) + instead of `ST`. + +For example, an unsigned big-endian 20-bit integer previously serialized into +a cell by a `STU 20` instruction is likely to be deserialized later by a matching +`LDU 20` instruction. + +Again, more detailed information about these instructions is provided in **A.7.2**. + +--- + +### 3.2.12. Other cell slice primitives. + +In addition to the cell deserialisation +primitives outlined above, TVM provides some obvious primitives for initializing and completing the cell deserialization process. + +For instance, one can +convert a `Cell` into a `Slice` (`CTOS`), so that its deserialisation might begin; +or check whether a `Slice` is empty, and generate an exception if it is not +(`ENDS`); or deserialize a cell reference and immediately convert it into a `Slice` +(`LDREFTOS`, equivalent to two instructions `LDREF` and `CTOS`). + +--- + +### 3.2.13. Modifying a serialized value in a cell. + +The reader might wonder +how the values serialized inside a cell may be modified. + +Suppose a cell contains three serialized 29-bit integers, `(x, y, z)`, representing the coordinates of +a point in space, and we want to replace `y` with `y' = y + 1`, leaving the other +coordinates intact. How would we achieve this? + +TVM does not offer any ways to modify existing values (cf. 2.3.4 and +2.3.5), so our example can only be accomplished with a series of operations +as follows: + +1. Deserialize the original cell into three `Integer`s `x`, `y`, `z` in the stack (e.g., + by `CTOS; LDI 29; LDI 29; LDI 29; ENDS`). +2. Increase `y` by one (e.g., by `SWAP; INC; SWAP`). +3. Finally, serialize the resulting `Integer`s into a new cell (e.g., by `XCHG s2; NEWC; STI 29; STI 29; STI 29; ENDC`). + +--- + +### 3.2.14. Modifying the persistent storage of a smart contract. + +If the +TVM code wants to modify its persistent storage, represented by the tree of +cells rooted at `c4`, it simply needs to rewrite control register `c4` by the root +of the tree of cells containing the new value of its persistent storage. (If only +part of the persistent storage needs to be modified, cf. 3.2.13.) + +--- + +## 3.3 Hashmaps, or dictionaries + +Hashmaps, or dictionaries, are a specific data structure represented by a tree +of cells. Essentially, a hashmap represents a map from keys, which are bitstrings of either fixed or variable length, into values of an arbitrary type `X`, +in such a way that fast lookups and modifications be possible. While any +such structure might be inspected or modified with the aid of generic cell serialization and deserialization primitives, TVM introduces special primitives +to facilitate working with these hashmaps. + +--- + +### 3.3.1. Basic hashmap types. + +The two most basic hashmap types predefined in TVM are `HashmapE n X` or `HashmapE(n, X)`, which represents +a partially defined map from n-bit strings (called keys) for some fixed `0 ≤ n ≤ 1023` into values of some type `X`, and `Hashmap(n, X)`, which is similar +to `HashmapE(n, X)` but is not allowed to be empty (i.e., it must contain at +least one key-value pair). + +Other hashmap types are also available—for example, one with keys of +arbitrary length up to some predefined bound (up to 1023 bits). + +--- + +### 3.3.2. Hashmaps as Patricia trees. + +The abstract representation of a +hashmap in TVM is a Patricia tree, or a compact binary trie. It is a binary +tree with edges labelled by bitstrings, such that the concatenation of all edge +labels on a path from the root to a leaf equals a key of the hashmap. The +corresponding value is kept in this leaf (for hashmaps with keys of fixed +length), or optionally in the intermediate vertices as well (for hashmaps with +keys of variable length). + +Furthermore, any intermediate vertex must have +two children, and the label of the left child must begin with a binary zero, +while the label of the right child must begin with a binary one. This enables +us not to store the first bit of the edge labels explicitly. + +It is easy to see that any collection of key-value pairs (with distinct keys) +is represented by a unique Patricia tree. + +--- + +### 3.3.3. Serialization of hashmaps. + +The serialization of a hashmap into a +tree of cells (or, more generally, into a `Slice`) is defined by the following TL-B +scheme: + +``` +bit#_ _:(## 1) = Bit; +hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) +{n = (~m) + l} node:(HashmapNode m X) = Hashmap n X; +hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X; +hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X) +right:^(Hashmap n X) = HashmapNode (n + 1) X; +hml_short$0 {m:#} {n:#} len:(Unary ~n) +s:(n * Bit) = HmLabel ~n m; +hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m; +hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m; +unary_zero$0 = Unary ~0; +unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1); +hme_empty$0 {n:#} {X:Type} = HashmapE n X; +hme_root$1 {n:#} {X:Type} root:^(Hashmap n X) = HashmapE n X; +true#_ = True; +_ {n:#} _:(Hashmap n True) = BitstringSet n; +``` + +--- + +### 3.3.4. Brief explanation of TL-B schemes. + +A TL-B scheme, like the +one above, includes the following components. + +The right-hand side of each “equation” is a type, either simple (such as +`Bit` or `True`) or parametrized (such as `Hashmap n X`). The parameters of a +type must be either natural numbers (i.e., non-negative integers, which are +required to fit into 32 bits in practice), such as `n` in `Hashmap n X`, or other +types, such as `X` in `Hashmap n X`. + +The left-hand side of each equation describes a way to define, or even to +serialize, a value of the type indicated in the right-hand side. Such a description begins with the name of a constructor, such as `hm_edge` or `hml_long`, +immediately followed by an optional constructor tag, such as `#_` or `$10`, which +describes the bitstring used to encode (serialize) the constructor in question. + +Such tags may be given in either binary (after a dollar sign) or hexadecimal +notation (after a hash sign), using the conventions described in 1.0. + +If a tag is not explicitly provided, TL-B computes a default 32-bit constructor tag +by hashing the text of the “equation” defining this constructor in a certain +fashion. Therefore, empty tags must be explicitly provided by `#_` or `$_`. All +constructor names must be distinct, and constructor tags for the same type +must constitute a prefix code (otherwise the deserialization would not be +unique). + +The constructor and its optional tag are followed by field definitions. Each +field definition is of the form `ident : type-expr`, where `ident` is an identifier +with the name of the field (replaced by an underscore for anonymous fields), +and `type-expr` is the field’s type. + +The type provided here is a type expression, +which may include simple types or parametrized types with suitable parameters. + +Variables—i.e., the identifiers of the previously defined fields of types +`#` (natural numbers) or `Type` (type of types)—may be used as parameters +for the parametrized types. The serialization process recursively serializes +each field according to its type, and the serialization of a value ultimately +consists of the concatenation of bitstrings representing the constructor (i.e., +the constructor tag) and the field values. + +Some fields may be implicit. Their definitions are surrounded by curly +braces, which indicate that the field is not actually present in the serialization, +but that its value must be deduced from other data (usually the parameters +of the type being serialized). + +Some occurrences of “variables” (i.e., already-defined fields) are prefixed +by a tilde. This indicates that the variable’s occurrence is used in the opposite way of the default behavior: in the left-hand side of the equation, it +means that the variable will be deduced (computed) based on this occurrence, +instead of substituting its previously computed value; in the right-hand side, +conversely, it means that the variable will not be deduced from the type being +serialized, but rather that it will be computed during the deserialization process. + +In other words, a tilde transforms an “input argument” into an “output +argument”, and vice versa.17 + +Finally, some equalities may be included in curly brackets as well. These +are certain “equations”, which must be satisfied by the “variables” included in +them. If one of the variables is prefixed by a tilde, its value will be uniquely +determined by the values of all other variables participating in the equation +(which must be known at this point) when the definition is processed from +the left to the right. + +A caret (`^`) preceding a type `X` means that instead of serializing a value +of type `X` as a bitstring inside the current cell, we place this value into a +separate cell, and add a reference to it into the current cell. Therefore `^X` +means “the type of references to cells containing values of type X”. + +Parametrized type `#<= p` with `p : #` (this notation means “p of type #”, +i.e., a natural number) denotes the subtype of the natural numbers type +`#`, consisting of integers `0 . . . p`; it is serialized into `⌈log2(p + 1)⌉` bits as an +unsigned big-endian integer. + +Type `#` by itself is serialized as an unsigned +32-bit integer. Parametrized type `## b` with `b : #<=31` is equivalent to `#<= 2^b − 1` (i.e., it is an unsigned b-bit integer). + +--- + +### 3.3.5. Application to the serialization of hashmaps. + +Let us explain +the net result of applying the general rules described in 3.3.4 to the TL-B +scheme presented in 3.3.3. + +Suppose we wish to serialize a value of type `HashmapE n X` for some +integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with n-bit keys +and values of type `X`, admitting an abstract representation as a Patricia tree +(cf. 3.3.2)). + +First of all, if our dictionary is empty, it is serialized into a single binary `0`, +which is the tag of nullary constructor `hme_empty`. Otherwise, its serialization +consists of a binary `1` (the tag of `hme_root`), along with a reference to a cell +containing the serialization of a value of type `Hashmap n X` (i.e., a necessarily +non-empty dictionary). + +The only way to serialize a value of type `Hashmap n X` is given by the +`hm_edge` constructor, which instructs us to serialize first the label `label` of +the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel l ⊥ n`, which means that it is a bitstring of length at most n, serialized in such +a way that the true length l of the label, `0 ≤ l ≤ n`, becomes known from +the serialization of the label. (This special serialization method is described +separately in 3.3.6.) + +The label must be followed by the serialization of a node of type +`HashmapNode m X`, where `m = n − l`. It corresponds to a vertex of the Patricia tree, +representing a non-empty subdictionary of the original dictionary with m-bit +keys, obtained by removing from all the keys of the original subdictionary +their common prefix of length l. + +If `m = 0`, a value of type `HashmapNode 0 X` is given by the `hmn_leaf` +constructor, which describes a leaf of the Patricia tree—or, equivalently, a +subdictionary with 0-bit keys. A leaf simply consists of the corresponding +value of type `X` and is serialized accordingly. + +On the other hand, if `m > 0`, a value of type `HashmapNode m X` corresponds to a fork (i.e., an intermediate node) in the Patricia tree, and is +given by the `hmn_fork` constructor. Its serialization consists of `left` and +`right`, two references to cells containing values of type `Hashmap m − 1 X`, +which correspond to the left and the right child of the intermediate node in +question—or, equivalently, to the two subdictionaries of the original dictionary consisting of key-value pairs with keys beginning with a binary `0` or +a binary `1`, respectively. Because the first bit of all keys in each of these +subdictionaries is known and fixed, it is removed, and the resulting (necessarily non-empty) subdictionaries are recursively serialized as values of type +`Hashmap m − 1 X`. + +--- + +### 3.3.6. Serialization of labels. + +There are several ways to serialize a label +of length at most n, if its exact length is `l ≤ n` (recall that the exact length +must be deducible from the serialization of the label itself, while the upper +bound n is known before the label is serialized or deserialized). These ways +are described by the three constructors `hml_short`, `hml_long`, and `hml_same` +of type `HmLabel l ⊥ n`: + +* `hml_short` — Describes a way to serialize “short” labels, of small length + `l ≤ n`. Such a serialization consists of a binary `0` (the constructor tag + of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary + representation of the length l), followed by l bits comprising the label + itself. + +* `hml_long` — Describes a way to serialize “long” labels, of arbitrary + length `l ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation + of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by l bits comprising the label itself. + +* `hml_same` — Describes a way to serialize “long” labels, consisting of l + repetitions of the same bit v. Such a serialization consists of `11` (the + constructor tag of `hml_same`), followed by the bit `v`, followed by the + length l stored in `⌈log2(n + 1)⌉` bits as before. + +Each label can always be serialized in at least two different fashions, using +`hml_short` or `hml_long` constructors. Usually the shortest serialization (and +in the case of a tie—the lexicographically smallest among the shortest) is +preferred and is generated by TVM hashmap primitives, while the other +variants are still considered valid. + +This label encoding scheme has been designed to be efficient for dictionaries +with “random” keys (e.g., hashes of some data), as well as for dictionaries with +“regular” keys (e.g., big-endian representations of integers in some range). + +--- + +### 3.3.7. An example of dictionary serialization. + +Consider a dictionary +with three 16-bit keys 13, 17, and 239 (considered as big-endian integers) +and corresponding 16-bit values 169, 289, and 57121. + +In binary form: + +``` +0000000000001101 => 0000000010101001 +0000000000010001 => 0000000100100001 +0000000011101111 => 1101111100100001 +``` + +The corresponding Patricia tree consists of a root `A`, two intermediate +nodes `B` and `C`, and three leaf nodes `D`, `E`, and `F`, corresponding to 13, 17, +and 239, respectively. The root `A` has only one child, `B`; the label on the +edge `AB` is `00000000 = 08`. The node `B` has two children: its left child is +an intermediate node `C` with the edge `BC` labelled by `(0)00`, while its right +child is the leaf `F` with `BF` labelled by `(1)1101111`. Finally, `C` has two leaf +children `D` and `E`, with `CD` labelled by `(0)1101` and `CE`—by `(1)0001`. + +The corresponding value of type `HashmapE 16 (## 16)` may be written +in human-readable form as: + +``` +(hme_root$1 + root:^(hm_edge label:(hml_same$11 v:0 n:8) node:(hm_fork + left:^(hm_edge label:(hml_short$0 len:$110 s:$00) node:(hm_fork + left:^(hm_edge label:(hml_long$10 n:4 s:$1101) + node:(hm_leaf value:169)) + right:^(hm_edge label:(hml_long$10 n:4 s:$0001) + node:(hm_leaf value:289)))) + right:^(hm_edge label:(hml_long$10 n:7 s:$1101111) + node:(hm_leaf value:57121))))) +``` + +The serialization of this data structure into a tree of cells consists of six +cells with the following binary data contained in them: + +``` +A := 1 +A.0 := 11 0 01000 +A.0.0 := 0 110 00 +A.0.0.0 := 10 100 1101 0000000010101001 +A.0.0.1 := 10 100 0001 0000000100100001 +A.0.1 := 10 111 1101111 1101111100100001 +``` + +Here `A` is the root cell, `A.0` is the cell at the first reference of `A`, `A.1` is +the cell at the second reference of `A`, and so on. This tree of cells can be +represented more compactly using the hexadecimal notation described in 1.0, +using indentation to reflect the tree-of-cells structure: + +``` +C_ +C8 +62_ +A68054C_ +A08090C_ +BEFDF21 +``` + +A total of 93 data bits and 5 references in 6 cells have been used to serialize +this dictionary. Notice that a straightforward representation of three 16- +bit keys and their corresponding 16-bit values would already require 96 bits +(albeit without any references), so this particular serialization turns out to +be quite efficient. + +--- + +### 3.3.8. Ways to describe the serialization of type X. + +Notice that the +built-in TVM primitives for dictionary manipulation need to know something +about the serialization of type `X`; otherwise, they would not be able to work +correctly with `Hashmap n X`, because values of type `X` are immediately +contained in the Patricia tree leaf cells. There are several options available +to describe the serialization of type `X`: + +* The simplest case is when `X = ^Y` for some other type `Y`. In this case + the serialization of `X` itself always consists of one reference to a cell, + which in fact must contain a value of type `Y`, something that is not + relevant for dictionary manipulation primitives. + +* Another simple case is when the serialization of any value of type `X` + always consists of `0 ≤ b ≤ 1023` data bits and `0 ≤ r ≤ 4` references. Integers `b` and `r` can then be passed to a dictionary manipulation primitive + as a simple description of `X`. (Notice that the previous case corresponds + to `b = 0, r = 1`.) + +* A more sophisticated case can be described by four integers + `1 ≤ b0, b1 ≤ 1023`, `0 ≤ r0, r1 ≤ 4`, with `bi` and `ri` used when the first bit of the + serialization equals `i`. When `b0 = b1` and `r0 = r1`, this case reduces to + the previous one. + +* Finally, the most general description of the serialization of a type `X` + is given by a splitting function `splitX` for `X`, which accepts one `Slice` + parameter `s`, and returns two `Slice`s, `s'` and `s''`, where `s'` + is the only prefix of `s` that is the serialization of a value of type `X`, and `s''` is + the remainder of `s`. If no such prefix exists, the splitting function is + expected to throw an exception. Notice that a compiler for a high-level + language, which supports some or all algebraic TL-B types, is likely to + automatically generate splitting functions for all types defined in the + program. + +--- + +### 3.3.9. A simplifying assumption on the serialization of `X`. + +One +may notice that values of type `X` always occupy the remaining part of an +`hm_edge`/`hme_leaf` cell inside the serialization of a `HashmapE n X`. Therefore, if we do not insist on strict validation of all dictionaries accessed, we +may assume that everything left unparsed in an `hm_edge`/`hme_leaf` cell after deserializing its label is a value of type `X`. This greatly simplifies the +creation of dictionary manipulation primitives, because in most cases they +turn out not to need any information about `X` at all. + +--- + +### 3.3.10. Basic dictionary operations. + +Let us present a classification of +basic operations with dictionaries (i.e., values `D` of type `HashmapE n X`): + +* `Get(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns + the corresponding value `D[k] : X?` kept in `D`. +* `Set(D, k, x)` — Given `D : HashmapE(n, X)`, a key `k : n · bit`, and a + value `x : X`, sets `D0[k]` to `x` in a copy `D0` of `D`, and returns the resulting + dictionary `D0` (cf. 2.3.4). +* `Add(D, k, x)` — Similar to `Set`, but adds the key-value pair `(k, x)` to + `D` only if key `k` is absent in `D`. +* `Replace(D, k, x)` — Similar to `Set`, but changes `D0[k]` to `x` only if key + `k` is already present in `D`. +* `GetSet`, `GetAdd`, `GetReplace` — Similar to `Set`, `Add`, and `Replace`, + respectively, but returns the old value of `D[k]` as well. +* `Delete(D, k)` — Deletes key `k` from dictionary `D`, and returns the + resulting dictionary `D0`. +* `GetMin(D)`, `GetMax(D)` — Gets the minimal or maximal key `k` + from dictionary `D`, along with the associated value `x : X`. +* `RemoveMin(D)`, `RemoveMax(D)` — Similar to `GetMin` and `GetMax`, but also removes the key in question from dictionary `D`, and + returns the modified dictionary `D0`. May be used to iterate over all + elements of `D`, effectively using (a copy of) `D` itself as an iterator. +* `GetNext(D, k)` — Computes the minimal key `k0 > k` (or `k0 ≥ k` in a + variant) and returns it along with the corresponding value `x0 : X`. May + be used to iterate over all elements of `D`. +* `GetPrev(D, k)` — Computes the maximal key `k0 < k` (or `k0 ≤ k` in a + variant) and returns it along with the corresponding value `x0 : X`. +* `Empty(n)` — Creates an empty dictionary `D : HashmapE(n, X)`. +* `IsEmpty(D)` — Checks whether a dictionary is empty. +* `Create(n, {(ki , xi)})` — Given `n`, creates a dictionary from a list `(ki , xi)` + of key-value pairs passed in stack. +* `GetSubdict(D, l, k0)` — Given `D : HashmapE(n, X)` and some `l`-bit + string `k0 : l · bit` for `0 ≤ l ≤ n`, returns subdictionary `D0 = D/k0` of `D`, + consisting of keys beginning with `k0`. The result `D0` may be of either + type `HashmapE(n, X)` or type `HashmapE(n − l, X)`. +* `ReplaceSubdict(D, l, k0, D0)` — Given `D : HashmapE(n, X)`, `0 ≤ + l ≤ n`, `k0 : l · bit`, and `D0 : HashmapE(n − l, X)`, replaces with `D0` + the subdictionary `D/k0` of `D` consisting of keys beginning with `k0`, and + returns the resulting dictionary `D00 : HashmapE(n, X)`. Some variants + of `ReplaceSubdict` may also return the old value of the subdictionary + `D/k0` in question. +* `DeleteSubdict(D, l, k0)` — Equivalent to `ReplaceSubdict` with `D0` + being an empty dictionary. +* `Split(D)` — Given `D : HashmapE(n, X)`, returns `D0 := D/0` and + `D1 := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with 0 and 1, respectively. +* `Merge(D0, D1)` — Given `D0` and `D1 : HashmapE(n−1, X)`, computes + `D : HashmapE(n, X)`, such that `D/0 = D0` and `D/1 = D1`. +* `Foreach(D, f)` — Executes a function `f` with two arguments `k` and + `x`, with `(k, x)` running over all key-value pairs of a dictionary `D` in + lexicographical order.18 +* `ForeachRev(D, f)` — Similar to `Foreach`, but processes all keyvalue pairs in reverse order. +* `TreeReduce(D, o, f, g)` — Given `D : HashmapE(n, X)`, a value `o : X`, + and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree + reduction” of `D` by first applying `f` to all the leaves, and then using `g` + to compute the value corresponding to a fork starting from the values + assigned to its children.19 + +--- + +### 3.3.11. Taxonomy of dictionary primitives. + +The dictionary primitives, +described in detail in A.10, can be classified according to the following categories: + +* Which dictionary operation (cf. 3.3.10) do they perform? +* Are they specialized for the case `X = ^Y`? If so, do they represent values of type `Y` by `Cells` or by `Slices`? (Generic versions always represent + values of type `X` as `Slices`.) +* Are the dictionaries themselves passed and returned as `Cells` or as + `Slices`? (Most primitives represent dictionaries as `Slices`.) +* Is the key length `n` fixed inside the primitive, or is it passed in the + stack? +* Are the keys represented by `Slices`, or by signed or unsigned `Integer`s? + +In addition, TVM includes special serialization/deserialization primitives, +such as `STDICT`, `LDDICT`, and `PLDDICT`. They can be used to extract a dictionary from a serialization of an encompassing object, or to insert a dictionary +into such a serialization. + +--- + +Great — here’s **3.4 Hashmaps with variable-length keys** in Markdown, text unchanged and with inline code backticked where needed: + +--- + +### 3.4 Hashmaps with variable-length keys + +TVM provides some support for dictionaries, or hashmaps, with variablelength keys, in addition to its support for dictionaries with fixed-length keys +(as described in 3.3 above). + +#### 3.4.1. Serialization of dictionaries with variable-length keys. + +The +serialization of a `VarHashmap` into a tree of cells (or, more generally, into a +`Slice`) is defined by a TL-B scheme, similar to that described in 3.3.3: + +``` +vhm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) +{n = (~m) + l} node:(VarHashmapNode m X) += VarHashmap n X; + +vhmn_leaf$00 {n:#} {X:Type} value:X = VarHashmapNode n X; + +vhmn_fork$01 {n:#} {X:Type} left:^(VarHashmap n X) +right:^(VarHashmap n X) value:(Maybe X) += VarHashmapNode (n + 1) X; + +vhmn_cont$1 {n:#} {X:Type} branch:bit child:^(VarHashmap n X) +value:X = VarHashmapNode (n + 1) X; + +nothing$0 {X:Type} = Maybe X; + +just$1 {X:Type} value:X = Maybe X; + +vhme_empty$0 {n:#} {X:Type} = VarHashmapE n X; + +vhme_root$1 {n:#} {X:Type} root:^(VarHashmap n X) += VarHashmapE n X; +``` + +# 4 Control flow, continuations, and exceptions + +This chapter describes continuations, which may represent execution tokens +and exception handlers in TVM. Continuations are deeply involved with the +control flow of a TVM program; in particular, subroutine calls and conditional and iterated execution are implemented in TVM using special primitives that accept one or more continuations as their arguments. +We conclude this chapter with a discussion of the problem of recursion +and of families of mutually recursive functions, exacerbated by the fact that +cyclic references are not allowed in TVM data structures (including TVM +code). + +## 4.1 Continuations and subroutines + +Recall (cf.1.1.3) that `Continuation` values represent “execution tokens” that +can be executed later—for example, by `EXECUTE=CALLX` (“execute” or “call +indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations +are responsible for the execution of the program, and are heavily used by +control flow primitives, enabling subroutine calls, conditional expressions, +loops, and so on. + +### 4.1.1. Ordinary continuations. + +The most common kind of continuations +are the ordinary continuations, containing the following data: +• A `Slice` code (cf. 1.1.3 and 3.2.2), containing (the remainder of) the +TVM code to be executed. +• A (possibly empty) `Stack` stack, containing the original contents of +the stack for the code to be executed. +• A (possibly empty) list `save` of pairs (`c(i)`, `vi`) (also called “savelist”), +containing the values of control registers to be restored before the execution of the code. +• A 16-bit integer value `cp`, selecting the TVM codepage used to interpret +the TVM code from code. +• An optional non-negative integer `nargs`, indicating the number of arguments expected by the continuation. + +### 4.1.2. Simple ordinary continuations. + +In most cases, the ordinary continuations are the simplest ones, having empty stack and `save`. They consist +essentially of a reference `code` to (the remainder of) the code to be executed, +and of the codepage `cp` to be used while decoding the instructions from this +code. + +### 4.1.3. Current continuation `cc`. + +The “current continuation” `cc` is an important part of the total state of TVM, representing the code being executed +right now (cf. 1.1). In particular, what we call “the current stack” (or simply +“the stack”) when discussing all other primitives is in fact the stack of the +current continuation. All other components of the total state of TVM may +be also thought of as parts of the current continuation `cc`; however, they +may be extracted from the current continuation and kept separately as part +of the total state for performance reasons. This is why we describe the stack, +the control registers, and the codepage as separate parts of the TVM state +in 1.4. + +### 4.1.4. Normal work of TVM, or the main loop. + +TVM usually performs +the following operations: +If the current continuation `cc` is an ordinary one, it decodes the first +instruction from the `Slice` `code`, similarly to the way other cells are deserialized by TVM `LD*` primitives (cf. 3.2 and 3.2.11): it decodes the opcode +first, and then the parameters of the instruction (e.g., 4-bit fields indicating +“stack registers” involved for stack manipulation primitives, or constant values for “push constant” or “literal” primitives). The remainder of the `Slice` +is then put into the `code` of the new `cc`, and the decoded operation is executed on the current stack. This entire process is repeated until there are no +operations left in `cc.code`. +If the code is empty (i.e., contains no bits of data and no references), or if +a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, +the current continuation is discarded, and the “return continuation” from +control register `c0` is loaded into `cc` instead (this process is discussed in +more detail starting in 4.1.6).20 Then the execution continues by parsing +operations from the new current continuation. + +### 4.1.5. Extraordinary continuations. + +In addition to the ordinary continuations considered so far (cf. 4.1.1), TVM includes some extraordinary continuations, representing certain less common states. Examples of extraordinary +continuations include: +• The continuation `ec_quit` with its parameter set to zero, which represents the end of the work of TVM. This continuation is the original +value of `c0` when TVM begins executing the code of a smart contract. +• The continuation `ec_until`, which contains references to two other +continuations (ordinary or not) representing the body of the loop being +executed and the code to be executed after the loop. +Execution of an extraordinary continuation by TVM depends on its specific +class, and differs from the operations for ordinary continuations described in +4.1.4. +21 + +### 4.1.6. Switching to another continuation: `JMP` and `RET`. + +The process of +switching to another continuation `c` may be performed by such instructions +as `JMPX` (which takes `c` from the stack) or `RET` (which uses `c0` as `c`). This +process is slightly more complex than simply setting the value of `cc` to `c`: +before doing this, either all values or the top `n` values in the current stack +are moved to the stack of the continuation `c`, and only then is the remainder +of the current stack discarded. +If all values need to be moved (the most common case), and if the continuation `c` has an empty stack (also the most common case; notice that +extraordinary continuations are assumed to have an empty stack), then the +new stack of `c` equals the stack of the current continuation, so we can simply +transfer the current stack in its entirety to `c`. (If we keep the current stack +as a separate part of the total state of TVM, we have to do nothing at all.) + +### 4.1.7. Determining the number `n` of arguments passed to the next continuation `c`. + +By default, `n` equals the depth of the current stack. However, if `c` has an explicit value of `nargs` (number of arguments to be provided), +then `n` is computed as `n0`, equal to `c.nargs` minus the current depth of `c`’s +stack. +Furthermore, there are special forms of `JMPX` and `RET` that provide an +explicit value `n00`, the number of parameters from the current stack to be +passed to continuation `c`. If `n00` is provided, it must be less than or equal to +the depth of the current stack, or else a stack underflow exception occurs. If +both `n0` and `n00` are provided, we must have `n0 ≤ n00`, in which case `n = n0` is +used. If `n00` is provided and `n0` +is not, then `n = n00` is used. +One could also imagine that the default value of `n00` equals the depth of +the original stack, and that `n00` values are always removed from the top of +the original stack even if only `n0` of them are actually moved to the stack of +the next continuation `c`. Even though the remainder of the current stack is +discarded afterwards, this description will become useful later. + +### 4.1.8. Restoring control registers from the new continuation `c`. + +After +the new stack is computed, the values of control registers present in `c.save` +are restored accordingly, and the current codepage `cp` is also set to `c.cp`. +Only then does TVM set `cc` equal to the new `c` and begin its execution.22 + +### 4.1.9. Subroutine calls: `CALLX` or `EXECUTE` primitives. + +The execution +of continuations as subroutines is slightly more complicated than switching +to continuations. +Consider the `CALLX` or `EXECUTE` primitive, which takes a continuation `c` +from the (current) stack and executes it as a subroutine. +Apart from doing the stack manipulations described in 4.1.6 and 4.1.7 +and setting the new control registers and codepage as described in 4.1.8, +these primitives perform several additional steps: + +1. After the top `n00` values are removed from the current stack (cf. 4.1.7), + the (usually empty) remainder is not discarded, but instead is stored + in the (old) current continuation `cc`. +2. The old value of the special register `c0` is saved into the (previously + empty) savelist `cc.save`. +3. The continuation `cc` thus modified is not discarded, but instead is set + as the new `c0`, which performs the role of “next continuation” or “return + continuation” for the subroutine being called. +4. After that, the switching to `c` continues as before. In particular, some + control registers are restored from `c.save`, potentially overwriting the + value of `c0` set in the previous step. (Therefore, a good optimization + would be to check that `c0` is present in `c.save` from the very beginning, + and skip the three previous steps as useless in this case.) + In this way, the called subroutine can return control to the caller by + switching the current continuation to the return continuation saved in `c0`. + Nested subroutine calls work correctly because the previous value of `c0` ends + up saved into the new `c0`’s control register savelist `c0.save`, from which it is + restored later. + +### 4.1.10. Determining the number of arguments passed to and/or return values accepted from a subroutine. + +Similarly to `JMPX` and `RET`, +`CALLX` also has special (rarely used) forms, which allow us to explicitly specify +the number `n00` of arguments passed from the current stack to the called +subroutine (by default, `n00` equals the depth of the current stack, i.e., it is +passed in its entirety). Furthermore, a second number `n000` can be specified, +used to set `nargs` of the modified `cc` continuation before storing it into the +new `c0`; the new `nargs` equals the depth of the old stack minus `n00` plus `n000`. +This means that the caller is willing to pass exactly `n00` arguments to the +called subroutine, and is willing to accept exactly `n000` results in their stead. +Such forms of `CALLX` and `RET` are mostly intended for library functions +that accept functional arguments and want to invoke them safely. Another +application is related to the “virtualization support” of TVM, which enables +TVM code to run other TVM code inside a “virtual TVM machine”. Such +virtualization techniques might be useful for implementing sophisticated payment channels in the TON Blockchain (cf. \[1, 5]). + +### 4.1.11. `CALLCC`: call with current continuation. + +Notice that TVM supports a form of the “call with current continuation” primitive. Namely, primitive `CALLCC` is similar to `CALLX` or `JMPX` in that it takes a continuation `c` from +the stack and switches to it; however, `CALLCC` does not discard the previous +current continuation `c0` +(as `JMPX` does) and does not write `c0` +to `c0` (as `CALLX` +does), but rather pushes `c0` +into the (new) stack as an extra argument to `c`. +The primitive `JMPXDATA` does a similar thing, but pushes only the (remainder +of the) code of the previous current continuation as a `Slice`. + +## 4.2 Control flow primitives: conditional and iterated + +execution + +### 4.2.1. Conditional execution: `IF`, `IFNOT`, `IFELSE`. + +An important modification of `EXECUTE` (or `CALLX`) consists in its conditional forms. For example, +`IF` accepts an integer `x` and a continuation `c`, and executes `c` (in the same +way as `EXECUTE` would do it) only if `x` is non-zero; otherwise both values +are simply discarded from the stack. Similarly, `IFNOT` accepts `x` and `c`, but +executes `c` only if `x = 0`. Finally, `IFELSE` accepts `x`, `c`, and `c0`, removes these +values from the stack, and executes `c` if `x 6= 0` or `c0` if `x = 0`. + +### 4.2.2. Iterated execution and loops. + +More sophisticated modifications +of `EXECUTE` include: +• `REPEAT` — Takes an integer `n` and a continuation `c`, and executes `c` `n` +times.23 +• `WHILE` — Takes `c0` and `c00`, executes `c0`, and then takes the top value `x` +from the stack. If `x` is non-zero, it executes `c00` and then begins a new +loop by executing `c0` again; if `x` is zero, it stops. +• `UNTIL` — Takes `c`, executes it, and then takes the top integer `x` from +the stack. If `x` is zero, a new iteration begins; if `x` is non-zero, the +previously executed code is resumed. + +### 4.2.3. Constant, or literal, continuations. + +We see that we can create +arbitrarily complex conditional expressions and loops in the TVM code, provided we have a means to push constant continuations into the stack. In fact, +TVM includes special versions of “literal” or “constant” primitives that cut +the next `n` bytes or bits from the remainder of the current code `cc.code` into +a cell slice, and then push it into the stack not as a `Slice` (as a `PUSHSLICE` +does) but as a simple ordinary `Continuation` (which has only `code` and `cp`). +The simplest of these primitives is `PUSHCONT`, which has an immediate +argument `n` describing the number of subsequent bytes (in a byte-oriented +version of TVM) or bits to be converted into a simple continuation. Another +primitive is `PUSHREFCONT`, which removes the first cell reference from the +current continuation `cc.code`, converts the cell referred to into a cell slice, +and finally converts the cell slice into a simple continuation. + +### 4.2.4. Constant continuations combined with conditional or iterated execution primitives. + +Because constant continuations are very often +used as arguments to conditional or iterated execution primitives, combined +versions of these primitives (e.g., `IFCONT` or `UNTILREFCONT`) may be defined +in a future revision of TVM, which combine a `PUSHCONT` or `PUSHREFCONT` +with another primitive. If one inspects the resulting code, `IFCONT` looks very +much like the more customary “conditional-branch-forward” instruction. + +## 4.3 Operations with continuations + +### 4.3.1. Continuations are opaque. + +Notice that all continuations are opaque, +at least in the current version of TVM, meaning that there is no way to +modify a continuation or inspect its internal data. Almost the only use of a +continuation is to supply it to a control flow primitive. +While there are some arguments in favor of including support for nonopaque continuations in TVM (along with opaque continuations, which are +required for virtualization), the current revision offers no such support. + +### 4.3.2. Allowed operations with continuations. + +However, some operations with opaque continuations are still possible, mostly because they are +equivalent to operations of the kind “create a new continuation, which will +do something special, and then invoke the original continuation”. Allowed +operations with continuations include: +• Push one or several values into the stack of a continuation `c` (thus +creating a partial application of a function, or a closure). +• Set the saved value of a control register `c(i)` inside the savelist `c.save` +of a continuation `c`. If there is already a value for the control register +in question, this operation silently does nothing. + +### 4.3.3. Example: operations with control registers. + +TVM has some +primitives to set and inspect the values of control registers. The most important of them are `PUSH c(i)` (pushes the current value of `c(i)` into the stack) +and `POP c(i)` (sets the value of `c(i)` from the stack, if the supplied value is +of the correct type). However, there is also a modified version of the latter +instruction, called `POPSAVE c(i)`, which saves the old value of `c(i)` (for `i > 0`) +into the continuation at `c0` as described in 4.3.2 before setting the new value. + +### 4.3.4. Example: setting the number of arguments to a function in its code. + +The primitive `LEAVEARGS n` demonstrates another application of +continuations in an operation: it leaves only the top `n` values of the current stack, and moves the remainder to the stack of the continuation in `c0`. +This primitive enables a called function to “return” unneeded arguments to +its caller’s stack, which is useful in some situations (e.g., those related to +exception handling). + +### 4.3.5. Boolean circuits. + +A continuation `c` may be thought of as a piece +of code with two optional exit points kept in the savelist of `c`: the principal +exit point given by `c.c0 := c.save(c0)`, and the auxiliary exit point given +by `c.c1 := c.save(c1)`. If executed, a continuation performs whatever action +it was created for, and then (usually) transfers control to the principal exit +point, or, on some occasions, to the auxiliary exit point. We sometimes say +that a continuation `c` with both exit points `c.c0` and `c.c1` defined is a two-exit +continuation, or a boolean circuit, especially if the choice of the exit point +depends on some internally-checked condition. + +### 4.3.6. Composition of continuations. + +One can compose two continuations `c` and `c0` simply by setting `c.c0` or `c.c1` to `c0`. This creates a new +continuation denoted by `c ◦0 c0` or `c ◦1 c0`, which differs from `c` in its savelist. +(Recall that if the savelist of `c` already has an entry corresponding to the control register in question, such an operation silently does nothing as explained +in 4.3.2). +By composing continuations, one can build chains or other graphs, possibly with loops, representing the control flow. In fact, the resulting graph +resembles a flow chart, with the boolean circuits corresponding to the “condition nodes” (containing code that will transfer control either to `c0` or to `c1` +depending on some condition), and the one-exit continuations corresponding +to the “action nodes”. + +### 4.3.7. Basic continuation composition primitives. + +Two basic primitives for composing continuations are `COMPOS` (also known as `SETCONT c0` and +`BOOLAND`) and `COMPOSALT` (also known as `SETCONT c1` and `BOOLOR`), which +take `c` and `c0` from the stack, set `c.c0` or `c.c1` to `c0`, and return the resulting continuation `c00 = c ◦0 c0` or `c ◦1 c0`. All other continuation composition +operations can be expressed in terms of these two primitives. + +--- + +### 4.3.8. Advanced continuation composition primitives. + +However, TVM can compose continuations not only taken from stack, but also taken from `c0` or `c1`, or from the current continuation `cc`; likewise, the result may be pushed into the stack, stored into either `c0` or `c1`, or used as the new current continuation (i.e., the control may be transferred to it). Furthermore, TVM can define conditional composition primitives, performing some of the above actions only if an integer value taken from the stack is non-zero. + +For instance, `EXECUTE` can be described as `cc ← c ◦0 cc`, with continuation `c` taken from the original stack. Similarly, `JMPX` is `cc ← c`, and `RET` (also known as `RETTRUE` in a boolean circuit context) is `cc ← c0`. Other interesting primitives include `THENRET` (`c0 ← c ◦0 c0`) and `ATEXIT` (`c0 ← c ◦0 c0`). + +Finally, some “experimental” primitives also involve `c1` and `◦1`. For example: + +* `RETALT` or `RETFALSE` does `cc ← c1`. +* Conditional versions of `RET` and `RETALT` may also be useful: `RETBOOL` takes an integer `x` from the stack, and performs `RETTRUE` if `x 6= 0`, `RETFALSE` otherwise. +* `INVERT` does `c0 ↔ c1`; if the two continuations in `c0` and `c1` represent the two branches we should select depending on some boolean expression, `INVERT` negates this expression on the outer level. +* `INVERTCONT` does `c.c0 ↔ c.c1` to a continuation `c` taken from the stack. +* Variants of `ATEXIT` include `ATEXITALT` (`c1 ← c ◦1 c1`) and `SETEXITALT` (`c1 ← (c ◦0 c0) ◦1 c1`). +* `BOOLEVAL` takes a continuation `c` from the stack and does: + + ``` + cc ← ((c ◦0 (PUSH − 1)) ◦1 (PUSH0)) ◦0 cc + ``` + + If `c` represents a boolean circuit, the net effect is to evaluate it and push either `−1` or `0` into the stack before continuing. + +--- + +## 4.4 Continuations as objects + +### 4.4.1. Representing objects using continuations. + +Object-oriented programming in Smalltalk (or Objective C) style may be implemented with the +aid of continuations. For this, an object is represented by a special continuation `o`. If it has any data fields, they can be kept in the stack of `o`, making +`o` a partial application (i.e., a continuation with a non-empty stack). +When somebody wants to invoke a method `m` of `o` with arguments `x1, x2, +. . . , xn`, she pushes the arguments into the stack, then pushes a magic number +corresponding to the method `m`, and then executes `o` passing `n+1` arguments +(cf. 4.1.10). Then `o` uses the top-of-stack integer `m` to select the branch with +5 + +### 4.5. Exception handling + +the required method, and executes it. If `o` needs to modify its state, it simply +computes a new continuation `o0` of the same sort (perhaps with the same code +as `o`, but with a different initial stack). The new continuation `o0` +is returned +to the caller along with whatever other return values need to be returned. + +### 4.4.2. Serializable objects. + +Another way of representing Smalltalk-style +objects as continuations, or even as trees of cells, consists in using the +`JMPREFDATA` primitive (a variant of `JMPXDATA`, cf. 4.1.11), which takes the +first cell reference from the code of the current continuation, transforms the +cell referred to into a simple ordinary continuation, and transfers control to +it, first pushing the remainder of the current continuation as a `Slice` into the +stack. In this way, an object might be represented by a cell `o˜` that contains +`JMPREFDATA` at the beginning of its data, and the actual code of the object +in the first reference (one might say that the first reference of cell `o˜` is the +class of object `o˜`). Remaining data and references of this cell will be used for +storing the fields of the object. +Such objects have the advantage of being trees of cells, and not just +continuations, meaning that they can be stored into the persistent storage of +a TON smart contract. + +### 4.4.3. Unique continuations and capabilities. + +It might make sense (in +a future revision of TVM) to mark some continuations as unique, meaning +that they cannot be copied, even in a delayed manner, by increasing their +reference counter to a value greater than one. If an opaque continuation is +unique, it essentially becomes a capability, which can either be used by its +owner exactly once or be transferred to somebody else. +For example, imagine a continuation that represents the output stream to +a printer (this is an example of a continuation used as an object, cf. 4.4.1). +When invoked with one integer argument `n`, this continuation outputs the +character with code `n` to the printer, and returns a new continuation of +the same kind reflecting the new state of the stream. Obviously, copying +such a continuation and using the two copies in parallel would lead to some +unintended side effects; marking it as unique would prohibit such adverse +usage. + +## 4.5 Exception handling + +TVM’s exception handling is quite simple and consists in a transfer of control +to the continuation kept in control register `c2`. + +### 4.5.1. Two arguments of the exception handler: exception parameter and exception number. + +Every exception is characterized by two +arguments: the exception number (an `Integer`) and the exception parameter +(any value, most often a zero `Integer`). Exception numbers 0–31 are reserved +for TVM, while all other exception numbers are available for user-defined +exceptions. + +### 4.5.2. Primitives for throwing an exception. + +There are several special primitives used for throwing an exception. The most general of them, +`THROWANY`, takes two arguments, `v` and `0 ≤ n < 2^16`, from the stack, and +throws the exception with number `n` and value `v`. There are variants of +this primitive that assume `v` to be a zero integer, store `n` as a literal value, +and/or are conditional on an integer value taken from the stack. User-defined +exceptions may use arbitrary values as `v` (e.g., trees of cells) if needed. + +### 4.5.3. Exceptions generated by TVM. + +Of course, some exceptions are +generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit +into a signed 257-bit integer. In such cases, the arguments of the exception, +`v` and `n`, are determined by TVM itself. + +### 4.5.4. Exception handling. + +The exception handling itself consists in a +control transfer to the exception handler—i.e., the continuation specified in +control register `c2`, with `v` and `n` supplied as the two arguments to this +continuation, as if a `JMP` to `c2` had been requested with `n00 = 2` arguments +(cf. 4.1.7 and 4.1.6). As a consequence, `v` and `n` end up in the top of the +stack of the exception handler. The remainder of the old stack is discarded. +Notice that if the continuation in `c2` has a value for `c2` in its savelist, it +will be used to set up the new value of `c2` before executing the exception +handler. In particular, if the exception handler invokes `THROWANY`, it will rethrow the original exception with the restored value of `c2`. This trick enables +the exception handler to handle only some exceptions, and pass the rest to +an outer exception handler. + +### 4.5.5. Default exception handler. + +When an instance of TVM is created, +`c2` contains a reference to the “default exception handler continuation”, which +is an `ec_fatal` extraordinary continuation (cf. 4.1.5). Its execution leads +to the termination of the execution of TVM, with the arguments `v` and `n` +of the exception returned to the outside caller. In the context of the TON +Blockchain, `n` will be stored as a part of the transaction’s result. +59 + +### 4.5.6. `TRY` primitive. + +A `TRY` primitive can be used to implement C++-like +exception handling. This primitive accepts two continuations, `c` and `c0`. It +stores the old value of `c2` into the savelist of `c0`, sets `c2` to `c0`, and executes `c` +just as `EXECUTE` would, but additionally saving the old value of `c2` into the +savelist of the new `c0` as well. Usually a version of the `TRY` primitive with an +explicit number of arguments `n00` passed to the continuation `c` is used. +The net result is roughly equivalent to C++’s `try { c } catch(...) { c0 }` operator. + +### 4.5.7. List of predefined exceptions + +Predefined exceptions of TVM correspond to exception numbers `n` in the range `0–31`. They include: + +* **Normal termination (`n = 0`)** — Should never be generated, but it is useful for some tricks. +* **Alternative termination (`n = 1`)** — Again, should never be generated. +* **Stack underflow (`n = 2`)** — Not enough arguments in the stack for a primitive. +* **Stack overflow (`n = 3`)** — More values have been stored on a stack than allowed by this version of TVM. +* **Integer overflow (`n = 4`)** — Integer does not fit into `−2^256 ≤ x < 2^256`, or a division by zero has occurred. +* **Range check error (`n = 5`)** — Integer out of expected range. +* **Invalid opcode (`n = 6`)** — Instruction or its immediate arguments cannot be decoded. +* **Type check error (`n = 7`)** — An argument to a primitive is of incorrect value type. +* **Cell overflow (`n = 8`)** — Error in one of the serialization primitives. +* **Cell underflow (`n = 9`)** — Deserialization error. +* **Dictionary error (`n = 10`)** — Error while deserializing a dictionary object. +* **Unknown error (`n = 11`)** — Unknown error, may be thrown by user programs. +* **Fatal error (`n = 12`)** — Thrown by TVM in situations deemed impossible. +* **Out of gas (`n = 13`)** — Thrown by TVM when the remaining gas (`gr`) becomes negative. This exception usually cannot be caught and leads to an immediate termination of TVM. + +Most of these exceptions have no parameter (i.e., use a zero integer instead). +The order in which these exceptions are checked is outlined below in **4.5.8**. + +--- + +### 4.5.8. Order of stack underflow, type check, and range check exceptions. + +All TVM primitives first check whether the stack contains the +required number of arguments, generating a stack underflow exception if this +is not the case. Only then are the type tags of the arguments and their ranges +(e.g., if a primitive expects an argument not only to be an `Integer`, but also +to be in the range from 0 to 256) checked, starting from the value in the top +of the stack (the last argument) and proceeding deeper into the stack. If an +argument’s type is incorrect, a type-checking exception is generated; if the +type is correct, but the value does not fall into the expected range, a range +check exception is generated. +Some primitives accept a variable number of arguments, depending on the +values of some small fixed subset of arguments located near the top of the +stack. In this case, the above procedure is first run for all arguments from +this small subset. Then it is repeated for the remaining arguments, once +their number and types have been determined from the arguments already +processed. + + +--- + +# 4.6 Functions, recursion, and dictionaries + +### 4.6.1. The problem of recursion. + +The conditional and iterated execution primitives described in 4.2—along with the unconditional branch, call, and return primitives described in 4.1— enable one to implement more or less arbitrary code with nested loops and conditional expressions, with one notable exception: one can only create new constant continuations from parts of the current continuation. (In particular, one cannot invoke a subroutine from itself in this way.) Therefore, the code being executed—i.e., the current continuation—gradually becomes smaller and smaller. + +### 4.6.2. Y -combinator solution: pass a continuation as an argument to itself. + +One way of dealing with the problem of recursion is by passing a copy of the continuation representing the body of a recursive function as an extra argument to itself. Consider, for example, the following code for a factorial function: + +``` +71 PUSHINT 1 +9C PUSHCONT { +22 PUSH s2 +72 PUSHINT 2 +B9 LESS +DC IFRET +59 ROTREV +21 PUSH s1 +A8 MUL +01 SWAP +A5 DEC +02 XCHG s2 +20 DUP +D9 JMPX +} +20 DUP +D8 EXECUTE +30 DROP +31 NIP +``` + +This roughly corresponds to defining an auxiliary function body with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, n·x, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. + +### 4.6.3. A variant of Y -combinator solution. + +Another way of recursively computing the factorial, more closely following the classical recursive definition + +``` +fact(n) := ( +1 if n < 2, +n · fact(n − 1) otherwise +) +``` + +is as follows: + +``` +9D PUSHCONT { +21 OVER +C102 LESSINT 2 +92 PUSHCONT { +5B 2DROP +71 PUSHINT 1 +} +E0 IFJMP +21 OVER +A5 DEC +01 SWAP +20 DUP +D8 EXECUTE +A8 MUL +} +20 DUP +D9 JMPX +``` + +This definition of the factorial function is two bytes shorter than the previous one, but it uses general recursion instead of tail recursion, so it cannot be easily transformed into a loop. + +### 4.6.4. Comparison: non-recursive definition of the factorial function. + +Incidentally, a non-recursive definition of the factorial with the aid of a `REPEAT` loop is also possible, and it is much shorter than both recursive definitions: + +``` +71 PUSHINT 1 +01 SWAP +20 DUP +94 PUSHCONT { +66 TUCK +A8 MUL +01 SWAP +A5 DEC +} +E4 REPEAT +30 DROP +``` + +### 4.6.5. Several mutually recursive functions. + +If one has a collection `f1, . . . , fn` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fi}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. + +### 4.6.6. Combining several functions into one tuple. + +One might also combine a collection of continuations representing functions `f1, . . . , fn` into a “tuple” `f := (f1, . . . , fn)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fi`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. + +### 4.6.7. Combining several functions into a selector function. + +Another approach is to combine several functions `f1, . . . , fn` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fi` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. + +### 4.6.8. Using a dedicated register to keep the selector function. + +However, even if we use one of the two previous approaches to combine all functions into one extra argument, passing this argument to all mutually recursive functions is still quite cumbersome and requires a lot of additional stack manipulation operations. Because this argument changes very rarely, one might use a dedicated register to keep it and transparently pass it to all functions called. This is the approach used by TVM by default. + +### 4.6.9. Special register c3 for the selector function. + +In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. A.8.7) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. + +In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). + +### 4.6.10. Initialization of c3. + +A TVM program might initialize `c3` by means of a `POP c3` instruction. However, because this usually is the very first action undertaken by a program (e.g., a smart contract), TVM makes some provisions for the automatic initialization of `c3`. Namely, `c3` is initialized by the code (the initial value of `cc`) of the program itself, and an extra zero (or, in some cases, some other predefined number `s`) is pushed into the stack before the program’s execution. This is approximately equivalent to invoking `JMPDICT 0` (or `JMPDICT s`) at the very beginning of a program—i.e., the function with index zero is effectively the `main()` function for the program. + +### 4.6.11. Creating selector functions and switch statements. + +TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. A.8.2). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. + +Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. A.7.2). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. + +### 4.6.12. Alternative: using a hashmap to select the correct function. + +Yet another alternative is to use a `Hashmap` (cf. 3.3) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. A.10) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. A.8.5) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. A.10.11). This approach may be more efficient for larger programs and switch statements. + + +Got it ✅ — here’s **Chapter 5: Codepages and instruction encoding** converted cleanly into Markdown. +I kept the **text exactly as-is** (no paraphrasing), just formatted with proper Markdown: headings, subheadings, inline backticks for mnemonics/opcodes, and bullet lists where appropriate. + +--- + +# 5 Codepages and instruction encoding + +This chapter describes the codepage mechanism, which allows TVM to be +flexible and extendable while preserving backward compatibility with respect +to previously generated code. +We also discuss some general considerations about instruction encodings +(applicable to arbitrary machine code, not just TVM), as well as the implications of these considerations for TVM and the choices made while designing +TVM’s (experimental) codepage zero. The instruction encodings themselves +are presented later in Appendix A. + +## 5.1 Codepages and interoperability of different TVM versions + +The codepages are an essential mechanism of backward compatibility and +of future extensions to TVM. They enable transparent execution of code +written for different revisions of TVM, with transparent interaction between +instances of such code. The mechanism of the codepages, however, is general +and powerful enough to enable some other originally unintended applications. + +### 5.1.1. Codepages in continuations + +Every ordinary continuation contains +a 16-bit codepage field `cp` (cf. 4.1.1), which determines the codepage that +will be used to execute its code. If a continuation is created by a `PUSHCONT` +(cf. 4.2.3) or similar primitive, it usually inherits the current codepage (i.e., +the codepage of `cc`).25 + +### 5.1.2. Current codepage + +The current codepage `cp` (cf. 1.4) is the codepage of the current continuation `cc`. It determines the way the next instruction will be decoded from `cc.code`, the remainder of the current continuation’s code. Once the instruction has been decoded and executed, it +determines the next value of the current codepage. In most cases, the current codepage is left unchanged. + +On the other hand, all primitives that switch the current continuation +load the new value of `cp` from the new current continuation. In this way, all +code in continuations is always interpreted exactly as it was intended to be. + +--- + +### 5.1.3. Different versions of TVM may use different codepages + +Different versions of TVM may use different codepages for their code. For +example, the original version of TVM might use codepage zero. A newer +version might use codepage one, which contains all the previously defined +opcodes, along with some newly defined ones, using some of the previously +unused opcode space. A subsequent version might use yet another codepage, +and so on. + +However, a newer version of TVM will execute old code for codepage zero +exactly as before. If the old code contained an opcode used for some new +operations that were undefined in the original version of TVM, it will still +generate an invalid opcode exception, because the new operations are absent +in codepage zero. + +--- + +### 5.1.4. Changing the behavior of old operations + +New codepages can +also change the effects of some operations present in the old codepages while +preserving their opcodes and mnemonics. + +For example, imagine a future 513-bit upgrade of TVM (replacing the +current 257-bit design). It might use a 513-bit Integer type within the same +arithmetic primitives as before. However, while the opcodes and instructions +in the new codepage would look exactly like the old ones, they would work +differently, accepting 513-bit integer arguments and results. On the other +hand, during the execution of the same code in codepage zero, the new +machine would generate exceptions whenever the integers used in arithmetic +and other primitives do not fit into 257 bits.26 In this way, the upgrade would +not change the behavior of the old code. + +--- + +### 5.1.5. Improving instruction encoding + +Another application for codepages is to change instruction encodings, reflecting improved knowledge of +the actual frequencies of such instructions in the code base. In this case, +the new codepage will have exactly the same instructions as the old one, but +with different encodings, potentially of differing lengths. + +For example, one +might create an experimental version of the first version of TVM, using a +(prefix) bitcode instead of the original bytecode, aiming to achieve higher +code density. + +--- + +### 5.1.6. Making instruction encoding context-dependent + +Another way +of using codepages to improve code density is to use several codepages with +different subsets of the whole instruction set defined in each of them, or with +the whole instruction set defined, but with different length encodings for the +same instructions in different codepages. + +Imagine, for instance, a “stack manipulation” codepage, where stack manipulation primitives have short encodings at the expense of all other operations, and a “data processing” codepage, where all other operations are +shorter at the expense of stack manipulation operations. If stack manipulation operations tend to come one after another, we can automatically +switch to “stack manipulation” codepage after executing any such instruction. When a data processing instruction occurs, we switch back to “data +processing” codepage. + +If conditional probabilities of the class of the next instruction depending on the class of the previous instruction are considerably +different from corresponding unconditional probabilities, this technique— +automatically switching into stack manipulation mode to rearrange the stack +with shorter instructions, then switching back—might considerably improve +the code density. + +--- + +### 5.1.7. Using codepages for status and control flags + +Another potential +application of multiple codepages inside the same revision of TVM consists in +switching between several codepages depending on the result of the execution +of some instructions. + +For example, imagine a version of TVM that uses two new codepages, `2` +and `3`. Most operations do not change the current codepage. However, the +integer comparison operations will switch to codepage `2` if the condition is +false, and to codepage `3` if it is true. Furthermore, a new operation `?EXECUTE`, +similar to `EXECUTE`, will indeed be equivalent to `EXECUTE` in codepage `3`, but +will instead be a `DROP` in codepage `2`. Such a trick effectively uses bit 0 of +the current codepage as a status flag. + +Alternatively, one might create a couple of codepages—say, `4` and `5`— +which differ only in their cell deserialisation primitives. For instance, in +codepage `4` they might work as before, while in codepage `5` they might deserialize data not from the beginning of a Slice, but from its end. Two new +instructions—say, `CLD` and `STD`—might be used for switching to codepage `4` +or codepage `5`. Clearly, we have now described a status flag, affecting the +execution of some instructions in a certain new manner. + +--- + +### 5.1.8. Setting the codepage in the code itself + +For convenience, we +reserve some opcode in all codepages—say, `FF n`—for the instruction `SETCP n`, +with `n` from 0 to 255 (cf. A.13). Then by inserting such an instruction +into the very beginning of (the main function of) a program (e.g., a TON +Blockchain smart contract) or a library function, we can ensure that the code +will always be executed in the intended codepage. + +--- + +## 5.2 Instruction encoding + +This section discusses the general principles of instruction encoding valid for +all codepages and all versions of TVM. Later, 5.3 discusses the choices made +for the experimental “codepage zero”. + +### 5.2.1. Instructions are encoded by a binary prefix code + +All complete instructions (i.e., instructions along with all their parameters, such as +the names of stack registers `s(i)` or other embedded constants) of a TVM +codepage are encoded by a **binary prefix code**. This means that a (finite) +binary string (i.e., a bitstring) corresponds to each complete instruction, in +such a way that binary strings corresponding to different complete instructions do not coincide, and no binary string among the chosen subset is a +prefix of another binary string from this subset. + +--- + +### 5.2.2. Determining the first instruction from a code stream + +As a consequence of this encoding method, any binary string admits at most one +prefix, which is an encoding of some complete instruction. In particular, +the code `cc.code` of the current continuation (which is a Slice, and thus a +bitstring along with some cell references) admits at most one such prefix, +which corresponds to the (uniquely determined) instruction that TVM will +execute first. After execution, this prefix is removed from the code of the +current continuation, and the next instruction can be decoded. + +--- + +### 5.2.3. Invalid opcode + +If no prefix of `cc.code` encodes a valid instruction +in the current codepage, an invalid opcode exception is generated (cf. 4.5.7). + +However, the case of an empty `cc.code` is treated separately as explained +in 4.1.4 (the exact behavior may depend on the current codepage). + +--- + +### 5.2.4. Special case: end-of-code padding + +As an exception to the above +rule, some codepages may accept some values of `cc.code` that are too short +to be valid instruction encodings as additional variants of `NOP`, thus effectively +using the same procedure for them as for an empty `cc.code`. Such bitstrings +may be used for padding the code near its end. + +For example, if binary string `00000000` (i.e., `x00`, cf. 1.0.3) is used in a +codepage to encode `NOP`, its proper prefixes cannot encode any instructions. +So this codepage may accept `0`, `00`, `000`, …, `0000000` as variants of `NOP` if +this is all that is left in `cc.code`, instead of generating an invalid opcode +exception. + +Such a padding may be useful, for example, if the `PUSHCONT` primitive +(cf. 4.2.3) creates only continuations with code consisting of an integral +number of bytes, but not all instructions are encoded by an integral number +of bytes. + +--- + +### 5.2.5. TVM code is a bitcode, not a bytecode + +Recall that TVM is +a bit-oriented machine in the sense that its Cells (and Slices) are naturally +considered as sequences of bits, not just of octets (bytes), cf. 3.2.5. Because +the TVM code is also kept in cells (cf. 3.1.9 and 4.1.4), there is no reason +to use only bitstrings of length divisible by eight as encodings of complete +instructions. In other words, generally speaking, the TVM code is a **bitcode**, +not a **bytecode**. + +That said, some codepages (such as our experimental codepage zero) may +opt to use a bytecode (i.e., to use only encodings consisting of an integral +number of bytes)—either for simplicity, or for the ease of debugging and of +studying memory (i.e., cell) dumps.27 + +--- + +### 5.2.6. Opcode space used by a complete instruction + +Recall from coding theory that the lengths of bitstrings `li` used in a binary prefix code satisfy +Kraft–McMillan inequality: + +``` +Σ 2^(-li) ≤ 1 +``` + +This is applicable in particular to +the (complete) instruction encoding used by a TVM codepage. We say that +a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2^(-l)` of the opcode space, if it is encoded +by an `l`-bit string. One can see that all complete instructions together utilize +at most 1 (i.e., “at most the whole opcode space”). + +--- + +### 5.2.7. Opcode space used by an instruction, or a class of instructions + +The above terminology is extended to instructions (considered with +all admissible values of their parameters), or even classes of instructions (e.g., +all arithmetic instructions). We say that an (incomplete) instruction, or a +class of instructions, occupies portion `α` of the opcode space, if `α` is the sum +of the portions of the opcode space occupied by all complete instructions +belonging to that class. + +--- + +### 5.2.8. Opcode space for bytecodes + +A useful approximation of the above +definitions is as follows: + +Consider all 256 possible values for the first byte of +an instruction encoding. Suppose that `k` of these values correspond to the +specific instruction or class of instructions we are considering. Then this +instruction or class of instructions occupies approximately the portion `k/256` +of the opcode space. + +This approximation shows why all instructions cannot occupy together +more than the portion `256/256 = 1` of the opcode space, at least without +compromising the uniqueness of instruction decoding. + +--- + +### 5.2.9. Almost optimal encodings + +Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete +instruction (`2^(-l)`, if the complete instruction is encoded in `l` bits) should be +approximately equal to the probability or frequency of its occurrence in real +programs.28 The same should hold for (incomplete) instructions, or primitives +(i.e., generic instructions without specified values of parameters), and +for classes of instructions. + +--- + +### 5.2.10. Example: stack manipulation primitives + +For instance, if stack +manipulation instructions constitute approximately half of all instructions in +a typical TVM program, one should allocate approximately half of the opcode +space for encoding stack manipulation instructions. + +One might reserve the +first bytes (“opcodes”) `0x00–0x7f` for such instructions. If a quarter of these +instructions are `XCHG`, it would make sense to reserve `0x00–0x1f` for `XCHG`s. +Similarly, if half of all `XCHG`s involve the top of stack `s0`, it would make sense +to use `0x00–0x0f` to encode `XCHG s0,s(i)`. + +--- + +### 5.2.11. Simple encodings of instructions + +In most cases, simple encodings of complete instructions are used. Simple encodings begin with a fixed +bitstring called the opcode of the instruction, followed by, say, 4-bit fields +containing the indices `i` of stack registers `s(i)` specified in the instruction, followed by all other constant (literal, immediate) parameters included in the +complete instruction. + +While simple encodings may not be exactly optimal, +they admit short descriptions, and their decoding and encoding can be easily +implemented. + +If a (generic) instruction uses a simple encoding with an `l`-bit opcode, then +the instruction will utilize `2^(-l)` portion of the opcode space. This observation +might be useful for considerations described in 5.2.9 and 5.2.10. + +--- + +### 5.2.12. Optimizing code density further: Huffman codes + +One might +construct optimally dense binary code for the set of all complete instructions, +provided their probabilities or frequencies in real code are known. This is the +well-known **Huffman code** (for the given probability distribution). However, +such code would be highly unsystematic and hard to decode. + +--- + +### 5.2.13. Practical instruction encodings + +In practice, instruction encodings used in TVM and other virtual machines offer a compromise between +code density and ease of encoding and decoding. Such a compromise may +be achieved by selecting simple encodings (cf. 5.2.11) for all instructions +(maybe with separate simple encodings for some often used variants, such +as `XCHG s0,s(i)` among all `XCHG s(i),s(j)`), and allocating opcode space for +such simple encodings using the heuristics outlined in 5.2.9 and 5.2.10; this +is the approach currently used in TVM. + +--- + +## 5.3 Instruction encoding in codepage zero + +This section provides details about the experimental instruction encoding +for codepage zero, as described elsewhere in this document (cf. Appendix A) +and used in the preliminary test version of TVM. + +### 5.3.1. Upgradability + +First of all, even if this preliminary version somehow gets into the production version of the TON Blockchain, the codepage +mechanism (cf. 5.1) enables us to introduce better versions later without +compromising backward compatibility.29 So in the meantime, we are free to +experiment. + +--- + +### 5.3.2. Choice of instructions + +We opted to include many “experimental” +and not strictly necessary instructions in codepage zero just to see how they +might be used in real code. For example, we have both the basic (cf. 2.2.1) +and the compound (cf. 2.2.3) stack manipulation primitives, as well as some +“unsystematic” ones such as `ROT` (mostly borrowed from Forth). If such +primitives are rarely used, their inclusion just wastes some part of the opcode +space and makes the encodings of other instructions slightly less effective, +something we can afford at this stage of TVM’s development. + +--- + +### 5.3.3. Using experimental instructions + +Some of these experimental +instructions have been assigned quite long opcodes, just to fit more of them +into the opcode space. One should not be afraid to use them just because +they are long; if these instructions turn out to be useful, they will receive +shorter opcodes in future revisions. Codepage zero is not meant to be fine +tuned in this respect. + +--- + +### 5.3.4. Choice of bytecode. + +We opted to use a bytecode (i.e., to use encodings of complete instructions of lengths divisible by eight). While this may not produce optimal code density, because such a length restriction makes it more difficult to match portions of opcode space used for the encoding of instructions with estimated frequencies of these instructions in TVM code +(cf. 5.2.11 and 5.2.9), such an approach has its advantages: it admits a +simpler instruction decoder and simplifies debugging (cf. 5.2.5). + +After all, we do not have enough data on the relative frequencies of different instructions right now, so our code density optimizations are likely to +be very approximate at this stage. The ease of debugging and experimenting +and the simplicity of implementation are more important at this point. + +### 5.3.5. Simple encodings for all instructions. + +For similar reasons, we +opted to use simple encodings for all instructions (cf. 5.2.11 and 5.2.13), +with separate simple encodings for some very frequently used subcases as +outlined in 5.2.13. That said, we tried to distribute opcode space using the +heuristics described in 5.2.9 and 5.2.10. + +### 5.3.6. Lack of context-dependent encodings. + +This version of TVM also +does not use context-dependent encodings (cf. 5.1.6). They may be added +at a later stage, if deemed useful. + +### 5.3.7. The list of all instructions. + +The list of all instructions available in codepage zero, along with their encodings and (in some cases) short descriptions, may be found in Appendix A. + +--- + +# A Instructions and opcodes + +This appendix lists all instructions available in the (experimental) codepage +zero of TVM, as explained in 5.3. +We list the instructions in lexicographical opcode order. However, the +opcode space is distributed in such way as to make all instructions in each +category (e.g., arithmetic primitives) have neighboring opcodes. So we first +list a number of stack manipulation primitives, then constant primitives, +arithmetic primitives, comparison primitives, cell primitives, continuation +primitives, dictionary primitives, and finally application-specific primitives. +We use hexadecimal notation (cf. 1.0) for bitstrings. Stack registers `s(i)` +usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare +occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, +8-bit, or variable length. +The stack notation described in 2.1.10 is extensively used throughout +this appendix. + +## A.1 Gas prices + +The gas price for most primitives equals the basic gas price, computed as +`Pb := 10 + b + 5r`, where `b` is the instruction length in bits and `r` is the +number of cell references included in the instruction. When the gas price +of an instruction differs from this basic price, it is indicated in parentheses +after its mnemonics, either as `(x)`, meaning that the total gas price equals +`x`, or as `(+x)`, meaning `Pb + x`. Apart from integer constants, the following +expressions may appear: + +* `Cr` — The total price of “reading” cells (i.e., transforming cell references + into cell slices). Currently equal to 100 or 25 gas units per cell + depending on whether it is the first time a cell with this hash is being + “read” during the current run of the VM or not. +* `L` — The total price of loading cells. Depends on the loading action + required. +* `Bw` — The total price of creating new `Builder`s. Currently equal to 0 + gas units per builder. +* `Cw` — The total price of creating new `Cell`s from `Builder`s. Currently + equal to 500 gas units per cell. + +By default, the gas price of an instruction equals `P := Pb + Cr + L + Bw + Cw`. + +## A.2 Stack manipulation primitives + +This section includes both the basic (cf. 2.2.1) and the compound (cf. 2.2.3) +stack manipulation primitives, as well as some “unsystematic” ones. Some +compound stack manipulation primitives, such as `XCPU` or `XCHG2`, turn out +to have the same length as an equivalent sequence of simpler operations. We +have included these primitives regardless, so that they can easily be allocated +shorter opcodes in a future revision of TVM—or removed for good. +Some stack manipulation instructions have two mnemonics: one Forth- +style (e.g., `-ROT`), the other conforming to the usual rules for identifiers (e.g., +`ROTREV`). Whenever a stack manipulation primitive (e.g., `PICK`) accepts an +integer parameter `n` from the stack, it must be within the range `0 . . . 255`; +otherwise a range check exception happens before any further checks. + +### A.2.1. Basic stack manipulation primitives. + +* `00` — **NOP**, does nothing. +* `01` — **XCHG s1**, also known as **SWAP**. +* `0i` — **XCHG s(i)** or **XCHG s0,s(i)**, interchanges the top of the stack with `s(i)`, `1 ≤ i ≤ 15`. +* `10ij` — **XCHG s(i),s(j)**, `1 ≤ i < j ≤ 15`, interchanges `s(i)` with `s(j)`. +* `11ii` — **XCHG s0,s(ii)**, with `0 ≤ ii ≤ 255`. +* `1i` — **XCHG s1,s(i)**, `2 ≤ i ≤ 15`. +* `2i` — **PUSH s(i)**, `0 ≤ i ≤ 15`, pushes a copy of the old `s(i)` into the stack. +* `20` — **PUSH s0**, also known as **DUP**. +* `21` — **PUSH s1**, also known as **OVER**. +* `3i` — **POP s(i)**, `0 ≤ i ≤ 15`, pops the old top-of-stack value into the old `s(i)`. +* `30` — **POP s0**, also known as **DROP**, discards the top-of-stack value. +* `31` — **POP s1**, also known as **NIP**. + + +### A.2.2. Compound stack manipulation primitives. + +Parameters `i`, `j`, +and `k` of the following primitives all are 4-bit integers in the range `0 . . . 15`. +* `4ijk` — **XCHG3 s(i),s(j),s(k)**, equivalent to **XCHG s2,s(i); XCHG s1,s(j); XCHG s0,s(k)**, with `0 ≤ i, j, k ≤ 15`. +* `50ij` — **XCHG2 s(i),s(j)**, equivalent to **XCHG s1,s(i); XCHG s(j)**. +* `51ij` — **XCPU s(i),s(j)**, equivalent to **XCHG s(i); PUSH s(j)**. +* `52ij` — **PUXC s(i),s(j − 1)**, equivalent to **PUSH s(i); SWAP; XCHG s(j)**. +* `53ij` — **PUSH2 s(i),s(j)**, equivalent to **PUSH s(i); PUSH s(j + 1)**. +* `540ijk` — **XCHG3 s(i),s(j),s(k)** (long form). +* `541ijk` — **XC2PU s(i),s(j),s(k)**, equivalent to **XCHG2 s(i),s(j); PUSH s(k)**. +* `542ijk` — **XCPUXC s(i),s(j),s(k−1)**, equivalent to **XCHG s1,s(i); PUXC s(j),s(k − 1)**. +* `543ijk` — **XCPU2 s(i),s(j),s(k)**, equivalent to **XCHG s(i); PUSH2 s(j),s(k)**. +* `544ijk` — **PUXC2 s(i),s(j − 1),s(k − 1)**, equivalent to **PUSH s(i); XCHG s2; XCHG2 s(j),s(k)**. +* `545ijk` — **PUXCPU s(i),s(j−1),s(k−1)**, equivalent to **PUXC s(i),s(j− 1); PUSH s(k)**. +* `546ijk` — **PU2XC s(i),s(j−1),s(k−2)**, equivalent to **PUSH s(i); SWAP; PUXC s(j),s(k − 1)**. +* `547ijk` — **PUSH3 s(i),s(j),s(k)**, equivalent to **PUSH s(i); PUSH2 s(j + 1),s(k + 1)**. +* `54C_` — **unused**. + +### A.2.3. Exotic stack manipulation primitives. + +* `55ij` — **BLKSWAP i+1,j+1**, permutes two blocks `s(j + i + 1)…s(j + 1)` and `s(j)…s0`, for `0 ≤ i, j ≤ 15`. Equivalent to **REVERSE i+1,j+1; REVERSE j+1,0; REVERSE i+j+2,0**. +* `5513` — **ROT2** or **2ROT** (`a b c d e f – c d e f a b`), rotates the three topmost pairs of stack entries. +* `550i` — **ROLL i+1**, rotates the top `i+1` stack entries. Equivalent to **BLKSWAP 1,i+1**. +* `55i0` — **ROLLREV i+1** or **-ROLL i+1**, rotates the top `i+1` stack entries in the other direction. Equivalent to **BLKSWAP i+1,1**. +* `56ii` — **PUSH s(ii)** for `0 ≤ ii ≤ 255`. +* `57ii` — **POP s(ii)** for `0 ≤ ii ≤ 255`. +* `58` — **ROT** (`a b c – b c a`), equivalent to **BLKSWAP 1,2** or to **XCHG2 s2,s1**. +* `59` — **ROTREV** or **-ROT** (`a b c – c a b`), equivalent to **BLKSWAP 2,1** or to **XCHG2 s2,s2**. +* `5A` — **SWAP2** or **2SWAP** (`a b c d – c d a b`), equivalent to **BLKSWAP 2,2** or to **XCHG2 s3,s2**. +* `5B` — **DROP2** or **2DROP** (`a b –`), equivalent to **DROP; DROP**. +* `5C` — **DUP2** or **2DUP** (`a b – a b a b`), equivalent to **PUSH2 s1,s0**. +* `5D` — **OVER2** or **2OVER** (`a b c d – a b c d a b`), equivalent to **PUSH2 s3,s2**. +* `5Eij` — **REVERSE i+2,j**, reverses the order of `s(j+i+1)…s(j)` for `0 ≤ i, j ≤ 15`; equivalent to a sequence of `⌊i/2⌋+1` **XCHG**s. +* `5F0i` — **BLKDROP i**, equivalent to **DROP** performed `i` times. +* `5Fij` — **BLKPUSH i,j**, equivalent to **PUSH s(j)** performed `i` times, `1 ≤ i ≤ 15`, `0 ≤ j ≤ 15`. +* `60` — **PICK** or **PUSHX**, pops integer `i` from the stack, then performs **PUSH s(i)**. +* `61` — **ROLLX**, pops integer `i` from the stack, then performs **BLKSWAP 1,i**. +* `62` — **-ROLLX** or **ROLLREVX**, pops integer `i` from the stack, then performs **BLKSWAP i,1**. +* `63` — **BLKSWX**, pops integers `i,j` from the stack, then performs **BLKSWAP i,j**. +* `64` — **REVX**, pops integers `i,j` from the stack, then performs **REVERSE i,j**. +* `65` — **DROPX**, pops integer `i` from the stack, then performs **BLKDROP i**. +* `66` — **TUCK** (`a b – b a b`), equivalent to **SWAP; OVER** or to **XCPU s1,s1**. +* `67` — **XCHGX**, pops integer `i` from the stack, then performs **XCHG s(i)**. +* `68` — **DEPTH**, pushes the current depth of the stack. +* `69` — **CHKDEPTH**, pops integer `i` from the stack, then checks whether there are at least `i` elements, generating a stack underflow exception otherwise. +* `6A` — **ONLYTOPX**, pops integer `i` from the stack, then removes all but the top `i` elements. +* `6B` — **ONLYX**, pops integer `i` from the stack, then leaves only the bottom `i` elements. Approximately equivalent to **DEPTH; SWAP; SUB; DROPX**. +* `6C00–6C0F` — **reserved** for stack operations. +* `6Cij` — **BLKDROP2 i,j**, drops `i` stack elements under the top `j` elements, where `1 ≤ i ≤ 15` and `0 ≤ j ≤ 15`. Equivalent to **REVERSE i+j,0; BLKDROP i; REVERSE j,0**. + + +## A.3 Tuple, List, and Null primitives + +Tuples are ordered collections consisting of at most 255 TVM stack values of +arbitrary types (not necessarily the same). Tuple primitives create, modify, +and unpack Tuples; they manipulate values of arbitrary types in the process, +similarly to the stack primitives. We do not recommend using Tuples of more +than 15 elements. +When a Tuple `t` contains elements `x1, . . . , xn` (in that order), we write +`t = (x1, . . . , xn)`; number `n ≥ 0` is the length of Tuple `t`. It is also denoted +by `|t|`. Tuples of length two are called pairs, and Tuples of length three are +triples. +Lisp-style lists are represented with the aid of pairs, i.e., tuples consisting +of exactly two elements. An empty list is represented by a `Null` value, and +a non-empty list is represented by pair `(h, t)`, where `h` is the first element of +the list, and `t` is its tail. + +### A.3.1. Null primitives. + +The following primitives work with (the only) +value `⊥` of type `Null`, useful for representing empty lists, empty branches +of binary trees, and absence of values in `Maybe X` types. An empty Tuple +created by `NIL` could have been used for the same purpose; however, `Null` is +more efficient and costs less gas. + +* `6D` — `NULL` or `PUSHNULL` `( – ⊥)`, pushes the only value of type `Null`. +* `6E` — `ISNULL` `(x – ? )`, checks whether `x` is a `Null`, and returns `−1` or `0` + accordingly. + +### A.3.2. Tuple primitives. + +* `6F0n` — `TUPLE n` `(x1 . . . xn – t)`, creates a new Tuple `t = (x1, . . . , xn)` + containing `n` values `x1, . . . , xn`, where `0 ≤ n ≤ 15`. +* `6F00` — `NIL` `( – t)`, pushes the only Tuple `t = ()` of length zero. +* `6F01` — `SINGLE` `(x – t)`, creates a singleton `t := (x)`, i.e., a Tuple of + length one. +* `6F02` — `PAIR` or `CONS` `(x y – t)`, creates pair `t := (x, y)`. +* `6F03` — `TRIPLE` `(x y z – t)`, creates triple `t := (x, y, z)`. +* `6F1k` — `INDEX k` `(t – x)`, returns the `k`-th element of a Tuple `t`, where + `0 ≤ k ≤ 15`. In other words, returns `xk+1` if `t = (x1, . . . , xn)`. If `k ≥ n`, + throws a range check exception. +* `6F10` — `FIRST` or `CAR` `(t – x)`, returns the first element of a Tuple. +* `6F11` — `SECOND` or `CDR` `(t – y)`, returns the second element of a Tuple. +* `6F12` — `THIRD` `(t – z)`, returns the third element of a Tuple +* `6F2n` — `UNTUPLE n` `(t – x1 . . . xn)`, unpacks a Tuple `t = (x1, . . . , xn)` of + length equal to `0 ≤ n ≤ 15`. If `t` is not a Tuple, of if `|t| 6= n`, a type + check exception is thrown. +* `6F21` — `UNSINGLE` `(t – x)`, unpacks a singleton `t = (x)`. +* `6F22` — `UNPAIR` or `UNCONS` `(t – x y)`, unpacks a pair `t = (x, y)`. +* `6F23` — `UNTRIPLE` `(t – x y z)`, unpacks a triple `t = (x, y, z)`. +* `6F3k` — `UNPACKFIRST k` `(t – x1 . . . xk)`, unpacks first `0 ≤ k ≤ 15` + elements of a Tuple `t`. If `|t| < k`, throws a type check exception. +* `6F30` — `CHKTUPLE` `(t – )`, checks whether `t` is a Tuple. +* `6F4n` — `EXPLODE n` `(t – x1 . . . xm m)`, unpacks a Tuple `t = (x1, . . . , xm)` + and returns its length `m`, but only if `m ≤ n ≤ 15`. Otherwise throws a + type check exception. +* `6F5k` — `SETINDEX k` `(t x – t' )`, computes Tuple `t'` that differs from `t` + only at position `t'k+1`, which is set to `x`. In other words, `|t'| = |t|`, `t'i = ti` + for `i 6= k + 1`, and `t'k+1 = x`, for given `0 ≤ k ≤ 15`. If `k ≥ |t|`, throws a + range check exception. +* `6F50` — `SETFIRST` `(t x – t' )`, sets the first component of Tuple `t` to `x` + and returns the resulting Tuple `t'`. +* `6F51` — `SETSECOND` `(t x – t' )`, sets the second component of Tuple `t` to + `x` and returns the resulting Tuple `t'`. +* `6F52` — `SETTHIRD` `(t x – t' )`, sets the third component of Tuple `t` to `x` + and returns the resulting Tuple `t'`. +* `6F6k` — `INDEXQ k` `(t – x)`, returns the `k`-th element of a Tuple `t`, where + `0 ≤ k ≤ 15`. In other words, returns `xk+1` if `t = (x1, . . . , xn)`. If `k ≥ n`, + or if `t` is `Null`, returns a `Null` instead of `x`. +* `6F7k` — `SETINDEXQ k` `(t x – t' )`, sets the `k`-th component of Tuple `t` to + `x`, where `0 ≤ k < 16`, and returns the resulting Tuple `t'`. If `|t| ≤ k`, first + extends the original Tuple to length `k+1` by setting all new components + to `Null`. If the original value of `t` is `Null`, treats it as an empty Tuple. + If `t` is not `Null` or `Tuple`, throws an exception. If `x` is `Null` and either + `|t| ≤ k` or `t` is `Null`, then always returns `t' = t` (and does not consume + tuple creation gas). +* `6F80` — `TUPLEVAR` `(x1 . . . xn n – t)`, creates a new Tuple `t` of length `n` + similarly to `TUPLE`, but with `0 ≤ n ≤ 255` taken from the stack. +* `6F81` — `INDEXVAR` `(t k – x)`, similar to `INDEX k`, but with `0 ≤ k ≤ 254` + taken from the stack. +* `6F82` — `UNTUPLEVAR` `(t n – x1 . . . xn)`, similar to `UNTUPLE n`, but with + `0 ≤ n ≤ 255` taken from the stack. +* `6F83` — `UNPACKFIRSTVAR` `(t n – x1 . . . xn)`, similar to `UNPACKFIRST n`, + but with `0 ≤ n ≤ 255` taken from the stack. +* `6F84` — `EXPLODEVAR` `(t n – x1 . . . xm m)`, similar to `EXPLODE n`, but + with `0 ≤ n ≤ 255` taken from the stack. +* `6F85` — `SETINDEXVAR` `(t x k – t' )`, similar to `SETINDEX k`, but with + `0 ≤ k ≤ 254` taken from the stack. +* `6F86` — `INDEXVARQ` `(t k – x)`, similar to `INDEXQ n`, but with `0 ≤ k ≤ 254` + taken from the stack. +* `6F87` — `SETINDEXVARQ` `(t x k – t' )`, similar to `SETINDEXQ k`, but with + `0 ≤ k ≤ 254` taken from the stack. +* `6F88` — `TLEN` `(t – n)`, returns the length of a Tuple. +* `6F89` — `QTLEN` `(t – n or −1)`, similar to `TLEN`, but returns `−1` if `t` is not + a Tuple. +* `6F8A` — `ISTUPLE` `(t – ? )`, returns `−1` or `0` depending on whether `t` is a + Tuple. +* `6F8B` — `LAST` `(t – x)`, returns the last element `t|t|` of a non-empty Tuple `t`. +* `6F8C` — `TPUSH` or `COMMA` `(t x – t' )`, appends a value `x` to a Tuple `t = + (x1, . . . , xn)`, but only if the resulting Tuple `t' = (x1, . . . , xn, x)` is of + length at most 255. Otherwise throws a type check exception. +* `6F8D` — `TPOP` `(t – t' x)`, detaches the last element `x = xn` from a non- + empty Tuple `t = (x1, . . . , xn)`, and returns both the resulting Tuple `t' = + (x1, . . . , xn−1)` and the original last element `x`. +* `6FA0` — `NULLSWAPIF` `(x – x or ⊥ x)`, pushes a `Null` under the topmost + Integer `x`, but only if `x 6= 0`. +* `6FA1` — `NULLSWAPIFNOT` `(x – x or ⊥ x)`, pushes a `Null` under the topmost + Integer `x`, but only if `x = 0`. May be used for stack alignment + after quiet primitives such as `PLDUXQ`. +* `6FA2` — `NULLROTRIF` `(x y – x y or ⊥ x y)`, pushes a `Null` under the + second stack entry from the top, but only if the topmost Integer `y` is + non-zero. +* `6FA3` — `NULLROTRIFNOT` `(x y – x y or ⊥ x y)`, pushes a `Null` under the + second stack entry from the top, but only if the topmost Integer `y` is + zero. May be used for stack alignment after quiet primitives such as + `LDUXQ`. +* `6FA4` — `NULLSWAPIF2` `(x – x or ⊥ ⊥ x)`, pushes two `Null`s under the + topmost Integer `x`, but only if `x 6= 0`. Equivalent to `NULLSWAPIF; + NULLSWAPIF`. +* `6FA5` — `NULLSWAPIFNOT2` `(x – x or ⊥ ⊥ x)`, pushes two `Null`s under the + topmost Integer `x`, but only if `x = 0`. Equivalent to `NULLSWAPIFNOT; + NULLSWAPIFNOT`. +* `6FA6` — `NULLROTRIF2` `(x y – x y or ⊥ ⊥ x y)`, pushes two `Null`s under + the second stack entry from the top, but only if the topmost Integer `y` + is non-zero. Equivalent to `NULLROTRIF; NULLROTRIF`. +* `6FA7` — `NULLROTRIFNOT2` `(x y – x y or ⊥ ⊥ x y)`, pushes two `Null`s + under the second stack entry from the top, but only if the topmost + Integer `y` is zero. Equivalent to `NULLROTRIFNOT; NULLROTRIFNOT`. +* `6FBij` — `INDEX2 i,j` `(t – x)`, recovers `x = (ti+1)j+1` for `0 ≤ i, j ≤ 3`. + Equivalent to `INDEX i; INDEX j`. +* `6FB4` — `CADR` `(t – x)`, recovers `x = (t2)1`. +* `6FB5` — `CDDR` `(t – x)`, recovers `x = (t2)2`. +* `6FE_ijk` — `INDEX3 i,j,k` `(t – x)`, recovers `x = ((ti+1)j+1)k+1` for `0 ≤ + i, j, k ≤ 3`. Equivalent to `INDEX2 i,j; INDEX k`. +* `6FD4` — `CADDR` `(t – x)`, recovers `x = ((t2)2)1`. +* `6FD5` — `CDDDR` `(t – x)`, recovers `x = ((t2)2)2`. + +## A.4 Constant, or literal primitives + +The following primitives push into the stack one literal (or unnamed constant) +of some type and range, stored as a part (an immediate argument) of the +instruction. Therefore, if the immediate argument is absent or too short, an +“invalid or too short opcode” exception (code `6`) is thrown. + +### A.4.1. Integer and boolean constants. + +* `7i` — `PUSHINT x` with `−5 ≤ x ≤ 10`, pushes integer `x` into the stack; + here `i` equals four lower-order bits of `x` (i.e., `i = x mod 16`). +* `70` — `ZERO`, `FALSE`, or `PUSHINT 0`, pushes a zero. +* `71` — `ONE` or `PUSHINT 1`. +* `72` — `TWO` or `PUSHINT 2`. +* `7A` — `TEN` or `PUSHINT 10`. +* `7F` — `TRUE` or `PUSHINT -1`. +* `80xx` — `PUSHINT xx` with `−128 ≤ xx ≤ 127`. +* `81xxxx` — `PUSHINT xxxx` with `−2^15 ≤ xxxx < 2^15` a signed 16-bit + big-endian integer. +* `81FC18` — `PUSHINT −1000`. +* `82lxxx` — `PUSHINT xxx`, where 5-bit `0 ≤ l ≤ 30` determines the length + `n = 8l + 19` of signed big-endian integer `xxx`. The total length of this + instruction is `l + 4` bytes or `n + 13 = 8l + 32` bits. +* `821005F5E100` — `PUSHINT 1088`. +* `83xx` — `PUSHPOW2 xx + 1`, (quietly) pushes `2^(xx+1)` for `0 ≤ xx ≤ 255`. +* `83FF` — `PUSHNAN`, pushes a `NaN`. +* `84xx` — `PUSHPOW2DEC xx + 1`, pushes `2^(xx+1) − 1` for `0 ≤ xx ≤ 255`. +* `85xx` — `PUSHNEGPOW2 xx + 1`, pushes `−2^(xx+1)` for `0 ≤ xx ≤ 255`. +* `86, 87` — reserved for integer constants. + +### A.4.2. Constant slices, continuations, cells, and references. + +Most +of the instructions listed below push literal slices, continuations, cells, and +cell references, stored as immediate arguments to the instruction. Therefore, +if the immediate argument is absent or too short, an “invalid or too short +opcode” exception (code `6`) is thrown. + +* `88` — `PUSHREF`, pushes the first reference of `cc.code` into the stack as + a `Cell` (and removes this reference from the current continuation). +* `89` — `PUSHREFSLICE`, similar to `PUSHREF`, but converts the cell into a + `Slice`. +* `8A` — `PUSHREFCONT`, similar to `PUSHREFSLICE`, but makes a simple ordinary `Continuation` out of the cell. +* `8Bxsss` — `PUSHSLICE sss`, pushes the (prefix) subslice of `cc.code` + consisting of its first `8x + 4` bits and no references (i.e., essentially a bitstring), where `0 ≤ x ≤ 15`. A completion tag is assumed, meaning that + all trailing zeroes and the last binary one (if present) are removed from + this bitstring. If the original bitstring consists only of zeroes, an empty + slice will be pushed. +* `8B08` — `PUSHSLICE x8_`, pushes an empty slice (bitstring `‘’`). +* `8B04` — `PUSHSLICE x4_`, pushes bitstring `‘0’`. +* `8B0C` — `PUSHSLICE xC_`, pushes bitstring `‘1’`. +* `8Crxxssss` — `PUSHSLICE ssss`, pushes the (prefix) subslice of `cc.code` + consisting of its first `1 ≤ r + 1 ≤ 4` references and up to first `8xx + 1` + bits of data, with `0 ≤ xx ≤ 31`. A completion tag is also assumed. +* `8C01` is equivalent to `PUSHREFSLICE`. +* `8Drxxsssss` — `PUSHSLICE sssss`, pushes the subslice of `cc.code` consisting of `0 ≤ r ≤ 4` references and up to `8xx + 6` bits of data, with + `0 ≤ xx ≤ 127`. A completion tag is assumed. +* `8DE_` — unused (reserved). +* `8F_rxxcccc` — `PUSHCONT cccc`, where `cccc` is the simple ordinary + continuation made from the first `0 ≤ r ≤ 3` references and the first + `0 ≤ xx ≤ 127` bytes of `cc.code`. +* `9xccc` — `PUSHCONT ccc`, pushes an `x`-byte continuation for `0 ≤ x ≤ 15`. + +## A.5 Arithmetic primitives + +### A.5.1. Addition, subtraction, multiplication. + +* `A0` — `ADD` `(x y – x + y)`, adds together two integers. +* `A1` — `SUB` `(x y – x − y)`. +* `A2` — `SUBR` `(x y – y − x)`, equivalent to `SWAP; SUB`. +* `A3` — `NEGATE` `(x – −x)`, equivalent to `MULCONST −1` or to `ZERO; SUBR`. + Notice that it triggers an integer overflow exception if `x = −2^256`. +* `A4` — `INC` `(x – x + 1)`, equivalent to `ADDCONST 1`. +* `A5` — `DEC` `(x – x − 1)`, equivalent to `ADDCONST −1`. +* `A6cc` — `ADDCONST cc` `(x – x + cc)`, `−128 ≤ cc ≤ 127`. +* `A7cc` — `MULCONST cc` `(x – x · cc)`, `−128 ≤ cc ≤ 127`. +* `A8` — `MUL` `(x y – xy)`. + +### A.5.2. Division. + +The general encoding of a `DIV`, `DIVMOD`, or `MOD` operation is `A9mscdf`, with +an optional pre-multiplication and an optional replacement of the division or +multiplication by a shift. Variable one- or two-bit fields `m`, `s`, `c`, `d`, and `f` are +as follows `0 ≤ m ≤ 1` — Indicates whether there is pre-multiplication (`MULDIV` +operation and its variants), possibly replaced by a left shift. + +* `0 ≤ s ≤ 2` — Indicates whether either the multiplication or the division + have been replaced by shifts: `s = 0`—no replacement, `s = 1`—division + replaced by a right shift, `s = 2`—multiplication replaced by a left shift + (possible only for `m = 1`). +* `0 ≤ c ≤ 1` — Indicates whether there is a constant one-byte argument + `tt` for the shift operator (if `s 6= 0`). For `s = 0`, `c = 0`. If `c = 1`, then + `0 ≤ tt ≤ 255`, and the shift is performed by `tt + 1` bits. If `s 6= 0` + and `c = 0`, then the shift amount is provided to the instruction as a + top-of-stack `Integer` in range `0 . . . 256`. +* `1 ≤ d ≤ 3` — Indicates which results of division are required: `1`—only + the quotient, `2`—only the remainder, `3`—both. +* `0 ≤ f ≤ 2` — Rounding mode: `0`—floor, `1`—nearest integer, `2`—ceiling + (cf. 1.5.6). + +Examples: + +* `A904` — `DIV` `(x y – q := ⌊x/y⌋)`. +* `A905` — `DIVR` `(x y – q' := ⌊x/y + 1/2⌋)`. +* `A906` — `DIVC` `(x y – q'' := ⌈x/y⌉)`. +* `A908` — `MOD` `(x y – r)`, where `q := ⌊x/y⌋`, `r := x mod y := x − yq`. +* `A90C` — `DIVMOD` `(x y – q r)`, where `q := ⌊x/y⌋`, `r := x − yq`. +* `A90D` — `DIVMODR` `(x y – q' r')`, where `q' := ⌊x/y + 1/2⌋`, `r' := x − yq'`. +* `A90E` — `DIVMODC` `(x y – q'' r'')`, where `q'' := ⌈x/y⌉`, `r'' := x − yq''`. +* `A924` — same as `RSHIFT`: `(x y – ⌊x · 2^(−y)⌋)` for `0 ≤ y ≤ 256`. +* `A934tt` — same as `RSHIFT tt + 1`: `(x – ⌊x · 2^(−tt−1)⌋)`. +* `A938tt` — `MODPOW2 tt + 1`: `(x – x mod 2^(tt+1))`. +* `A985` — `MULDIVR` `(x y z – q')`, where `q' = ⌊xy/z + 1/2⌋`. +* `A98C` — `MULDIVMOD` `(x y z – q r)`, where `q := ⌊x · y/z⌋`, `r := x · y mod z` + (same as `*/MOD` in Forth). +* `A9A4` — `MULRSHIFT` `(x y z – ⌊xy · 2^(−z)⌋)` for `0 ≤ z ≤ 256`. +* `A9A5` — `MULRSHIFTR` `(x y z – ⌊xy · 2^(−z) + 1/2⌋)` for `0 ≤ z ≤ 256`. +* `A9B4tt` — `MULRSHIFT tt + 1` `(x y – ⌊xy · 2^(−tt−1)⌋)`. +* `A9B5tt` — `MULRSHIFTR tt + 1` `(x y – ⌊xy · 2^(−tt−1) + 1/2⌋)`. +* `A9C4` — `LSHIFTDIV` `(x y z – ⌊2^z x/y⌋)` for `0 ≤ z ≤ 256`. +* `A9C5` — `LSHIFTDIVR` `(x y z – ⌊2^z x/y + 1/2⌋)` for `0 ≤ z ≤ 256`. +* `A9D4tt` — `LSHIFTDIV tt + 1` `(x y – ⌊2^(tt+1) x/y⌋)`. +* `A9D5tt` — `LSHIFTDIVR tt + 1` `(x y – ⌊2^(tt+1) x/y + 1/2⌋)`. + +The most useful of these operations are `DIV`, `DIVMOD`, `MOD`, `DIVR`, `DIVC`, +`MODPOW2 t`, and `RSHIFTR t` (for integer arithmetic); and `MULDIVMOD`, `MULDIV`, +`MULDIVR`, `LSHIFTDIVR t`, and `MULRSHIFTR t` (for fixed-point arithmetic). + +### A.5.3. Shifts, logical operations. + +* `AAcc` — `LSHIFT cc + 1` `(x – x · 2^(cc+1))`, `0 ≤ cc ≤ 255`. +* `AA00` — `LSHIFT 1`, equivalent to `MULCONST 2` or to Forth’s `2*`. +* `ABcc` — `RSHIFT cc + 1` `(x – ⌊x · 2^(−cc−1)⌋)`, `0 ≤ cc ≤ 255`. +* `AC` — `LSHIFT` `(x y – x · 2^y)`, `0 ≤ y ≤ 1023`. +* `AD` — `RSHIFT` `(x y – ⌊x · 2^(−y)⌋)`, `0 ≤ y ≤ 1023`. +* `AE` — `POW2` `(y – 2^y)`, `0 ≤ y ≤ 1023`, equivalent to `ONE; SWAP; LSHIFT`. +* `AF` — reserved. +* `B0` — `AND` `(x y – x&y)`, bitwise “and” of two signed integers `x` and `y`, + sign-extended to infinity. +* `B1` — `OR` `(x y – x ∨ y)`, bitwise “or” of two integers. +* `B2` — `XOR` `(x y – x ⊕ y)`, bitwise “xor” of two integers. +* `B3` — `NOT` `(x – x ⊕ −1 = −1 − x)`, bitwise “not” of an integer. +* `B4cc` — `FITS cc + 1` `(x – x)`, checks whether `x` is a `cc + 1`-bit signed + integer for `0 ≤ cc ≤ 255` (i.e., whether `−2^cc ≤ x < 2^cc`). If not, either + triggers an integer overflow exception, or replaces `x` with a `NaN` (quiet + version). +* `B400` — `FITS 1` or `CHKBOOL` `(x – x)`, checks whether `x` is a “boolean + value” (i.e., either `0` or `-1`). +* `B5cc` — `UFITS cc + 1` `(x – x)`, checks whether `x` is a `cc + 1`-bit unsigned + integer for `0 ≤ cc ≤ 255` (i.e., whether `0 ≤ x < 2^(cc+1)`). +* `B500` — `UFITS 1` or `CHKBIT`, checks whether `x` is a binary digit (i.e., + zero or one). +* `B600` — `FITSX` `(x c – x)`, checks whether `x` is a `c`-bit signed integer for + `0 ≤ c ≤ 1023`. +* `B601` — `UFITSX` `(x c – x)`, checks whether `x` is a `c`-bit unsigned integer + for `0 ≤ c ≤ 1023`. +* `B602` — `BITSIZE` `(x – c)`, computes smallest `c ≥ 0` such that `x` fits into + a `c`-bit signed integer (`−2^(c−1) ≤ c < 2^(c−1)`). +* `B603` — `UBITSIZE` `(x – c)`, computes smallest `c ≥ 0` such that `x` fits + into a `c`-bit unsigned integer (`0 ≤ x < 2^c`), or throws a range check + exception. +* `B608` — `MIN` `(x y – x or y)`, computes the minimum of two integers `x` + and `y`. +* `B609` — `MAX` `(x y – x or y)`, computes the maximum of two integers `x` + and `y`. +* `B60A` — `MINMAX` or `INTSORT2` `(x y – x y or y x)`, sorts two integers. Quiet + version of this operation returns two `NaN`s if any of the arguments are + `NaN`s. +* `B60B` — `ABS` `(x – |x|)`, computes the absolute value of an integer `x`. + +### A.5.4. Quiet arithmetic primitives. + +We opted to make all arithmetic +operations “non-quiet” (signaling) by default, and create their quiet counterparts by means of a prefix. Such an encoding is definitely sub-optimal. It is +not yet clear whether it should be done in this way, or in the opposite way +by making all arithmetic operations quiet by default, or whether quiet and +non-quiet operations should be given opcodes of equal length; this can only +be settled by practice. + +* `B7xx` — `QUIET` prefix, transforming any arithmetic operation into its + “quiet” variant, indicated by prefixing a `Q` to its mnemonic. Such operations return `NaN`s instead of throwing integer overflow exceptions if + the results do not fit in `Integer`s, or if one of their arguments is a `NaN`. + Notice that this does not extend to shift amounts and other parameters that must be within a small range (e.g., `0–1023`). Also notice that + this does not disable type-checking exceptions if a value of a type other + than `Integer` is supplied. +* `B7A0` — `QADD` `(x y – x + y)`, always works if `x` and `y` are `Integer`s, but + returns a `NaN` if the addition cannot be performed. +* `B7A904` — `QDIV` `(x y – ⌊x/y⌋)`, returns a `NaN` if `y = 0`, or if `y = −1` and + `x = −2^256`, or if either of `x` or `y` is a `NaN`. +* `B7B0` — `QAND` `(x y – x&y)`, bitwise “and” (similar to `AND`), but returns + a `NaN` if either `x` or `y` is a `NaN` instead of throwing an integer overflow + exception. However, if one of the arguments is zero, and the other is a + `NaN`, the result is zero. +* `B7B1` — `QOR` `(x y – x∨y)`, bitwise “or”. If `x = −1` or `y = −1`, the result + is always `−1`, even if the other argument is a `NaN`. +* `B7B507` — `QUFITS 8` `(x – x' )`, checks whether `x` is an unsigned byte + (i.e., whether `0 ≤ x < 2^8`), and replaces `x` with a `NaN` if this is not the + case; leaves `x` intact otherwise (i.e., if `x` is an unsigned byte). + +## A.6 Comparison primitives + +### A.6.1. Integer comparison. + +All integer comparison primitives return integer `−1` (“true”) or `0` (“false”) to indicate the result of the comparison. We +do not define their “boolean circuit” counterparts, which would transfer control to `c0` or `c1` depending on the result of the comparison. If needed, such +instructions can be simulated with the aid of `RETBOOL`. +Quiet versions of integer comparison primitives are also available, encoded +with the aid of the `QUIET` prefix (`B7`). If any of the integers being compared +are `NaN`s, the result of a quiet comparison will also be a `NaN` (“undefined”), +instead of a `−1` (“yes”) or `0` (“no”), thus effectively supporting ternary logic. + +* `B8` — `SGN` `(x – sgn(x))`, computes the sign of an integer `x`: `−1` if `x < 0`, + `0` if `x = 0`, `1` if `x > 0`. +* `B9` — `LESS` `(x y – x < y)`, returns `−1` if `x < y`, `0` otherwise. +* `BA` — `EQUAL` `(x y – x = y)`, returns `−1` if `x = y`, `0` otherwise. +* `BB` — `LEQ` `(x y – x ≤ y)`. +* `BC` — `GREATER` `(x y – x > y)`. +* `BD` — `NEQ` `(x y – x 6= y)`, equivalent to `EQUAL; NOT`. +* `BE` — `GEQ` `(x y – x ≥ y)`, equivalent to `LESS; NOT`. +* `BF` — `CMP` `(x y – sgn(x − y))`, computes the sign of `x − y`: `−1` if `x < y`, + `0` if `x = y`, `1` if `x > y`. No integer overflow can occur here unless `x` or `y` + is a `NaN`. +* `C0yy` — `EQINT yy` `(x – x = yy)` for `−2^7 ≤ yy < 2^7`. +* `C000` — `ISZERO`, checks whether an integer is zero. Corresponds to + Forth’s `0=`. +* `C1yy` — `LESSINT yy` `(x – x < yy)` for `−2^7 ≤ yy < 2^7`. +* `C100` — `ISNEG`, checks whether an integer is negative. Corresponds to + Forth’s `0<`. +* `C101` — `ISNPOS`, checks whether an integer is non-positive. +* `C2yy` — `GTINT yy` `(x – x > yy)` for `−2^7 ≤ yy < 2^7`. +* `C200` — `ISPOS`, checks whether an integer is positive. Corresponds to + Forth’s `0>`. +* `C2FF` — `ISNNEG`, checks whether an integer is non-negative. +* `C3yy` — `NEQINT yy` `(x – x 6= yy)` for `−2^7 ≤ yy < 2^7`. +* `C4` — `ISNAN` `(x – x = NaN)`, checks whether `x` is a `NaN`. +* `C5` — `CHKNAN` `(x – x)`, throws an arithmetic overflow exception if `x` is a + `NaN`. +* `C6` — reserved for integer comparison. + +### A.6.2. Other comparison. + +Most of these “other comparison” primitives actually compare the data +portions of `Slice`s as bitstrings. + +* `C700` — `SEMPTY` `(s – s = ∅)`, checks whether a `Slice s` is empty (i.e., + contains no bits of data and no cell references). +* `C701` — `SDEMPTY` `(s – s ≈ ∅)`, checks whether `Slice s` has no bits of + data. +* `C702` — `SREMPTY` `(s – r(s) = 0)`, checks whether `Slice s` has no references. +* `C703` — `SDFIRST` `(s – s0 = 1)`, checks whether the first bit of `Slice s` is + a one. +* `C704` — `SDLEXCMP` `(s s0 – c)`, compares the data of `s` lexicographically + with the data of `s0`, returning `−1`, `0`, or `1` depending on the result. +* `C705` — `SDEQ` `(s s0 – s ≈ s0)`, checks whether the data parts of `s` and `s0` + coincide, equivalent to `SDLEXCMP; ISZERO`. +* `C708` — `SDPFX` `(s s0 – ? )`, checks whether `s` is a prefix of `s0`. +* `C709` — `SDPFXREV` `(s s0 – ? )`, checks whether `s0` is a prefix of `s`, equivalent + to `SWAP; SDPFX`. +* `C70A` — `SDPPFX` `(s s0 – ? )`, checks whether `s` is a proper prefix of `s0` (i.e., + a prefix distinct from `s0`). +* `C70B` — `SDPPFXREV` `(s s0 – ? )`, checks whether `s0` is a proper prefix of `s`. +* `C70C` — `SDSFX` `(s s0 – ? )`, checks whether `s` is a suffix of `s0`. +* `C70D` — `SDSFXREV` `(s s0 – ? )`, checks whether `s0` is a suffix of `s`. +* `C70E` — `SDPSFX` `(s s0 – ? )`, checks whether `s` is a proper suffix of `s0`. +* `C70F` — `SDPSFXREV` `(s s0 – ? )`, checks whether `s0` is a proper suffix of `s`. +* `C710` — `SDCNTLEAD0` `(s – n)`, returns the number of leading zeroes in + `s`. +* `C711` — `SDCNTLEAD1` `(s – n)`, returns the number of leading ones in `s`. +* `C712` — `SDCNTTRAIL0` `(s – n)`, returns the number of trailing zeroes in + `s`. +* `C713` — `SDCNTTRAIL1` `(s – n)`, returns the number of trailing ones in `s`. + +## A.7 Cell primitives + +The cell primitives are mostly either cell serialization primitives, which work +with `Builder`s, or cell deserialization primitives, which work with `Slice`s. + +### A.7.1. Cell serialization primitives. + +All these primitives first check whether there is enough space in the Builder, and only then check the range of the value being serialized. + +* `C8` — `NEWC` ( – b), creates a new empty Builder. +* `C9` — `ENDC` (b – c), converts a Builder into an ordinary Cell. +* `CAcc` — `STI cc + 1` (x b – b0), stores a signed cc + 1-bit integer x into Builder b for 0 ≤ cc ≤ 255, throws a range check exception if x does not fit into cc + 1 bits. +* `CBcc` — `STU cc + 1` (x b – b0), stores an unsigned cc + 1-bit integer x into Builder b. In all other respects it is similar to STI. +* `CC` — `STREF` (c b – b0), stores a reference to Cell c into Builder b. +* `CD` — `STBREFR` or `ENDCST` (b b00 – b), equivalent to ENDC; SWAP; STREF. +* `CE` — `STSLICE` (s b – b0), stores Slice s into Builder b. +* `CF00` — `STIX` (x b l – b0), stores a signed l-bit integer x into b for 0 ≤ l ≤ 257. +* `CF01` — `STUX` (x b l – b0), stores an unsigned l-bit integer x into b for 0 ≤ l ≤ 256. +* `CF02` — `STIXR` (b x l – b0), similar to STIX, but with arguments in a different order. +* `CF03` — `STUXR` (b x l – b0), similar to STUX, but with arguments in a different order. +* `CF04` — `STIXQ` (x b l – x b f or b0 0), a quiet version of STIX. If there is no space in b, sets b0 = b and f = −1. If x does not fit into l bits, sets b0 = b and f = 1. If the operation succeeds, b0 is the new Builder and f = 0. However, 0 ≤ l ≤ 257, with a range check exception if this is not so. +* `CF05` — `STUXQ` (x b l – b0 f). +* `CF06` — `STIXRQ` (b x l – b x f or b0 0). +* `CF07` — `STUXRQ` (b x l – b x f or b0 0). +* `CF08cc` — a longer version of `STI cc + 1`. +* `CF09cc` — a longer version of `STU cc + 1`. +* `CF0Acc` — `STIR cc + 1` (b x – b0), equivalent to SWAP; STI cc + 1. +* `CF0Bcc` — `STUR cc + 1` (b x – b0), equivalent to SWAP; STU cc + 1. +* `CF0Ccc` — `STIQ cc + 1` (x b – x b f or b0 0). +* `CF0Dcc` — `STUQ cc + 1` (x b – x b f or b0 0). +* `CF0Ecc` — `STIRQ cc + 1` (b x – b x f or b0 0). +* `CF0Fcc` — `STURQ cc + 1` (b x – b x f or b0 0). +* `CF10` — a longer version of `STREF` (c b – b0). +* `CF11` — `STBREF` (b0 b – b00), equivalent to SWAP; STBREFREV. +* `CF12` — a longer version of `STSLICE` (s b – b0). +* `CF13` — `STB` (b0 b – b00), appends all data from Builder b0 to Builder b. +* `CF14` — `STREFR` (b c – b0). +* `CF15` — `STBREFR` (b b0 – b00), a longer encoding of STBREFR. +* `CF16` — `STSLICER` (b s – b0). +* `CF17` — `STBR` (b b0 – b00), concatenates two Builder s, equivalent to SWAP; STB. +* `CF18` — `STREFQ` (c b – c b −1 or b0 0). +* `CF19` — `STBREFQ` (b0 b – b0 b −1 or b00 0). +* `CF1A` — `STSLICEQ` (s b – s b −1 or b0 0). +* `CF1B` — `STBQ` (b0 b – b0 b −1 or b00 0). +* `CF1C` — `STREFRQ` (b c – b c −1 or b0 0). +* `CF1D` — `STBREFRQ` (b b0 – b b0 −1 or b00 0). +* `CF1E` — `STSLICERQ` (b s – b s −1 or b00 0). +* `CF1F` — `STBRQ` (b b0 – b b0 −1 or b00 0). +* `CF20` — `STREFCONST`, equivalent to PUSHREF; STREFR. +* `CF21` — `STREF2CONST`, equivalent to STREFCONST; STREFCONST. +* `CF23` — `ENDXC` (b x – c), if x 6= 0, creates a special or exotic cell (cf. 3.1.2) from Builder b. The type of the exotic cell must be stored in the first 8 bits of b. If x = 0, it is equivalent to ENDC. Otherwise some validity checks on the data and references of b are performed before creating the exotic cell. +* `CF28` — `STILE4` (x b – b0), stores a little-endian signed 32-bit integer. +* `CF29` — `STULE4` (x b – b0), stores a little-endian unsigned 32-bit integer. +* `CF2A` — `STILE8` (x b – b0), stores a little-endian signed 64-bit integer. +* `CF2B` — `STULE8` (x b – b0), stores a little-endian unsigned 64-bit integer. +* `CF30` — `BDEPTH` (b – x), returns the depth of Builder b. If no cell references are stored in b, then x = 0; otherwise x is one plus the maximum of depths of cells referred to from b. +* `CF31` — `BBITS` (b – x), returns the number of data bits already stored in Builder b. +* `CF32` — `BREFS` (b – y), returns the number of cell references already stored in b. +* `CF33` — `BBITREFS` (b – x y), returns the numbers of both data bits and cell references in b. +* `CF35` — `BREMBITS` (b – x0), returns the number of data bits that can still be stored in b. +* `CF36` — `BREMREFS` (b – y0). +* `CF37` — `BREMBITREFS` (b – x0 y0). +* `CF38cc` — `BCHKBITS cc + 1` (b –), checks whether cc + 1 bits can be stored into b, where 0 ≤ cc ≤ 255. +* `CF39` — `BCHKBITS` (b x – ), checks whether x bits can be stored into b, 0 ≤ x ≤ 1023. If there is no space for x more bits in b, or if x is not within the range 0 . . . 1023, throws an exception. +* `CF3A` — `BCHKREFS` (b y – ), checks whether y references can be stored into b, 0 ≤ y ≤ 7. +* `CF3B` — `BCHKBITREFS` (b x y – ), checks whether x bits and y references can be stored into b, 0 ≤ x ≤ 1023, 0 ≤ y ≤ 7. +* `CF3Ccc` — `BCHKBITSQ cc + 1` (b – ?), checks whether cc + 1 bits can be stored into b, where 0 ≤ cc ≤ 255. +* `CF3D` — `BCHKBITSQ` (b x – ?), checks whether x bits can be stored into b, 0 ≤ x ≤ 1023. +* `CF3E` — `BCHKREFSQ` (b y – ?), checks whether y references can be stored into b, 0 ≤ y ≤ 7. +* `CF3F` — `BCHKBITREFSQ` (b x y – ?), checks whether x bits and y references can be stored into b, 0 ≤ x ≤ 1023, 0 ≤ y ≤ 7. +* `CF40` — `STZEROES` (b n – b0), stores n binary zeroes into Builder b. +* `CF41` — `STONES` (b n – b0), stores n binary ones into Builder b. +* `CF42` — `STSAME` (b n x – b0), stores n binary xes (0 ≤ x ≤ 1) into Builder b. +* `CFC0_xysss` — `STSLICECONST sss` (b – b0), stores a constant subslice sss consisting of 0 ≤ x ≤ 3 references and up to 8y + 1 data bits, with 0 ≤ y ≤ 7. Completion bit is assumed. +* `CF81` — `STSLICECONST ‘0’` or `STZERO` (b – b0), stores one binary zero. +* `CF83` — `STSLICECONST ‘1’` or `STONE` (b – b0), stores one binary one. +* `CFA2` — equivalent to `STREFCONST`. +* `CFA3` — almost equivalent to `STSLICECONST ‘1’`; `STREFCONST`. +* `CFC2` — equivalent to `STREF2CONST`. +* `CFE2` — `STREF3CONST`. + +--- + +### A.7.2. Cell deserialization primitives + +* `D0` — `CTOS` (c – s), converts a Cell into a Slice. Notice that `c` must be either an ordinary cell, or an exotic cell (cf. 3.1.2) which is automatically loaded to yield an ordinary cell `c0`, converted into a Slice afterwards. +* `D1` — `ENDS` (s – ), removes a Slice `s` from the stack, and throws an exception if it is not empty. +* `D2cc` — `LDI cc + 1` (s – x s0), loads (i.e., parses) a signed cc + 1-bit integer `x` from Slice `s`, and returns the remainder of `s` as `s0`. +* `D3cc` — `LDU cc + 1` (s – x s0), loads an unsigned cc + 1-bit integer `x` from Slice `s`. +* `D4` — `LDREF` (s – c s0), loads a cell reference `c` from `s`. +* `D5` — `LDREFRTOS` (s – s0 s00), equivalent to `LDREF`; `SWAP`; `CTOS`. +* `D6cc` — `LDSLICE cc + 1` (s – s00 s0), cuts the next cc + 1 bits of `s` into a separate Slice `s00`. +* `D700` — `LDIX` (s l – x s0), loads a signed `l`-bit (0 ≤ l ≤ 257) integer `x` from Slice `s`, and returns the remainder of `s` as `s0`. +* `D701` — `LDUX` (s l – x s0), loads an unsigned `l`-bit integer `x` from Slice `s`, 0 ≤ l ≤ 256. +* `D702` — `PLDIX` (s l – x), preloads a signed `l`-bit integer from Slice `s`, 0 ≤ l ≤ 257. +* `D703` — `PLDUX` (s l – x), preloads an unsigned `l`-bit integer from `s`, 0 ≤ l ≤ 256. +* `D704` — `LDIXQ` (s l – x s0 −1 or s0), quiet version of `LDIX`. If `s` has fewer than `l` bits, returns a flag instead of exception. +* `D705` — `LDUXQ` (s l – x s0 −1 or s0), quiet version of `LDUX`. +* `D706` — `PLDIXQ` (s l – x −1 or 0), quiet version of `PLDIX`. +* `D707` — `PLDUXQ` (s l – x −1 or 0), quiet version of `PLDUX`. +* `D708cc` — longer encoding of `LDI cc + 1`. +* `D709cc` — longer encoding of `LDU cc + 1`. +* `D70Acc` — `PLDI cc + 1` (s – x), preloads a signed cc + 1-bit integer from Slice `s`. +* `D70Bcc` — `PLDU cc + 1` (s – x), preloads an unsigned cc + 1-bit integer from `s`. +* `D70Ccc` — `LDIQ cc + 1` (s – x s0 −1 or s0), quiet version of `LDI`. +* `D70Dcc` — `LDUQ cc + 1` (s – x s0 −1 or s0), quiet version of `LDU`. +* `D70Ecc` — `PLDIQ cc + 1` (s – x −1 or 0), quiet version of `PLDI`. +* `D70Fcc` — `PLDUQ cc + 1` (s – x −1 or 0), quiet version of `PLDU`. +* `D714_c` — `PLDUZ 32(c + 1)` (s – s x), preloads first 32(c + 1) bits of Slice `s` into an unsigned integer `x`, 0 ≤ c ≤ 7. Missing bits are assumed zero. Used with `IFBITJMP` etc. +* `D718` — `LDSLICEX` (s l – s00 s0), loads first 0 ≤ l ≤ 1023 bits of `s` into a new Slice `s00`, returns the remainder as `s0`. +* `D719` — `PLDSLICEX` (s l – s00), returns first 0 ≤ l ≤ 1023 bits of `s` as `s00`. +* `D71A` — `LDSLICEXQ` (s l – s00 s0 −1 or s0), quiet version of `LDSLICEX`. +* `D71B` — `PLDSLICEXQ` (s l – s0 −1 or 0), quiet version of `PLDSLICEX`. +* `D71Ccc` — longer encoding of `LDSLICE cc + 1`. +* `D71Dcc` — `PLDSLICE cc + 1` (s – s00), returns first 0 < cc + 1 ≤ 256 bits of `s` as `s00`. +* `D71Ecc` — `LDSLICEQ cc + 1` (s – s00 s0 −1 or s0), quiet version of `LDSLICE`. +* `D71Fcc` — `PLDSLICEQ cc + 1` (s – s00 −1 or 0), quiet version of `PLDSLICE`. +* `D720` — `SDCUTFIRST` (s l – s0), returns first 0 ≤ l ≤ 1023 bits of `s`. Equivalent to `PLDSLICEX`. +* `D721` — `SDSKIPFIRST` (s l – s0), returns all but first 0 ≤ l ≤ 1023 bits of `s`. Equivalent to `LDSLICEX`; `NIP`. +* `D722` — `SDCUTLAST` (s l – s0), returns last 0 ≤ l ≤ 1023 bits of `s`. +* `D723` — `SDSKIPLAST` (s l – s0), returns all but last 0 ≤ l ≤ 1023 bits of `s`. +* `D724` — `SDSUBSTR` (s l l0 – s0), returns substring of length 0 ≤ l0 ≤ 1023 starting at offset 0 ≤ l ≤ 1023. +* `D726` — `SDBEGINSX` (s s0 – s00), checks whether `s` begins with data bits of `s0`. Removes `s0` on success. Throws exception on failure. +* `D727` — `SDBEGINSXQ` (s s0 – s00 −1 or s0), quiet version of `SDBEGINSX`. +* `D72A_xsss` — `SDBEGINS` (s – s00), checks whether `s` begins with constant bitstring `sss` of length 8x + 3 (completion bit assumed). Removes on success. +* `D72802` — `SDBEGINS ‘0’` (s – s00), checks whether `s` begins with binary zero. +* `D72806` — `SDBEGINS ‘1’` (s – s00), checks whether `s` begins with binary one. +* `D72E_xsss` — `SDBEGINSQ` (s – s00 −1 or s0), quiet version of `SDBEGINS`. +* `D730` — `SCUTFIRST` (s l r – s0), returns first 0 ≤ l ≤ 1023 bits and 0 ≤ r ≤ 4 references of `s`. +* `D731` — `SSKIPFIRST` (s l r – s0). +* `D732` — `SCUTLAST` (s l r – s0), returns last 0 ≤ l ≤ 1023 bits and last 0 ≤ r ≤ 4 references. +* `D733` — `SSKIPLAST` (s l r – s0). +* `D734` — `SUBSLICE` (s l r l0 r0 – s0), returns 0 ≤ l0 ≤ 1023 bits and 0 ≤ r0 ≤ 4 refs after skipping first l bits and r refs. +* `D736` — `SPLIT` (s l r – s0 s00), splits off first l bits and r refs of `s` into `s0`, returns remainder as `s00`. +* `D737` — `SPLITQ` (s l r – s0 s00 −1 or s0), quiet version of `SPLIT`. +* `D739` — `XCTOS` (c – s ?), converts a Cell (ordinary or exotic) into a Slice. Returns flag if exotic. +* `D73A` — `XLOAD` (c – c0), loads exotic cell `c` to ordinary `c0`. +* `D73B` — `XLOADQ` (c – c0 −1 or c0), quiet version of `XLOAD`. +* `D741` — `SCHKBITS` (s l – ), checks there are ≥ l data bits. Throws exception if not. +* `D742` — `SCHKREFS` (s r – ), checks ≥ r references. +* `D743` — `SCHKBITREFS` (s l r – ), checks ≥ l bits and ≥ r references. +* `D745` — `SCHKBITSQ` (s l – ?), quiet version of `SCHKBITS`. +* `D746` — `SCHKREFSQ` (s r – ?). +* `D747` — `SCHKBITREFSQ` (s l r – ?). +* `D748` — `PLDREFVAR` (s n – c), returns n-th cell reference of Slice `s`, 0 ≤ n ≤ 3. +* `D749` — `SBITS` (s – l), returns number of data bits. +* `D74A` — `SREFS` (s – r), returns number of references. +* `D74B` — `SBITREFS` (s – l r), returns both bit and ref counts. +* `D74E_n` — `PLDREFIDX n` (s – c), returns n-th reference, 0 ≤ n ≤ 3. +* `D74C` — `PLDREF` (s – c), preloads first reference of `s`. +* `D750` — `LDILE4` (s – x s0), loads little-endian signed 32-bit integer. +* `D751` — `LDULE4` (s – x s0), loads little-endian unsigned 32-bit integer. +* `D752` — `LDILE8` (s – x s0), loads little-endian signed 64-bit integer. +* `D753` — `LDULE8` (s – x s0), loads little-endian unsigned 64-bit integer. +* `D754` — `PLDILE4` (s – x), preloads little-endian signed 32-bit integer. +* `D755` — `PLDULE4` (s – x), preloads little-endian unsigned 32-bit integer. +* `D756` — `PLDILE8` (s – x), preloads little-endian signed 64-bit integer. +* `D757` — `PLDULE8` (s – x), preloads little-endian unsigned 64-bit integer. +* `D758` — `LDILE4Q` (s – x s0 −1 or s0), quiet 32-bit signed LE load. +* `D759` — `LDULE4Q` (s – x s0 −1 or s0), quiet 32-bit unsigned LE load. +* `D75A` — `LDILE8Q` (s – x s0 −1 or s0), quiet 64-bit signed LE load. +* `D75B` — `LDULE8Q` (s – x s0 −1 or s0), quiet 64-bit unsigned LE load. +* `D75C` — `PLDILE4Q` (s – x −1 or 0), quiet preload 32-bit signed. +* `D75D` — `PLDULE4Q` (s – x −1 or 0), quiet preload 32-bit unsigned. +* `D75E` — `PLDILE8Q` (s – x −1 or 0), quiet preload 64-bit signed. +* `D75F` — `PLDULE8Q` (s – x −1 or 0), quiet preload 64-bit unsigned. +* `D760` — `LDZEROES` (s – n s0), returns count n of leading zero bits in `s` and removes them. +* `D761` — `LDONES` (s – n s0), returns count n of leading one bits in `s` and removes them. +* `D762` — `LDSAME` (s x – n s0), returns count n of leading bits equal to `x` (0 ≤ x ≤ 1) in `s`, removes them. +* `D764` — `SDEPTH` (s – x), returns depth of Slice `s`. If no references, x = 0; else x = 1 + max depth of cells referred. +* `D765` — `CDEPTH` (c – x), returns depth of Cell `c`. If no refs, x = 0; else 1 + max depth. If `c` = Null, returns 0. + +--- + +## A.8 Continuation and control flow primitives + +### A.8.1. Unconditional control flow primitives. + +* `D8` — **EXECUTE** or **CALLX** `(c – )`, calls or executes continuation `c` (i.e., `cc ← c ◦0 cc`). +* `D9` — **JMPX** `(c – )`, jumps, or transfers control, to continuation `c` (i.e., `cc ← c ◦0 c0, or rather cc ← (c ◦0 c0) ◦1 c1`). The remainder of the previous current continuation `cc` is discarded. +* `DApr` — **CALLXARGS p,r** `(c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. +* `DB0p` — **CALLXARGS p,−1** `(c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. +* `DB1p` — **JMPXARGS p** `(c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). +* `DB2r` — **RETARGS r**, returns to `c0`, with `0 ≤ r ≤ 15` return values taken from the current stack. +* `DB30` — **RET** or **RETTRUE**, returns to the continuation at `c0` (i.e., performs `cc ← c0`). The remainder of the current continuation `cc` is discarded. Approximately equivalent to `PUSH c0; JMPX`. +* `DB31` — **RETALT** or **RETFALSE**, returns to the continuation at `c1` (i.e., `cc ← c1`). Approximately equivalent to `PUSH c1; JMPX`. +* `DB32` — **BRANCH** or **RETBOOL** `(f – )`, performs **RETTRUE** if integer `f ≠ 0`, or **RETFALSE** if `f = 0`. +* `DB34` — **CALLCC** `(c – )`, call with current continuation, transfers control to `c`, pushing the old value of `cc` into `c`’s stack (instead of discarding it or writing it into new `c0`). +* `DB35` — **JMPXDATA** `(c – )`, similar to **CALLCC**, but the remainder of the current continuation (the old value of `cc`) is converted into a Slice before pushing it into the stack of `c`. +* `DB36pr` — **CALLCCARGS p,r** `(c – )`, similar to **CALLXARGS**, but pushes the old value of `cc` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `cc.nargs` to `−1 ≤ r ≤ 14`. +* `DB38` — **CALLXVARARGS** `(c p r – )`, similar to **CALLXARGS**, but takes `−1 ≤ p, r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1 . . . 254`. +* `DB39` — **RETVARARGS** `(p r – )`, similar to **RETARGS**. +* `DB3A` — **JMPXVARARGS** `(c p r – )`, similar to **JMPXARGS**. +* `DB3B` — **CALLCCVARARGS** `(c p r – )`, similar to **CALLCCARGS**. +* `DB3C` — **CALLREF**, equivalent to `PUSHREFCONT; CALLX`. +* `DB3D` — **JMPREF**, equivalent to `PUSHREFCONT; JMPX`. +* `DB3E` — **JMPREFDATA**, equivalent to `PUSHREFCONT; JMPXDATA`. +* `DB3F` — **RETDATA**, equivalent to `PUSH c0; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. + +--- + +## A.8 Continuation and control flow primitives + +### A.8.2. Conditional control flow primitives + +* `DC` — **IFRET** `(f – )`, performs a **RET**, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. +* `DD` — **IFNOTRET** `(f – )`, performs a **RET**, but only if integer `f` is zero. +* `DE` — **IF** `(f c – )`, performs **EXECUTE** for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. +* `DF` — **IFNOT** `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. +* `E0` — **IFJMP** `(f c – )`, jumps to `c` (similarly to **JMPX**), but only if `f` is non-zero. +* `E1` — **IFNOTJMP** `(f c – )`, jumps to `c` (similarly to **JMPX**), but only if `f` is zero. +* `E2` — **IFELSE** `(f c c0 – )`, if integer `f` is non-zero, executes `c`, otherwise executes `c0`. Equivalent to `CONDSELCHK; EXECUTE`. +* `E300` — **IFREF** `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. +* `E301` — **IFNOTREF** `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. +* `E302` — **IFJMPREF** `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. +* `E303` — **IFNOTJMPREF** `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. +* `E304` — **CONDSEL** `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. +* `E305` — **CONDSELCHK** `(f x y – x or y)`, same as **CONDSEL**, but first checks whether `x` and `y` have the same type. +* `E308` — **IFRETALT** `(f – )`, performs **RETALT** if integer `f ≠ 0`. +* `E309` — **IFNOTRETALT** `(f – )`, performs **RETALT** if integer `f = 0`. +* `E30D` — **IFREFELSE** `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. +* `E30E` — **IFELSEREF** `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. +* `E30F` — **IFREFELSEREF** `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. +* `E310–E31F` — reserved for loops with break operators (cf. A.8.3). +* `E39_n` — **IFBITJMP n** `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs **JMPX** to continuation `c`. Value `x` is left in the stack. +* `E3B_n` — **IFNBITJMP n** `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `E3D_n` — **IFBITJMPREF n** `(x – x)`, performs a **JMPREF** if bit `0 ≤ n ≤ 31` is set in integer `x`. +* `E3F_n` — **IFNBITJMPREF n** `(x – x)`, performs a **JMPREF** if bit `0 ≤ n ≤ 31` is not set in integer `x`. + +--- + +### A.8.3. Control flow primitives: loops + +Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. 4.1.5), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have \*BRK versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for \*ENDBRK versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for \*ENDBRK versions). + +* `E4` — **REPEAT** `(n c – )`, executes continuation `c` `n` times, if integer `n` is non-negative. If `n ≥ 2^31` or `n < −2^31`, generates a range check exception. Notice that a **RET** inside the code of `c` works as a continue, not as a break. One should use either alternative (experimental) loops or alternative **RETALT** (along with a **SETEXITALT** before the loop) to break out of a loop. +* `E5` — **REPEATEND** `(n – )`, similar to **REPEAT**, but it is applied to the current continuation `cc`. +* `E6` — **UNTIL** `(c – )`, executes continuation `c`, then pops an integer `x` from the resulting stack. If `x` is zero, performs another iteration of this loop. Implemented with extraordinary continuation `ec_until`. +* `E7` — **UNTILEND** `( – )`, similar to **UNTIL**, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs a **RET**. +* `E8` — **WHILE** `(c0 c – )`, executes `c0` and pops an integer `x` from the resulting stack. If `x = 0`, exits the loop and transfers control to the original `cc`. If `x ≠ 0`, executes `c`, and then begins a new iteration. +* `E9` — **WHILEEND** `(c0 – )`, similar to **WHILE**, but uses the current continuation `cc` as the loop body. +* `EA` — **AGAIN** `(c – )`, similar to **REPEAT**, but executes `c` infinitely many times. A **RET** only begins a new iteration of the infinite loop, which can be exited only by an exception, or a **RETALT** (or an explicit **JMPX**). +* `EB` — **AGAINEND** `( – )`, similar to **AGAIN**, but performed with respect to the current continuation `cc`. +* `E314` — **REPEATBRK** `(n c – )`, similar to **REPEAT**, but also sets `c1` to the original `cc` after saving the old value of `c1` into the savelist of the original `cc`. In this way **RETALT** could be used to break out of the loop body. +* `E315` — **REPEATENDBRK** `(n – )`, similar to **REPEATEND**, but also sets `c1` to the original `c0` after saving the old value of `c1` into the savelist of the original `c0`. Equivalent to `SAMEALTSAVE; REPEATEND`. +* `E316` — **UNTILBRK** `(c – )`, similar to **UNTIL**, but also modifies `c1` in the same way as **REPEATBRK**. +* `E317` — **UNTILENDBRK** `( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. +* `E318` — **WHILEBRK** `(c0 c – )`, similar to **WHILE**, but also modifies `c1` in the same way as **REPEATBRK**. +* `E319` — **WHILEENDBRK** `(c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. +* `E31A` — **AGAINBRK** `(c – )`, similar to **AGAIN**, but also modifies `c1` in the same way as **REPEATBRK**. +* `E31B` — **AGAINENDBRK** `( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. + +--- + +### A.9 Exception generating and handling primitives + +#### A.9.1. Throwing exceptions + +* `F22_nn` — **THROW nn** `( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. +* `F26_nn` — **THROWIF nn** `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. +* `F2A_nn` — **THROWIFNOT nn** `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. +* `F2C4_nn` — **THROW nn** for `0 ≤ nn < 2^11`, an encoding of **THROW nn** for larger values. +* `F2CC_nn` — **THROWARG nn** `(x – x nn)`, throws exception `0 ≤ nn < 2^11` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. +* `F2D4_nn` — **THROWIF nn** `(f – )` for `0 ≤ nn < 2^11`. +* `F2DC_nn` — **THROWARGIF nn** `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f ≠ 0`. +* `F2E4_nn` — **THROWIFNOT nn** `(f – )` for `0 ≤ nn < 2^11`. +* `F2EC_nn` — **THROWARGIFNOT nn** `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f = 0`. +* `F2F0` — **THROWANY** `(n – 0 n)`, throws exception `0 ≤ n < 2^16` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. +* `F2F1` — **THROWARGANY** `(x n – x n)`, throws exception `0 ≤ n < 2^16` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. +* `F2F2` — **THROWANYIF** `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f ≠ 0`. +* `F2F3` — **THROWARGANYIF** `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f ≠ 0`. +* `F2F4` — **THROWANYIFNOT** `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f = 0`. +* `F2F5` — **THROWARGANYIFNOT** `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f = 0`. + +#### A.9.2. Catching and handling exceptions + +* `F2FF` — **TRY** `(c c0 – )`, sets `c2` to `c0`, saving the old value of `c2` both into the savelist of `c0` and into the savelist of the current continuation. Then runs `c`. If `c` does not throw any exceptions, the original value of `c2` is restored. If an exception occurs, execution is transferred to `c0`. +* `F3pr` — **TRYARGS p,r** `(c c0 – )`, similar to **TRY**, but with **CALLARGS p,r** internally used instead of **EXECUTE**. + +--- + +# A.10 Dictionary manipulation primitives + +TVM’s dictionary support is discussed at length in 3.3. The basic operations with dictionaries are listed in 3.3.10, while the taxonomy of dictionary +115 +A.10. Dictionary manipulation primitives +manipulation primitives is provided in 3.3.11. Here we use the concepts and notation introduced in those sections. + +Dictionaries admit two different representations as TVM stack values: + +* A `Slice` `s` with a serialization of a TL-B value of type `HashmapE(n, X)`. In other words, `s` consists either of one bit equal to zero (if the dictionary is empty), or of one bit equal to one and a reference to a `Cell` containing the root of the binary tree, i.e., a serialized value of type `Hashmap(n, X)`. +* A “maybe `Cell`” `c ?`, i.e., a value that is either a `Cell` (containing a serialized value of type `Hashmap(n, X)` as before) or a `Null` (corresponding to an empty dictionary). When a “maybe `Cell`” `c ?` is used to represent a dictionary, we usually denote it by `D` in the stack notation. + +Most of the dictionary primitives listed below accept and return dictionaries in the second form, which is more convenient for stack manipulation. However, serialized dictionaries inside larger TL-B objects use the first representation. + +Opcodes starting with `F4` and `F5` are reserved for dictionary operations. + +## A.10.1. Dictionary creation. + +* `6D` — **NEWDICT** `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for **PUSHNULL**, cf. A.3.1. +* `6E` — **DICTEMPTY** `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for **ISNULL**, cf. A.3.1. + +## A.10.2. Dictionary serialization and deserialization. + +* `CE` — **STDICTS** `(s b – b 0)`, stores a `Slice`-represented dictionary `s` into `Builder` `b`. It is actually a synonym for **STSLICE**. +* `F400` — **STDICT** or **STOPTREF** `(D b – b 0)`, stores dictionary `D` into `Builder` `b`, returing the resulting `Builder` `b 0`. In other words, if `D` is a cell, performs **STONE** and **STREF**; if `D` is `Null`, performs **NIP** and **STZERO**; otherwise throws a type checking exception. +* `F401` — **SKIPDICT** or **SKIPOPTREF** `(s – s 0)`, equivalent to **LDDICT**; **NIP** +* `F402` — **LDDICTS** `(s – s 0 s 00)`, loads (parses) a (`Slice`-represented) dictionary `s 0` from `Slice` `s`, and returns the remainder of `s` as `s 00`. This is a “split function” for all `HashmapE(n, X)` dictionary types. +* `F403` — **PLDDICTS** `(s – s 0)`, preloads a (`Slice`-represented) dictionary `s 0` from `Slice` `s`. Approximately equivalent to **LDDICTS**; **DROP**. +* `F404` — **LDDICT** or **LDOPTREF** `(s – D s0)`, loads (parses) a dictionary `D` from `Slice` `s`, and returns the remainder of `s` as `s 0`. May be applied to dictionaries or to values of arbitrary `(ˆY ) ?` types. +* `F405` — **PLDDICT** or **PLDOPTREF** `(s – D)`, preloads a dictionary `D` from `Slice` `s`. Approximately equivalent to **LDDICT**; **DROP**. +* `F406` — **LDDICTQ** `(s – D s0 −1 or s 0)`, a quiet version of **LDDICT**. +* `F407` — **PLDDICTQ** `(s – D −1 or 0)`, a quiet version of **PLDDICT**. + +## A.10.3. Get dictionary operations. + +* `F40A` — **DICTGET** `(k D n – x −1 or 0)`, looks up key `k` (represented by a `Slice`, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the value found as a `Slice` `x`. +* `F40B` — **DICTGETREF** `(k D n – c −1 or 0)`, similar to **DICTGET**, but with a **LDREF**; **ENDS** applied to `x` on success. This operation is useful for dictionaries of type `HashmapE(n, ˆY )`. +* `F40C` — **DICTIGET** `(i D n – x −1 or 0)`, similar to **DICTGET**, but with a signed (big-endian) n-bit `Integer` `i` as a key. If `i` does not fit into n bits, returns `0`. If `i` is a `NaN`, throws an integer overflow exception. +* `F40D` — **DICTIGETREF** `(i D n – c −1 or 0)`, combines **DICTIGET** with **DICTGETREF**: it uses signed n-bit `Integer` `i` as a key and returns a `Cell` instead of a `Slice` on success. +* `F40E` — **DICTUGET** `(i D n – x −1 or 0)`, similar to **DICTIGET**, but with unsigned (big-endian) n-bit `Integer` `i` used as a key. +* `F40F` — **DICTUGETREF** `(i D n – c −1 or 0)`, similar to **DICTIGETREF**, but with an unsigned n-bit `Integer` key `i`. + 117 + A.10. Dictionary manipulation primitives + +## A.10.4. Set/Replace/Add dictionary operations. + +The mnemonics of the following dictionary primitives are constructed in a systematic fashion according to the regular expression `DICT[, I, U](SET, REPLACE, ADD)[GET][REF]` depending on the type of the key used (a `Slice` or a signed or unsigned `Integer`), the dictionary operation to be performed, and the way the values are accepted and returned (as `Cells` or as `Slices`). Therefore, we provide a detailed description only for some primitives, assuming that this information is sufficient for the reader to understand the precise action of the remaining primitives. + +* `F412` — **DICTSET** `(x k D n – D0)`, sets the value associated with n-bit key `k` (represented by a `Slice` as in **DICTGET**) in dictionary `D` (also represented by a `Slice`) to value `x` (again a `Slice`), and returns the resulting dictionary as `D0`. +* `F413` — **DICTSETREF** `(c k D n – D0)`, similar to **DICTSET**, but with the value set to a reference to `Cell` `c`. +* `F414` — **DICTISET** `(x i D n – D0)`, similar to **DICTSET**, but with the key represented by a (big-endian) signed n-bit integer `i`. If `i` does not fit into n bits, a range check exception is generated. +* `F415` — **DICTISETREF** `(c i D n – D0)`, similar to **DICTSETREF**, but with the key a signed n-bit integer as in **DICTISET**. +* `F416` — **DICTUSET** `(x i D n – D0)`, similar to **DICTISET**, but with `i` an unsigned n-bit integer. +* `F417` — **DICTUSETREF** `(c i D n – D0)`, similar to **DICTISETREF**, but with `i` unsigned. +* `F41A` — **DICTSETGET** `(x k D n – D0 y −1 or D0 0)`, combines **DICTSET** with **DICTGET**: it sets the value corresponding to key `k` to `x`, but also returns the old value `y` associated with the key in question, if present. +* `F41B` — **DICTSETGETREF** `(c k D n – D0 c 0 −1 or D0 0)`, combines **DICTSETREF** with **DICTGETREF** similarly to **DICTSETGET**. +* `F41C` — **DICTISETGET** `(x i D n – D0 y −1 or D0 0)`, similar to **DICTSETGET**, but with the key represented by a big-endian signed n-bit `Integer` `i` +* `F41D` — **DICTISETGETREF** `(c i D n – D0 c 0 −1 or D0 0)`, a version of **DICTSETGETREF** with signed `Integer` `i` as a key. +* `F41E` — **DICTUSETGET** `(x i D n – D0 y −1 or D0 0)`, similar to **DICTISETGET**, but with `i` an unsigned n-bit integer. +* `F41F` — **DICTUSETGETREF** `(c i D n – D0 c 0 −1 or D0 0)`. +* `F422` — **DICTREPLACE** `(x k D n – D0 −1 or D 0)`, a Replace operation, which is similar to **DICTSET**, but sets the value of key `k` in dictionary `D` to `x` only if the key `k` was already present in `D`. +* `F423` — **DICTREPLACEREF** `(c k D n – D0 −1 or D 0)`, a Replace counterpart of **DICTSETREF**. +* `F424` — **DICTIREPLACE** `(x i D n – D0 −1 or D 0)`, a version of **DICTREPLACE** with signed n-bit `Integer` `i` used as a key. +* `F425` — **DICTIREPLACEREF** `(c i D n – D0 −1 or D 0)`. +* `F426` — **DICTUREPLACE** `(x i D n – D0 −1 or D 0)`. +* `F427` — **DICTUREPLACEREF** `(c i D n – D0 −1 or D 0)`. +* `F42A` — **DICTREPLACEGET** `(x k D n – D0 y −1 or D 0)`, a Replace counterpart of **DICTSETGET**: on success, also returns the old value associated with the key in question. +* `F42B` — **DICTREPLACEGETREF** `(c k D n – D0 c 0 −1 or D 0)`. +* `F42C` — **DICTIREPLACEGET** `(x i D n – D0 y −1 or D 0)`. +* `F42D` — **DICTIREPLACEGETREF** `(c i D n – D0 c 0 −1 or D 0)`. +* `F42E` — **DICTUREPLACEGET** `(x i D n – D0 y −1 or D 0)`. +* `F42F` — **DICTUREPLACEGETREF** `(c i D n – D0 c 0 −1 or D 0)`. +* `F432` — **DICTADD** `(x k D n – D0 −1 or D 0)`, an Add counterpart of **DICTSET**: sets the value associated with key `k` in dictionary `D` to `x`, but only if it is not already present in `D`. +* `F433` — **DICTADDREF** `(c k D n – D0 −1 or D 0)`. + 119 + A.10. Dictionary manipulation primitives +* `F434` — **DICTIADD** `(x i D n – D0 −1 or D 0)`. +* `F435` — **DICTIADDREF** `(c i D n – D0 −1 or D 0)`. +* `F436` — **DICTUADD** `(x i D n – D0 −1 or D 0)`. +* `F437` — **DICTUADDREF** `(c i D n – D0 −1 or D 0)`. +* `F43A` — **DICTADDGET** `(x k D n – D0 −1 or D y 0)`, an Add counterpart of **DICTSETGET**: sets the value associated with key `k` in dictionary `D` to `x`, but only if key `k` is not already present in `D`. Otherwise, just returns the old value `y` without changing the dictionary. +* `F43B` — **DICTADDGETREF** `(c k D n – D0 −1 or D c0 0)`, an Add counterpart of **DICTSETGETREF**. +* `F43C` — **DICTIADDGET** `(x i D n – D0 −1 or D y 0)`. +* `F43D` — **DICTIADDGETREF** `(c i D n – D0 −1 or D c0 0)`. +* `F43E` — **DICTUADDGET** `(x i D n – D0 −1 or D y 0)`. +* `F43F` — **DICTUADDGETREF** `(c i D n – D0 −1 or D c0 0)`. + +## A.10.5. Builder-accepting variants of Set dictionary operations. + +The following primitives accept the new value as a `Builder` `b` instead of a `Slice` `x`, which often is more convenient if the value needs to be serialized from several components computed in the stack. (This is reflected by appending a `B` to the mnemonics of the corresponding Set primitives that work with `Slices`.) The net effect is roughly equivalent to converting `b` into a `Slice` by **ENDC**; **CTOS** and executing the corresponding primitive listed in A.10.4. + +* `F441` — **DICTSETB** `(b k D n – D0)`. +* `F442` — **DICTISETB** `(b i D n – D0)`. +* `F443` — **DICTUSETB** `(b i D n – D0)`. +* `F445` — **DICTSETGETB** `(b k D n – D0 y −1 or D0 0)`. +* `F446` — **DICTISETGETB** `(b i D n – D0 y −1 or D0 0)`. +* `F447` — **DICTUSETGETB** `(b i D n – D0 y −1 or D0 0)`. +* `F449` — **DICTREPLACEB** `(b k D n – D0 −1 or D 0)`. +* `F44A` — **DICTIREPLACEB** `(b i D n – D0 −1 or D 0)`. +* `F44B` — **DICTUREPLACEB** `(b i D n – D0 −1 or D 0)`. +* `F44D` — **DICTREPLACEGETB** `(b k D n – D0 y −1 or D 0)`. +* `F44E` — **DICTIREPLACEGETB** `(b i D n – D0 y −1 or D 0)`. +* `F44F` — **DICTUREPLACEGETB** `(b i D n – D0 y −1 or D 0)`. +* `F451` — **DICTADDB** `(b k D n – D0 −1 or D 0)`. +* `F452` — **DICTIADDB** `(b i D n – D0 −1 or D 0)`. +* `F453` — **DICTUADDB** `(b i D n – D0 −1 or D 0)`. +* `F455` — **DICTADDGETB** `(b k D n – D0 −1 or D y 0)`. +* `F456` — **DICTIADDGETB** `(b i D n – D0 −1 or D y 0)`. +* `F457` — **DICTUADDGETB** `(b i D n – D0 −1 or D y 0)`. + +## A.10.6. Delete dictionary operations. + +* `F459` — **DICTDEL** `(k D n – D0 −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0` and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. +* `F45A` — **DICTIDEL** `(i D n – D0 ?)`, a version of **DICTDEL** with the key represented by a signed n-bit `Integer` `i`. If `i` does not fit into n bits, simply returns `D 0` (“key not found, dictionary unmodified”). +* `F45B` — **DICTUDEL** `(i D n – D0 ?)`, similar to **DICTIDEL**, but with `i` an unsigned n-bit integer. +* `F462` — **DICTDELGET** `(k D n – D0 x −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0`, the original value `x` associated with the key `k` (represented by a `Slice`), and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. + 121 + A.10. Dictionary manipulation primitives +* `F463` — **DICTDELGETREF** `(k D n – D0 c −1 or D 0)`, similar to **DICTDELGET**, but with **LDREF**; **ENDS** applied to `x` on success, so that the value returned `c` is a `Cell`. +* `F464` — **DICTIDELGET** `(i D n – D0 x −1 or D 0)`, a variant of primitive **DICTDELGET** with signed n-bit integer `i` as a key. +* `F465` — **DICTIDELGETREF** `(i D n – D0 c −1 or D 0)`, a variant of primitive **DICTIDELGET** returning a `Cell` instead of a `Slice`. +* `F466` — **DICTUDELGET** `(i D n – D0 x −1 or D 0)`, a variant of primitive **DICTDELGET** with unsigned n-bit integer `i` as a key. +* `F467` — **DICTUDELGETREF** `(i D n – D0 c −1 or D 0)`, a variant of primitive **DICTUDELGET** returning a `Cell` instead of a `Slice`. + +## A.10.7. “Maybe reference” dictionary operations. + +The following operations assume that a dictionary is used to store values `c ?` of type `Cell ?` (“Maybe `Cell`”), which can be used in particular to store dictionaries as values in other dictionaries. The representation is as follows: if `c ?` is a `Cell`, it is stored as a value with no data bits and exactly one reference to this `Cell`. If `c ?` is `Null`, then the corresponding key must be absent from the dictionary altogether. + +* `F469` — **DICTGETOPTREF** `(k D n – c ? )`, a variant of **DICTGETREF** that returns `Null` instead of the value `c ?` if the key `k` is absent from dictionary `D`. +* `F46A` — **DICTIGETOPTREF** `(i D n – c ? )`, similar to **DICTGETOPTREF**, but with the key given by signed n-bit `Integer` `i`. If the key `i` is out of range, also returns `Null`. +* `F46B` — **DICTUGETOPTREF** `(i D n – c ? )`, similar to **DICTGETOPTREF**, but with the key given by unsigned n-bit `Integer` `i`. +* `F46D` — **DICTSETGETOPTREF** `(c ? k D n – D0 c˜ ? )`, a variant of both **DICTGETOPTREF** and **DICTSETGETREF** that sets the value corresponding to key `k` in dictionary `D` to `c ?` (if `c ?` is `Null`, then the key is deleted instead), and returns the old value `c˜ ?` (if the key `k` was absent before, returns `Null` instead). +* `F46E` — **DICTISETGETOPTREF** `(c ? i D n – D0 c˜ ? )`, similar to primitive **DICTSETGETOPTREF**, but using signed n-bit `Integer` `i` as a key. If `i` does not fit into n bits, throws a range checking exception. +* `F46F` — **DICTUSETGETOPTREF** `(c ? i D n – D0 c˜ ? )`, similar to primitive **DICTSETGETOPTREF**, but using unsigned n-bit `Integer` `i` as a key. + +## A.10.8. Prefix code dictionary operations. + +These are some basic operations for constructing prefix code dictionaries (cf. 3.4.2). The primary application for prefix code dictionaries is deserializing TL-B serialized data structures, or, more generally, parsing prefix codes. Therefore, most prefix code dictionaries will be constant and created at compile time, not by the following primitives. +Some Get operations for prefix code dictionaries may be found in A.10.11. +Other prefix code dictionary operations include: + +* `F470` — **PFXDICTSET** `(x k D n – D0 −1 or D 0)`. +* `F471` — **PFXDICTREPLACE** `(x k D n – D0 −1 or D 0)`. +* `F472` — **PFXDICTADD** `(x k D n – D0 −1 or D 0)`. +* `F473` — **PFXDICTDEL** `(k D n – D0 −1 or D 0)`. + +These primitives are completely similar to their non-prefix code counterparts **DICTSET** etc (cf. A.10.4), with the obvious difference that even a Set may fail in a prefix code dictionary, so a success flag must be returned by **PFXDICTSET** as well. + +## A.10.9. Variants of GetNext and GetPrev operations. + +* `F474` — **DICTGETNEXT** `(k D n – x 0 k 0 −1 or 0)`, computes the minimal key `k 0` in dictionary `D` that is lexicographically greater than `k`, and returns `k 0` (represented by a `Slice`) along with associated value `x 0` (also represented by a `Slice`). +* `F475` — **DICTGETNEXTEQ** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETNEXT**, but computes the minimal key `k 0` that is lexicographically greater than or equal to `k`. +* `F476` — **DICTGETPREV** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETNEXT**, but computes the maximal key `k 0` lexicographically smaller than `k`. + 123 + A.10. Dictionary manipulation primitives +* `F477` — **DICTGETPREVEQ** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETPREV**, but computes the maximal key `k 0` lexicographically smaller than or equal to `k`. +* `F478` — **DICTIGETNEXT** `(i D n – x 0 i 0 −1 or 0)`, similar to **DICTGETNEXT**, but interprets all keys in dictionary `D` as big-endian signed n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits). +* `F479` — **DICTIGETNEXTEQ** `(i D n – x 0 i 0 −1 or 0)`. +* `F47A` — **DICTIGETPREV** `(i D n – x 0 i 0 −1 or 0)`. +* `F47B` — **DICTIGETPREVEQ** `(i D n – x 0 i 0 −1 or 0)`. +* `F47C` — **DICTUGETNEXT** `(i D n – x 0 i 0 −1 or 0)`, similar to **DICTGETNEXT**, but interprets all keys in dictionary `D` as big-endian unsigned n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits, and is not necessarily nonnegative). +* `F47D` — **DICTUGETNEXTEQ** `(i D n – x 0 i 0 −1 or 0)`. +* `F47E` — **DICTUGETPREV** `(i D n – x 0 i 0 −1 or 0)`. +* `F47F` — **DICTUGETPREVEQ** `(i D n – x 0 i 0 −1 or 0)`. + +## A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. + +* `F482` — **DICTMIN** `(D n – x k −1 or 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. +* `F483` — **DICTMINREF** `(D n – c k −1 or 0)`, similar to **DICTMIN**, but returns the only reference in the value as a `Cell` `c`. +* `F484` — **DICTIMIN** `(D n – x i −1 or 0)`, somewhat similar to **DICTMIN**, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by **DICTMIN** and **DICTUMIN** +* `F485` — **DICTIMINREF** `(D n – c i −1 or 0)`. +* `F486` — **DICTUMIN** `(D n – x i −1 or 0)`, similar to **DICTMIN**, but returns the key as an unsigned n-bit `Integer` `i`. +* `F487` — **DICTUMINREF** `(D n – c i −1 or 0)`. +* `F48A` — **DICTMAX** `(D n – x k −1 or 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. +* `F48B` — **DICTMAXREF** `(D n – c k −1 or 0)`. +* `F48C` — **DICTIMAX** `(D n – x i −1 or 0)`. +* `F48D` — **DICTIMAXREF** `(D n – c i −1 or 0)`. +* `F48E` — **DICTUMAX** `(D n – x i −1 or 0)`. +* `F48F` — **DICTUMAXREF** `(D n – c i −1 or 0)`. +* `F492` — **DICTREMMIN** `(D n – D0 x k −1 or D 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. +* `F493` — **DICTREMMINREF** `(D n – D0 c k −1 or D 0)`, similar to **DICTREMMIN**, but returns the only reference in the value as a `Cell` `c`. +* `F494` — **DICTIREMMIN** `(D n – D0 x i −1 or D 0)`, somewhat similar to **DICTREMMIN**, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by **DICTREMMIN** and **DICTUREMMIN**. +* `F495` — **DICTIREMMINREF** `(D n – D0 c i −1 or D 0)`. +* `F496` — **DICTUREMMIN** `(D n – D0 x i −1 or D 0)`, similar to **DICTREMMIN**, but returns the key as an unsigned n-bit `Integer` `i`. +* `F497` — **DICTUREMMINREF** `(D n – D0 c i −1 or D 0)`. + 125 + A.10. Dictionary manipulation primitives +* `F49A` — **DICTREMMAX** `(D n – D0 x k −1 or D 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. +* `F49B` — **DICTREMMAXREF** `(D n – D0 c k −1 or D 0)`. +* `F49C` — **DICTIREMMAX** `(D n – D0 x i −1 or D 0)`. +* `F49D` — **DICTIREMMAXREF** `(D n – D0 c i −1 or D 0)`. +* `F49E` — **DICTUREMMAX** `(D n – D0 x i −1 or D 0)`. +* `F49F` — **DICTUREMMAXREF** `(D n – D0 c i −1 or D 0)`. + +## A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. + +* `F4A0` — **DICTIGETJMP** `(i D n – )`, similar to **DICTIGET** (cf. A.10.12), but with `x` **BLESS**ed into a continuation with a subsequent **JMPX** to it on success. On failure, does nothing. This is useful for implementing switch/case constructions. +* `F4A1` — **DICTUGETJMP** `(i D n – )`, similar to **DICTIGETJMP**, but performs **DICTUGET** instead of **DICTIGET**. +* `F4A2` — **DICTIGETEXEC** `(i D n – )`, similar to **DICTIGETJMP**, but with **EXECUTE** instead of **JMPX**. +* `F4A3` — **DICTUGETEXEC** `(i D n – )`, similar to **DICTUGETJMP**, but with **EXECUTE** instead of **JMPX**. +* `F4A6_n` — **DICTPUSHCONST n** `( – D n)`, pushes a non-empty constant dictionary `D` (as a `Cell ?`) along with its key length `0 ≤ n ≤ 1023`, stored as a part of the instruction. The dictionary itself is created from the first of remaining references of the current continuation. In this way, the complete **DICTPUSHCONST** instruction can be obtained by first serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and a cell reference), and then the unsigned 10-bit integer `n` (as if by a **STU 10** instruction). An empty dictionary can be pushed by a **NEWDICT** primitive (cf. A.10.1) instead. +* `F4A8` — **PFXDICTGETQ** `(s D n – s 0 x s00 −1 or s 0)`, looks up the unique prefix of `Slice` `s` present in the prefix code dictionary (cf. 3.4.2) represented by `Cell ?` `D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is returned as `s 0`, and the corresponding value (also a `Slice`) as `x`. The remainder of `s` is returned as a `Slice` `s 00`. If no prefix of `s` is a key in prefix code dictionary `D`, returns the unchanged `s` and a zero flag to indicate failure. +* `F4A9` — **PFXDICTGET** `(s D n – s 0 x s00)`, similar to **PFXDICTGET**, but throws a cell deserialization failure exception on failure. +* `F4AA` — **PFXDICTGETJMP** `(s D n – s 0 s 00 or s)`, similar to **PFXDICTGETQ**, but on success **BLESS**es the value `x` into a `Continuation` and transfers control to it as if by a **JMPX**. On failure, returns `s` unchanged and continues execution. +* `F4AB` — **PFXDICTGETEXEC** `(s D n – s 0 s 00)`, similar to **PFXDICTGETJMP**, but **EXEC**utes the continuation found instead of jumping to it. On failure, throws a cell deserialization exception. +* `F4AE_n` — **PFXDICTCONSTGETJMP n** or **PFXDICTSWITCH n** `(s – s 0 s 00 or s)`, combines **DICTPUSHCONST n** for `0 ≤ n ≤ 1023` with **PFXDICTGETJMP**. +* `F4BC` — **DICTIGETJMPZ** `(i D n – i or nothing)`, a variant of **DICTIGETJMP** that returns index `i` on failure. +* `F4BD` — **DICTUGETJMPZ** `(i D n – i or nothing)`, a variant of **DICTUGETJMP** that returns index `i` on failure. +* `F4BE` — **DICTIGETEXECZ** `(i D n – i or nothing)`, a variant of **DICTIGETEXEC** that returns index `i` on failure. +* `F4BF` — **DICTUGETEXECZ** `(i D n – i or nothing)`, a variant of **DICTUGETEXEC** that returns index `i` on failure. + +## A.10.12. SubDict dictionary operations. + +* `F4B1` — **SUBDICTGET** `(k l D n – D0)`, constructs a subdictionary consisting of all keys beginning with prefix `k` (represented by a `Slice`, the first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, + 127 + A.11. Application-specific primitives + returns the new subdictionary of the same type `HashmapE(n, X)` as a `Slice` `D0`. +* `F4B2` — **SUBDICTIGET** `(x l D n – D0)`, variant of **SUBDICTGET** with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. +* `F4B3` — **SUBDICTUGET** `(x l D n – D0)`, variant of **SUBDICTGET** with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. +* `F4B5` — **SUBDICTRPGET** `(k l D n – D0)`, similar to **SUBDICTGET**, but removes the common prefix `k` from all keys of the new dictionary `D0`, which becomes of type `HashmapE(n − l, X)`. +* `F4B6` — **SUBDICTIRPGET** `(x l D n – D0)`, variant of **SUBDICTRPGET** with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. +* `F4B7` — **SUBDICTURPGET** `(x l D n – D0)`, variant of **SUBDICTRPGET** with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. +* `F4BC–F4BF` — used by **DICT...Z** primitives in A.10.11. + +--- +# A.11 Application-specific primitives + +Opcode range `F8...FB` is reserved for the application-specific primitives. When TVM is used to execute TON Blockchain smart contracts, these application-specific primitives are in fact TON Blockchain-specific. + +## A.11.1. External actions and access to blockchain configuration data. + +Some of the primitives listed below pretend to produce some externally visible actions, such as sending a message to another smart contract. In fact, the execution of a smart contract in TVM never has any effect apart from a modification of the TVM state. All external actions are collected into a linked list stored in special register `c5` (“output actions”). Additionally, some primitives use the data kept in the first component of the Tuple stored in `c7` (“root of temporary data”, cf. 1.3.2). Smart contracts are free to modify any other data kept in the cell `c7`, provided the first reference remains intact (otherwise some application-specific primitives would be likely to throw exceptions when invoked). + +Most of the primitives listed below use 16-bit opcodes. + +A.11. Application-specific primitives + +## A.11.2. Gas-related primitives. + +Of the following primitives, only the first two are “pure” in the sense that they do not use `c5` or `c7`. + +* `F800` — **ACCEPT**, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. 1.4), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence no gas) with themselves. +* `F801` — **SETGASLIMIT** `(g – )`, sets current gas limit `gl` to the minimum of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed so far (including the present instruction) exceeds the resulting value of `gl`, an (unhandled) out of gas exception is thrown before setting new gas limits. Notice that **SETGASLIMIT** with an argument `g ≥ 2^63 − 1` is equivalent to **ACCEPT**. +* `F802` — **BUYGAS** `(x – )`, computes the amount of gas that can be bought for `x` nanograms, and sets `gl` accordingly in the same way as **SETGASLIMIT**. +* `F804` — **GRAMTOGAS** `(x – g)`, computes the amount of gas that can be bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `2^63−1`, it is replaced with this value. +* `F805` — **GASTOGRAM** `(g – x)`, computes the price of `g` gas in nanograms. +* `F806–F80E` — Reserved for gas-related primitives. +* `F80F` — **COMMIT** `( – )`, commits the current state of registers `c4` (“persistent data”) and `c5` (“actions”) so that the current execution is considered “successful” with the saved values even if an exception is thrown later. + +## A.11.3. Pseudo-random number generator primitives. + +The pseudo-random number generator uses the random seed (parameter `#6`, cf. A.11.4), an unsigned 256-bit `Integer`, and (sometimes) other data kept in `c7`. +The initial value of the random seed before a smart contract is executed in TON Blockchain is a hash of the smart contract address and the global block random seed. If there are several runs of the same smart contract inside a block, then all of these runs will have the same random seed. This can be fixed, for example, by running **LTIME**; **ADDRAND** before using the pseudo-random number generator for the first time. + +* `F810` — **RANDU256** `( – x)`, generates a new pseudo-random unsigned 256-bit `Integer` `x`. The algorithm is as follows: if `r` is the old value of the random seed, considered as a 32-byte array (by constructing the big-endian representation of an unsigned 256-bit integer), then its `sha512(r)` is computed; the first 32 bytes of this hash are stored as the new value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`. +* `F811` — **RAND** `(y – z)`, generates a new pseudo-random integer `z` in the range `0 ... y − 1` (or `y ... − 1`, if `y < 0`). More precisely, an unsigned random value `x` is generated as in **RAND256U**; then `z := ⌊x·y/2^256⌋` is computed. Equivalent to **RANDU256**; **MULRSHIFT** `256`. +* `F814` — **SETRAND** `(x – )`, sets the random seed to unsigned 256-bit `Integer` `x`. +* `F815` — **ADDRAND** `(x – )`, mixes unsigned 256-bit `Integer` `x` into the random seed `r` by setting the random seed to `sha256` of the concatenation of two 32-byte strings: the first with the big-endian representation of the old seed `r`, and the second with the big-endian representation of `x`. +* `F810–F81F` — Reserved for pseudo-random number generator primitives. + `129` + A.11. Application-specific primitives + +## A.11.4. Configuration primitives. + +The following primitives read configuration data provided in the Tuple stored in the first component of the Tuple at `c7`. Whenever TVM is invoked for executing TON Blockchain smart contracts, this Tuple is initialized by a `SmartContractInfo` structure; configuration primitives assume that it has remained intact. + +* `F82i` — **GETPARAM** `i` `( – x)`, returns the `i`-th parameter from the Tuple provided at `c7` for `0 ≤ i < 16`. Equivalent to **PUSH** `c7`; **FIRST**; **INDEX** `i`. If one of these internal operations fails, throws an appropriate type checking or range checking exception +* `F823` — **NOW** `( – x)`, returns the current Unix time as an `Integer`. If it is impossible to recover the requested value starting from `c7`, throws a type checking or range checking exception as appropriate. Equivalent to **GETPARAM** `3`. +* `F824` — **BLOCKLT** `( – x)`, returns the starting logical time of the current block. Equivalent to **GETPARAM** `4`. +* `F825` — **LTIME** `( – x)`, returns the logical time of the current transaction. Equivalent to **GETPARAM** `5`. +* `F826` — **RANDSEED** `( – x)`, returns the current random seed as an unsigned 256-bit `Integer`. Equivalent to **GETPARAM** `6`. +* `F827` — **BALANCE** `( – t)`, returns the remaining balance of the smart contract as a `Tuple` consisting of an `Integer` (the remaining Gram balance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys representing the balance of “extra currencies”). Equivalent to **GETPARAM** `7`. Note that RAW primitives such as **SENDRAWMSG** do not update this field. +* `F828` — **MYADDR** `( – s)`, returns the internal address of the current smart contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed further using primitives such as **PARSESTDADDR** or **REWRITESTDADDR**. Equivalent to **GETPARAM** `8`. +* `F829` — **CONFIGROOT** `( – D)`, returns the `Maybe Cell` `D` with the current global configuration dictionary. Equivalent to **GETPARAM** `9`. +* `F830` — **CONFIGDICT** `( – D 32)`, returns the global configuration dictionary along with its key length (`32`). Equivalent to **CONFIGROOT**; **PUSHINT** `32`. +* `F832` — **CONFIGPARAM** `(i – c −1 or 0)`, returns the value of the global configuration parameter with integer index `i` as a `Cell` `c`, and a flag to indicate success. Equivalent to **CONFIGDICT**; **DICTIGETREF**. +* `F833` — **CONFIGOPTPARAM** `(i – c ? )`, returns the value of the global configuration parameter with integer index `i` as a `Maybe Cell` `c ?`. Equivalent to **CONFIGDICT**; **DICTIGETOPTREF**. +* `F820–F83F` — Reserved for configuration primitives. + `131` + A.11. Application-specific primitives + +## A.11.5. Global variable primitives. + +The “global variables” may be helpful in implementing some high-level smart-contract languages. They are in fact stored as components of the Tuple at `c7`: the `k`-th global variable simply is the `k`-th component of this Tuple, for `1 ≤ k ≤ 254`. By convention, the `0`-th component is used for the “configuration parameters” of A.11.4, so it is not available as a global variable. + +* `F840` — **GETGLOBVAR** `(k – x)`, returns the `k`-th global variable for `0 ≤ k < 255`. Equivalent to **PUSH** `c7`; **SWAP**; **INDEXVARQ** (cf. A.3.2). +* `F85_k` — **GETGLOB** `k` `( – x)`, returns the `k`-th global variable for `1 ≤ k ≤ 31`. Equivalent to **PUSH** `c7`; **INDEXQ** `k`. +* `F860` — **SETGLOBVAR** `(x k – )`, assigns `x` to the `k`-th global variable for `0 ≤ k < 255`. Equivalent to **PUSH** `c7`; **ROTREV**; **SETINDEXVARQ**; **POP** `c7`. +* `F87_k` — **SETGLOB** `k` `(x – )`, assigns `x` to the `k`-th global variable for `1 ≤ k ≤ 31`. Equivalent to **PUSH** `c7`; **SWAP**; **SETINDEXQ** `k`; **POP** `c7`. + +## A.11.6. Hashing and cryptography primitives. + +* `F900` — **HASHCU** `(c – x)`, computes the representation hash (cf. 3.1.5) of a `Cell` `c` and returns it as a 256-bit unsigned integer `x`. Useful for signing and checking signatures of arbitrary entities represented by a tree of cells. +* `F901` — **HASHSU** `(s – x)`, computes the hash of a `Slice` `s` and returns it as a 256-bit unsigned integer `x`. The result is the same as if an ordinary cell containing only data and references from `s` had been created and its hash computed by **HASHCU**. +* `F902` — **SHA256U** `(s – x)`, computes `sha256` of the data bits of `Slice` `s`. If the bit length of `s` is not divisible by eight, throws a cell underflow exception. The hash value is returned as a 256-bit unsigned integer `x`. +* `F910` — **CHKSIGNU** `(h s k – ? )`, checks the Ed25519-signature `s` of a hash `h` (a 256-bit unsigned integer, usually computed as the hash of some data) using public key `k` (also represented by a 256-bit unsigned integer). The signature `s` must be a `Slice` containing at least 512 databits; only the first 512 bits are used. The result is `−1` if the signature is valid, `0` otherwise. Notice that **CHKSIGNU** is equivalent to **ROT**; **NEWB**; **STU** `256`; **ENDB**; **NEWC**; **ROTREV**; **CHKSIGNS**, i.e., to **CHKSIGNS** with the first argument `d` set to 256-bit `Slice` containing `h`. Therefore, if `h` is computed as the hash of some data, these data are hashed twice, the second hashing occurring inside **CHKSIGNS**. +* `F911` — **CHKSIGNS** `(d s k – ? )`, checks whether `s` is a valid Ed25519-signature of the data portion of `Slice` `d` using public key `k`, similarly to **CHKSIGNU**. If the bit length of `Slice` `d` is not divisible by eight, throws a cell underflow exception. The verification of Ed25519 signatures is the standard one, with `sha256` used to reduce `d` to the 256-bit number that is actually signed. +* `F912–F93F` — Reserved for hashing and cryptography primitives. + +## A.11.7. Miscellaneous primitives. + +* `F940` — **CDATASIZEQ** `(c n – x y z −1 or 0)`, recursively computes the count of distinct cells `x`, data bits `y`, and cell references `z` in the dag rooted at `Cell` `c`, effectively returning the total storage used by this dag taking into account the identification of equal cells. The values of `x`, `y`, and `z` are computed by a depth-first traversal of this dag, with a hash table of visited cell hashes used to prevent visits of already-visited cells. The total count of visited cells `x` cannot exceed non-negative `Integer` `n`; otherwise the computation is aborted before visiting the `(n + 1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, returns `x = y = z = 0`. +* `F941` — **CDATASIZE** `(c n – x y z)`, a non-quiet version of **CDATASIZEQ** that throws a cell overflow exception (8) on failure. +* `F942` — **SDATASIZEQ** `(s n – x y z −1 or 0)`, similar to **CDATASIZEQ**, but accepting a `Slice` `s` instead of a `Cell`. The returned value of `x` does not take into account the cell that contains the slice `s` itself; however, the data bits and the cell references of `s` are accounted for in `y` and `z`. +* `F943` — **SDATASIZE** `(s n – x y z)`, a non-quiet version of **SDATASIZEQ** that throws a cell overflow exception (8) on failure. +* `F944–F97F` — Reserved for miscellaneous TON-specific primitives that do not fall into any other specific category. + `133` + A.11. Application-specific primitives + +## A.11.8. Currency manipulation primitives. + +* `FA00` — **LDGRAMS** or **LDVARUINT16** `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to **LDU** `4`; **SWAP**; **LSHIFT** `3`; **LDUX**. +* `FA01` — **LDVARINT16** `(s – x s0)`, similar to **LDVARUINT16**, but loads a signed `Integer` `x`. Approximately equivalent to **LDU** `4`; **SWAP**; **LSHIFT** `3`; **LDIX**. +* `FA02` — **STGRAMS** or **STVARUINT16** `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2^120−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2^(8l)`, followed by an `8l`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. +* `FA03` — **STVARINT16** `(b x – b 0)`, similar to **STVARUINT16**, but serializes a signed `Integer` `x` in the range `−2^119 ... 2^119 − 1`. +* `FA04` — **LDVARUINT32** `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2^248`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to **LDU** `5`; **SWAP**; **SHIFT** `3`; **LDUX**. +* `FA05` — **LDVARINT32** `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2^247 ≤ x < 2^247`. +* `FA06` — **STVARUINT32** `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2^248` as a `VarUInteger 32`. +* `FA07` — **STVARINT32** `(b x – b 0)`, serializes an `Integer` `−2^247 ≤ x < 2^247` as a `VarInteger 32`. +* `FA08–FA1F` — Reserved for currency manipulation primitives. + +## A.11.9. Message and address manipulation primitives. + +The message and address manipulation primitives listed below serialize and deserialize values according to the following TL-B scheme (cf. 3.3.4): + +``` +addr_none$00 = MsgAddressExt; +addr_extern$01 len:(## 8) external_address:(bits len) = MsgAddressExt; +anycast_info$_ depth:(#<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; +addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt; +addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) workchain_id:int32 address:(bits addr_len) = MsgAddressInt; +_ _:MsgAddressInt = MsgAddress; +_ _:MsgAddressExt = MsgAddress; + +int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + src:MsgAddress dest:MsgAddressInt + value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams + created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; + +ext_out_msg_info$11 src:MsgAddress dest:MsgAddressExt + created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; +``` + +A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: + +* `addr_none` is represented by `t = (0)`, i.e., a `Tuple` containing exactly one `Integer` equal to zero. +* `addr_extern` is represented by `t = (1, s)`, where `Slice` `s` contains the field `external_address`. In other words, `t` is a pair (a `Tuple` consisting of two entries), containing an `Integer` equal to one and `Slice` `s`. +* `addr_std` is represented by `t = (2, u, x, s)`, where `u` is either a `Null` (if `anycast` is absent) or a `Slice` `s0` containing `rewrite_pfx` (if `anycast` is present). Next, `Integer` `x` is the `workchain_id`, and `Slice` `s` contains the address. + `135` + A.11. Application-specific primitives +* `addr_var` is represented by `t = (3, u, x, s)`, where `u`, `x`, and `s` have the same meaning as for `addr_std`. + +The following primitives, which use the above conventions, are defined: + +* `FA40` — **LDMSGADDR** `(s – s 0 s 00)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s 0` and the remainder `s 00` of `s` as `CellSlices`. +* `FA41` — **LDMSGADDRQ** `(s – s 0 s 00 −1 or s 0)`, a quiet version of **LDMSGADDR**: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. +* `FA42` — **PARSEMSGADDR** `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. +* `FA43` — **PARSEMSGADDRQ** `(s – t −1 or 0)`, a quiet version of **PARSEMSGADDR**: returns a zero on error instead of throwing an exception. +* `FA44` — **REWRITESTDADDR** `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. +* `FA45` — **REWRITESTDADDRQ** `(s – x y −1 or 0)`, a quiet version of primitive **REWRITESTDADDR**. +* `FA46` — **REWRITEVARADDR** `(s – x s0)`, a variant of **REWRITESTDADDR** that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). +* `FA47` — **REWRITEVARADDRQ** `(s – x s0 −1 or 0)`, a quiet version of primitive **REWRITEVARADDR**. +* `FA48–FA5F` — Reserved for message and address manipulation primitives. + +## A.11.10. Outbound message and output action primitives. + +* `FB00` — **SENDRAWMSG** `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. +* `FB02` — **RAWRESERVE** `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. +* `FB03` — **RAWRESERVEX** `(x D y – )`, similar to **RAWRESERVE**, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. + `137` + A.12. Debug primitives +* `FB04` — **SETCODE** `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. +* `FB06` — **SETLIBCODE** `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. +* `FB07` — **CHANGELIB** `(h x – )`, creates an output action similarly to **SETLIBCODE**, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. +* `FB08–FB3F` — Reserved for output action primitives. + +--- +# A.12 Debug primitives + +Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) **NOP** operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. + +## A.12.1. Debug primitives as multibyte NOPs. + +`138` +A.12. Debug primitives + +* `FEnn` — **DEBUG** `nn`, for `0 ≤ nn < 240`, is a two-byte **NOP**. +* `FEFnssss` — **DEBUGSTR** `ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte **NOP**, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. + +## A.12.2. Debug primitives as operations without side-effect. + +Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte **NOP**s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as **NOP**s, but they cannot throw exceptions. + +* `FE00` — **DUMPSTK**, dumps the stack (at most the top 255 values) and shows the total stack depth. +* `FE0n` — **DUMPSTKTOP** `n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. +* `FE10` — **HEXDUMP**, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. +* `FE11` — **HEXPRINT**, similar to **HEXDUMP**, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. +* `FE12` — **BINDUMP**, dumps `s0` in binary form, similarly to **HEXDUMP**. +* `FE13` — **BINPRINT**, outputs the binary representation of `s0` to a text buffer. +* `FE14` — **STRDUMP**, dumps the `Slice` at `s0` as an UTF-8 string. +* `FE15` — **STRPRINT**, similar to **STRDUMP**, but outputs the string into a text buffer (without carriage return). +* `FE1E` — **DEBUGOFF**, disables all debug output until it is re-enabled by a **DEBUGON**. More precisely, this primitive increases an internal counter, which disables all debug operations (except **DEBUGOFF** and **DEBUGON**) when strictly positive. + `139` + A.13. Codepage primitives +* `FE1F` — **DEBUGON**, enables debug output (in a debug version of TVM). +* `FE2n` — **DUMP s(n)**, `0 ≤ n < 15`, dumps `s(n)`. +* `FE3n` — **PRINT s(n)**, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. +* `FEC0–FEEF` — Use these opcodes for custom/experimental debug operations. +* `FEFnssss` — **DUMPTOSFMT** `ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). +* `FEFn00ssss` — **LOGSTR** `ssss`, string `ssss` is `n` bytes long. +* `FEF000` — **LOGFLUSH**, flushes all pending debug output from the buffer into the debug log. +* `FEFn01ssss` — **PRINTSTR** `ssss`, string `ssss` is `n` bytes long. + +# A.13 Codepage primitives + +The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. 5.1.8). + +* `FFnn` — **SETCP** `nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. +* `FF00` — **SETCP0**, selects TVM (test) codepage zero as described in this document +* `FFFz` — **SETCP** `z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 . . . − 1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in B.2.6. Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. +* `FFF0` — **SETCPX** `(c – )`, selects codepage `c` with `−2^15 ≤ c < 2^15` passed in the top of the stack. + +--- + +# B Formal properties and specifications of TVM + +This appendix discusses certain formal properties of TVM that are necessary for executing smart contracts in the TON Blockchain and validating such executions afterwards. + +## B.1 Serialization of the TVM state + +Recall that a virtual machine used for executing smart contracts in a blockchain must be deterministic, otherwise the validation of each execution would require the inclusion of all intermediate steps of the execution into a block, or at least of the choices made when indeterministic operations have been performed. + +Furthermore, the state of such a virtual machine must be (uniquely) serializable, so that even if the state itself is not usually included in a block, its hash is still well-defined and can be included into a block for verification purposes. + +### B.1.1. TVM stack values. + +TVM stack values can be serialized as follows: + +``` +vm_stk_tinyint#01 value:int64 = VmStackValue; +vm_stk_int#0201_ value:int257 = VmStackValue; +vm_stk_nan#02FF = VmStackValue; +vm_stk_cell#03 cell:^Cell = VmStackValue; +_ cell:^Cell st_bits:(## 10) end_bits:(## 10) + { st_bits <= end_bits } + st_ref:(#<= 4) end_ref:(#<= 4) + { st_ref <= end_ref } = VmCellSlice; +vm_stk_slice#04 _:VmCellSlice = VmStackValue; +vm_stk_builder#05 cell:^Cell = VmStackValue; +vm_stk_cont#06 cont:VmCont = VmStackValue; +``` + +Of these, `vm_stk_tinyint` is never used by TVM in codepage zero; it is used only in restricted modes. + +### B.1.2. TVM stack. + +The TVM stack can be serialized as follows: + +``` +vm_stack#_ depth:(## 24) stack:(VmStackList depth) = VmStack; +vm_stk_cons#_ {n:#} head:VmStackValue tail:^(VmStackList n) + = VmStackList (n + 1); +vm_stk_nil#_ = VmStackList 0; +``` + +### B.1.3. TVM control registers. + +Control registers in TVM can be serialized as follows: + +``` +_ cregs:(HashmapE 4 VmStackValue) = VmSaveList; +``` + +### B.1.4. TVM gas limits. + +Gas limits in TVM can be serialized as follows: + +``` +gas_limits#_ remaining:int64 _:^[ + max_limit:int64 cur_limit:int64 credit:int64 ] += VmGasLimits; +``` + +### B.1.5. TVM library environment. + +The TVM library environment can be serialized as follows: + +``` +_ libraries:(HashmapE 256 ^Cell) = VmLibraries; +``` + +### B.1.6. TVM continuations. + +Continuations in TVM can be serialized as follows: + +``` +vmc_std$00 nargs:(## 22) stack:(Maybe VmStack) save:VmSaveList + cp:int16 code:VmCellSlice = VmCont; +vmc_envelope$01 nargs:(## 22) stack:(Maybe VmStack) + save:VmSaveList next:^VmCont = VmCont; +vmc_quit$1000 exit_code:int32 = VmCont; +vmc_quit_exc$1001 = VmCont; +vmc_until$1010 body:^VmCont after:^VmCont = VmCont; +vmc_again$1011 body:^VmCont = VmCont; +vmc_while_cond$1100 cond:^VmCont body:^VmCont + after:^VmCont = VmCont; +vmc_while_body$1101 cond:^VmCont body:^VmCont + after:^VmCont = VmCont; +vmc_pushint$1111 value:int32 next:^VmCont = VmCont; +``` + +### B.1.7. TVM state. + +The total state of TVM can be serialized as follows: + +``` +vms_init$00 cp:int16 step:int32 gas:GasLimits + stack:(Maybe VmStack) save:VmSaveList code:VmCellSlice + lib:VmLibraries = VmState; + +vms_exception$01 cp:int16 step:int32 gas:GasLimits + exc_no:int32 exc_arg:VmStackValue + save:VmSaveList lib:VmLibraries = VmState; + +vms_running$10 cp:int16 step:int32 gas:GasLimits stack:VmStack + save:VmSaveList code:VmCellSlice lib:VmLibraries + = VmState; + +vms_finished$11 cp:int16 step:int32 gas:GasLimits + exit_code:int32 no_gas:Boolean stack:VmStack + save:VmSaveList lib:VmLibraries = VmState; +``` + +When TVM is initialized, its state is described by a `vms_init`, usually with `step` set to zero. The step function of TVM does nothing to a `vms_finished` state, and transforms all other states into `vms_running`, `vms_exception`, or `vms_finished`, with `step` increased by one. + +## B.2 Step function of TVM + +A formal specification of TVM would be completed by the definition of a step function `f : VmState → VmState`. This function deterministically transforms a valid VM state into a valid subsequent VM state, and is allowed to throw exceptions or return an invalid subsequent state if the original state was invalid. + +### B.2.1. A high-level definition of the step function. + +We might present a very long formal definition of the TVM step function in a high-level functional programming language. Such a specification, however, would mostly be useful as a reference for the (human) developers. We have chosen another approach, better adapted to automated formal verification by computers. + +### B.2.2. An operational definition of the step function. + +Notice that the step function `f` is a well-defined computable function from trees of cells into trees of cells. As such, it can be computed by a universal Turing machine. Then a program `P` computing `f` on such a machine would provide a machine-checkable specification of the step function `f`. This program `P` effectively is an emulator of TVM on this Turing machine. + +### B.2.3. A reference implementation of the TVM emulator inside TVM. + +We see that the step function of TVM may be defined by a reference implementation of a TVM emulator on another machine. An obvious idea is to use TVM itself, since it is well-adapted to working with trees of cells. However, an emulator of TVM inside itself is not very useful if we have doubts about a particular implementation of TVM and want to check it. For instance, if such an emulator interpreted a **DICTISET** instruction simply by invoking this instruction itself, then a bug in the underlying implementation of TVM would remain unnoticed. + +### B.2.4. Reference implementation inside a minimal version of TVM. + +We see that using TVM itself as a host machine for a reference implementation of TVM emulator would yield little insight. A better idea is to define a stripped-down version of TVM, which supports only the bare minimum of primitives and 64-bit integer arithmetic, and provide a reference implementation `P` of the TVM step function `f` for this stripped-down version of TVM. + +In that case, one must carefully implement and check only a handful of primitives to obtain a stripped-down version of TVM, and compare the reference implementation `P` running on this stripped-down version to the full custom TVM implementation being verified. In particular, if there are any doubts about the validity of a specific run of a custom TVM implementation, they can now be easily resolved with the aid of the reference implementation. + +### B.2.5. Relevance for the TON Blockchain. + +The TON Blockchain adopts this approach to validate the runs of TVM (e.g., those used for processing inbound messages by smart contracts) when the validators’ results do not match one another. In this case, a reference implementation of TVM, stored inside the masterchain as a configurable parameter (thus defining the current revision of TVM), is used to obtain the correct result. + +### B.2.6. Codepage −1. + +Codepage `−1` of TVM is reserved for the stripped-down version of TVM. Its main purpose is to execute the reference implementation of the step function of the full TVM. This codepage contains only special versions of arithmetic primitives working with “tiny integers” (64-bit signed integers); therefore, TVM’s 257-bit `Integer` arithmetic must be defined in terms of 64-bit arithmetic. Elliptic curve cryptography primitives are also implemented directly in codepage `−1`, without using any third-party libraries. Finally, a reference implementation of the `sha256` hash function is also provided in codepage `−1`. + +### B.2.7. Codepage −2. + +This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage `−2`”. All 64-bit arithmetic used in codepage `−1` would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage `−1`. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer. + +--- + +# C Code density of stack and register machines + +This appendix extends the general consideration of stack manipulation primitives provided in 2.2, explaining the choice of such primitives for TVM, with a comparison of stack machines and register machines in terms of the quantity of primitives used and the code density. We do this by comparing the machine code that might be generated by an optimizing compiler for the same source files, for different (abstract) stack and register machines. + +It turns out that the stack machines (at least those equipped with the basic stack manipulation primitives described in 2.2.1) have far superior code density. Furthermore, the stack machines have excellent extendability with respect to additional arithmetic and arbitrary data processing operations, especially if one considers machine code automatically generated by optimizing compilers. + +## C.1 Sample leaf function + +We start with a comparison of machine code generated by an (imaginary) optimizing compiler for several abstract register and stack machines, corresponding to the same high-level language source code that contains the definition of a leaf function (i.e., a function that does not call any other functions). For both the register machines and stack machines, we observe the notation and conventions introduced in 2.1. + +### C.1.1. Sample source file for a leaf function. + +The source file we consider contains one function f that takes six (integer) arguments, a, b, c, d, e, f, and returns two (integer) values, x and y, which are the solutions of the system of two linear equations + +``` +( +ax + by = e +cx + dy = f +(6) +``` + +The source code of the function, in a programming language similar to C, might look as follows: + +```c +(int, int) f(int a, int b, int c, int d, int e, int f) { +int D = a*d - b*c; +int Dx = e*d - b*f; +int Dy = a*f - e*c; +147 +C.1. Sample leaf function +return (Dx / D, Dy / D); +} +``` + +We assume (cf. 2.1) that the register machines we consider accept the six parameters a. . . f in registers r0. . . r5, and return the two values x and y in r0 and r1. We also assume that the register machines have 16 registers, and that the stack machine can directly access s0 to s15 by its stack manipulation primitives; the stack machine will accept the parameters in s5 to s0, and return the two values in s0 and s1, somewhat similarly to the register machine. Finally, we assume at first that the register machine is allowed to destroy values in all registers (which is slightly unfair towards the stack machine); this assumption will be revisited later. + +### C.1.2. Three-address register machine. + +The machine code (or rather the corresponding assembly code) for a three-address register machine (cf. 2.1.7) might look as follows: + +``` +IMUL r6,r0,r3 // r6 := r0 * r3 = ad +IMUL r7,r1,r2 // r7 := bc +SUB r6,r6,r7 // r6 := ad-bc = D +IMUL r3,r4,r3 // r3 := ed +IMUL r1,r1,r5 // r1 := bf +SUB r3,r3,r1 // r3 := ed-bf = Dx +IMUL r1,r0,r5 // r1 := af +IMUL r7,r4,r2 // r7 := ec +SUB r1,r1,r7 // r1 := af-ec = Dy +IDIV r0,r3,r6 // x := Dx/D +IDIV r1,r1,r6 // y := Dy/D +RET +``` + +We have used 12 operations and at least 23 bytes (each operation uses 3×4 = 12 bits to indicate the three registers involved, and at least 4 bits to indicate the operation performed; thus we need two or three bytes to encode each operation). A more realistic estimate would be 34 (three bytes for each arithmetic operation) or 31 bytes (two bytes for addition and subtraction, three bytes for multiplication and division). + +### C.1.3. Two-address register machine. + +The machine code for a two-address register machine might look as follows: + +``` +MOV r6,r0 // r6 := r0 = a +MOV r7,r1 // r7 := b +IMUL r6,r3 // r6 := r6*r3 = ad +IMUL r7,r2 // r7 := bc +IMUL r3,r4 // r3 := de +IMUL r1,r5 // r1 := bf +SUB r6,r7 // r6 := ad-bc = D +IMUL r5,r0 // r5 := af +SUB r3,r1 // r3 := de-bf = Dx +IMUL r2,r4 // r2 := ce +MOV r0,r3 // r0 := Dx +SUB r5,r2 // r5 := af-ce = Dy +IDIV r0,r6 // r0 := x = Dx/D +MOV r1,r5 // r1 := Dy +IDIV r1,r6 // r1 := Dy/D +RET +``` + +We have used 16 operations; optimistically assuming each of them (with the exception of RET) can be encoded by two bytes, this code would require 31 bytes.31 + +### C.1.4. One-address register machine. + +The machine code for a one-address register machine might look as follows: + +``` +MOV r8,r0 // r8 := r0 = a +XCHG r1 // r0 <-> r1; r0 := b, r1 := a +MOV r6,r0 // r6 := b +IMUL r2 // r0 := r0*r2; r0 := bc +MOV r7,r0 // r7 := bc +MOV r0,r8 // r0 := a +IMUL r3 // r0 := ad +31It is interesting to compare this code with that generated by optimizing C compilers +for the x86-64 architecture. +First of all, the integer division operation for x86-64 uses the one-address form, with +the (double-length) dividend to be supplied in accumulator pair r2:r0. The quotient is +also returned in r0. As a consequence, two single-to-double extension operations (CDQ or +CQO) and at least one move operation need to be added. +Secondly, the encoding used for arithmetic and move operations is less optimistic than +in our example above, requiring about three bytes per operation on average. As a result, +we obtain a total of 43 bytes for 32-bit integers, and 68 bytes for 64-bit integers. +C.1. Sample leaf function +SUB r7 // r0 := ad-bc = D +XCHG r1 // r1 := D, r0 := b +IMUL r5 // r0 := bf +XCHG r3 // r0 := d, r3 := bf +IMUL r4 // r0 := de +SUB r3 // r0 := de-bf = Dx +IDIV r1 // r0 := Dx/D = x +XCHG r2 // r0 := c, r2 := x +IMUL r4 // r0 := ce +XCHG r5 // r0 := f, r5 := ce +IMUL r8 // r0 := af +SUB r5 // r0 := af-ce = Dy +IDIV r1 // r0 := Dy/D = y +MOV r1,r0 // r1 := y +MOV r0,r2 // r0 := x +RET +``` + +We have used 23 operations; if we assume one-byte encoding for all arithmetic operations and XCHG, and two-byte encodings for MOV, the total size of the code will be 29 bytes. Notice, however, that to obtain the compact code shown above we had to choose a specific order of computation, and made heavy use of the commutativity of multiplication. (For example, we compute bc before af, and af − bc immediately after af.) It is not clear whether a compiler would be able to make all such optimizations by itself. + +### C.1.5. Stack machine with basic stack primitives. + +The machine code for a stack machine equipped with basic stack manipulation primitives described in 2.2.1 might look as follows: + +``` +PUSH s5 // a b c d e f a +PUSH s3 // a b c d e f a d +IMUL // a b c d e f ad +PUSH s5 // a b c d e f ad b +PUSH s5 // a b c d e f ad b c +IMUL // a b c d e f ad bc +SUB // a b c d e f ad-bc +XCHG s3 // a b c ad-bc e f d +PUSH s2 // a b c ad-bc e f d e +IMUL // a b c ad-bc e f de +XCHG s5 // a de c ad-bc e f b +PUSH s1 // a de c ad-bc e f b f +IMUL // a de c ad-bc e f bf +XCHG s1,s5 // a f c ad-bc e de bf +SUB // a f c ad-bc e de-bf +XCHG s3 // a f de-bf ad-bc e c +IMUL // a f de-bf ad-bc ec +XCHG s3 // a ec de-bf ad-bc f +XCHG s1,s4 // ad-bc ec de-bf a f +IMUL // D ec Dx af +XCHG s1 // D ec af Dx +XCHG s2 // D Dx af ec +SUB // D Dx Dy +XCHG s1 // D Dy Dx +PUSH s2 // D Dy Dx D +IDIV // D Dy x +XCHG s2 // x Dy D +IDIV // x y +RET +``` + +We have used 29 operations; assuming one-byte encodings for all stack operations involved (including XCHG s1,s(i)), we have used 29 code bytes as well. Notice that with one-byte encoding, the “unsystematic” operation ROT (equivalent to XCHG s1; XCHG s2) would reduce the operation and byte count to 28. This shows that such “unsystematic” operations, borrowed from Forth, may indeed reduce the code size on some occasions. + +Notice as well that we have implicitly used the commutativity of multiplication in this code, computing de − bf instead of ed − bf as specified in high-level language source code. If we were not allowed to do so, an extra XCHG s1 would need to be inserted before the third IMUL, increasing the total size of the code by one operation and one byte. + +The code presented above might have been produced by a rather unsophisticated compiler that simply computed all expressions and subexpressions in the order they appear, then rearranged the arguments near the top of the stack before each operation as outlined in 2.2.2. The only “manual” optimization done here involves computing ec before af; one can check that the other order would lead to slightly shorter code of 28 operations and bytes (or 29, if we are not allowed to use the commutativity of multiplication), but +151 +C.1. Sample leaf function +the ROT optimization would not be applicable. + +### C.1.6. Stack machine with compound stack primitives. + +A stack machine with compound stack primitives (cf. 2.2.3) would not significantly improve code density of the code presented above, at least in terms of bytes used. The only difference is that, if we were not allowed to use commutativity of multiplication, the extra XCHG s1 inserted before the third IMUL might be combined with two previous operations XCHG s3, PUSH s2 into one compound operation PUXC s2,s3; we provide the resulting code below. To make this less redundant, we show a version of the code that computes subexpression af before ec as specified in the original source file. We see that this replaces six operations (starting from line 15) with five other operations, and disables the ROT optimization: + +``` +PUSH s5 // a b c d e f a +PUSH s3 // a b c d e f a d +IMUL // a b c d e f ad +PUSH s5 // a b c d e f ad b +PUSH s5 // a b c d e f ad b c +IMUL // a b c d e f ad bc +SUB // a b c d e f ad-bc +PUXC s2,s3 // a b c ad-bc e f e d +IMUL // a b c ad-bc e f ed +XCHG s5 // a ed c ad-bc e f b +PUSH s1 // a ed c ad-bc e f b f +IMUL // a ed c ad-bc e f bf +XCHG s1,s5 // a f c ad-bc e ed bf +SUB // a f c ad-bc e ed-bf +XCHG s4 // a ed-bf c ad-bc e f +XCHG s1,s5 // e Dx c D a f +IMUL // e Dx c D af +XCHG s2 // e Dx af D c +XCHG s1,s4 // D Dx af e c +IMUL // D Dx af ec +SUB // D Dx Dy +XCHG s1 // D Dy Dx +PUSH s2 // D Dy Dx D +IDIV // D Dy x +XCHG s2 // x Dy D +IDIV // x y +RET +``` + +We have used a total of 27 operations and 28 bytes, the same as the previous version (with the ROT optimization). However, we did not use the commutativity of multiplication here, so we can say that compound stack manipulation primitives enable us to reduce the code size from 29 to 28 bytes. + +Yet again, notice that the above code might have been generated by an unsophisticated compiler. Manual optimizations might lead to more compact code; for instance, we could use compound operations such as XCHG3 to prepare in advance not only the correct values of s0 and s1 for the next arithmetic operation, but also the value of s2 for the arithmetic operation after that. The next section provides an example of such an optimization. + +### C.1.7. Stack machine with compound stack primitives and manually optimized code. + +The previous version of code for a stack machine with compound stack primitives can be manually optimized as follows. + +By interchanging XCHG operations with preceding XCHG, PUSH, and arithmetic operations whenever possible, we obtain code fragment XCHG s2,s6; XCHG s1,s0; XCHG s0,s5, which can then be replaced by compound operation XCHG3 s6,s0,s5. This compound operation would admit a two-byte encoding, thus leading to 27-byte code using only 21 operations: + +``` +PUSH2 s5,s2 // a b c d e f a d +IMUL // a b c d e f ad +PUSH2 s5,s4 // a b c d e f ad b c +IMUL // a b c d e f ad bc +SUB // a b c d e f ad-bc +PUXC s2,s3 // a b c ad-bc e f e d +IMUL // a b c D e f ed +XCHG3 s6,s0,s5 // (same as XCHG s2,s6; XCHG s1,s0; XCHG s0,s5) +// e f c D a ed b +PUSH s5 // e f c D a ed b f +IMUL // e f c D a ed bf +SUB // e f c D a ed-bf +XCHG s4 // e Dx c D a f +IMUL // e Dx c D af +XCHG2 s4,s2 // D Dx af e c +IMUL // D Dx af ec +153 +C.2. Comparison of machine code for sample leaf function +SUB // D Dx Dy +XCPU s1,s2 // D Dy Dx D +IDIV // D Dy x +XCHG s2 // x Dy D +IDIV // x y +RET +``` + +It is interesting to note that this version of stack machine code contains only 9 stack manipulation primitives for 11 arithmetic operations. It is not clear, however, whether an optimizing compiler would be able to reorganize the code in such a manner by itself. + +---- + +# C.2 Comparison of machine code for sample leaf function + +Table 1 summarizes the properties of machine code corresponding to the same source file described in C.1.1, generated for a hypothetical three-address register machine (cf. C.1.2), with both “optimistic” and “realistic” instruction encodings; a two-address machine (cf. C.1.3); a one-address machine (cf. C.1.4); and a stack machine, similar to TVM, using either only the basic stack manipulation primitives (cf. C.1.5) or both the basic and the composite stack primitives (cf. C.1.7). + +The meaning of the columns in Table 1 is as follows: + +* “Operations” — The quantity of instructions used, split into “data” (i.e., register move and exchange instructions for register machines, and stack manipulation instructions for stack machines) and “arithmetic” (instructions for adding, subtracting, multiplying and dividing integer numbers). The “total” is one more than the sum of these two, because there is also a one-byte RET instruction at the end of machine code. +* “Code bytes” — The total amount of code bytes used. +* “Opcode space” — The portion of “opcode space” (i.e., of possible choices for the first byte of the encoding of an instruction) used by data and arithmetic instructions in the assumed instruction encoding. For example, the “optimistic” encoding for the three-address machine assumes two-byte encodings for all arithmetic instructions `op r(i), r(j), r(k)`. Each arithmetic instruction would then consume portion `16/256 = 1/16` of the opcode space. Notice that for the stack machine we have assumed one-byte encodings for `XCHG s(i)`, `PUSH s(i)` and `POP s(i)` in all cases, augmented by `XCHG s1,s(i)` for the basic stack instructions case only. As for the compound stack operations, we have assumed two-byte encodings for `PUSH3`, `XCHG3`, `XCHG2`, `XCPU`, `PUXC`, `PUSH2`, but not for `XCHG s1,s(i)`. + +The “code bytes” column reflects the density of the code for the specific sample source. However, “opcode space” is also important, because it reflects the extendability of the achieved density to other classes of operations (e.g., if one were to complement arithmetic operations with string manipulation operations and so on). Here the “arithmetic” subcolumn is more important than the “data” subcolumn, because no further data manipulation operations would be required for such extensions. + +We see that the three-address register machine with the “optimistic” encoding, assuming two-byte encodings for all three-register arithmetic operations, achieves the best code density, requiring only 23 bytes. However, this comes at a price: each arithmetic operation consumes 1/16 of the opcode space, so the four operations already use a quarter of the opcode space. At most 11 other operations, arithmetic or not, might be added to this architecture while preserving such high code density. On the other hand, when we consider the “realistic” encoding for the three-address machine, using two-byte encodings only for the most frequently used addition/subtraction operations (and longer encodings for less frequently used multiplication/division operations, reflecting the fact that the possible extension operations would likely fall in this class), then the three-address machine ceases to offer such attractive code density. + +In fact, the two-address machine becomes equally attractive at this point: it is capable of achieving the same code size of 31 bytes as the three-address machine with the “realistic” encoding, using only 6/256 of the opcode space for this! However, 31 bytes is the worst result in this table. + +The one-address machine uses 29 bytes, slightly less than the two-address machine. However, it utilizes a quarter of the opcode space for its arithmetic operations, hampering its extendability. In this respect it is similar to the three-address machine with the “optimistic” encoding, but requires 29 bytes instead of 23! So there is no reason to use the one-address machine at all, in terms of extendability (reflected by opcode space used for arithmetic operations) compared to code density. + +Finally, the stack machine wins the competition in terms of code density (27 or 28 bytes), losing only to the three-address machine with the “optimistic” encoding (which, however, is terrible in terms of extendability). + +To summarize: the two-address machine and stack machine achieve the best extendability with respect to additional arithmetic or data processing instructions (using only 1/256 of code space for each such instruction), while the stack machine additionally achieves the best code density by a small margin. The stack machine utilizes a significant part of its code space (more than a quarter) for data (i.e., stack) manipulation instructions; however, this does not seriously hamper extendability, because the stack manipulation instructions occupy a constant part of the opcode stace, regardless of all other instructions and extensions. + +While one might still be tempted to use a two-address register machine, we will explain shortly (cf. C.3) why the two-address register machine offers worse code density and extendability in practice than it appears based on this table. + +As for the choice between a stack machine with only basic stack manipulation primitives or one supporting compound stack primitives as well, the case for the more sophisticated stack machine appears to be weaker: it offers only one or two fewer bytes of code at the expense of using considerably more opcode space for stack manipulation, and the optimized code using these additional instructions is hard for programmers to write and for compilers to automatically generate. + +### Table 1 + +| Machine | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | +| --------------- | ------------------- | -------------------- | -------------------- | ------------------- | -------------------- | -------------------- | --------------------- | ---------------------- | ---------------------- | +| 3-addr. (opt.) | 0 | 11 | 12 | 0 | 22 | 23 | 0/256 | 64/256 | 65/256 | +| 3-addr. (real.) | 0 | 11 | 12 | 0 | 30 | 31 | 0/256 | 34/256 | 35/256 | +| 2-addr. | 4 | 11 | 16 | 8 | 22 | 31 | 1/256 | 4/256 | 6/256 | +| 1-addr. | 11 | 11 | 23 | 17 | 11 | 29 | 17/256 | 64/256 | 82/256 | +| stack (basic) | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | +| stack (comp.) | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | + +Table 1: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. C.1.1). The two most important columns, reflecting code density and extendability to other operations, are marked by bold font. Smaller values are better in both of these columns. + +--- + +### C.2.1. Register calling conventions: some registers must be preserved by functions. + +Up to this point, we have considered the machinecode of only one function, without taking into account the interplay between this function and other functions in the same program. + +Usually a program consists of more than one function, and when a function is not a “simple” or “leaf” function, it must call other functions. Therefore, it becomes important whether a called function preserves all or at least some registers. If it preserves all registers except those used to return results, the caller can safely keep its local and temporary variables in certain registers; however, the callee needs to save all the registers it will use for its temporary values somewhere (usually into the stack, which also exists on register machines), and then restore the original values. On the other hand, if the called function is allowed to destroy all registers, it can be written in the manner described in C.1.2, C.1.3, and C.1.4, but the caller will now be responsible for saving all its temporary values into the stack before the call, and restoring these values afterwards. + +In most cases, calling conventions for register machines require preservation of some but not all registers. We will assume that m ≤ n registers will be preserved by functions (unless they are used for return values), and that these registers are r(n − m). . . r(n − 1). Case m = 0 corresponds to the case “the callee is free to destroy all registers” considered so far; it is quite painful for the caller. Case m = n corresponds to the case “the callee must preserve all registers”; it is quite painful for the callee, as we will see in a moment. Usually a value of m around n/2 is used in practice. + +The following sections consider cases m = 0, m = 8, and m = 16 for our register machines with n = 16 registers. + +### C.2.2. Case m = 0: no registers to preserve. + +This case has been considered and summarized in C.2 and Table 1 above. + +### C.2.3. Case m = n = 16: all registers must be preserved. + +This case is the most painful one for the called function. It is especially difficult for leaf functions like the one we have been considering, which do not benefit at all from the fact that other functions preserve some registers when called—they do not call any functions, but instead must preserve all registers themselves. + +In order to estimate the consequences of assuming m = n = 16, we will assume that all our register machines are equipped with a stack, and with one-byte instructions `PUSH r(i)` and `POP r(i)`, which push or pop a register into/from the stack. For example, the three-address machine code provided in C.1.2 destroys the values in registers r2, r3, r6, and r7; this means that the code of this function must be augmented by four instructions `PUSH r2; PUSH r3; PUSH r6; PUSH r7` at the beginning, and by four instructions `POP r7; POP r6; POP r3; POP r2` right before the `RET` instruction, in order to restore the original values of these registers from the stack. These four additional `PUSH/POP` pairs would increase the operation count and code size in bytes by `4 × 2 = 8`. A similar analysis can be done for other register machines as well, leading to Table 2. + +We see that under these assumptions the stack machines are the obvious winners in terms of code density, and are in the winning group with respect to extendability. + +### Table 2 + +| Machine | r | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | +| --------------- | - | ------------------- | -------------------- | -------------------- | ------------------- | -------------------- | -------------------- | --------------------- | ---------------------- | ---------------------- | +| 3-addr. (opt.) | 4 | 8 | 11 | 20 | 8 | 22 | 31 | 32/256 | 64/256 | 97/256 | +| 3-addr. (real.) | 4 | 8 | 11 | 20 | 8 | 30 | 39 | 32/256 | 34/256 | 67/256 | +| 2-addr. | 5 | 14 | 11 | 26 | 18 | 22 | 41 | 33/256 | 4/256 | 38/256 | +| 1-addr. | 6 | 23 | 11 | 35 | 29 | 11 | 41 | 49/256 | 64/256 | 114/256 | +| stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | +| stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | + +Table 2: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. C.1.1), assuming all of the 16 registers must be preserved by called functions (m = n = 16). The new column labeled r denotes the number of registers to be saved and restored, leading to 2r more operations and code bytes compared to Table 1. Newly-added PUSH and POP instructions for register machines also utilize 32/256 of the opcode space. The two rows corresponding to stack machines remain unchanged. + +### C.2.4. Case m = 8, n = 16: registers r8. . . r15 must be preserved. + +The analysis of this case is similar to the previous one. The results are summarized in Table 3. + +Notice that the resulting table is very similar to Table 1, apart from the “Opcode space” columns and the row for the one-address machine. Therefore, the conclusions of C.2 still apply in this case, with some minor modifications. We must emphasize, however, that these conclusions are valid only for leaf functions, i.e., functions that do not call other functions. Any program aside from the very simplest will have many non-leaf functions, especially if we are minimizing resulting machine code size (which prevents inlining of functions in most cases). + +### Table 3 + +| Machine | r | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | +| --------------- | - | ------------------- | -------------------- | -------------------- | ------------------- | -------------------- | -------------------- | --------------------- | ---------------------- | ---------------------- | +| 3-addr. (opt.) | 0 | 0 | 11 | 12 | 0 | 22 | 23 | 32/256 | 64/256 | 97/256 | +| 3-addr. (real.) | 0 | 0 | 11 | 12 | 0 | 30 | 31 | 32/256 | 34/256 | 67/256 | +| 2-addr. | 0 | 4 | 11 | 16 | 8 | 22 | 31 | 33/256 | 4/256 | 38/256 | +| 1-addr. | 1 | 13 | 11 | 25 | 19 | 11 | 31 | 49/256 | 64/256 | 114/256 | +| stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | +| stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | + +Table 3: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address and stack machines, generated for a sample leaf function (cf. C.1.1), assuming that only the last 8 of the 16 registers must be preserved by called functions (m = 8, n = 16). This table is similar to Table 2, but has smaller values of r. + +### C.2.5. A fairer comparison using a binary code instead of a byte code. + +The reader may have noticed that our preceding discussion of kaddress register machines and stack machines depended very much on our insistence that complete instructions be encoded by an integer number of bytes. If we had been allowed to use a “bit” or “binary code” instead of a byte code for encoding instructions, we could more evenly balance the opcode space used by different machines. For instance, the opcode of SUB for a threeaddress machine had to be either 4-bit (good for code density, bad for opcode space) or 12-bit (very bad for code density), because the complete instruction has to occupy a multiple of eight bits (e.g., 16 or 24 bits), and 3 · 4 = 12 of those bits have to be used for the three register names. + +Therefore, let us get rid of this restriction. + +Now that we can use any number of bits to encode an instruction, we can choose all opcodes of the same length for all the machines considered. For instance, all arithmetic instructions can have 8-bit opcodes, as the stack machine does, using 1/256 of the opcode space each; then the three-address register machine will use 20 bits to encode each complete arithmetic instruction. All MOVs, XCHGs, PUSHes, and POPs on register machines can be assumed to have 4-bit opcodes, because this is what we do for the most common stack manipulation primitives on a stack machine. The results of these changes are shown in Table 4. + +We can see that the performance of the various machines is much more balanced, with the stack machine still the winner in terms of the code density, but with the three-address machine enjoying the second place it really merits. If we were to consider the decoding speed and the possibility of parallel execution of instructions, we would have to choose the three-address machine, because it uses only 12 instructions instead of 21. + +### Table 4 + +| Machine | r | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | +| ------------- | - | ------------------- | -------------------- | -------------------- | ------------------- | -------------------- | -------------------- | --------------------- | ---------------------- | ---------------------- | +| 3-addr. | 0 | 0 | 11 | 12 | 0 | 27.5 | 28.5 | 64/256 | 4/256 | 69/256 | +| 2-addr. | 0 | 4 | 11 | 16 | 6 | 22 | 29 | 64/256 | 4/256 | 69/256 | +| 1-addr. | 1 | 13 | 11 | 25 | 16 | 16.5 | 32.5 | 64/256 | 4/256 | 69/256 | +| stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | +| stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | + +Table 4: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address and stack machines, generated for a sample leaf function (cf. C.1.1), assuming that only 8 of the 16 registers must be preserved by functions (m = 8, n = 16). This time we can use fractions of bytes to encode instructions, so as to match opcode space used by different machines. All arithmetic instructions have 8-bit opcodes, all data/stack manipulation instructions have 4-bit opcodes. In other respects this table is similar to Table 3. + +# C.3 Sample non-leaf function + +This section compares the machine code for different register machines for a sample non-leaf function. Again, we assume that either m = 0, m = 8, or m = 16 registers are preserved by called functions, with m = 8 representing the compromise made by most modern compilers and operating systems. + +## C.3.1. Sample source code for a non-leaf function. + +A sample source file may be obtained by replacing the built-in integer type with a custom Rational type, represented by a pointer to an object in memory, in our function for solving systems of two linear equations (cf. C.1.1): + +```c +struct Rational; +typedef struct Rational *num; +extern num r_add(num, num); +extern num r_sub(num, num); +extern num r_mul(num, num); +extern num r_div(num, num); +(num, num) r_f(num a, num b, num c, num d, num e, num f) { +num D = r_sub(r_mul(a, d), r_mul(b, c)); // a*d-b*c +num Dx = r_sub(r_mul(e, d), r_mul(b, f)); // e*d-b*f +num Dy = r_sub(r_mul(a, f), r_mul(e, c)); // a*f-e*c +return (r_div(Dx, D), r_div(Dy, D)); // Dx/D, Dy/D +} +``` + +We will ignore all questions related to allocating new objects of type Rational in memory (e.g., in heap), and to preventing memory leaks. We may assume that the called subroutines r\_sub, r\_mul, and so on allocate new objects simply by advancing some pointer in a pre-allocated buffer, and that unused objects are later freed by a garbage collector, external to the code being analysed. + +Rational numbers will now be represented by pointers, addresses, or references, which will fit into registers of our hypothetical register machines or into the stack of our stack machines. If we want to use TVM as an instance of these stack machines, we should use values of type Cell to represent such references to objects of type Rational in memory. + +We assume that subroutines (or functions) are called by a special CALL instruction, which is encoded by three bytes, including the specification of the function to be called (e.g., the index in a “global function table”). + +## C.3.2. Three-address and two-address register machines, m = 0 preserved registers. + +Because our sample function does not use built-in arithmetic instructions at all, compilers for our hypothetical three-address and two-address register machines will produce the same machine code. Apart from the previously introduced PUSH r(i) and POP r(i) one-byte instructions, we assume that our two- and three-address machines support the following two-byte instructions: MOV r(i),s(j), MOV s(j),r(i), and XCHG r(i),s(j), for 0 ≤ i, j ≤ 15. Such instructions occupy only 3/256 of the opcode space, so their addition seems quite natural. + +We first assume that m = 0 (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for r\_f does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. A size-optimizing compiler might produce the following code: + +``` +PUSH r4 // STACK: e +PUSH r1 // STACK: e b +PUSH r0 // .. e b a +PUSH r6 // .. e b a f +PUSH r2 // .. e b a f c +PUSH r3 // .. e b a f c d +MOV r0,r1 // b +MOV r1,r2 // c +CALL r_mul // bc +161 +C.3. Sample non-leaf function +PUSH r0 // .. e b a f c d bc +MOV r0,s4 // a +MOV r1,s1 // d +CALL r_mul // ad +POP r1 // bc; .. e b a f c d +CALL r_sub // D:=ad-bc +XCHG r0,s4 // b ; .. e D a f c d +MOV r1,s2 // f +CALL r_mul // bf +POP r1 // d ; .. e D a f c +PUSH r0 // .. e D a f c bf +MOV r0,s5 // e +CALL r_mul // ed +POP r1 // bf; .. e D a f c +CALL r_sub // Dx:=ed-bf +XCHG r0,s4 // e ; .. Dx D a f c +POP r1 // c ; .. Dx D a f +CALL r_mul // ec +XCHG r0,s1 // a ; .. Dx D ec f +POP r1 // f ; .. Dx D ec +CALL r_mul // af +POP r1 // ec; .. Dx D +CALL r_sub // Dy:=af-ec +XCHG r0,s1 // Dx; .. Dy D +MOV r1,s0 // D +CALL r_div // x:=Dx/D +XCHG r0,s1 // Dy; .. x D +POP r1 // D ; .. x +CALL r_div // y:=Dy/D +MOV r1,r0 // y +POP r0 // x ; .. +RET +``` + +We have used 41 instructions: 17 one-byte (eight PUSH/POP pairs and one RET), 13 two-byte (MOV and XCHG; out of them 11 “new” ones, involving the stack),and 11 three-byte (CALL), for a total of 17 · 1 + 13 · 2 + 11 · 3 = 76 bytes. + +## C.3.3. Three-address and two-address register machines, m = 8 preserved registers. + +Now we have eight registers, r8 to r15, that are preserved by subroutine calls. We might keep some intermediate values there instead of pushing them into the stack. However, the penalty for doing so consists in a PUSH/POP pair for every such register that we choose to use, because our function is also required to preserve its original value. It seems that using these registers under such a penalty does not improve the density of the code, so the optimal code for three- and two-address machines for m = 8 preserved registers is the same as that provided in C.3.2, with a total of 42 instructions and 74 code bytes. + +## C.3.4. Three-address and two-address register machines, m = 16 preserved registers. + +This time all registers must be preserved by the subroutines, excluding those used for returning the results. This means that our code must preserve the original values of r2 to r5, as well as any other registers it uses for temporary values. A straightforward way of writing the code of our subroutine would be to push registers r2 up to, say, r8 into the stack, then perform all the operations required, using r6–r8 for intermediate values, and finally restore registers from the stack. However, this would not optimize code size. We choose another approach: + +``` +PUSH r0 // STACK: a +PUSH r1 // STACK: a b +MOV r0,r1 // b +MOV r1,r2 // c +CALL r_mul // bc +PUSH r0 // .. a b bc +MOV r0,s2 // a +MOV r1,r3 // d +CALL r_mul // ad +POP r1 // bc; .. a b +CALL r_sub // D:=ad-bc +XCHG r0,s0 // b; .. a D +MOV r1,r5 // f +CALL r_mul // bf +PUSH r0 // .. a D bf +with size-optimization enabled actually occupied 150 bytes, due mostly to the fact that +actual instruction encodings are about twice as long as we had optimistically assumed. +163 +C.3. Sample non-leaf function +MOV r0,r4 // e +MOV r1,r3 // d +CALL r_mul // ed +POP r1 // bf; .. a D +CALL r_sub // Dx:=ed-bf +XCHG r0,s1 // a ; .. Dx D +MOV r1,r5 // f +CALL r_mul // af +PUSH r0 // .. Dx D af +MOV r0,r4 // e +MOV r1,r2 // c +CALL r_mul // ec +MOV r1,r0 // ec +POP r0 // af; .. Dx D +CALL r_sub // Dy:=af-ec +XCHG r0,s1 // Dx; .. Dy D +MOV r1,s0 // D +CALL r_div // x:=Dx/D +XCHG r0,s1 // Dy; .. x D +POP r1 // D ; .. x +CALL r_div // y:=Dy/D +MOV r1,r0 // y +POP r0 // x +RET +``` + +We have used 39 instructions: 11 one-byte, 17 two-byte (among them 5 “new” instructions), and 11 three-byte, for a total of 11 · 1 + 17 · 2 + 11 · 3 = 78 bytes. Somewhat paradoxically, the code size in bytes is slightly longer than in the previous case (cf. C.3.2), contrary to what one might have expected. This is partially due to the fact that we have assumed two-byte encodings for “new” MOV and XCHG instructions involving the stack, similarly to the “old” instructions. Most existing architectures (such as x86-64) use longer encodings (maybe even twice as long) for their counterparts of our “new” move and exchange instructions compared to the “usual” register-register ones. Taking this into account, we see that we would have obtained here 83 bytes (versus 87 for the code in C.3.2) assuming three-byte encodings of new operations, and 88 bytes (versus 98) assuming four-byte encodings. This shows that, for two-address architectures without optimized encodings for register-stackmove and exchange operations, m = 16 preserved registers might result in slightly shorter code for some non-leaf functions, at the expense of leaf functions (cf. C.2.3 and C.2.4), which would become considerably longer. + +## C.3.5. One-address register machine, m = 0 preserved registers. + +For our one-address register machine, we assume that new register-stack instructions work through the accumulator only. Therefore, we have three new instructions, LD s(j) (equivalent to MOV r0,s(j) of two-address machines), ST s(j) (equivalent to MOV s(j),r0), and XCHG s(j) (equivalent to XCHG r0,s(j)). To make the comparison with two-address machines more interesting, we assume one-byte encodings for these new instructions, even though this would consume 48/256 = 3/16 of the opcode space. + +By adapting the code provided in C.3.2 to the one-address machine, we obtain the following: + +``` +PUSH r4 // STACK: e +PUSH r1 // STACK: e b +PUSH r0 // .. e b a +PUSH r6 // .. e b a f +PUSH r2 // .. e b a f c +PUSH r3 // .. e b a f c d +LD s1 // r0:=c +XCHG r1 // r0:=b, r1:=c +CALL r_mul // bc +PUSH r0 // .. e b a f c d bc +LD s1 // d +XCHG r1 // r1:=d +LD s4 // a +CALL r_mul // ad +POP r1 // bc; .. e b a f c d +CALL r_sub // D:=ad-bc +XCHG s4 // b ; .. e D a f c d +XCHG r1 +LD s2 // f +XCHG r1 // r0:=b, r1:=f +CALL r_mul // bf +POP r1 // d ; .. e D a f c +PUSH r0 // .. e D a f c bf +LD s5 // e +165 +C.3. Sample non-leaf function +CALL r_mul // ed +POP r1 // bf; .. e D a f c +CALL r_sub // Dx:=ed-bf +XCHG s4 // e ; .. Dx D a f c +POP r1 // c ; .. Dx D a f +CALL r_mul // ec +XCHG s1 // a ; .. Dx D ec f +POP r1 // f ; .. Dx D ec +CALL r_mul // af +POP r1 // ec; .. Dx D +CALL r_sub // Dy:=af-ec +XCHG s1 // Dx; .. Dy D +POP r1 // D ; .. Dy +PUSH r1 // .. Dy D +CALL r_div // x:=Dx/D +XCHG s1 // Dy; .. x D +POP r1 // D ; .. x +CALL r_div // y:=Dy/D +XCHG r1 // r1:=y +POP r0 // r0:=x ; .. +RET +``` + +We have used 45 instructions: 34 one-byte and 11 three-byte, for a total of 67 bytes. Compared to the 76 bytes used by two- and three-address machines in C.3.2, we see that, again, the one-address register machine code may be denser than that of two-register machines, at the expense of utilizing more opcode space (just as shown in C.2). However, this time the extra 3/16 of the opcode space was used for data manipulation instructions, which do not depend on specific arithmetic operations or user functions invoked. + +## C.3.6. One-address register machine, m = 8 preserved registers. + +As explained in C.3.3, the preservation of r8–r15 between subroutine calls does not improve the size of our previously written code, so the one-address machine will use for m = 8 the same code provided in C.3.5. + +## C.3.7. One-address register machine, m = 16 preserved registers. + +We simply adapt the code provided in C.3.4 to the one-address register machine: + +``` +PUSH r0 // STACK: aPUSH r1 // STACK: a b +MOV r0,r1 // b +MOV r1,r2 // c +CALL r_mul // bc +PUSH r0 // .. a b bc +LD s2 // a +MOV r1,r3 // d +CALL r_mul // ad +POP r1 // bc; .. a b +CALL r_sub // D:=ad-bc +XCHG s0 // b; .. a D +MOV r1,r5 // f +CALL r_mul // bf +PUSH r0 // .. a D bf +MOV r0,r4 // e +MOV r1,r3 // d +CALL r_mul // ed +POP r1 // bf; .. a D +CALL r_sub // Dx:=ed-bf +XCHG s1 // a ; .. Dx D +MOV r1,r5 // f +CALL r_mul // af +PUSH r0 // .. Dx D af +MOV r0,r4 // e +MOV r1,r2 // c +CALL r_mul // ec +MOV r1,r0 // ec +POP r0 // af; .. Dx D +CALL r_sub // Dy:=af-ec +XCHG s1 // Dx; .. Dy D +POP r1 // D ; .. Dy +PUSH r1 // .. Dy D +CALL r_div // x:=Dx/D +XCHG s1 // Dy; .. x D +POP r1 // D ; .. x +CALL r_div // y:=Dy/D +MOV r1,r0 // y +POP r0 // x +167 +C.3. Sample non-leaf function +RET +``` + +We have used 40 instructions: 18 one-byte, 11 two-byte, and 11 three-byte, for a total of 18 · 1 + 11 · 2 + 11 · 3 = 73 bytes. + +## C.3.8. Stack machine with basic stack primitives. + +We reuse the code provided in C.1.5, simply replacing arithmetic primitives (VM instructions) with subroutine calls. The only substantive modification is the insertion of the previously optional XCHG s1 before the third multiplication, because even an optimizing compiler cannot now know whether CALL r\_mul is a commutative operation. We have also used the “tail recursion optimization” by replacing the final CALL r\_div followed by RET with JMP r\_div. + +``` +PUSH s5 // a b c d e f a +PUSH s3 // a b c d e f a d +CALL r_mul // a b c d e f ad +PUSH s5 // a b c d e f ad b +PUSH s5 // a b c d e f ad b c +CALL r_mul // a b c d e f ad bc +CALL r_sub // a b c d e f ad-bc +XCHG s3 // a b c ad-bc e f d +PUSH s2 // a b c ad-bc e f d e +XCHG s1 // a b c ad-bc e f e d +CALL r_mul // a b c ad-bc e f ed +XCHG s5 // a ed c ad-bc e f b +PUSH s1 // a ed c ad-bc e f b f +CALL r_mul // a ed c ad-bc e f bf +XCHG s1,s5 // a f c ad-bc e ed bf +CALL r_sub // a f c ad-bc e ed-bf +XCHG s3 // a f ed-bf ad-bc e c +CALL r_mul // a f ed-bf ad-bc ec +XCHG s3 // a ec ed-bf ad-bc f +XCHG s1,s4 // ad-bc ec ed-bf a f +CALL r_mul // D ec Dx af +XCHG s1 // D ec af Dx +XCHG s2 // D Dx af ec +CALL r_sub // D Dx Dy +XCHG s1 // D Dy Dx +PUSH s2 // D Dy Dx D +CALL r_div // D Dy x +XCHG s2 // x Dy D +JMP r_div // x y +``` + +We have used 29 instructions; assuming one-byte encodings for all stack operations, and three-byte encodings for CALL and JMP instructions, we end up with 51 bytes. + +## C.3.9. Stack machine with compound stack primitives. + +We again reuse the code provided in C.1.7, replacing arithmetic primitives with subroutine calls and making the tail recursion optimization: + +``` +PUSH2 s5,s2 // a b c d e f a d +CALL r_mul // a b c d e f ad +PUSH2 s5,s4 // a b c d e f ad b c +CALL r_mul // a b c d e f ad bc +CALL r_sub // a b c d e f ad-bc +PUXC s2,s3 // a b c ad-bc e f e d +CALL r_mul // a b c D e f ed +XCHG3 s6,s0,s5 // (same as XCHG s2,s6; XCHG s1,s0; XCHG s0,s5) +// e f c D a ed b +PUSH s5 // e f c D a ed b f +CALL r_mul // e f c D a ed bf +CALL r_sub // e f c D a ed-bf +XCHG s4 // e Dx c D a f +CALL r_mul // e Dx c D af +XCHG2 s4,s2 // D Dx af e c +CALL r_mul // D Dx af ec +CALL r_sub // D Dx Dy +XCPU s1,s2 // D Dy Dx D +CALL r_div // D Dy x +XCHG s2 // x Dy D +JMP r_div // x y +``` + +This code uses only 20 instructions, 9 stack-related and 11 control flowrelated (CALL and JMP), for a total of 48 bytes. + +--- + +### Table 5 + +| Machine | m | data | cont. | total | data | cont. | total | data/256 | arith/256 | total/256 | +| ------------- | --- | ---- | ----- | ----- | ---- | ----- | ----- | -------- | --------- | --------- | +| 3-addr. | 0,8 | 29 | 12 | 41 | 42 | 34 | 76 | 35/256 | 34/256 | 72/256 | +| | 16 | 27 | 12 | 39 | 44 | 34 | 78 | | | | +| 2-addr. | 0,8 | 29 | 12 | 41 | 42 | 34 | 76 | 37/256 | 4/256 | 44/256 | +| | 16 | 27 | 12 | 39 | 44 | 34 | 78 | | | | +| 1-addr. | 0,8 | 33 | 12 | 45 | 33 | 34 | 67 | 97/256 | 64/256 | 164/256 | +| | 16 | 28 | 12 | 40 | 39 | 34 | 73 | | | | +| stack (basic) | − | 18 | 11 | 29 | 18 | 33 | 51 | 64/256 | 4/256 | 71/256 | +| stack (comp.) | − | 9 | 11 | 20 | 15 | 33 | 48 | 84/256 | 4/256 | 91/256 | + +Table 5: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. C.3.1), assuming m of the 16 registers must be preserved by called subroutines. + +--- + +# C.4 Comparison of machine code for sample non-leaf + +function + +Table 5 summarizes the properties of machine code corresponding to the same source file provided in C.3.1. We consider only the “realistically” encoded three-address machines. Three-address and two-address machines have the same code density properties, but differ in the utilization of opcode space. The one-address machine, somewhat surprisingly, managed to produced shorter code than the two-address and three-address machines, at the expense of using up more than half of all opcode space. The stack machine is the obvious winner in this code density contest, without compromizing its excellent extendability (measured in opcode space used for arithmetic and other data transformation instructions). + +## C.4.1. Combining with results for leaf functions. + +It is instructive to compare this table with the results in C.2 for a sample leaf function, summarized in Table 1 (for m = 0 preserved registers) and the very similar Table 3 (for m = 8 preserved registers), and, if one is still interested in case m = 16 (which turned out to be worse than m = 8 in almost all situations), also to Table 2. +We see that the stack machine beats all register machines on non-leaf functions. As for the leaf functions, only the three-address machine with the “optimistic” encoding of arithmetic instructions was able to beat the stack machine, winning by 15%, by compromising its extendability. However, the same three-address machine produces 25% longer code for non-leaf functions. + +### C.4. Comparison of machine code for sample non-leaf function + +**Operations** | **Code bytes** | **Opcode space** + +| Machine | m | data | cont. | total | data | cont. | total | data | arith | total | +| ------------- | --- | ---- | ----- | ----- | ---- | ----- | ----- | ------- | ----- | ------- | +| 3-addr. | 0,8 | 29 | 12 | 41 | 35.5 | 34 | 69.5 | 110/256 | 4/256 | 117/256 | +| 3-addr. | 16 | 27 | 12 | 39 | 35.5 | 34 | 69.5 | | | | +| 2-addr. | 0,8 | 29 | 12 | 41 | 35.5 | 34 | 69.5 | 110/256 | 4/256 | 117/256 | +| 2-addr. | 16 | 27 | 12 | 39 | 35.5 | 34 | 69.5 | | | | +| 1-addr. | 0,8 | 33 | 12 | 45 | 33 | 34 | 67 | 112/256 | 4/256 | 119/256 | +| 1-addr. | 16 | 28 | 12 | 40 | 33.5 | 34 | 67.5 | | | | +| stack (basic) | − | 18 | 11 | 29 | 18 | 33 | 51 | 64/256 | 4/256 | 71/256 | +| stack (comp.) | − | 9 | 11 | 20 | 15 | 33 | 48 | 84/256 | 4/256 | 91/256 | + +Table 6: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. C.3.1), assuming m of the 16 registers must be preserved by called subroutines. This time we use fractions of bytes to encode instructions, enabling a fairer comparison. Otherwise, this table is similar to Table 5. + +If a typical program consists of a mixture of leaf and non-leaf functions in approximately equal proportion, then the stack machine will still win. + +## C.4.2. A fairer comparison using a binary code instead of a byte code. + +Similarly to C.2.5, we may offer a fairer comparison of different register machines and the stack machine by using arbitrary binary codes instead of byte codes to encode instructions, and matching the opcode space used for data manipulation and arithmetic instructions by different machines. The results of this modified comparison are summarized in Table 6. We see that the stack machines still win by a large margin, while using less opcode space for stack/data manipulation. + +## C.4.3. Comparison with real machines. + +Note that our hypothetical register machines have been considerably optimized to produce shorter code than actually existing register machines; the latter are subject to other design considerations apart from code density and extendability, such as backward compatibility, faster instruction decoding, parallel execution of neighboring instructions, ease of automatically producing optimized code by compilers, and so on. +For example, the very popular two-address register architecture x86-64 produces code that is approximately twice as long as our “ideal” results for the two-address machines. On the other hand, our results for the stack machines are directly applicable to TVM, which has been explicitly designed with the considerations presented in this appendix in mind. Furthermore, the actual TVM code is even shorter (in bytes) than shown in Table 5 because of the presence of the two-byte CALL instruction, allowing TVM to call up to 256 user-defined functions from the dictionary at c3. This means that one should subtract 10 bytes from the results for stack machines in Table 5 if one wants to specifically consider TVM, rather than an abstract stack machine; this produces a code size of approximately 40 bytes (or shorter), almost half that of an abstract two-address or three-address machine. + +## C.4.4. Automatic generation of optimized code. + +An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in 2.2.2 and 2.2.5. The only exception is the unimportant “manual” XCHG3 optimization described in C.1.7, which enabled us to shorten the code by one more byte. +By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. \ No newline at end of file From be98593cfcf3cde34461446b1d79f4fb3fd9b2d9 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Sat, 6 Sep 2025 23:55:54 +0100 Subject: [PATCH 02/18] update chapter 1 of the tvm --- docs.json | 1 + ton/tvm.mdx | 132 ++++++++++++++++++++++++++++------------------------ 2 files changed, 71 insertions(+), 62 deletions(-) diff --git a/docs.json b/docs.json index 5c3e63f5..be432ee8 100644 --- a/docs.json +++ b/docs.json @@ -130,6 +130,7 @@ "ton/precompiled", "ton/network", "ton/blocks", + "ton/tvm", "ton/glossary" ] }, diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 8aaf890a..98510fb1 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -1,20 +1,33 @@ --- -title: "TVM" +title: "Telegram Open Network Virtual Machine" +sidebarTitle: "TVM" --- +*Nikolai Durov* +*March 23, 2020* -## Introduction -The primary purpose of the Telegram Open Network Virtual Machine (TON VM or TVM) is to execute smart-contract code in the TON Blockchain. TVM must support all operations required to parse incoming messages and persistent data, and to create new messages and modify persistent data. +## Abstract + +The aim of this text is to provide a description of the Telegram Open Network Virtual Machine (TON VM or TVM), used to execute smart contracts in the TON Blockchain. + +## 1 Introduction + +The primary purpose of the Telegram Open Network Virtual Machine (TON VM or TVM) is to execute smart-contract code in the TON Blockchain. +TVM must support all operations required to parse incoming messages and persistent data, and to create new messages and modify persistent data. Additionally, TVM must meet the following requirements: -* It must provide for possible future extensions and improvements while retaining backward compatibility and interoperability, because the code of a smart contract, once committed into the blockchain, must continue working in a predictable manner regardless of any future modifications to the VM. -* It must strive to attain high "(virtual) machine code" density, so that the code of a typical smart contract occupies as little persistent blockchain storage as possible. -* It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used.[^1] -The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM,[^2] the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. +- **Backward compatibility:** It must provide for possible future extensions and improvements while retaining backward compatibility and interoperability, because the code of a smart contract, once committed into the blockchain, must continue working in a predictable manner regardless of any future modifications to the VM. +- **Code density:** It must strive to attain high “(virtual) machine code” density, so that the code of a typical smart contract occupies as little persistent blockchain storage as possible. +- **Determinism:** It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used. [^1](#footnote-1) + +The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM, [^2](#footnote-2), the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. TVM is not intended to be implemented in hardware (e.g., in a specialized microprocessor chip); rather, it should be implemented in software running on conventional hardware. This consideration lets us incorporate some high-level concepts and operations in TVM that would require convoluted microcode in a hardware implementation but pose no significant problems for a software implementation. Such operations are useful for achieving high code density and minimizing the byte (or storage cell) profile of smart-contract code when deployed in the TON Blockchain. --- +# 1 Overview + +This chapter provides an overview of the main features and design principles of TVM. More detail on each topic is provided in subsequent chapters. ## 1.0 Notation for bitstrings @@ -22,28 +35,24 @@ The following notation is used for bit strings (or bitstrings)—i.e., finite st ### 1.0.1 Hexadecimal notation for bitstrings -When the length of a bitstring is a multiple of four, we subdivide it into groups of four bits and represent each group by one of sixteen hexadecimal digits 0–9, A–F in the usual manner: - -* 0₁₆ ↔ 0000 -* 1₁₆ ↔ 0001 -* … -* F₁₆ ↔ 1111 +When the length of a bitstring is a multiple of four, we subdivide it into groups of four bits and represent each group by one of sixteen hexadecimal digits 0–9, A–F in the usual manner: +`0₁₆ ↔ 0000, 1₁₆ ↔ 0001, …, F₁₆ ↔ 1111`. The resulting hexadecimal string is our equivalent representation for the original binary string. ### 1.0.2 Bitstrings of lengths not divisible by four -If the length of a binary string is not divisible by four, we augment it by one `1` and several (maybe zero) `0`s at the end, so that its length becomes divisible by four, and then transform it into a string of hexadecimal digits as described above. To indicate that such a transformation has taken place, a special **completion tag** `_` is added to the end of the hexadecimal string. +If the length of a binary string is not divisible by four, we augment it by one `1` and several (maybe zero) `0`s at the end, so that its length becomes divisible by four, and then transform it into a string of hexadecimal digits as described above. To indicate that such a transformation has taken place, a special **completion tag** `_` is added to the end of the hexadecimal string. The reverse transformation (applied if the completion tag is present) consists in first replacing each hexadecimal digit by four corresponding bits, and then removing all trailing zeroes (if any) and the last `1` immediately preceding them (if the resulting bitstring is non-empty at this point). -Notice that there are several admissible hexadecimal representations for the same bitstring. Among them, the shortest one is **canonical**. It can be deterministically obtained by the above procedure. +Notice that there are several admissible hexadecimal representations for the same bitstring. Among them, the shortest one is “canonical”. It can be deterministically obtained by the above procedure. -For example: +For example: +- `8A` corresponds to binary string `10001010`. +- `8A_` and `8A0_` both correspond to `100010`. -* `8A` corresponds to binary string `10001010`. -* `8A_` and `8A0_` both correspond to `100010`. -* An empty bitstring may be represented by either `''`, `8_`, `0_`, `_`, or `00_`. +An empty bitstring may be represented by either `''`, `8_`, `0_`, `_`, or `00_`. ### 1.0.3 Emphasizing that a string is a hexadecimal representation of a bitstring @@ -53,72 +62,59 @@ This should not be confused with hexadecimal numbers, usually prepended by `0x` ### 1.0.4 Serializing a bitstring into a sequence of octets -When a bitstring needs to be represented as a sequence of 8-bit bytes (octets), which take values in integers 0…255, this is achieved essentially in the same fashion as above: we split the bitstring into groups of eight bits and interpret each group as the binary representation of an integer 0…255. +When a bitstring needs to be represented as a sequence of 8-bit bytes (octets), which take values in integers 0…255, this is achieved essentially in the same fashion as above: we split the bitstring into groups of eight bits and interpret each group as the binary representation of an integer 0…255. -If the length of the bitstring is not a multiple of eight, the bitstring is augmented by a binary `1` and up to seven binary `0`s before being split into groups. The fact that such a completion has been applied is usually reflected by a **completion tag** bit. +If the length of the bitstring is not a multiple of eight, the bitstring is augmented by a binary `1` and up to seven binary `0`s before being split into groups. The fact that such a completion has been applied is usually reflected by a “completion tag” bit. -For instance, `00101101100` corresponds to the sequence of two octets: - -* `(0x2d, 0x90)` in hexadecimal -* `(45, 144)` in decimal - -…along with a completion tag bit equal to `1` (meaning that the completion has been applied), which must be stored separately. +For instance, `00101101100` corresponds to the sequence of two octets `(0x2d, 0x90)` (hexadecimal), or `(45, 144)` (decimal), along with a completion tag bit equal to 1 (meaning that the completion has been applied), which must be stored separately. In some cases, it is more convenient to assume the completion is enabled by default rather than store an additional completion tag bit separately. Under such conventions, `8n`-bit strings are represented by `n + 1` octets, with the last octet always equal to `0x80 = 128`. -Perfect — I’ll keep the **exact wording** from your excerpt, only formatting it in Markdown for readability (headings, lists, code style for inline values). Numbering stays **exactly as in the source**. - --- -# 1.1 TVM is a stack machine +## 1.1 TVM is a stack machine -First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective.³ +First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective. [^3](#footnote-3) Most operations and user-defined functions take their arguments from the top of the stack, and replace them with their result. For example, the integer addition primitive (built-in operation) `ADD` does not take any arguments describing which registers or immediate values should be added together and where the result should be stored. Instead, the two top values are taken from the stack, they are added together, and their sum is pushed into the stack in their place. -³ A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. - ---- +### 1.1.1 TVM values -## 1.1.1 TVM values +The entities that can be stored in the TVM stack will be called **TVM values**, or simply **values** for brevity. They belong to one of several predefined value types. Each value belongs to exactly one value type. -The entities that can be stored in the TVM stack will be called **TVM values**, or simply **values** for brevity. They belong to one of several predefined value types. Each value belongs to exactly one value type. The values are always kept on the stack along with tags uniquely determining their types, and all built-in TVM operations (or primitives) only accept values of predefined types. +The values are always kept on the stack along with tags uniquely determining their types, and all built-in TVM operations (or primitives) only accept values of predefined types. For example, the integer addition primitive `ADD` accepts only two integer values, and returns one integer value as a result. One cannot supply `ADD` with two strings instead of two integers expecting it to concatenate these strings or to implicitly transform the strings into their decimal integer values; any attempt to do so will result in a run-time type-checking exception. ---- - -## 1.1.2 Static typing, dynamic typing, and run-time type checking +### 1.1.2 Static typing, dynamic typing, and run-time type checking In some respects TVM performs a kind of dynamic typing using run-time type checking. However, this does not make the TVM code a “dynamically typed language” like PHP or Javascript, because all primitives accept values and return results of predefined (value) types, each value belongs to strictly one type, and values are never implicitly converted from one type to another. -If, on the other hand, one compares the TVM code to the conventional microprocessor machine code, one sees that the TVM mechanism of value tagging prevents, for example, using the address of a string as a number—or, potentially even more disastrously, using a number as the address of a string—thus eliminating the possibility of all sorts of bugs and security vulnerabilities related to invalid memory accesses, usually leading to memory corruption and segmentation faults. +If, on the other hand, one compares the TVM code to the conventional microprocessor machine code, one sees that the TVM mechanism of value tagging prevents, for example, using the address of a string as a number—or, potentially even more disastrously, using a number as the address of a string—thus eliminating the possibility of all sorts of bugs and security vulnerabilities related to invalid memory accesses, usually leading to memory corruption and segmentation faults. This property is highly desirable for a VM used to execute smart contracts in a blockchain. In this respect, TVM’s insistence on tagging all values with their appropriate types, instead of reinterpreting the bit sequence in a register depending on the needs of the operation it is used in, is just an additional run-time type-safety mechanism. An alternative would be to somehow analyze the smart-contract code for type correctness and type safety before allowing its execution in the VM, or even before allowing it to be uploaded into the blockchain as the code of a smart contract. Such a static analysis of code for a Turing-complete machine appears to be a time-consuming and non-trivial problem (likely to be equivalent to the stopping problem for Turing machines), something we would rather avoid in a blockchain smart-contract context. -One should bear in mind that one always can implement compilers from statically typed high-level smart-contract languages into the TVM code (and we do expect that most smart contracts for TON will be written in such languages), just as one can compile statically typed languages into conventional machine code (e.g., x86 architecture). If the compiler works correctly, the resulting machine code will never generate any run-time type-checking exceptions. +One should bear in mind that one always can implement compilers from statically typed high-level smart-contract languages into the TVM code (and we do expect that most smart contracts for TON will be written in such languages), just as one can compile statically typed languages into conventional machine code (e.g., x86 architecture). If the compiler works correctly, the resulting machine code will never generate any run-time type-checking exceptions. All type tags attached to values processed by TVM will always have expected values and may be safely ignored during the analysis of the resulting TVM code, apart from the fact that the run-time generation and verification of these type tags by TVM will slightly slow down the execution of the TVM code. ---- - -## 1.1.3 Preliminary list of value types +### 1.1.3 Preliminary list of value types A preliminary list of value types supported by TVM is as follows: -* **Integer** — Signed 257-bit integers, representing integer numbers in the range −2²⁵⁶ … 2²⁵⁶−1, as well as a special “not-a-number” value `NaN`. -* **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. \[1, 2.5.14]). -* **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. -* **Null** — A type with exactly one value ⊥, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. -* **Slice** — A TVM cell slice, or slice for short, is a contiguous “sub-cell” of an existing cell, containing some of its bits of data and some of its references. Essentially, a slice is a read-only view for a subcell of a cell. Slices are used for unpacking data previously stored (or serialized) in a cell or a tree of cells. -* **Builder** — A TVM cell builder, or builder for short, is an “incomplete” cell that supports fast operations of appending bitstrings and cell references at its end. Builders are used for packing (or serializing) data from the top of the stack into new cells (e.g., before transferring them to persistent storage). -* **Continuation** — A special value containing TVM code and execution context that can be invoked (executed) later. As such, it generalizes function addresses (i.e., function pointers and references), subroutine return addresses, instruction pointer addresses, exception handler addresses, closures, partial applications, anonymous functions, and so on. +- **Integer** — Signed 257-bit integers, representing integer numbers in the range `−2^256 … 2^256 − 1`, as well as a special “not-a-number” value `NaN`. +- **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. [1, 2.5.14]). +- **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. +- **Null** — A type with exactly one value `⊥`, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. +- **Slice** — A TVM cell slice, or slice for short, is a contiguous “sub-cell” of an existing cell, containing some of its bits of data and some of its references. Essentially, a slice is a read-only view for a subcell of a cell. Slices are used for unpacking data previously stored (or serialized) in a cell or a tree of cells. +- **Builder** — A TVM cell builder, or builder for short, is an “incomplete” cell that supports fast operations of appending bitstrings and cell references at its end. Builders are used for packing (or serializing) data from the top of the stack into new cells (e.g., before transferring them to persistent storage). +- **Continuation** — Represents an “execution token” for TVM, which may be invoked (executed) later. As such, it generalizes function addresses (i.e., function pointers and references), subroutine return addresses, instruction pointer addresses, exception handler addresses, closures, partial applications, anonymous functions, and so on. -This list of value types is incomplete and may be extended in future revisions of TVM without breaking the old TVM code, due mostly to the fact that all originally defined primitives accept only values of types known to them and will fail (generate a type-checking exception) if invoked on values of new types. +This list of value types is incomplete and may be extended in future revisions of TVM without breaking the old TVM code, due mostly to the fact that all originally defined primitives accept only values of types known to them and will fail (generate a type-checking exception) if invoked on values of new types. -Furthermore, existing value types themselves can also be extended in the future: for example, 257-bit `Integer` might become 513-bit `LongInteger`, with originally defined arithmetic primitives failing if either of the arguments or the result does not fit into the original subtype `Integer`. +Furthermore, existing value types themselves can also be extended in the future: for example, 257-bit `Integer` might become 513-bit `LongInteger`, with originally defined arithmetic primitives failing if either of the arguments or the result does not fit into the original subtype `Integer`. Backward compatibility with respect to the introduction of new value types and extension of existing value types will be discussed in more detail later (cf. 5.1.4). @@ -126,15 +122,17 @@ Backward compatibility with respect to the introduction of new value types and e ## 1.2 Categories of TVM instructions -TVM instructions, also called **primitives** and sometimes **(built-in) operations**, are the smallest operations atomically performed by TVM that can be present in the TVM code. They fall into several categories, depending on the types of values (cf. 1.1.3) they work on. The most important of these categories are: +TVM instructions, also called **primitives** and sometimes **(built-in) operations**, are the smallest operations atomically performed by TVM that can be present in the TVM code. + +They fall into several categories, depending on the types of values (cf. 1.1.3) they work on. The most important of these categories are: -* **Stack (manipulation) primitives** — Rearrange data in the TVM stack, so that the other primitives and user-defined functions can later be called with correct arguments. Unlike most other primitives, they are polymorphic, i.e., work with values of arbitrary types. -* **Tuple (manipulation) primitives** — Construct, modify, and decompose Tuples. Similarly to the stack primitives, they are polymorphic. -* **Constant or literal primitives** — Push into the stack some “constant” or “literal” values embedded into the TVM code itself, thus providing arguments to the other primitives. They are somewhat similar to stack primitives, but are less generic because they work with values of specific types. -* **Arithmetic primitives** — Perform the usual integer arithmetic operations on values of type Integer. -* **Cell (manipulation) primitives** — Create new cells and store data in them (cell creation primitives) or read data from previously created cells (cell parsing primitives). Because all memory and persistent storage of TVM consists of cells, these cell manipulation primitives actually correspond to “memory access instructions” of other architectures. Cell creation primitives usually work with values of type Builder, while cell parsing primitives work with Slices. -* **Continuation and control flow primitives** — Create and modify Continuations, as well as execute existing Continuations in different ways, including conditional and repeated execution. -* **Custom or application-specific primitives** — Efficiently perform specific high-level actions required by the application (in our case, the TON Blockchain), such as computing hash functions, performing elliptic curve cryptography, sending new blockchain messages, creating new smart contracts, and so on. These primitives correspond to standard library functions rather than microprocessor instructions. +- **Stack (manipulation) primitives** — Rearrange data in the TVM stack, so that the other primitives and user-defined functions can later be called with correct arguments. Unlike most other primitives, they are polymorphic, i.e., work with values of arbitrary types. +- **Tuple (manipulation) primitives** — Construct, modify, and decompose Tuples. Similarly to the stack primitives, they are polymorphic. +- **Constant or literal primitives** — Push into the stack some “constant” or “literal” values embedded into the TVM code itself, thus providing arguments to the other primitives. They are somewhat similar to stack primitives, but are less generic because they work with values of specific types. +- **Arithmetic primitives** — Perform the usual integer arithmetic operations on values of type `Integer`. +- **Cell (manipulation) primitives** — Create new cells and store data in them (cell creation primitives) or read data from previously created cells (cell parsing primitives). Because all memory and persistent storage of TVM consists of cells, these cell manipulation primitives actually correspond to “memory access instructions” of other architectures. Cell creation primitives usually work with values of type `Builder`, while cell parsing primitives work with `Slices`. +- **Continuation and control flow primitives** — Create and modify `Continuations`, as well as execute existing `Continuations` in different ways, including conditional and repeated execution. +- **Custom or application-specific primitives** — Efficiently perform specific high-level actions required by the application (in our case, the TON Blockchain), such as computing hash functions, performing elliptic curve cryptography, sending new blockchain messages, creating new smart contracts, and so on. These primitives correspond to standard library functions rather than microprocessor instructions. --- @@ -4760,4 +4758,14 @@ For example, the very popular two-address register architecture x86-64 produces ## C.4.4. Automatic generation of optimized code. An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in 2.2.2 and 2.2.5. The only exception is the unimportant “manual” XCHG3 optimization described in C.1.7, which enabled us to shorten the code by one more byte. -By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. \ No newline at end of file +By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. + + + +## Footnotes + + **1.** There are no floating-point arithmetic operations (which could be efficiently implemented using hardware-supported `double` type on most modern CPUs) present in TVM, because the result of performing such operations is dependent on the specific underlying hardware implementation and rounding mode settings. Instead, TVM supports special integer arithmetic operations, which can be used to simulate fixed-point arithmetic if needed. [Back ↑](#1-introduction) + + **2.** The production version will likely require some tweaks and modifications prior to launch, which will become apparent only after using the experimental version in the test environment for some time. [Back ↑](#1-introduction) + + **3.** A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. [Back ↑](#11-tvm-is-a-stack-machine) From c0b574d0982cf23076fc31d798a86580df72805f Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Sun, 7 Sep 2025 04:22:30 +0100 Subject: [PATCH 03/18] update tvm formatting --- ton/tvm.mdx | 3758 ++++++++++++++++++--------------------------------- 1 file changed, 1336 insertions(+), 2422 deletions(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 98510fb1..75fedb0c 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -18,9 +18,9 @@ Additionally, TVM must meet the following requirements: - **Backward compatibility:** It must provide for possible future extensions and improvements while retaining backward compatibility and interoperability, because the code of a smart contract, once committed into the blockchain, must continue working in a predictable manner regardless of any future modifications to the VM. - **Code density:** It must strive to attain high “(virtual) machine code” density, so that the code of a typical smart contract occupies as little persistent blockchain storage as possible. -- **Determinism:** It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used. [^1](#footnote-1) +- **Determinism:** It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used. [1](#footnote-1) -The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM, [^2](#footnote-2), the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. +The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM, [2](#footnote-2), the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. TVM is not intended to be implemented in hardware (e.g., in a specialized microprocessor chip); rather, it should be implemented in software running on conventional hardware. This consideration lets us incorporate some high-level concepts and operations in TVM that would require convoluted microcode in a hardware implementation but pose no significant problems for a software implementation. Such operations are useful for achieving high code density and minimizing the byte (or storage cell) profile of smart-contract code when deployed in the TON Blockchain. @@ -74,7 +74,7 @@ In some cases, it is more convenient to assume the completion is enabled by defa ## 1.1 TVM is a stack machine -First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective. [^3](#footnote-3) +First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective.[3](#footnote-3) Most operations and user-defined functions take their arguments from the top of the stack, and replace them with their result. For example, the integer addition primitive (built-in operation) `ADD` does not take any arguments describing which registers or immediate values should be added together and where the result should be stored. Instead, the two top values are taken from the stack, they are added together, and their sum is pushed into the stack in their place. @@ -105,7 +105,7 @@ All type tags attached to values processed by TVM will always have expected valu A preliminary list of value types supported by TVM is as follows: - **Integer** — Signed 257-bit integers, representing integer numbers in the range `−2^256 … 2^256 − 1`, as well as a special “not-a-number” value `NaN`. -- **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. [1, 2.5.14]). +- **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. [1](#reference-1) 2.5.14]). - **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. - **Null** — A type with exactly one value `⊥`, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. - **Slice** — A TVM cell slice, or slice for short, is a contiguous “sub-cell” of an existing cell, containing some of its bits of data and some of its references. Essentially, a slice is a read-only view for a subcell of a cell. Slices are used for unpacking data previously stored (or serialized) in a cell or a tree of cells. @@ -116,7 +116,7 @@ This list of value types is incomplete and may be extended in future revisions o Furthermore, existing value types themselves can also be extended in the future: for example, 257-bit `Integer` might become 513-bit `LongInteger`, with originally defined arithmetic primitives failing if either of the arguments or the result does not fit into the original subtype `Integer`. -Backward compatibility with respect to the introduction of new value types and extension of existing value types will be discussed in more detail later (cf. 5.1.4). +Backward compatibility with respect to the introduction of new value types and extension of existing value types will be discussed in more detail later (cf. [5.1.4](#5-1-4-changing-the-behavior-of-old-operations)). --- @@ -124,7 +124,7 @@ Backward compatibility with respect to the introduction of new value types and e TVM instructions, also called **primitives** and sometimes **(built-in) operations**, are the smallest operations atomically performed by TVM that can be present in the TVM code. -They fall into several categories, depending on the types of values (cf. 1.1.3) they work on. The most important of these categories are: +They fall into several categories, depending on the types of values (cf. [1.1.3](#1-1-3-preliminary-list-of-value-types)) they work on. The most important of these categories are: - **Stack (manipulation) primitives** — Rearrange data in the TVM stack, so that the other primitives and user-defined functions can later be called with correct arguments. Unlike most other primitives, they are polymorphic, i.e., work with values of arbitrary types. - **Tuple (manipulation) primitives** — Construct, modify, and decompose Tuples. Similarly to the stack primitives, they are polymorphic. @@ -135,34 +135,27 @@ They fall into several categories, depending on the types of values (cf. 1.1.3) - **Custom or application-specific primitives** — Efficiently perform specific high-level actions required by the application (in our case, the TON Blockchain), such as computing hash functions, performing elliptic curve cryptography, sending new blockchain messages, creating new smart contracts, and so on. These primitives correspond to standard library functions rather than microprocessor instructions. --- - ## 1.3 Control registers While TVM is a stack machine, some rarely changed values needed in almost all functions are better passed in certain special registers, and not near the top of the stack. Otherwise, a prohibitive number of stack reordering operations would be required to manage all these values. -To this end, the TVM model includes, apart from the stack, up to **16 special control registers**, denoted by `c0` to `c15`, or `c(0)` to `c(15)`. The original version of TVM makes use of only some of these registers; the rest may be supported later. - ---- +To this end, the TVM model includes, apart from the stack, up to 16 special control registers, denoted by `c0` to `c15`, or `c(0)` to `c(15)`. The original version of TVM makes use of only some of these registers; the rest may be supported later. ### 1.3.1 Values kept in control registers The values kept in control registers are of the same types as those kept on the stack. However, some control registers accept only values of specific types, and any attempt to load a value of a different type will lead to an exception. ---- - ### 1.3.2 List of control registers The original version of TVM defines and uses the following control registers: -* **c0** — Contains the return continuation (similar to the subroutine return address in conventional designs). This value must be a Continuation. -* **c1** — Contains the alternative (return) continuation; this value must be a Continuation. It is used in some (experimental) control flow primitives, allowing TVM to define and call “subroutines with two exit points”. -* **c2** — Contains the exception handler. This value is a Continuation, invoked whenever an exception is triggered. -* **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in 4.6, this value is also a Continuation, not a Cell as one might expect. -* **c4** — Contains the root of persistent data, or simply the data. This value is a Cell. When the code of a smart contract is invoked, `c4` points to the root cell of its persistent data kept in the blockchain state. If the smart contract needs to modify this data, it changes `c4` before returning. -* **c5** — Contains the output actions. It is also a Cell initialized by a reference to an empty cell, but its final value is considered one of the smart contract outputs. For instance, the `SENDMSG` primitive, specific for the TON Blockchain, simply inserts the message into a list stored in the output actions. -* **c7** — Contains the root of temporary data. It is a Tuple, initialized by a reference to an empty Tuple before invoking the smart contract and discarded after its termination.⁴ - -⁴ In the TON Blockchain context, `c7` is initialized with a singleton Tuple, the only component of which is a Tuple containing blockchain-specific data. The smart contract is free to modify `c7` to store its temporary data provided the first component of this Tuple remains intact. +- **c0** — Contains the next continuation or return continuation (similar to the subroutine return address in conventional designs). This value must be a `Continuation`. +- **c1** — Contains the alternative (return) continuation; this value must be a `Continuation`. It is used in some (experimental) control flow primitives, allowing TVM to define and call “subroutines with two exit points”. +- **c2** — Contains the exception handler. This value is a `Continuation`, invoked whenever an exception is triggered. +- **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in [4.6](#4-6-...-reference), this value is also a `Continuation`, not a `Cell` as one might expect. +- **c4** — Contains the root of persistent data, or simply the data. This value is a `Cell`. When the code of a smart contract is invoked, `c4` points to the root cell of its persistent data kept in the blockchain state. If the smart contract needs to modify this data, it changes `c4` before returning. +- **c5** — Contains the output actions. It is also a `Cell` initialized by a reference to an empty cell, but its final value is considered one of the smart contract outputs. For instance, the `SENDMSG` primitive, specific for the TON Blockchain, simply inserts the message into a list stored in the output actions. +- **c7** — Contains the root of temporary data. It is a `Tuple`, initialized by a reference to an empty `Tuple` before invoking the smart contract and discarded after its termination.[4](#footnote-4) More control registers may be defined in the future for specific TON Blockchain or high-level programming language purposes, if necessary. @@ -172,1035 +165,541 @@ More control registers may be defined in the future for specific TON Blockchain The total state of TVM consists of the following components: -* **Stack** (cf. 1.1) — Contains zero or more values (cf. 1.1.1), each belonging to one of value types listed in 1.1.3. -* **Control registers `c0–c15`** — Contain some specific values as described in 1.3.2. (Only seven control registers are used in the current version.) -* **Current continuation `cc`** — Contains the current continuation (i.e., the code that would be normally executed after the current primitive is completed). This component is similar to the instruction pointer register (`ip`) in other architectures. -* **Current codepage `cp`** — A special signed 16-bit integer value that selects the way the next TVM opcode will be decoded. For example, future versions of TVM might use different codepages to add new opcodes while preserving backward compatibility. -* **Gas limits `gas`** — Contains four signed 64-bit integers: the current gas limit `gl`, the maximal gas limit `gm`, the remaining gas `gr`, and the gas credit `gc`. Always `0 ≤ gl ≤ gm`, `gc ≥ 0`, and `gr ≤ gl + gc`; `gc` is usually initialized by zero, `gr` is initialized by `gl + gc` and gradually decreases as the TVM runs. When `gr` becomes negative or if the final value of `gr` is less than `gc`, an out of gas exception is triggered. - -Notice that there is no “return stack” containing the return addresses of all previously called but unfinished functions. Instead, only control register `c0` is used. The reason for this will be explained later in 4.1.9. +- **Stack (cf. [1.1](#1-1-tvm-is-a-stack-machine))** — Contains zero or more values (cf. [1.1.1](#1-1-1-tvm-values)), each belonging to one of value types listed in [1.1.3](#1-1-3-preliminary-list-of-value-types). +- **Control registers c0–c15** — Contain some specific values as described in [1.3.2](#1-3-2-list-of-control-registers). (Only seven control registers are used in the current version.) +- **Current continuation `cc`** — Contains the current continuation (i.e., the code that would be normally executed after the current primitive is completed). This component is similar to the instruction pointer register (`ip`) in other architectures. +- **Current codepage `cp`** — A special signed 16-bit integer value that selects the way the next TVM opcode will be decoded. For example, future versions of TVM might use different codepages to add new opcodes while preserving backward compatibility. +- **Gas limits `gas`** — Contains four signed 64-bit integers: the current gas limit `gl`, the maximal gas limit `gm`, the remaining gas `gr`, and the gas credit `gc`. Always `0 ≤ gl ≤ gm`, `gc ≥ 0`, and `gr ≤ gl + gc`; `gc` is usually initialized by zero, `gr` is initialized by `gl + gc` and gradually decreases as the TVM runs. When `gr` becomes negative or if the final value of `gr` is less than `gc`, an out of gas exception is triggered. -Also notice that there are no general-purpose registers, because TVM is a stack machine (cf. 1.1). So the above list, which can be summarized as “stack, control, continuation, codepage, and gas” (**SCCCG**), similarly to the classical SECD machine state (“stack, environment, control, dump”), is indeed the total state of TVM. +Notice that there is no “return stack” containing the return addresses of all previously called but unfinished functions. Instead, only control register `c0` is used. The reason for this will be explained later in [4.1.9](#4-1-9-subroutine-calls%3A-callx-or-execute-primitives). -Perfect — here’s the next part, keeping the **exact wording** but properly formatted into Markdown. +Also notice that there are no general-purpose registers, because TVM is a stack machine (cf. [1.1](#1-1-tvm-is-a-stack-machine)). So the above list, which can be summarized as **“stack, control, continuation, codepage, and gas” (SCCCG)**, similarly to the classical SECD machine state (“stack, environment, control, dump”), is indeed the total state of TVM.[5](#footnote-5) --- ## 1.5 Integer arithmetic -All arithmetic primitives of TVM operate on several arguments of type **Integer**, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that Integer represents all integer values in the range `−2²⁵⁶ ≤ x < 2²⁵⁶`, and additionally contains a special value **NaN** (“not-a-number”). +All arithmetic primitives of TVM operate on several arguments of type `Integer`, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that `Integer` represents all integer values in the range `−2^256 ≤ x < 2^256`, and additionally contains a special value `NaN` (“not-a-number”). -If one of the results does not fit into the supported range of integers—or if one of the arguments is a NaN—then this result or all of the results are replaced by a NaN, and (by default) an integer overflow exception is generated. However, special “quiet” versions of arithmetic operations will simply produce NaNs and keep going. If these NaNs end up being used in a “non-quiet” arithmetic operation, or in a non-arithmetic operation, an integer overflow exception will occur. - ---- +If one of the results does not fit into the supported range of integers—or if one of the arguments is a `NaN`—then this result or all of the results are replaced by a `NaN`, and (by default) an integer overflow exception is generated. However, special “quiet” versions of arithmetic operations will simply produce `NaN`s and keep going. If these `NaN`s end up being used in a “non-quiet” arithmetic operation, or in a non-arithmetic operation, an integer overflow exception will occur. ### 1.5.1 Absence of automatic conversion of integers -Notice that TVM Integers are “mathematical” integers, and not 257-bit strings interpreted differently depending on the primitive used, as is common for other machine code designs. For example, TVM has only one multiplication primitive `MUL`, rather than two (`MUL` for unsigned multiplication and `IMUL` for signed multiplication) as occurs, for example, in the popular x86 architecture. - ---- +Notice that TVM `Integer`s are “mathematical” integers, and not 257-bit strings interpreted differently depending on the primitive used, as is common for other machine code designs. For example, TVM has only one multiplication primitive `MUL`, rather than two (`MUL` for unsigned multiplication and `IMUL` for signed multiplication) as occurs, for example, in the popular x86 architecture. ### 1.5.2 Automatic overflow checks -Notice that all TVM arithmetic primitives perform overflow checks of the results. If a result does not fit into the Integer type, it is replaced by a NaN, and (usually) an exception occurs. In particular, the result is not automatically reduced modulo `2²⁵⁶` or `2²⁵⁷`, as is common for most hardware machine code architectures. +Notice that all TVM arithmetic primitives perform overflow checks of the results. If a result does not fit into the `Integer` type, it is replaced by a `NaN`, and (usually) an exception occurs. ---- +In particular, the result is not automatically reduced modulo `2^256` or `2^257`, as is common for most hardware machine code architectures. ### 1.5.3 Custom overflow checks -In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. - -* `FITS n` checks whether the value on the top of the stack is an integer `x` in the range `−2ⁿ⁻¹ ≤ x < 2ⁿ⁻¹`. -* `UFITS n` checks whether the value is in the range `0 ≤ x < 2ⁿ`. - -If the value does not fit, it is replaced with a NaN and (optionally) an integer overflow exception is generated. +In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. These primitives check whether the value on (the top of) the stack is an integer `x` in the range `−2^(n−1) ≤ x < 2^(n−1)` or `0 ≤ x < 2^n`, respectively, and replace the value with a `NaN` and (optionally) generate an integer overflow exception if this is not the case. -This greatly simplifies the implementation of arbitrary `n`-bit integer types, signed or unsigned: the programmer or the compiler must insert appropriate `FITS` or `UFITS` primitives either after each arithmetic operation (which is more reasonable, but requires more checks) or before storing computed values and returning them from functions. This is important for smart contracts, where unexpected integer overflows happen to be among the most common source of bugs. +This greatly simplifies the implementation of arbitrary n-bit integer types, signed or unsigned: the programmer or the compiler must insert appropriate `FITS` or `UFITS` primitives either after each arithmetic operation (which is more reasonable, but requires more checks) or before storing computed values and returning them from functions. ---- +This is important for smart contracts, where unexpected integer overflows happen to be among the most common source of bugs. ### 1.5.4 Reduction modulo 2ⁿ -TVM also has a primitive `MODPOW2 n`, which reduces the integer at the top of the stack modulo `2ⁿ`, with the result ranging from `0` to `2ⁿ − 1`. - ---- +TVM also has a primitive `MODPOW2 n`, which reduces the integer at the top of the stack modulo `2^n`, with the result ranging from `0` to `2^n − 1`. ### 1.5.5 Integer is 257-bit, not 256-bit -One can understand now why TVM’s Integer is (signed) 257-bit, not 256-bit. The reason is that it is the smallest integer type containing both signed 256-bit integers and unsigned 256-bit integers, which does not require automatic reinterpreting of the same 256-bit string depending on the operation used (cf. 1.5.1). - ---- +One can understand now why TVM’s `Integer` is (signed) 257-bit, not 256-bit. The reason is that it is the smallest integer type containing both signed 256-bit integers and unsigned 256-bit integers, which does not require automatic reinterpreting of the same 256-bit string depending on the operation used (cf. [1.5.1](#1-5-1-absence-of-automatic-conversion-of-integers)). ### 1.5.6 Division and rounding -The most important division primitives are `DIV`, `MOD`, and `DIVMOD`. All of them take two numbers from the stack, `x` and `y` (`y` is taken from the top of the stack, and `x` is originally under it), compute the quotient `q` and remainder `r` of the division of `x` by `y` (i.e., two integers such that `x = yq + r` and `|r| < |y|`), and return either `q`, `r`, or both of them. +The most important division primitives are `DIV`, `MOD`, and `DIVMOD`. All of them take two numbers from the stack, `x` and `y` (`y` is taken from the top of the stack, and `x` is originally under it), compute the quotient `q` and remainder `r` of the division of `x` by `y` (i.e., two integers such that `x = yq + r` and `|r| < |y|`), and return either `q`, `r`, or both of them. -* If `y` is zero, then all of the expected results are replaced by NaNs, and (usually) an integer overflow exception is generated. -* By default, these primitives round to `−∞`, meaning that `q = ⌊x / y⌋`, and `r` has the same sign as `y`. (Most conventional implementations of division use “rounding to zero” instead, meaning that `r` has the same sign as `x`.) +If `y` is zero, then all of the expected results are replaced by `NaN`s, and (usually) an integer overflow exception is generated. -Apart from this **floor rounding**, two other rounding modes are available: +The implementation of division in TVM somewhat differs from most other implementations with regards to rounding. By default, these primitives round to `−∞`, meaning that `q = ⌊x/y⌋`, and `r` has the same sign as `y`. (Most conventional implementations of division use “rounding to zero” instead, meaning that `r` has the same sign as `x`.) -* **Ceiling rounding**: `q = ⌈x / y⌉`, and `r` and `y` have opposite signs. -* **Nearest rounding**: `q = ⌊x / y + 1/2⌋` and `|r| ≤ |y| / 2`. +Apart from this “floor rounding”, two other rounding modes are available, called **ceiling rounding** (with `q = ⌈x/y⌉`, and `r` and `y` having opposite signs) and **nearest rounding** (with `q = ⌊x/y + 1/2⌋` and `|r| ≤ |y|/2`). These rounding modes are selected by using other division primitives, with letters `C` and `R` appended to their mnemonics. For example, `DIVMODR` computes both the quotient and the remainder using rounding to the nearest integer. ---- - ### 1.5.7 Combined multiply-divide, multiply-shift, and shift-divide operations -To simplify implementation of fixed-point arithmetic, TVM supports combined multiply-divide, multiply-shift, and shift-divide operations with double-length (i.e., 514-bit) intermediate product. +To simplify implementation of fixed-point arithmetic, TVM supports combined multiply-divide, multiply-shift, and shift-divide operations with double-length (i.e., 514-bit) intermediate product. -For example, `MULDIVMODR` takes three integer arguments from the stack, `a`, `b`, and `c`, first computes `ab` using a 514-bit intermediate result, and then divides `ab` by `c` using rounding to the nearest integer. +For example, `MULDIVMODR` takes three integer arguments from the stack, `a`, `b`, and `c`, first computes `ab` using a 514-bit intermediate result, and then divides `ab` by `c` using rounding to the nearest integer. -* If `c` is zero or if the quotient does not fit into Integer, either two NaNs are returned, or an integer overflow exception is generated, depending on whether a quiet version of the operation has been used. -* Otherwise, both the quotient and the remainder are pushed into the stack. +If `c` is zero or if the quotient does not fit into `Integer`, either two `NaN`s are returned, or an integer overflow exception is generated, depending on whether a quiet version of the operation has been used. Otherwise, both the quotient and the remainder are pushed into the stack. --- # 2 The stack -This chapter contains a general discussion and comparison of register and -stack machines, expanded further in Appendix C, and describes the two -main classes of stack manipulation primitives employed by TVM: the basic -and the compound stack manipulation primitives. An informal explanation of -their sufficiency for all stack reordering required for correctly invoking other -primitives and user-defined functions is also provided. Finally, the problem -of efficiently implementing TVM stack manipulation primitives is discussed -in 2.3. +This chapter contains a general discussion and comparison of register and stack machines, expanded further in [Appendix C](#appendix-c), and describes the two main classes of stack manipulation primitives employed by TVM: the basic and the compound stack manipulation primitives. An informal explanation of their sufficiency for all stack reordering required for correctly invoking other primitives and user-defined functions is also provided. Finally, the problem of efficiently implementing TVM stack manipulation primitives is discussed in [2.3](#2-3-...). ## 2.1 Stack calling conventions -A stack machine, such as TVM, uses the stack—and especially the values -near the top of the stack—to pass arguments to called functions and primitives (such as built-in arithmetic operations) and receive their results. This -section discusses the TVM stack calling conventions, introduces some notation, and compares TVM stack calling conventions with those of certain -register machines. - -### 2.1.1. Notation for “stack registers”. - -Recall that a stack machine, as -opposed to a more conventional register machine, lacks general-purpose registers. However, one can treat the values near the top of the stack as a kind -of “stack registers”. -We denote by s0 or s(0) the value at the top of the stack, by s1 or s(1) -the value immediately under it, and so on. The total number of values in the -stack is called its depth. If the depth of the stack is n, then s(0), s(1), . . . , -s(n − 1) are well-defined, while s(n) and all subsequent s(i) with i > n are -not. Any attempt to use s(i) with i ≥ n should produce a stack underflow -exception. -A compiler, or a human programmer in “TVM code”, would use these -“stack registers” to hold all declared variables and intermediate values, similarly to the way general-purpose registers are used on a register machine. - -### 2.1.2. Pushing and popping values. - -When a value x is pushed into a -stack of depth n, it becomes the new s0; at the same time, the old s0 becomes -the new s1, the old s1—the new s2, and so on. The depth of the resulting -stack is n + 1. -Similarly, when a value x is popped from a stack of depth n ≥ 1, it is the -old value of s0 (i.e., the old value at the top of the stack). After this, it is -removed from the stack, and the old s1 becomes the new s0 (the new value -at the top of the stack), the old s2 becomes the new s1, and so on. The -depth of the resulting stack is n − 1. -If originally n = 0, then the stack is empty, and a value cannot be popped -from it. If a primitive attempts to pop a value from an empty stack, a stack -underflow exception occurs. - -### 2.1.3. Notation for hypothetical general-purpose registers. - -In order -to compare stack machines with sufficiently general register machines, we will -denote the general-purpose registers of a register machine by r0, r1, and so -on, or by r(0), r(1), . . . , r(n − 1), where n is the total number of registers. -When we need a specific value of n, we will use n = 16, corresponding to the -very popular x86-64 architecture. - -### 2.1.4. The top-of-stack register s0 vs. the accumulator register r0. - -Some register machine architectures require one of the arguments for most -arithmetic and logical operations to reside in a special register called the -accumulator. In our comparison, we will assume that the accumulator is -the general-purpose register r0; otherwise we could simply renumber the -registers. In this respect, the accumulator is somewhat similar to the top-ofstack “register” s0 of a stack machine, because virtually all operations of a -stack machine both use s0 as one of their arguments and return their result -as s0. - -### 2.1.5. Register calling conventions. - -When compiled for a register machine, high-level language functions usually receive their arguments in certain -registers in a predefined order. If there are too many arguments, these functions take the remainder from the stack (yes, a register machine usually has -a stack, too!). Some register calling conventions pass no arguments in registers at all, however, and only use the stack (for example, the original calling -conventions used in implementations of Pascal and C, although modern implementations of C use some registers as well). -For simplicity, we will assume that up to m ≤ n function arguments are -passed in registers, and that these registers are r0, r1, . . . , r(m − 1), in that -order (if some other registers are used, we can simply renumber them).6 -6Our inclusion of r0 here creates a minor conflict with our assumption that the ac - -### 2.1.6. Order of function arguments. - -If a function or primitive requires -m arguments x1, . . . , xm, they are pushed by the caller into the stack in the -same order, starting from x1. Therefore, when the function or primitive is -invoked, its first argument x1 is in s(m − 1), its second argument x2 is in -s(m − 2), and so on. The last argument xm is in s0 (i.e., at the top of the -stack). It is the called function or primitive’s responsibility to remove its -arguments from the stack. -In this respect the TVM stack calling conventions—obeyed, at least, by -TMV primitives—match those of Pascal and Forth, and are the opposite of -those of C (in which the arguments are pushed into the stack in the reverse -order, and are removed by the caller after it regains control, not the callee). -Of course, an implementation of a high-level language for TVM might -choose some other calling conventions for its functions, different from the -default ones. This might be useful for certain functions—for instance, if the -total number of arguments depends on the value of the first argument, as -happens for “variadic functions” such as scanf and printf. In such cases, -the first one or several arguments are better passed near the top of the stack, -not somewhere at some unknown location deep in the stack. - -### 2.1.7. Arguments to arithmetic primitives on register machines. - -On a stack machine, built-in arithmetic primitives (such as ADD or DIVMOD) -follow the same calling conventions as user-defined functions. In this respect, -user-defined functions (for example, a function computing the square root of -a number) might be considered as “extensions” or “custom upgrades” of the -stack machine. This is one of the clearest advantages of stack machines -(and of stack programming languages such as Forth) compared to register -machines. - -In contrast, arithmetic instructions (built-in operations) on register machines usually get their parameters from general-purpose registers encoded -in the full opcode. A binary operation, such as SUB, thus requires two arguments, r(i) and r(j), with i and j specified by the instruction. A register -r(k) for storing the result also must be specified. Arithmetic operations can -take several possible forms, depending on whether i, j, and k are allowed to -take arbitrary values: - -* Three-address form — Allows the programmer to arbitrarily choose - not only the two source registers r(i) and r(j), but also a separate - destination register r(k). This form is common for most RISC processors, and for the XMM and AVX SIMD instruction sets in the x86-64 - architecture. -* Two-address form — Uses one of the two operand registers (usually - r(i)) to store the result of an operation, so that k = i is never indicated - explicitly. Only i and j are encoded inside the instruction. This is the - most common form of arithmetic operations on register machines, and - is quite popular on microprocessors (including the x86 family). -* One-address form — Always takes one of the arguments from the accumulator r0, and stores the result in r0 as well; then i = k = 0, and - only j needs to be specified by the instruction. This form is used by - some simpler microprocessors (such as Intel 8080). - -Note that this flexibility is available only for built-in operations, but not for user-defined functions. In this respect, register machines are not as easily “upgradable” as stack machines.7 - -Got it ✅ — you want all the inline code-like things (mnemonics, variables, stack notation, etc.) properly wrapped in backticks (`` ` ``) for Markdown. I’ll take the exact text from Chapter 2 (as we’ve been doing), but ensure things like `s0`, `s(i)`, `XCHG`, `PUSH`, `DIV`, etc. are in backticks so they render as code. - -Here’s the **cleaned version with backticks applied** (continuing from §2.1.8 to the end of Chapter 2): +A stack machine, such as TVM, uses the stack—and especially the values near the top of the stack—to pass arguments to called functions and primitives (such as built-in arithmetic operations) and receive their results. This section discusses the TVM stack calling conventions, introduces some notation, and compares TVM stack calling conventions with those of certain register machines. ---- +### 2.1.1 Notation for “stack registers” -### 2.1.8. Return values of functions. - -In stack machines such as TVM, -when a function or primitive needs to return a result value, it simply pushes -it into the stack (from which all arguments to the function have already been -removed). Therefore, the caller will be able to access the result value through -the top-of-stack “register” `s0`. -This is in complete accordance with Forth calling conventions, but differs slightly from Pascal and C calling conventions, where the accumulator -register `r0` is normally used for the return value. - -### 2.1.9. Returning several values. - -Some functions might want to return -several values `y1, . . . , yk`, with `k` not necessarily equal to one. In these cases, -the `k` return values are pushed into the stack in their natural order, starting -from `y1`. -For example, the “divide with remainder” primitive `DIVMOD` needs to return two values, the quotient `q` and the remainder `r`. Therefore, `DIVMOD` -pushes `q` and `r` into the stack, in that order, so that the quotient is available -thereafter at `s1` and the remainder at `s0`. The net effect of `DIVMOD` is to -divide the original value of `s1` by the original value of `s0`, and return the -quotient in `s1` and the remainder in `s0`. In this particular case the depth -of the stack and the values of all other “stack registers” remain unchanged, -because `DIVMOD` takes two arguments and returns two results. In general, the -values of other “stack registers” that lie in the stack below the arguments -passed and the values returned are shifted according to the change of the -depth of the stack. -In principle, some primitives and user-defined functions might return a -variable number of result values. In this respect, the remarks above about -variadic functions (cf. 2.1.6) apply: the total number of result values and -their types should be determined by the values near the top of the stack. -(For example, one might push the return values `y1, . . . , yk`, and then push -their total number `k` as an integer. The caller would then determine the total -number of returned values by inspecting `s0`.) -In this respect TVM, again, faithfully observes Forth calling conventions. +Recall that a stack machine, as opposed to a more conventional register machine, lacks general-purpose registers. However, one can treat the values near the top of the stack as a kind of “stack registers”. -### 2.1.10. Stack notation. - -When a stack of depth `n` contains values `z1, . . . , -zn`, in that order, with `z1` the deepest element and `zn` the top of the stack, -the contents of the stack are often represented by a list `z1 z2 . . . zn`, in that -order. When a primitive transforms the original stack state `S0` -into a new -state `S00`, this is often written as `S0 – S00`; this is the so-called stack notation. -For example, the action of the division primitive `DIV` can be described by -`S x y – S ⌊x/y⌋`, where `S` is any list of values. This is usually abbreviated as -`x y – ⌊x/y⌋`, tacitly assuming that all other values deeper in the stack remain -intact. -Alternatively, one can describe `DIV` as a primitive that runs on a stack `S0` -of depth `n ≥ 2`, divides `s1` by `s0`, and returns the floor-rounded quotient as -`s0` of the new stack `S00` of depth `n − 1`. The new value of `s(i)` equals the old -value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but -saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `. . . x y` into `. . . ⌊x/y⌋`, is more -concise. -The stack notation is extensively used throughout Appendix A, where all -currently defined TVM primitives are listed. - -### 2.1.11. Explicitly defining the number of arguments to a function. - -Stack machines usually pass the current stack in its entirety to the invoked -primitive or function. That primitive or function accesses only the several -values near the top of the stack that represent its arguments, and pushes the -return values in their place, by convention leaving all deeper values intact. -Then the resulting stack, again in its entirety, is returned to the caller. -Most TVM primitives behave in this way, and we expect most user-defined -functions to be implemented under such conventions. However, TVM provides mechanisms to specify how many arguments must be passed to a called -function (cf. 4.1.10). When these mechanisms are employed, the specified -number of values are moved from the caller’s stack into the (usually initially -empty) stack of the called function, while deeper values remain in the caller’s -stack and are inaccessible to the callee. The caller can also specify how many -return values it expects from the called function. -Such argument-checking mechanisms might be useful, for example, for a -library function that calls user-provided functions passed as arguments to it. +We denote by `s0` or `s(0)` the value at the top of the stack, by `s1` or `s(1)` the value immediately under it, and so on. The total number of values in the stack is called its depth. If the depth of the stack is `n`, then `s(0)`, `s(1)`, …, `s(n − 1)` are well-defined, while `s(n)` and all subsequent `s(i)` with `i > n` are not. Any attempt to use `s(i)` with `i ≥ n` should produce a stack underflow exception. ---- +A compiler, or a human programmer in “TVM code”, would use these “stack registers” to hold all declared variables and intermediate values, similarly to the way general-purpose registers are used on a register machine. -## 2.2 Stack manipulation primitives +### 2.1.2 Pushing and popping values -A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, -so that they become located near the top of the stack in correct order. This -section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some -examples of code using these primitives can be found in Appendix C. +When a value `x` is pushed into a stack of depth `n`, it becomes the new `s0`; at the same time, the old `s0` becomes the new `s1`, the old `s1`—the new `s2`, and so on. The depth of the resulting stack is `n + 1`. -### 2.2.1. Basic stack manipulation primitives. +Similarly, when a value `x` is popped from a stack of depth `n ≥ 1`, it is the old value of `s0` (i.e., the old value at the top of the stack). After this, it is removed from the stack, and the old `s1` becomes the new `s0` (the new value at the top of the stack), the old `s2` becomes the new `s1`, and so on. The depth of the resulting stack is `n − 1`. -The most important stack -manipulation primitives used by TVM are the following: +If originally `n = 0`, then the stack is empty, and a value cannot be popped from it. If a primitive attempts to pop a value from an empty stack, a stack underflow exception occurs. -* Top-of-stack exchange operation: `XCHG s0,s(i)` or `XCHG s(i)` — Exchanges values of `s0` and `s(i)`. When `i = 1`, operation `XCHG s1` is - traditionally denoted by `SWAP`. When `i = 0`, this is a `NOP` (an operation - that does nothing, at least if the stack is non-empty). +### 2.1.3 Notation for hypothetical general-purpose registers -* Arbitrary exchange operation: `XCHG s(i),s(j)` — Exchanges values of - `s(i)` and `s(j)`. Notice that this operation is not strictly necessary, because it can be simulated by three top-of-stack exchanges: - `XCHG s(i); XCHG s(j); XCHG s(i)`. However, it is useful to have arbitrary exchanges - as primitives, because they are required quite often. +In order to compare stack machines with sufficiently general register machines, we will denote the general-purpose registers of a register machine by `r0`, `r1`, and so on, or by `r(0)`, `r(1)`, …, `r(n − 1)`, where `n` is the total number of registers. When we need a specific value of `n`, we will use `n = 16`, corresponding to the very popular x86-64 architecture. -* Push operation: `PUSH s(i)` — Pushes a copy of the (old) value of `s(i)` - into the stack. Traditionally, `PUSH s0` is also denoted by `DUP` (it duplicates the value at the top of the stack), and `PUSH s1` by `OVER`. +### 2.1.4 The top-of-stack register s0 vs. the accumulator register r0 -* Pop operation: `POP s(i)` — Removes the top-of-stack value and puts it - into the (new) `s(i − 1)`, or the old `s(i)`. Traditionally, `POP s0` is also - denoted by `DROP` (it simply drops the top-of-stack value), and `POP s1` - by `NIP`. +Some register machine architectures require one of the arguments for most arithmetic and logical operations to reside in a special register called the accumulator. In our comparison, we will assume that the accumulator is the general-purpose register `r0`; otherwise we could simply renumber the registers. In this respect, the accumulator is somewhat similar to the top-of-stack “register” `s0` of a stack machine, because virtually all operations of a stack machine both use `s0` as one of their arguments and return their result as `s0`. -Some other “unsystematic” stack manipulation operations might be also -defined (e.g., `ROT`, with stack notation `a b c – b c a`). While such operations are defined in stack languages like Forth (where `DUP`, `DROP`, `OVER`, `NIP` -and `SWAP` are also present), they are not strictly necessary because the basic -stack manipulation primitives listed above suffice to rearrange stack registers -to allow any arithmetic primitives and user-defined functions to be invoked -correctly. +### 2.1.5 Register calling conventions -Perfect 👍 — let’s continue from **§2.2.2** through the end of Chapter 2, with all mnemonics, variables, and stack notation in backticks for Markdown. +When compiled for a register machine, high-level language functions usually receive their arguments in certain registers in a predefined order. If there are too many arguments, these functions take the remainder from the stack (yes, a register machine usually has a stack, too!). Some register calling conventions pass no arguments in registers at all, however, and only use the stack (for example, the original calling conventions used in implementations of Pascal and C, although modern implementations of C use some registers as well). ---- +For simplicity, we will assume that up to `m ≤ n` function arguments are passed in registers, and that these registers are `r0, r1, …, r(m − 1)`, in that order (if some other registers are used, we can simply renumber them).[6](#footnote-6) -### 2.2.2. Basic stack manipulation primitives suffice. - -A compiler or a -human TVM-code programmer might use the basic stack primitives as follows. -Suppose that the function or primitive to be invoked is to be passed, say, -three arguments `x`, `y`, and `z`, currently located in stack registers `s(i)`, `s(j)`, -and `s(k)`. In this circumstance, the compiler (or programmer) might issue -operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) -or `XCHG s(i)` (if it will not be needed afterwards) to put the first argument -`x` into the top of the stack. Then, the compiler (or programmer) could use -either `PUSH s(j0)` or `XCHG s(j0)`, where `j0 = j` or `j + 1`, to put `y` into the new -top of the stack. - -Proceeding in this manner, we see that we can put the original values of -`x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using -a sequence of push and exchange operations (cf. 2.2.4 and 2.2.5 for a more -detailed explanation). In order to generate this sequence, the compiler will -need to know only the three values `i`, `j` and `k`, describing the old locations of -variables or temporary values in question, and some flags describing whether -each value will be needed thereafter or is needed only for this primitive or -function call. The locations of other variables and temporary values will be -affected in the process, but a compiler (or a human programmer) can easily -track their new locations. - -Similarly, if the results returned from a function need to be discarded -or moved to other stack registers, a suitable sequence of exchange and pop -operations will do the job. In the typical case of one return value in `s0`, -this is achieved either by an `XCHG s(i)` or a `POP s(i)` (in most cases, a `DROP`) -operation. - -Rearranging the result value or values before returning from a function is -essentially the same problem as arranging arguments for a function call, and -is achieved similarly. - -### 2.2.3. Compound stack manipulation primitives. - -In order to improve -the density of the TVM code and simplify development of compilers, compound stack manipulation primitives may be defined, each combining up to -four exchange and push or exchange and pop basic primitives. Such compound stack operations might include, for example: - -* `XCHG2 s(i),s(j)` — Equivalent to `XCHG s1,s(i); XCHG s(j)`. -* `PUSH2 s(i),s(j)` — Equivalent to `PUSH s(i); PUSH s(j + 1)`. -* `XCPU s(i),s(j)` — Equivalent to `XCHG s(i); PUSH s(j)`. -* `PUXC s(i),s(j)` — Equivalent to `PUSH s(i); SWAP; XCHG s(j+1)`. When - `j ≠ i` and `j ≠ 0`, it is also equivalent to `XCHG s(j); PUSH s(i); SWAP`. -* `XCHG3 s(i),s(j),s(k)` — Equivalent to `XCHG s2,s(i); XCHG s1,s(j); - XCHG s(k)`. -* `PUSH3 s(i),s(j),s(k)` — Equivalent to `PUSH s(i); PUSH s(j + 1); PUSH - s(k + 2)`. - -Of course, such operations make sense only if they admit a more compact -encoding than the equivalent sequence of basic operations. For example, -if all top-of-stack exchanges, `XCHG s1,s(i)` exchanges, and push and pop -operations admit one-byte encodings, the only compound stack operations -suggested above that might merit inclusion in the set of stack manipulation -primitives are `PUXC`, `XCHG3`, and `PUSH3`. - -Notice that the most common `XCHG s(i)` operation is not really required here if we -do not insist on keeping the same temporary value or variable always in the same stack -location, but rather keep track of its subsequent locations. We will move it to some other -location while preparing the arguments to the next primitive or function call. - -### 2.2.4. Mnemonics of compound stack operations. - -The mnemonics -of compound stack operations, some examples of which have been provided -in 2.2.3, are created as follows. -The `γ ≥ 2` formal arguments `s(i1), . . . , s(iγ)` to such an operation `O` -represent the values in the original stack that will end up in `s(γ − 1), . . . , -s0` after the execution of this compound operation, at least if all `iν, 1 ≤ -ν ≤ γ`, are distinct and at least γ. The mnemonic itself of the operation -`O` is a sequence of γ two-letter strings `PU` and `XC`, with `PU` meaning that -the corresponding argument is to be PUshed (i.e., a copy is to be created), -and `XC` meaning that the value is to be eXChanged (i.e., no other copy of -the original value is created). Sequences of several `PU` or `XC` strings may be -abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, -we write `PUXC2PU` instead of `PUXCXCPU`.) -As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, -so that the compound operation is equivalent to a sequence of `m` `PUSH`es or -`XCHG`s, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. - -### 2.2.5. Semantics of compound stack operations. - -Each compound `γ`- -ary operation `O s(i1),. . . ,s(iγ)` is translated into an equivalent sequence of -basic stack operations by induction in `γ` as follows: - -* As a base of induction, if `γ = 0`, the only nullary compound stack - operation corresponds to an empty sequence of basic stack operations. -* Equivalently, we might begin the induction from `γ = 1`. Then `PU s(i)` - corresponds to the sequence consisting of one basic operation `PUSH - s(i)`, and `XC s(i)` corresponds to the one-element sequence consisting - of `XCHG s(i)`. -* For `γ ≥ 1` (or for `γ ≥ 2`, if we use `γ = 1` as induction base), there are - two subcases: - - 1. `O s(i1), . . . , s(iγ)`, with `O = XCO0`, where `O0` - is a compound operation of arity `γ−1` (i.e., the mnemonic of `O0` - consists of `γ−1` strings - `XC` and `PU`). Let `α` be the total quantity of PUshes in `O`, and `β` be - that of eXChanges, so that `α+β = γ`. Then the original operation - is translated into `XCHG s(β −1),s(i1)`, followed by the translation - of `O0 s(i2), . . . , s(iγ)`, defined by the induction hypothesis. - - 2. `O s(i1), . . . , s(iγ)`, with `O = PUO0`, - where `O0` - is a compound operation of arity `γ − 1`. Then the original operation is translated into - `PUSH s(i1); XCHG s(β)`, followed by the translation of - `O0 s(i2 + 1), . . . , s(iγ + 1)`, defined by the induction hypothesis. - -An alternative, arguably better, translation of -`PUO0 s(i1), . . . , s(iγ)` consists of the -translation of `O0 s(i2), . . . , s(iγ)`, followed by -`PUSH s(i1 + α − 1); XCHG s(γ − 1)`. - -### 2.2.6. Stack manipulation instructions are polymorphic. - -Notice that -the stack manipulation instructions are almost the only “polymorphic” primitives in TVM—i.e., they work with values of arbitrary types (including the -value types that will appear only in future revisions of TVM). For example, `SWAP` always interchanges the two top values of the stack, even if one of -them is an integer and the other is a cell. Almost all other instructions, especially the data processing instructions (including arithmetic instructions), -require each of their arguments to be of some fixed type (possibly different -for different arguments). +### 2.1.6 Order of function arguments ---- +If a function or primitive requires `m` arguments `x1, …, xm`, they are pushed by the caller into the stack in the same order, starting from `x1`. Therefore, when the function or primitive is invoked, its first argument `x1` is in `s(m − 1)`, its second argument `x2` is in `s(m − 2)`, and so on. The last argument `xm` is in `s0` (i.e., at the top of the stack). It is the called function or primitive’s responsibility to remove its arguments from the stack. -## 2.3 Efficiency of stack manipulation primitives +In this respect the TVM stack calling conventions—obeyed, at least, by TMV primitives—match those of Pascal and Forth, and are the opposite of those of C (in which the arguments are pushed into the stack in the reverse order, and are removed by the caller after it regains control, not the callee). -Stack manipulation primitives employed by a stack machine, such as TVM, -have to be implemented very efficiently, because they constitute more than -half of all the instructions used in a typical program. In fact, TVM performs -all these instructions in a (small) constant time, regardless of the values -involved (even if they represent very large integers or very large trees of -cells). - -### 2.3.1. Implementation of stack manipulation primitives: using references for operations instead of objects. - -The efficiency of TVM’s -implementation of stack manipulation primitives results from the fact that a -typical TVM implementation keeps in the stack not the value objects themselves, but only the references (pointers) to such objects. Therefore, a `SWAP` -instruction only needs to interchange the references at `s0` and `s1`, not the -actual objects they refer to. - -### 2.3.2. Efficient implementation of DUP and PUSH instructions using copy-on-write. - -Furthermore, a `DUP` (or, more generally, `PUSH s(i)`) instruction, which appears to make a copy of a potentially large object, also works -in small constant time, because it uses a copy-on-write technique of delayed -copying: it copies only the reference instead of the object itself, but increases -the “reference counter” inside the object, thus sharing the object between the -two references. If an attempt to modify an object with a reference counter -greater than one is detected, a separate copy of the object in question is made -first (incurring a certain “non-uniqueness penalty” or “copying penalty” for -the data manipulation instruction that triggered the creation of a new copy). - -### 2.3.3. Garbage collecting and reference counting. - -When the reference counter of a TVM object becomes zero (for example, because the last -reference to such an object has been consumed by a `DROP` operation or an -arithmetic instruction), it is immediately freed. Because cyclic references -are impossible in TVM data structures, this method of reference counting -provides a fast and convenient way of freeing unused objects, replacing slow -and unpredictable garbage collectors. - -### 2.3.4. Transparency of the implementation: Stack values are “values”, not “references”. - -Regardless of the implementation details just discussed, all stack values are really “values”, not “references”, from the perspective of the TVM programmer, similarly to the values of all types in functional -programming languages. Any attempt to modify an existing object referred -to from any other objects or stack locations will result in a transparent replacement of this object by its perfect copy before the modification is actually -performed. -In other words, the programmer should always act as if the objects themselves were directly manipulated by stack, arithmetic, and other data transformation primitives, and treat the previous discussion only as an explanation -of the high efficiency of the stack manipulation primitives. - -### 2.3.5. Absence of circular references. - -One might attempt to create a -circular reference between two cells, `A` and `B`, as follows: first create `A` and -write some data into it; then create `B` and write some data into it, along -with a reference to previously constructed cell `A`; finally, add a reference to -`B` into `A`. While it may seem that after this sequence of operations we obtain -a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. -In fact, we obtain a new cell `A0`, which contains a copy of the data originally -stored into cell `A` along with a reference to cell `B`, which contains a reference -to (the original) cell `A`. -In this way the transparent copy-on-write mechanism and the “everything -is a value” paradigm enable us to create new cells using only previously -constructed cells, thus forbidding the appearance of circular references. This -property also applies to all other data structures: for instance, the absence -of circular references enables TVM to use reference counting to immediately -free unused memory instead of relying on garbage collectors. Similarly, this -property is crucial for storing data in the TON Blockchain. - -Great — here’s **Chapter 3 (Cells, memory, and persistent storage)** reformatted to Markdown with all mnemonics, variables, and notation in backticks. +Of course, an implementation of a high-level language for TVM might choose some other calling conventions for its functions, different from the default ones. This might be useful for certain functions—for instance, if the total number of arguments depends on the value of the first argument, as happens for “variadic functions” such as `scanf` and `printf`. In such cases, the first one or several arguments are better passed near the top of the stack, not somewhere at some unknown location deep in the stack. ---- +### 2.1.7 Arguments to arithmetic primitives on register machines -# 3 Cells, memory, and persistent storage +On a stack machine, built-in arithmetic primitives (such as `ADD` or `DIVMOD`) follow the same calling conventions as user-defined functions. In this respect, user-defined functions (for example, a function computing the square root of a number) might be considered as “extensions” or “custom upgrades” of the stack machine. This is one of the clearest advantages of stack machines (and of stack programming languages such as Forth) compared to register machines. -This chapter briefly describes TVM cells, used to represent all data structures -inside the TVM memory and its persistent storage, and the basic operations -used to create cells, write (or serialize) data into them, and read (or deserialize) data from them. +In contrast, arithmetic instructions (built-in operations) on register machines usually get their parameters from general-purpose registers encoded in the full opcode. A binary operation, such as `SUB`, thus requires two arguments, `r(i)` and `r(j)`, with `i` and `j` specified by the instruction. A register `r(k)` for storing the result also must be specified. Arithmetic operations can take several possible forms, depending on whether `i`, `j`, and `k` are allowed to take arbitrary values: -## 3.1 Generalities on cells +- **Three-address form** — Allows the programmer to arbitrarily choose not only the two source registers `r(i)` and `r(j)`, but also a separate destination register `r(k)`. This form is common for most RISC processors, and for the XMM and AVX SIMD instruction sets in the x86-64 architecture. +- **Two-address form** — Uses one of the two operand registers (usually `r(i)`) to store the result of an operation, so that `k = i` is never indicated explicitly. Only `i` and `j` are encoded inside the instruction. This is the most common form of arithmetic operations on register machines, and is quite popular on microprocessors (including the x86 family). +- **One-address form** — Always takes one of the arguments from the accumulator `r0`, and stores the result in `r0` as well; then `i = k = 0`, and only `j` needs to be specified by the instruction. This form is used by some simpler microprocessors (such as Intel 8080). -### 3.1.1. TVM memory and persistent storage consist of cells. +Note that this flexibility is available only for built-in operations, but not for user-defined functions. In this respect, register machines are not as easily “upgradable” as stack machines.[7](#footnote-7) -Recall -that the TVM memory and persistent storage consist of (TVM) cells. Each -cell contains up to `1023` bits of data and up to four references to other cells. -Circular references are forbidden and cannot be created by means of TVM -(cf. 2.3.5). In this way, all cells kept in TVM memory and persistent storage -constitute a directed acyclic graph (DAG). +### 2.1.8 Return values of functions -### 3.1.2. Ordinary and exotic cells. +In stack machines such as TVM, when a function or primitive needs to return a result value, it simply pushes it into the stack (from which all arguments to the function have already been removed). Therefore, the caller will be able to access the result value through the top-of-stack “register” `s0`. -Apart from the data and references, -a cell has a cell type, encoded by an integer `−1 ... 255`. A cell of type `−1` -is called ordinary; such cells do not require any special processing. Cells of -other types are called exotic, and may be loaded—automatically replaced by -other cells when an attempt to deserialize them (i.e., to convert them into -a `Slice` by a `CTOS` instruction) is made. They may also exhibit a non-trivial -behavior when their hashes are computed. +This is in complete accordance with Forth calling conventions, but differs slightly from Pascal and C calling conventions, where the accumulator register `r0` is normally used for the return value. -The most common use for exotic cells is to represent some other cells—for -instance, cells present in an external library, or pruned from the original tree -of cells when a Merkle proof has been created. +### 2.1.9 Returning several values -The type of an exotic cell is stored as the first eight bits of its data. If an -exotic cell has less than eight data bits, it is invalid. +Some functions might want to return several values `y1, …, yk`, with `k` not necessarily equal to one. In these cases, the `k` return values are pushed into the stack in their natural order, starting from `y1`. -### 3.1.3. The level of a cell. +For example, the “divide with remainder” primitive `DIVMOD` needs to return two values, the quotient `q` and the remainder `r`. Therefore, `DIVMOD` pushes `q` and `r` into the stack, in that order, so that the quotient is available thereafter at `s1` and the remainder at `s0`. The net effect of `DIVMOD` is to divide the original value of `s1` by the original value of `s0`, and return the quotient in `s1` and the remainder in `s0`. In this particular case the depth of the stack and the values of all other “stack registers” remain unchanged, because `DIVMOD` takes two arguments and returns two results. In general, the values of other “stack registers” that lie in the stack below the arguments passed and the values returned are shifted according to the change of the depth of the stack. -Every cell `c` has another attribute `Lvl(c)` called -its (de Brujn) level, which currently takes integer values in the range `0...3`. -The level of an ordinary cell is always equal to the maximum of the levels of -all its children `ci`: +In principle, some primitives and user-defined functions might return a variable number of result values. In this respect, the remarks above about variadic functions (cf. [2.1.6](#2-1-6-order-of-function-arguments)) apply: the total number of result values and their types should be determined by the values near the top of the stack. (For example, one might push the return values `y1, …, yk`, and then push their total number `k` as an integer. The caller would then determine the total number of returned values by inspecting `s0`.) -``` -Lvl(c) = max ( Lvl(ci) ) for 1 ≤ i ≤ r -``` +In this respect TVM, again, faithfully observes Forth calling conventions. -for an ordinary cell `c` containing `r` references to cells `c1, ..., cr`. -If `r = 0`, then `Lvl(c) = 0`. Exotic cells may have different rules for setting their level. +### 2.1.10 Stack notation -A cell’s level affects the number of higher hashes it has. More precisely, -a level `l` cell has `l` higher hashes `Hash1(c), ..., Hashl(c)` in addition to its -representation hash `Hash(c) = Hash∞(c)`. Cells of non-zero level appear -inside Merkle proofs and Merkle updates, after some branches of the tree of -cells representing a value of an abstract data type are pruned. +When a stack of depth `n` contains values `z1, …, zn`, in that order, with `z1` the deepest element and `zn` the top of the stack, the contents of the stack are often represented by a list `z1 z2 … zn`, in that order. When a primitive transforms the original stack state `S₀` into a new state `S₀₀`, this is often written as `S₀ – S₀₀`; this is the so-called **stack notation**. -### 3.1.4. Standard cell representation. +For example, the action of the division primitive `DIV` can be described by `S x y – S ⌊x/y⌋`, where `S` is any list of values. This is usually abbreviated as `x y – ⌊x/y⌋`, tacitly assuming that all other values deeper in the stack remain intact. -When a cell needs to be transferred -by a network protocol or stored in a disk file, it must be serialized. -The standard representation `CellRepr(c) = CellRepr∞(c)` of a cell `c` as an -octet (byte) sequence is constructed as follows: +Alternatively, one can describe `DIV` as a primitive that runs on a stack `S₀` of depth `n ≥ 2`, divides `s1` by `s0`, and returns the floor-rounded quotient as `s0` of the new stack `S₀₀` of depth `n − 1`. The new value of `s(i)` equals the old value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `… x y` into `… ⌊x/y⌋`, is more concise. -1. Two descriptor bytes `d1` and `d2` are serialized first. +The stack notation is extensively used throughout [Appendix A](#appendix-a), where all currently defined TVM primitives are listed. - * `d1 = r + 8s + 32l`, where `0 ≤ r ≤ 4` is the number of cell references contained - in the cell, `0 ≤ l ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is `1` for - exotic cells and `0` for ordinary cells. - * `d2 = ⌊b/8⌋ + ⌈b/8⌉`, where `0 ≤ b ≤ 1023` is the number of data bits in `c`. +### 2.1.11 Explicitly defining the number of arguments to a function -2. Then the data bits are serialized as `⌈b/8⌉` 8-bit octets (bytes). - If `b` is not a multiple of eight, a binary `1` and up to six binary `0`s are appended to - the data bits. After that, the data is split into `⌈b/8⌉` eight-bit groups, - and each group is interpreted as an unsigned big-endian integer `0...255` - and stored into an octet. +Stack machines usually pass the current stack in its entirety to the invoked primitive or function. That primitive or function accesses only the several values near the top of the stack that represent its arguments, and pushes the return values in their place, by convention leaving all deeper values intact. Then the resulting stack, again in its entirety, is returned to the caller. -3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(ci)` of the cell `ci` referred to. +Most TVM primitives behave in this way, and we expect most user-defined functions to be implemented under such conventions. However, TVM provides mechanisms to specify how many arguments must be passed to a called function (cf. [4.1.10](#4-1-10-determining-the-number-of-arguments-passed-to-and%2For-return-values-accepted-from-a-subroutine)). When these mechanisms are employed, the specified number of values are moved from the caller’s stack into the (usually initially empty) stack of the called function, while deeper values remain in the caller’s stack and are inaccessible to the callee. The caller can also specify how many return values it expects from the called function. -In this way, `2 + ⌈b/8⌉ + 32r` bytes of `CellRepr(c)` are obtained. +Such argument-checking mechanisms might be useful, for example, for a library function that calls user-provided functions passed as arguments to it. -### 3.1.5. The representation hash of a cell. +## 2.2 Stack manipulation primitives -The 256-bit representation -hash or simply hash `Hash(c)` of a cell `c` is recursively defined as the `sha256` -of the standard representation of the cell `c`: +A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, so that they become located near the top of the stack in correct order. This section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some examples of code using these primitives can be found in [Appendix C](#appendix-c). -``` -Hash(c) := sha256(CellRepr(c)) -``` +### 2.2.1 Basic stack manipulation primitives -Notice that cyclic cell references are not allowed and cannot be created by -means of the TVM (cf. 2.3.5), so this recursion always ends, and the representation hash of any cell is well-defined. +The most important stack manipulation primitives used by TVM are the following: -### 3.1.6. The higher hashes of a cell. +- **Top-of-stack exchange operation:** `XCHG s0,s(i)` or `XCHG s(i)` — Exchanges values of `s0` and `s(i)`. When `i = 1`, operation `XCHG s1` is traditionally denoted by `SWAP`. When `i = 0`, this is a `NOP` (an operation that does nothing, at least if the stack is non-empty). +- **Arbitrary exchange operation:** `XCHG s(i),s(j)` — Exchanges values of `s(i)` and `s(j)`. Notice that this operation is not strictly necessary, because it can be simulated by three top-of-stack exchanges: `XCHG s(i)`; `XCHG s(j)`; `XCHG s(i)`. However, it is useful to have arbitrary exchanges as primitives, because they are required quite often. +- **Push operation:** `PUSH s(i)` — Pushes a copy of the (old) value of `s(i)` into the stack. Traditionally, `PUSH s0` is also denoted by `DUP` (it duplicates the value at the top of the stack), and `PUSH s1` by `OVER`. +- **Pop operation:** `POP s(i)` — Removes the top-of-stack value and puts it into the (new) `s(i − 1)`, or the old `s(i)`. Traditionally, `POP s0` is also denoted by `DROP` (it simply drops the top-of-stack value), and `POP s1` by `NIP`. -Recall that a cell `c` of level `l` has `l` -higher hashes `Hashi(c)`, `1 ≤ i ≤ l`. Exotic cells have their own rules -for computing their higher hashes. Higher hashes `Hashi(c)` of an ordinary -cell `c` are computed similarly to its representation hash, but using the higher -hashes `Hashi(cj)` of its children `cj` instead of their representation hashes -`Hash(cj)`. By convention, we set `Hash∞(c) := Hash(c)`, and `Hashi(c) := Hash(c)` -for all `i > l`. +Some other “unsystematic” stack manipulation operations might be also defined (e.g., `ROT`, with stack notation `a b c – b c a`). While such operations are defined in stack languages like Forth (where `DUP`, `DROP`, `OVER`, `NIP` and `SWAP` are also present), they are not strictly necessary because the basic stack manipulation primitives listed above suffice to rearrange stack registers to allow any arithmetic primitives and user-defined functions to be invoked correctly. -Perfect — here’s the continuation of **Chapter 3**, keeping **all text exactly the same** but fully in Markdown, with mnemonics, variables, and formulas wrapped in backticks: +### 2.2.2 Basic stack manipulation primitives suffice ---- +A compiler or a human TVM-code programmer might use the basic stack primitives as follows. Suppose that the function or primitive to be invoked is to be passed, say, three arguments `x, y, z`, currently located in stack registers `s(i)`, `s(j)`, and `s(k)`. In this circumstance, the compiler (or programmer) might issue operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) or `XCHG s(i)` (if it will not be needed thereafter) to put the first argument `x` into the top of the stack. Then, the compiler (or programmer) could use either `PUSH s(j₀)` or `XCHG s(j₀)`, where `j₀ = j` or `j + 1`, to put `y` into the new top of the stack.[8](#footnote-8) -### 3.1.7. Types of exotic cells. +Proceeding in this manner, we see that we can put the original values of `x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using a sequence of push and exchange operations (cf. [2.2.4](#2-2-4-mnemonics-of-compound-stack-operations) and [2.2.5](#2-2-5-... ) for a more detailed explanation). In order to generate this sequence, the compiler will need to know only the three values `i, j, k`, describing the old locations of variables or temporary values in question, and some flags describing whether each value will be needed thereafter or is needed only for this primitive or function call. The locations of other variables and temporary values will be affected in the process, but a compiler (or a human programmer) can easily track their new locations. -TVM currently supports the following cell -types: +Similarly, if the results returned from a function need to be discarded or moved to other stack registers, a suitable sequence of exchange and pop operations will do the job. In the typical case of one return value in `s0`, this is achieved either by an `XCHG s(i)` or a `POP s(i)` (in most cases, a `DROP`) operation.[9](#footnote-9) -* **Type −1: Ordinary cell** — Contains up to `1023` bits of data and up to - four cell references. -* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ l ≤ 3`. It - contains exactly `8 + 256l` data bits: first an 8-bit integer equal to `1` - (representing the cell’s type), then its `l` higher hashes `Hash1(c), ..., - Hashl(c)`. The level `l` of a pruned branch cell may be called its *de - Brujn index*, because it determines the outer Merkle proof or Merkle - update during the construction of which the branch has been pruned. - An attempt to load a pruned branch cell usually leads to an exception. -* **Type 2: Library reference cell** — Always has level `0`, and contains `8+256` - data bits, including its 8-bit type integer `2` and the representation hash - `Hash(c0)` of the library cell being referred to. When loaded, a library - reference cell may be transparently replaced by the cell it refers to, if - found in the current library context. -* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c1` and level - `0 ≤ l ≤ 3`, which must be one less than the level of its only child `c1`: +Rearranging the result value or values before returning from a function is essentially the same problem as arranging arguments for a function call, and is achieved similarly. - ``` - Lvl(c) = max(Lvl(c1) − 1, 0) - ``` +### 2.2.3 Compound stack manipulation primitives - The `8 + 256` data bits of a Merkle proof cell contain its 8-bit type - integer `3`, followed by `Hash1(c1)` (assumed to be equal to `Hash(c1)` if - `Lvl(c1) = 0`). The higher hashes `Hashi(c)` of `c` are computed similarly - to the higher hashes of an ordinary cell, but with `Hashi+1(c1)` used - instead of `Hashi(c1)`. When loaded, a Merkle proof cell is replaced by - `c1`. -* **Type 4: Merkle update cell `c`** — Has two children `c1` and `c2`. Its level - `0 ≤ l ≤ 3` is given by: +In order to improve the density of the TVM code and simplify development of compilers, compound stack manipulation primitives may be defined, each combining up to four exchange and push or exchange and pop basic primitives. Such compound stack operations might include, for example: - ``` - Lvl(c) = max(Lvl(c1) − 1, Lvl(c2) − 1, 0) - ``` +- `XCHG2 s(i),s(j)` — Equivalent to `XCHG s1,s(i); XCHG s(j)`. +- `PUSH2 s(i),s(j)` — Equivalent to `PUSH s(i); PUSH s(j + 1)`. +- `XCPU s(i),s(j)` — Equivalent to `XCHG s(i); PUSH s(j)`. +- `PUXC s(i),s(j)` — Equivalent to `PUSH s(i); SWAP; XCHG s(j+1)`. When `j ≠ i` and `j ≠ 0`, it is also equivalent to `XCHG s(j); PUSH s(i); SWAP`. +- `XCHG3 s(i),s(j),s(k)` — Equivalent to `XCHG s2,s(i); XCHG s1,s(j); XCHG s(k)`. +- `PUSH3 s(i),s(j),s(k)` — Equivalent to `PUSH s(i); PUSH s(j + 1); PUSH s(k + 2)`. - A Merkle update behaves like a Merkle proof for both `c1` and `c2`, and - contains `8 + 256 + 256` data bits with `Hash1(c1)` and `Hash1(c2)`. - However, an extra requirement is that all pruned branch cells `c0` that are - descendants of `c2` and are bound by `c` must also be descendants of `c1`. - When a Merkle update cell is loaded, it is replaced by `c2`. +Of course, such operations make sense only if they admit a more compact encoding than the equivalent sequence of basic operations. For example, if all top-of-stack exchanges, `XCHG s1,s(i)` exchanges, and push and pop operations admit one-byte encodings, the only compound stack operations suggested above that might merit inclusion in the set of stack manipulation primitives are `PUXC`, `XCHG3`, and `PUSH3`. ---- +These compound stack operations essentially augment other primitives (instructions) in the code with the “true” locations of their operands, somewhat similarly to what happens with two-address or three-address register machine code. However, instead of encoding these locations inside the opcode of the arithmetic or another instruction, as is customary for register machines, we indicate these locations in a preceding compound stack manipulation operation. As already described in [2.1.7](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines), the advantage of such an approach is that user-defined functions (or rarely used specific primitives added in a future version of TVM) can benefit from it as well (cf. [C.3](#c-3-...) for a more detailed discussion with examples). -### 3.1.8. All values of algebraic data types are trees of cells. +### 2.2.4 Mnemonics of compound stack operations -Arbitrary -values of arbitrary algebraic data types (e.g., all types used in functional -programming languages) can be serialized into trees of cells (of level `0`), and -such representations are used for representing such values within TVM. +The mnemonics of compound stack operations, some examples of which have been provided in [2.2.3](#2-2-3-compound-stack-manipulation-primitives), are created as follows. -The copy-on-write mechanism (cf. 2.3.2) allows TVM to identify cells containing -the same data and references, and to keep only one copy of such cells. This -actually transforms a tree of cells into a directed acyclic graph (with the -additional property that all its vertices be accessible from a marked vertex -called the “root”). However, this is a storage optimization rather than an -essential property of TVM. From the perspective of a TVM code programmer, -one should think of TVM data structures as trees of cells. +The `γ ≥ 2` formal arguments `s(i₁), …, s(i_γ)` to such an operation `O` represent the values in the original stack that will end up in `s(γ − 1), …, s0` after the execution of this compound operation, at least if all `iν`, `1 ≤ ν ≤ γ`, are distinct and at least `γ`. The mnemonic itself of the operation `O` is a sequence of `γ` two-letter strings `PU` and `XC`, with `PU` meaning that the corresponding argument is to be **PU**shed (i.e., a copy is to be created), and `XC` meaning that the value is to be **eX**Changed (i.e., no other copy of the original value is created). Sequences of several `PU` or `XC` strings may be abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, we write `PUXC2PU` instead of `PUXCXCPU`.) + +As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, so that the compound operation is equivalent to a sequence of `m` `PUSH`es or `eXCHanGe`s, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. + +### 2.2.5 Semantics of compound stack operations + +Each compound γ-ary operation `O s(i₁), …, s(iγ)` is translated into an equivalent sequence of basic stack operations by induction in γ as follows: + +- As a base of induction, if γ = 0, the only nullary compound stack operation corresponds to an empty sequence of basic stack operations. +- Equivalently, we might begin the induction from γ = 1. Then `PU s(i)` corresponds to the sequence consisting of one basic operation `PUSH s(i)`, and `XC s(i)` corresponds to the one-element sequence consisting of `XCHG s(i)`. +- For γ ≥ 1 (or for γ ≥ 2, if we use γ = 1 as induction base), there are two subcases: + + 1. `O s(i₁), …, s(iγ)`, with `O = XC O₀`, where `O₀` is a compound operation of arity γ − 1 (i.e., the mnemonic of `O₀` consists of γ − 1 strings `XC` and `PU`). + Let α be the total quantity of **PU**shes in `O`, and β be that of eXChanges, so that α + β = γ. Then the original operation is translated into `XCHG s(β − 1), s(i₁)`, followed by the translation of `O₀ s(i₂), …, s(iγ)`, defined by the induction hypothesis. + + 2. `O s(i₁), …, s(iγ)`, with `O = PU O₀`, where `O₀` is a compound operation of arity γ − 1. + Then the original operation is translated into `PUSH s(i₁); XCHG s(β)`, followed by the translation of `O₀ s(i₂ + 1), …, s(iγ + 1)`, defined by the induction hypothesis.[10](#footnote-10) --- -### 3.1.9. TVM code is a tree of cells. +### 2.2.6 Stack manipulation instructions are polymorphic -The TVM code itself is also represented by a tree of cells. Indeed, TVM code is simply a value of some -complex algebraic data type, and as such, it can be serialized into a tree of -cells. +Notice that the stack manipulation instructions are almost the only “polymorphic” primitives in TVM—i.e., they work with values of arbitrary types (including the value types that will appear only in future revisions of TVM). -The exact way in which the TVM code (e.g., TVM assembly code) is -transformed into a tree of cells is explained later (cf. 4.1.4 and 5.2), in sections discussing control flow instructions, continuations, and TVM instruction encoding. +For example, `SWAP` always interchanges the two top values of the stack, even if one of them is an integer and the other is a cell. Almost all other instructions, especially the data processing instructions (including arithmetic instructions), require each of their arguments to be of some fixed type (possibly different for different arguments). --- -### 3.1.10. “Everything is a bag of cells” paradigm. +## 2.3 Efficiency of stack manipulation primitives -As described in `[1, -2.5.14]`, all the data used by the TON Blockchain, including the blocks -themselves and the blockchain state, can be represented—and are represented—as -collections, or “bags”, of cells. +Stack manipulation primitives employed by a stack machine, such as TVM, have to be implemented very efficiently, because they constitute more than half of all the instructions used in a typical program. In fact, TVM performs all these instructions in a (small) constant time, regardless of the values involved (even if they represent very large integers or very large trees of cells). -We see that TVM’s structure of data (cf. 3.1.8) -and code (cf. 3.1.9) nicely fits into this “everything is a bag of cells” paradigm. -In this way, TVM can naturally be used to execute smart contracts in the -TON Blockchain, and the TON Blockchain can be used to store the code -and persistent data of these smart contracts between invocations of TVM. +### 2.3.1 Implementation of stack manipulation primitives: using references for operations instead of objects -(Of course, both TVM and the TON Blockchain have been designed so that -this would become possible.) -Got it — here’s the continuation with **3.2 Data manipulation instructions and cells** in proper Markdown, keeping **all text exactly the same** but formatted (mnemonics, values, variables in backticks): +The efficiency of TVM’s implementation of stack manipulation primitives results from the fact that a typical TVM implementation keeps in the stack not the value objects themselves, but only the references (pointers) to such objects. ---- +Therefore, a `SWAP` instruction only needs to interchange the references at `s0` and `s1`, not the actual objects they refer to. -## 3.2 Data manipulation instructions and cells +### 2.3.2 Efficient implementation of DUP and PUSH instructions using copy-on-write -The next large group of TVM instructions consists of data manipulation -instructions, also known as cell manipulation instructions or simply cell -instructions. They correspond to memory access instructions of other architectures. +Furthermore, a `DUP` (or, more generally, `PUSH s(i)`) instruction, which appears to make a copy of a potentially large object, also works in small constant time, because it uses a copy-on-write technique of delayed copying: it copies only the reference instead of the object itself, but increases the “reference counter” inside the object, thus sharing the object between the two references. ---- +If an attempt to modify an object with a reference counter greater than one is detected, a separate copy of the object in question is made first (incurring a certain “non-uniqueness penalty” or “copying penalty” for the data manipulation instruction that triggered the creation of a new copy). -### 3.2.1. Classes of cell manipulation instructions. +### 2.3.3 Garbage collecting and reference counting -The TVM cell instructions are naturally subdivided into two principal classes: +When the reference counter of a TVM object becomes zero (for example, because the last reference to such an object has been consumed by a `DROP` operation or an arithmetic instruction), it is immediately freed. -* **Cell creation instructions** or **serialization instructions**, used to construct new cells from values previously kept in the stack and previously - constructed cells. -* **Cell parsing instructions** or **deserialization instructions**, used to extract - data previously stored into cells by cell creation instructions. +Because cyclic references are impossible in TVM data structures, this method of reference counting provides a fast and convenient way of freeing unused objects, replacing slow and unpredictable garbage collectors. -Additionally, there are exotic cell instructions used to create and inspect -exotic cells (cf. 3.1.2), which in particular are used to represent pruned -branches of Merkle proofs and Merkle proofs themselves. +### 2.3.4 Transparency of the implementation: Stack values are “values”, not “references” ---- +Regardless of the implementation details just discussed, all stack values are really “values”, not “references”, from the perspective of the TVM programmer, similarly to the values of all types in functional programming languages. -### 3.2.2. Builder and Slice values. +Any attempt to modify an existing object referred to from any other objects or stack locations will result in a transparent replacement of this object by its perfect copy before the modification is actually performed. -Cell creation instructions usually work -with `Builder` values, which can be kept only in the stack (cf. 1.1.3). Such -values represent partially constructed cells, for which fast operations for appending bitstrings, integers, other cells, and references to other cells can be -defined. Similarly, cell parsing instructions make heavy use of `Slice` values, -which represent either the remainder of a partially parsed cell, or a value -(subcell) residing inside such a cell and extracted from it by a parsing instruction. +In other words, the programmer should always act as if the objects themselves were directly manipulated by stack, arithmetic, and other data transformation primitives, and treat the previous discussion only as an explanation of the high efficiency of the stack manipulation primitives. ---- +### 2.3.5 Absence of circular references + +One might attempt to create a circular reference between two cells, `A` and `B`, as follows: first create `A` and write some data into it; then create `B` and write some data into it, along with a reference to previously constructed cell `A`; finally, add a reference to `B` into `A`. -### 3.2.3. Builder and Slice values exist only as stack values. +While it may seem that after this sequence of operations we obtain a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. In fact, we obtain a new cell `A₀`, which contains a copy of the data originally stored into cell `A` along with a reference to cell `B`, which contains a reference to (the original) cell `A`. -Notice that -`Builder` and `Slice` objects appear only as values in a TVM stack. They cannot -be stored in “memory” (i.e., trees of cells) or “persistent storage” (which is -also a bag of cells). In this sense, there are far more `Cell` objects than `Builder` -or `Slice` objects in a TVM environment, but, somewhat paradoxically, a TVM -program sees `Builder` and `Slice` objects in its stack more often than `Cell`s. +In this way the transparent copy-on-write mechanism and the “everything is a value” paradigm enable us to create new cells using only previously constructed cells, thus forbidding the appearance of circular references. -In fact, a TVM program does not have much use for `Cell` values, because they -are immutable and opaque; all cell manipulation primitives require that a -`Cell` value be transformed into either a `Builder` or a `Slice` first, before it can -be modified or inspected. +This property also applies to all other data structures: for instance, the absence of circular references enables TVM to use reference counting to immediately free unused memory instead of relying on garbage collectors. Similarly this property is crucial for storing data in the TON Blockchain. --- -### 3.2.4. TVM has no separate Bitstring value type. +# 3 Cells, memory, and persistent storage -Notice that TVM -offers no separate bitstring value type. Instead, bitstrings are represented by -`Slice`s that happen to have no references at all, but can still contain up to -`1023` data bits. +This chapter briefly describes TVM cells, used to represent all data structures inside the TVM memory and its persistent storage, and the basic operations used to create cells, write (or serialize) data into them, and read (or deserialize) data from them. ---- +## 3.1 Generalities on cells -### 3.2.5. Cells and cell primitives are bit-oriented, not byte-oriented. +This section presents a classification and general descriptions of cell types. -An important point is that TVM regards data kept in cells as sequences -(strings, streams) of (up to `1023`) bits, not of bytes. In other words, TVM -is a bit-oriented machine, not a byte-oriented machine. If necessary, an -application is free to use, say, `21`-bit integer fields inside records serialized into -TVM cells, thus using fewer persistent storage bytes to represent the same -data. +### 3.1.1 TVM memory and persistent storage consist of cells ---- +Recall that the TVM memory and persistent storage consist of (TVM) cells. Each cell contains up to 1023 bits of data and up to four references to other cells.[11](#footnote-11) -### 3.2.6. Taxonomy of cell creation (serialization) primitives. +Circular references are forbidden and cannot be created by means of TVM (cf. [2.3.5](#2-3-5-absence-of-circular-references)). In this way, all cells kept in TVM memory and persistent storage constitute a directed acyclic graph (DAG). -Cell creation primitives usually accept a `Builder` argument and an argument representing the value to be serialized. Additional arguments controlling some -aspects of the serialization process (e.g., how many bits should be used for -serialization) can be also provided, either in the stack or as an immediate -value inside the instruction. +### 3.1.2 Ordinary and exotic cells -The result of a cell creation primitive is usually -another `Builder`, representing the concatenation of the original builder and -the serialization of the value provided. +Apart from the data and references, a cell has a cell type, encoded by an integer −1…255. A cell of type −1 is called **ordinary**; such cells do not require any special processing. Cells of other types are called **exotic**, and may be loaded—automatically replaced by other cells when an attempt to deserialize them (i.e., to convert them into a `Slice` by a `CTOS` instruction) is made. They may also exhibit a non-trivial behavior when their hashes are computed. -Therefore, one can suggest a classification of cell serialization primitives -according to the answers to the following questions: +The most common use for exotic cells is to represent some other cells—for instance, cells present in an external library, or pruned from the original tree of cells when a Merkle proof has been created. -* Which is the type of values being serialized? -* How many bits are used for serialization? If this is a variable number, - does it come from the stack, or from the instruction itself? -* What happens if the value does not fit into the prescribed number of - bits? Is an exception generated, or is a success flag equal to zero silently - returned in the top of stack? -* What happens if there is insufficient space left in the `Builder`? Is an - exception generated, or is a zero success flag returned along with the - unmodified original `Builder`? +The type of an exotic cell is stored as the first eight bits of its data. If an exotic cell has less than eight data bits, it is invalid. -The mnemonics of cell serialization primitives usually begin with `ST`. Subsequent letters describe the following attributes: +### 3.1.3 The level of a cell -* The type of values being serialized and the serialization format (e.g., `I` - for signed integers, `U` for unsigned integers). -* The source of the field width in bits to be used (e.g., `X` for integer - serialization instructions means that the bit width `n` is supplied in - the stack; otherwise it has to be embedded into the instruction as an - immediate value). -* The action to be performed if the operation cannot be completed (by - default, an exception is generated; “quiet” versions of serialization instructions are marked by a `Q` letter in their mnemonics). +Every cell `c` has another attribute `Lvl(c)` called its (de Brujn) **level**, which currently takes integer values in the range 0…3. -This classification scheme is used to create a more complete taxonomy of cell -serialization primitives, which can be found in **A.7.1**. +The level of an ordinary cell is always equal to the maximum of the levels of all its children `ci`: ---- +```math +Lvl(c) = max_{1 ≤ i ≤ r} Lvl(ci) +```` -### 3.2.7. Integer serialization primitives. +for an ordinary cell `c` containing `r` references to cells `c1, …, cr`. +If `r = 0`, then `Lvl(c) = 0`. Exotic cells may have different rules for setting their level. -Integer serialization primitives -can be classified according to the above taxonomy as well. For example: +A cell’s level affects the number of higher hashes it has. More precisely, a level `l` cell has `l` higher hashes `Hash₁(c), …, Hash_l(c)` in addition to its representation hash `Hash(c) = Hash∞(c)`. -* There are signed and unsigned (big-endian) integer serialization primitives. -* The size `n` of the bit field to be used (`1 ≤ n ≤ 257` for signed integers, - `0 ≤ n ≤ 256` for unsigned integers) can either come from the top of - stack or be embedded into the instruction itself. -* If the integer `x` to be serialized is not in the range `−2^(n−1) ≤ x < 2^(n−1)` - (for signed integer serialization) or `0 ≤ x < 2^n` (for unsigned integer - serialization), a range check exception is usually generated, and if `n` bits - cannot be stored into the provided `Builder`, a cell overflow exception is - generated. -* Quiet versions of serialization instructions do not throw exceptions; - instead, they push `-1` on top of the resulting `Builder` upon success, or - return the original `Builder` with `0` on top of it to indicate failure. +Cells of non-zero level appear inside Merkle proofs and Merkle updates, after some branches of the tree of cells representing a value of an abstract data type are pruned. -Integer serialization instructions have mnemonics like `STU 20` (“store an -unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of -variable length provided in the stack”). +### 3.1.4 Standard cell representation -The full list of these instructions— -including their mnemonics, descriptions, and opcodes—is provided in **A.7.1**. +When a cell needs to be transferred by a network protocol or stored in a disk file, it must be serialized. The standard representation `CellRepr(c) = CellRepr∞(c)` of a cell `c` as an octet (byte) sequence is constructed as follows: ---- +1. Two descriptor bytes `d1` and `d2` are serialized first. -### 3.2.8. Integers in cells are big-endian by default. + * `d1 = r + 8s + 32l`, where `0 ≤ r ≤ 4` is the number of cell references contained in the cell, `0 ≤ l ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is 1 for exotic cells and 0 for ordinary cells. + * `d2 = ⌊b/8⌋ + ⌈b/8⌉`, where `0 ≤ b ≤ 1023` is the number of data bits in `c`. -Notice that the -default order of bits in `Integer`s serialized into `Cell`s is big-endian, not little- -endian. +2. Then the data bits are serialized as `⌈b/8⌉` 8-bit octets (bytes). If `b` is not a multiple of eight, a binary `1` and up to six binary `0`s are appended to the data bits. After that, the data is split into `⌈b/8⌉` eight-bit groups, and each group is interpreted as an unsigned big-endian integer 0…255 and stored into an octet. -In this respect TVM is a big-endian machine. However, this affects -only the serialization of integers inside cells. The internal representation of -the `Integer` value type is implementation-dependent and irrelevant for the -operation of TVM. +3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(ci)` (explained in [3.1.5](#3-1-5-the-representation-hash-of-a-cell)) of the cell `ci` referred to. -Besides, there are some special primitives such as `STULE` -for (de)serializing little-endian integers, which must be stored into an integral -number of bytes (otherwise “little-endianness” does not make sense, unless -one is also willing to revert the order of bits inside octets). +In this way, `2 + ⌈b/8⌉ + 32r` bytes of `CellRepr(c)` are obtained. -Such primitives are -useful for interfacing with the little-endian world—for instance, for parsing -custom-format messages arriving to a TON Blockchain smart contract from -the outside world. +### 3.1.5 The representation hash of a cell ---- +The 256-bit **representation hash** (or simply **hash**) `Hash(c)` of a cell `c` is recursively defined as the `sha256` of the standard representation of the cell `c`: -### 3.2.9. Other serialization primitives. +```math +Hash(c) := sha256(CellRepr(c)) +``` -Other cell creation primitives serialize bitstrings (i.e., cell slices without references), either taken from the stack -or supplied as literal arguments; cell slices (which are concatenated to the -cell builder in an obvious way); other `Builder`s (which are also concatenated); -and cell references (`STREF`). +Notice that cyclic cell references are not allowed and cannot be created by means of the TVM (cf. [2.3.5](#2-3-5-absence-of-circular-references)), so this recursion always ends, and the representation hash of any cell is well-defined. ---- +### 3.1.6 The higher hashes of a cell -### 3.2.10. Other cell creation primitives. +Recall that a cell `c` of level `l` has `l` higher hashes `Hashᵢ(c), 1 ≤ i ≤ l`, as well. Exotic cells have their own rules for computing their higher hashes. -In addition to the cell serialization primitives for certain built-in value types described above, there are -simple primitives that create a new empty `Builder` and push it into the stack -(`NEWC`), or transform a `Builder` into a `Cell` (`ENDC`), thus finishing the cell -creation process. +Higher hashes `Hashᵢ(c)` of an ordinary cell `c` are computed similarly to its representation hash, but using the higher hashes `Hashᵢ(cj)` of its children `cj` instead of their representation hashes `Hash(cj)`. -An `ENDC` can be combined with a `STREF` into a single instruction `ENDCST`, which finishes the creation of a cell and immediately stores -a reference to it in an “outer” `Builder`. +By convention: -There are also primitives that obtain -the quantity of data bits or references already stored in a `Builder`, and check how many data bits or references can be stored. +* `Hash∞(c) := Hash(c)` +* `Hashᵢ(c) := Hash∞(c) = Hash(c)` for all `i > l`. ---- +### 3.1.7 Types of exotic cells -### 3.2.11. Taxonomy of cell deserialisation primitives. +TVM currently supports the following cell types: -Cell parsing, or -deserialization, primitives can be classified as described in 3.2.6, with the -following modifications: +* **Type −1: Ordinary cell** — Contains up to 1023 bits of data and up to four cell references. -* They work with `Slice`s (representing the remainder of the cell being - parsed) instead of `Builder`s. -* They return deserialized values instead of accepting them as arguments. -* They may come in two flavors, depending on whether they remove the - deserialized portion from the `Slice` supplied (“fetch operations”) or leave - it unmodified (“prefetch operations”). -* Their mnemonics usually begin with `LD` (or `PLD` for prefetch operations) - instead of `ST`. +* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ l ≤ 3`. + Contains exactly `8 + 256l` data bits: first an 8-bit integer equal to `1` (the cell’s type), then its `l` higher hashes `Hash₁(c), …, Hash_l(c)`. + The level `l` may be called its **de Brujn index**, because it determines the outer Merkle proof or Merkle update during which the branch has been pruned. + An attempt to load a pruned branch cell usually leads to an exception. -For example, an unsigned big-endian 20-bit integer previously serialized into -a cell by a `STU 20` instruction is likely to be deserialized later by a matching -`LDU 20` instruction. +* **Type 2: Library reference cell** — Always has level 0, and contains `8 + 256` data bits, including its 8-bit type integer `2` and the representation hash `Hash(c₀)` of the library cell being referred to. + When loaded, a library reference cell may be transparently replaced by the cell it refers to, if found in the current library context. -Again, more detailed information about these instructions is provided in **A.7.2**. +* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c₁` and level `0 ≤ l ≤ 3`, which must be one less than the level of its only child `c₁`: ---- + ```math + Lvl(c) = max(Lvl(c₁) − 1, 0) + ``` -### 3.2.12. Other cell slice primitives. + The 8 + 256 data bits of a Merkle proof cell contain its 8-bit type integer `3`, followed by `Hash₁(c₁)` (assumed equal to `Hash(c₁)` if `Lvl(c₁) = 0`). -In addition to the cell deserialisation -primitives outlined above, TVM provides some obvious primitives for initializing and completing the cell deserialization process. + The higher hashes `Hashᵢ(c)` of `c` are computed similarly to the higher hashes of an ordinary cell, but with `Hashᵢ₊₁(c₁)` used instead of `Hashᵢ(c₁)`. + When loaded, a Merkle proof cell is replaced by `c₁`. -For instance, one can -convert a `Cell` into a `Slice` (`CTOS`), so that its deserialisation might begin; -or check whether a `Slice` is empty, and generate an exception if it is not -(`ENDS`); or deserialize a cell reference and immediately convert it into a `Slice` -(`LDREFTOS`, equivalent to two instructions `LDREF` and `CTOS`). +* **Type 4: Merkle update cell `c`** — Has two children `c₁` and `c₂`. Its level `0 ≤ l ≤ 3` is given by: ---- + ```math + Lvl(c) = max(Lvl(c₁) − 1, Lvl(c₂) − 1, 0) + ``` -### 3.2.13. Modifying a serialized value in a cell. + A Merkle update behaves like a Merkle proof for both `c₁` and `c₂`, and contains `8 + 256 + 256` data bits with `Hash₁(c₁)` and `Hash₁(c₂)`. -The reader might wonder -how the values serialized inside a cell may be modified. + However, an extra requirement is that all pruned branch cells `c₀` that are descendants of `c₂` and are bound by `c` must also be descendants of `c₁`. -Suppose a cell contains three serialized 29-bit integers, `(x, y, z)`, representing the coordinates of -a point in space, and we want to replace `y` with `y' = y + 1`, leaving the other -coordinates intact. How would we achieve this? + When a Merkle update cell is loaded, it is replaced by `c₂`.[13](#footnote-13) -TVM does not offer any ways to modify existing values (cf. 2.3.4 and -2.3.5), so our example can only be accomplished with a series of operations -as follows: +### 3.1.8 All values of algebraic data types are trees of cells -1. Deserialize the original cell into three `Integer`s `x`, `y`, `z` in the stack (e.g., - by `CTOS; LDI 29; LDI 29; LDI 29; ENDS`). -2. Increase `y` by one (e.g., by `SWAP; INC; SWAP`). -3. Finally, serialize the resulting `Integer`s into a new cell (e.g., by `XCHG s2; NEWC; STI 29; STI 29; STI 29; ENDC`). +Arbitrary values of algebraic data types can be serialized into trees of cells (of level 0), and such representations are used for representing such values within TVM. ---- +The copy-on-write mechanism (cf. [2.3.2](#2-3-2-efficient-implementation-of-dup-and-push-instructions-using-copy-on-write)) allows TVM to identify cells containing the same data and references, and to keep only one copy of such cells. -### 3.2.14. Modifying the persistent storage of a smart contract. +This actually transforms a tree of cells into a directed acyclic graph (with the additional property that all its vertices be accessible from a marked vertex called the “root”). However, this is a storage optimization rather than an essential property of TVM. -If the -TVM code wants to modify its persistent storage, represented by the tree of -cells rooted at `c4`, it simply needs to rewrite control register `c4` by the root -of the tree of cells containing the new value of its persistent storage. (If only -part of the persistent storage needs to be modified, cf. 3.2.13.) +From the perspective of a TVM code programmer, one should think of TVM data structures as trees of cells. ---- +### 3.1.9 TVM code is a tree of cells -## 3.3 Hashmaps, or dictionaries +The TVM code itself is also represented by a tree of cells. Indeed, TVM code is simply a value of some complex algebraic data type, and as such, it can be serialized into a tree of cells. -Hashmaps, or dictionaries, are a specific data structure represented by a tree -of cells. Essentially, a hashmap represents a map from keys, which are bitstrings of either fixed or variable length, into values of an arbitrary type `X`, -in such a way that fast lookups and modifications be possible. While any -such structure might be inspected or modified with the aid of generic cell serialization and deserialization primitives, TVM introduces special primitives -to facilitate working with these hashmaps. +The exact way in which the TVM code (e.g., TVM assembly code) is transformed into a tree of cells is explained later (cf. [4.1.4](#4-1-4-normal-work-of-tvm%2C-or-the-main-loop) and [5.2](#5-2-instruction-encoding)), in sections discussing control flow instructions, continuations, and TVM instruction encoding. ---- +### 3.1.10 “Everything is a bag of cells” paradigm -### 3.3.1. Basic hashmap types. +As described in [1](#reference-1), all the data used by the TON Blockchain, including the blocks themselves and the blockchain state, can be represented—and are represented—as collections, or “bags”, of cells. -The two most basic hashmap types predefined in TVM are `HashmapE n X` or `HashmapE(n, X)`, which represents -a partially defined map from n-bit strings (called keys) for some fixed `0 ≤ n ≤ 1023` into values of some type `X`, and `Hashmap(n, X)`, which is similar -to `HashmapE(n, X)` but is not allowed to be empty (i.e., it must contain at -least one key-value pair). +We see that TVM’s structure of data (cf. [3.1.8](#3-1-8-all-values-of-algebraic-data-types-are-trees-of-cells)) and code (cf. [3.1.9](#3-1-9-tvm-code-is-a-tree-of-cells)) nicely fits into this “everything is a bag of cells” paradigm. -Other hashmap types are also available—for example, one with keys of -arbitrary length up to some predefined bound (up to 1023 bits). +In this way, TVM can naturally be used to execute smart contracts in the TON Blockchain, and the TON Blockchain can be used to store the code and persistent data of these smart contracts between invocations of TVM. (Of course, both TVM and the TON Blockchain have been designed so that this would become possible.) --- -### 3.3.2. Hashmaps as Patricia trees. +## 3.2 Data manipulation instructions and cells + +The next large group of TVM instructions consists of data manipulation instructions, also known as cell manipulation instructions or simply cell instructions. They correspond to memory access instructions of other architectures. + +### 3.2.1 Classes of cell manipulation instructions + +The TVM cell instructions are naturally subdivided into two principal classes: + +- **Cell creation instructions** or **serialization instructions**, used to construct new cells from values previously kept in the stack and previously constructed cells. +- **Cell parsing instructions** or **deserialization instructions**, used to extract data previously stored into cells by cell creation instructions. + +Additionally, there are exotic cell instructions used to create and inspect exotic cells (cf. [3.1.2](#3-1-2-ordinary-and-exotic-cells)), which in particular are used to represent pruned branches of Merkle proofs and Merkle proofs themselves. + +### 3.2.2 Builder and Slice values + +Cell creation instructions usually work with **Builder** values, which can be kept only in the stack (cf. [1.1.3](#1-1-3-preliminary-list-of-value-types)). Such values represent partially constructed cells, for which fast operations for appending bitstrings, integers, other cells, and references to other cells can be defined. Similarly, cell parsing instructions make heavy use of **Slice** values, which represent either the remainder of a partially parsed cell, or a value (subcell) residing inside such a cell and extracted from it by a parsing instruction. + +### 3.2.3 Builder and Slice values exist only as stack values + +Notice that Builder and Slice objects appear only as values in a TVM stack. They cannot be stored in “memory” (i.e., trees of cells) or “persistent storage” (which is also a bag of cells). In this sense, there are far more Cell objects than Builder or Slice objects in a TVM environment, but, somewhat paradoxically, a TVM program sees Builder and Slice objects in its stack more often than Cells. In fact, a TVM program does not have much use for Cell values, because they are immutable and opaque; all cell manipulation primitives require that a Cell value be transformed into either a Builder or a Slice first, before it can be modified or inspected. + +### 3.2.4 TVM has no separate Bitstring value type + +Notice that TVM offers no separate bitstring value type. Instead, bitstrings are represented by Slices that happen to have no references at all, but can still contain up to 1023 data bits. + +### 3.2.5 Cells and cell primitives are bit-oriented, not byte-oriented + +An important point is that TVM regards data kept in cells as sequences (strings, streams) of (up to 1023) bits, not of bytes. In other words, TVM is a bit-oriented machine, not a byte-oriented machine. If necessary, an application is free to use, say, 21-bit integer fields inside records serialized into TVM cells, thus using fewer persistent storage bytes to represent the same data. + +### 3.2.6 Taxonomy of cell creation (serialization) primitives + +Cell creation primitives usually accept a Builder argument and an argument representing the value to be serialized. Additional arguments controlling some aspects of the serialization process (e.g., how many bits should be used for serialization) can be also provided, either in the stack or as an immediate value inside the instruction. The result of a cell creation primitive is usually another Builder, representing the concatenation of the original builder and the serialization of the value provided. + +Therefore, one can suggest a classification of cell serialization primitives according to the answers to the following questions: + +- Which is the type of values being serialized? +- How many bits are used for serialization? If this is a variable number, does it come from the stack, or from the instruction itself? +- What happens if the value does not fit into the prescribed number of bits? Is an exception generated, or is a success flag equal to zero silently returned in the top of stack? +- What happens if there is insufficient space left in the Builder? Is an exception generated, or is a zero success flag returned along with the unmodified original Builder? + +The mnemonics of cell serialization primitives usually begin with `ST`. Subsequent letters describe the following attributes: + +- The type of values being serialized and the serialization format (e.g., `I` for signed integers, `U` for unsigned integers). +- The source of the field width in bits to be used (e.g., `X` for integer serialization instructions means that the bit width `n` is supplied in the stack; otherwise it has to be embedded into the instruction as an immediate value). +- The action to be performed if the operation cannot be completed (by default, an exception is generated; “quiet” versions of serialization instructions are marked by a `Q` letter in their mnemonics). -The abstract representation of a -hashmap in TVM is a Patricia tree, or a compact binary trie. It is a binary -tree with edges labelled by bitstrings, such that the concatenation of all edge -labels on a path from the root to a leaf equals a key of the hashmap. The -corresponding value is kept in this leaf (for hashmaps with keys of fixed -length), or optionally in the intermediate vertices as well (for hashmaps with -keys of variable length). +This classification scheme is used to create a more complete taxonomy of cell serialization primitives, which can be found in [A.7.1](#a-7-1). -Furthermore, any intermediate vertex must have -two children, and the label of the left child must begin with a binary zero, -while the label of the right child must begin with a binary one. This enables -us not to store the first bit of the edge labels explicitly. +### 3.2.7 Integer serialization primitives -It is easy to see that any collection of key-value pairs (with distinct keys) -is represented by a unique Patricia tree. +Integer serialization primitives can be classified according to the above taxonomy as well. For example: + +- There are signed and unsigned (big-endian) integer serialization primitives. +- The size `n` of the bit field to be used (`1 ≤ n ≤ 257` for signed integers, `0 ≤ n ≤ 256` for unsigned integers) can either come from the top of stack or be embedded into the instruction itself. +- If the integer `x` to be serialized is not in the range `−2^(n−1) ≤ x < 2^(n−1)` (for signed integer serialization) or `0 ≤ x < 2^n` (for unsigned integer serialization), a range check exception is usually generated, and if `n` bits cannot be stored into the provided Builder, a cell overflow exception is generated. +- Quiet versions of serialization instructions do not throw exceptions; instead, they push `-1` on top of the resulting Builder upon success, or return the original Builder with `0` on top of it to indicate failure. + +Integer serialization instructions have mnemonics like `STU 20` (“store an unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of variable length provided in the stack”). The full list of these instructions—including their mnemonics, descriptions, and opcodes—is provided in [A.7.1](#a-7-1). + +### 3.2.8 Integers in cells are big-endian by default + +Notice that the default order of bits in Integers serialized into Cells is big-endian, not little-endian.[14](#footnote-14) In this respect TVM is a big-endian machine. However, this affects only the serialization of integers inside cells. The internal representation of the Integer value type is implementation-dependent and irrelevant for the operation of TVM. Besides, there are some special primitives such as `STULE` for (de)serializing little-endian integers, which must be stored into an integral number of bytes (otherwise “little-endianness” does not make sense, unless one is also willing to revert the order of bits inside octets). Such primitives are useful for interfacing with the little-endian world—for instance, for parsing custom-format messages arriving to a TON Blockchain smart contract from the outside world. + +### 3.2.9 Other serialization primitives + +Other cell creation primitives serialize bitstrings (i.e., cell slices without references), either taken from the stack or supplied as literal arguments; cell slices (which are concatenated to the cell builder in an obvious way); other Builders (which are also concatenated); and cell references (`STREF`). + +### 3.2.10 Other cell creation primitives + +In addition to the cell serialization primitives for certain built-in value types described above, there are simple primitives that create a new empty Builder and push it into the stack (`NEWC`), or transform a Builder into a Cell (`ENDC`), thus finishing the cell creation process. An `ENDC` can be combined with a `STREF` into a single instruction `ENDCST`, which finishes the creation of a cell and immediately stores a reference to it in an “outer” Builder. There are also primitives that obtain the quantity of data bits or references already stored in a Builder, and check how many data bits or references can be stored. + +### 3.2.11 Taxonomy of cell deserialisation primitives + +Cell parsing, or deserialization, primitives can be classified as described in [3.2.6](#3-2-6-taxonomy-of-cell-creation-serialization-primitives), with the following modifications: + +- They work with Slices (representing the remainder of the cell being parsed) instead of Builders. +- They return deserialized values instead of accepting them as arguments. +- They may come in two flavors, depending on whether they remove the deserialized portion from the Slice supplied (“fetch operations”) or leave it unmodified (“prefetch operations”). +- Their mnemonics usually begin with `LD` (or `PLD` for prefetch operations) instead of `ST`. + +For example, an unsigned big-endian 20-bit integer previously serialized into a cell by a `STU 20` instruction is likely to be deserialized later by a matching `LDU 20` instruction. + +Again, more detailed information about these instructions is provided in [A.7.2](#a-7-2). + +### 3.2.12 Other cell slice primitives + +In addition to the cell deserialisation primitives outlined above, TVM provides some obvious primitives for initializing and completing the cell deserialization process. For instance, one can convert a Cell into a Slice (`CTOS`), so that its deserialisation might begin; or check whether a Slice is empty, and generate an exception if it is not (`ENDS`); or deserialize a cell reference and immediately convert it into a Slice (`LDREFTOS`, equivalent to two instructions `LDREF` and `CTOS`). + +### 3.2.13 Modifying a serialized value in a cell + +The reader might wonder how the values serialized inside a cell may be modified. Suppose a cell contains three serialized 29-bit integers, `(x, y, z)`, representing the coordinates of a point in space, and we want to replace `y` with `y' = y + 1`, leaving the other coordinates intact. How would we achieve this? + +TVM does not offer any ways to modify existing values (cf. [2.3.4](#2-3-4-transparency-of-the-implementation-stack-values-are-values-not-references) and [2.3.5](#2-3-5-absence-of-circular-references)), so our example can only be accomplished with a series of operations as follows: + +1. Deserialize the original cell into three Integers `x, y, z` in the stack (e.g., by `CTOS; LDI 29; LDI 29; LDI 29; ENDS`). +2. Increase `y` by one (e.g., by `SWAP; INC; SWAP`). +3. Finally, serialize the resulting Integers into a new cell (e.g., by `XCHG s2; NEWC; STI 29; STI 29; STI 29; ENDC`). + +### 3.2.14 Modifying the persistent storage of a smart contract + +If the TVM code wants to modify its persistent storage, represented by the tree of cells rooted at `c4`, it simply needs to rewrite control register `c4` by the root of the tree of cells containing the new value of its persistent storage. (If only part of the persistent storage needs to be modified, cf. [3.2.13](#3-2-13-modifying-a-serialized-value-in-a-cell).) --- -### 3.3.3. Serialization of hashmaps. +## 3.3 Hashmaps, or dictionaries + +Hashmaps, or dictionaries, are a specific data structure represented by a tree of cells. Essentially, a hashmap represents a map from keys, which are bitstrings of either fixed or variable length, into values of an arbitrary type `X`, in such a way that fast lookups and modifications be possible. While any such structure might be inspected or modified with the aid of generic cell serialization and deserialization primitives, TVM introduces special primitives to facilitate working with these hashmaps. -The serialization of a hashmap into a -tree of cells (or, more generally, into a `Slice`) is defined by the following TL-B -scheme: +### 3.3.1 Basic hashmap types -``` +The two most basic hashmap types predefined in TVM are `HashmapE n X` or `HashmapE(n, X)`, which represents a partially defined map from `n`-bit strings (called keys) for some fixed `0 ≤ n ≤ 1023` into values of some type `X`, and `Hashmap(n, X)`, which is similar to `HashmapE(n, X)` but is not allowed to be empty (i.e., it must contain at least one key-value pair). + +Other hashmap types are also available—for example, one with keys of arbitrary length up to some predefined bound (up to 1023 bits). + +### 3.3.2 Hashmaps as Patricia trees + +The abstract representation of a hashmap in TVM is a Patricia tree, or a compact binary trie. It is a binary tree with edges labelled by bitstrings, such that the concatenation of all edge labels on a path from the root to a leaf equals a key of the hashmap. The corresponding value is kept in this leaf (for hashmaps with keys of fixed length), or optionally in the intermediate vertices as well (for hashmaps with keys of variable length). Furthermore, any intermediate vertex must have two children, and the label of the left child must begin with a binary zero, while the label of the right child must begin with a binary one. This enables us not to store the first bit of the edge labels explicitly. + +It is easy to see that any collection of key-value pairs (with distinct keys) is represented by a unique Patricia tree. + +### 3.3.3 Serialization of hashmaps + +The serialization of a hashmap into a tree of cells (or, more generally, into a `Slice`) is defined by the following TL-B scheme:[15](#footnote-15) + +```tlb bit#_ _:(## 1) = Bit; hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(HashmapNode m X) = Hashmap n X; @@ -1219,173 +718,57 @@ true#_ = True; _ {n:#} _:(Hashmap n True) = BitstringSet n; ``` ---- +### 3.3.4 Brief explanation of TL-B schemes -### 3.3.4. Brief explanation of TL-B schemes. - -A TL-B scheme, like the -one above, includes the following components. - -The right-hand side of each “equation” is a type, either simple (such as -`Bit` or `True`) or parametrized (such as `Hashmap n X`). The parameters of a -type must be either natural numbers (i.e., non-negative integers, which are -required to fit into 32 bits in practice), such as `n` in `Hashmap n X`, or other -types, such as `X` in `Hashmap n X`. - -The left-hand side of each equation describes a way to define, or even to -serialize, a value of the type indicated in the right-hand side. Such a description begins with the name of a constructor, such as `hm_edge` or `hml_long`, -immediately followed by an optional constructor tag, such as `#_` or `$10`, which -describes the bitstring used to encode (serialize) the constructor in question. - -Such tags may be given in either binary (after a dollar sign) or hexadecimal -notation (after a hash sign), using the conventions described in 1.0. - -If a tag is not explicitly provided, TL-B computes a default 32-bit constructor tag -by hashing the text of the “equation” defining this constructor in a certain -fashion. Therefore, empty tags must be explicitly provided by `#_` or `$_`. All -constructor names must be distinct, and constructor tags for the same type -must constitute a prefix code (otherwise the deserialization would not be -unique). - -The constructor and its optional tag are followed by field definitions. Each -field definition is of the form `ident : type-expr`, where `ident` is an identifier -with the name of the field (replaced by an underscore for anonymous fields), -and `type-expr` is the field’s type. - -The type provided here is a type expression, -which may include simple types or parametrized types with suitable parameters. - -Variables—i.e., the identifiers of the previously defined fields of types -`#` (natural numbers) or `Type` (type of types)—may be used as parameters -for the parametrized types. The serialization process recursively serializes -each field according to its type, and the serialization of a value ultimately -consists of the concatenation of bitstrings representing the constructor (i.e., -the constructor tag) and the field values. - -Some fields may be implicit. Their definitions are surrounded by curly -braces, which indicate that the field is not actually present in the serialization, -but that its value must be deduced from other data (usually the parameters -of the type being serialized). - -Some occurrences of “variables” (i.e., already-defined fields) are prefixed -by a tilde. This indicates that the variable’s occurrence is used in the opposite way of the default behavior: in the left-hand side of the equation, it -means that the variable will be deduced (computed) based on this occurrence, -instead of substituting its previously computed value; in the right-hand side, -conversely, it means that the variable will not be deduced from the type being -serialized, but rather that it will be computed during the deserialization process. - -In other words, a tilde transforms an “input argument” into an “output -argument”, and vice versa.17 - -Finally, some equalities may be included in curly brackets as well. These -are certain “equations”, which must be satisfied by the “variables” included in -them. If one of the variables is prefixed by a tilde, its value will be uniquely -determined by the values of all other variables participating in the equation -(which must be known at this point) when the definition is processed from -the left to the right. - -A caret (`^`) preceding a type `X` means that instead of serializing a value -of type `X` as a bitstring inside the current cell, we place this value into a -separate cell, and add a reference to it into the current cell. Therefore `^X` -means “the type of references to cells containing values of type X”. - -Parametrized type `#<= p` with `p : #` (this notation means “p of type #”, -i.e., a natural number) denotes the subtype of the natural numbers type -`#`, consisting of integers `0 . . . p`; it is serialized into `⌈log2(p + 1)⌉` bits as an -unsigned big-endian integer. - -Type `#` by itself is serialized as an unsigned -32-bit integer. Parametrized type `## b` with `b : #<=31` is equivalent to `#<= 2^b − 1` (i.e., it is an unsigned b-bit integer). +A TL-B scheme, like the one above, includes the following components. ---- +The right-hand side of each “equation” is a type, either simple (such as `Bit` or `True`) or parametrized (such as `Hashmap n X`). The parameters of a type must be either natural numbers (i.e., non-negative integers, which are required to fit into 32 bits in practice), such as `n` in `Hashmap n X`, or other types, such as `X` in `Hashmap n X`. -### 3.3.5. Application to the serialization of hashmaps. - -Let us explain -the net result of applying the general rules described in 3.3.4 to the TL-B -scheme presented in 3.3.3. - -Suppose we wish to serialize a value of type `HashmapE n X` for some -integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with n-bit keys -and values of type `X`, admitting an abstract representation as a Patricia tree -(cf. 3.3.2)). - -First of all, if our dictionary is empty, it is serialized into a single binary `0`, -which is the tag of nullary constructor `hme_empty`. Otherwise, its serialization -consists of a binary `1` (the tag of `hme_root`), along with a reference to a cell -containing the serialization of a value of type `Hashmap n X` (i.e., a necessarily -non-empty dictionary). - -The only way to serialize a value of type `Hashmap n X` is given by the -`hm_edge` constructor, which instructs us to serialize first the label `label` of -the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel l ⊥ n`, which means that it is a bitstring of length at most n, serialized in such -a way that the true length l of the label, `0 ≤ l ≤ n`, becomes known from -the serialization of the label. (This special serialization method is described -separately in 3.3.6.) - -The label must be followed by the serialization of a node of type -`HashmapNode m X`, where `m = n − l`. It corresponds to a vertex of the Patricia tree, -representing a non-empty subdictionary of the original dictionary with m-bit -keys, obtained by removing from all the keys of the original subdictionary -their common prefix of length l. - -If `m = 0`, a value of type `HashmapNode 0 X` is given by the `hmn_leaf` -constructor, which describes a leaf of the Patricia tree—or, equivalently, a -subdictionary with 0-bit keys. A leaf simply consists of the corresponding -value of type `X` and is serialized accordingly. - -On the other hand, if `m > 0`, a value of type `HashmapNode m X` corresponds to a fork (i.e., an intermediate node) in the Patricia tree, and is -given by the `hmn_fork` constructor. Its serialization consists of `left` and -`right`, two references to cells containing values of type `Hashmap m − 1 X`, -which correspond to the left and the right child of the intermediate node in -question—or, equivalently, to the two subdictionaries of the original dictionary consisting of key-value pairs with keys beginning with a binary `0` or -a binary `1`, respectively. Because the first bit of all keys in each of these -subdictionaries is known and fixed, it is removed, and the resulting (necessarily non-empty) subdictionaries are recursively serialized as values of type -`Hashmap m − 1 X`. +The left-hand side of each equation describes a way to define, or even to serialize, a value of the type indicated in the right-hand side. Such a description begins with the name of a constructor, such as `hm_edge` or `hml_long`, immediately followed by an optional constructor tag, such as `#_` or `$10`, which describes the bitstring used to encode (serialize) the constructor in question. Such tags may be given in either binary (after a dollar sign) or hexadecimal notation (after a hash sign), using the conventions described in [1.0](#1-0-notation-for-bitstrings). If a tag is not explicitly provided, TL-B computes a default 32-bit constructor tag by hashing the text of the “equation” defining this constructor in a certain fashion. Therefore, empty tags must be explicitly provided by `#_` or `$_`. All constructor names must be distinct, and constructor tags for the same type must constitute a prefix code (otherwise the deserialization would not be unique). ---- +The constructor and its optional tag are followed by field definitions. Each field definition is of the form `ident : type-expr`, where ident is an identifier with the name of the field[16](#footnote-16) (replaced by an underscore for anonymous fields), and `type-expr` is the field’s type. The type provided here is a type expression, which may include simple types or parametrized types with suitable parameters. Variables—i.e., the (identifiers of the) previously defined fields of types `#` (natural numbers) or `Type` (type of types)—may be used as parameters for the parametrized types. The serialization process recursively serializes each field according to its type, and the serialization of a value ultimately consists of the concatenation of bitstrings representing the constructor (i.e., the constructor tag) and the field values. -### 3.3.6. Serialization of labels. +Some fields may be implicit. Their definitions are surrounded by curly braces, which indicate that the field is not actually present in the serialization, but that its value must be deduced from other data (usually the parameters of the type being serialized). -There are several ways to serialize a label -of length at most n, if its exact length is `l ≤ n` (recall that the exact length -must be deducible from the serialization of the label itself, while the upper -bound n is known before the label is serialized or deserialized). These ways -are described by the three constructors `hml_short`, `hml_long`, and `hml_same` -of type `HmLabel l ⊥ n`: +Some occurrences of “variables” (i.e., already-defined fields) are prefixed by a tilde. This indicates that the variable’s occurrence is used in the opposite way of the default behavior: in the left-hand side of the equation, it means that the variable will be deduced (computed) based on this occurrence, instead of substituting its previously computed value; in the right-hand side, conversely, it means that the variable will not be deduced from the type being serialized, but rather that it will be computed during the deserialization process. In other words, a tilde transforms an “input argument” into an “output argument”, and vice versa.[17](#footnote-17) -* `hml_short` — Describes a way to serialize “short” labels, of small length - `l ≤ n`. Such a serialization consists of a binary `0` (the constructor tag - of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary - representation of the length l), followed by l bits comprising the label - itself. +Finally, some equalities may be included in curly brackets as well. These are certain “equations”, which must be satisfied by the “variables” included in them. If one of the variables is prefixed by a tilde, its value will be uniquely determined by the values of all other variables participating in the equation (which must be known at this point) when the definition is processed from the left to the right. -* `hml_long` — Describes a way to serialize “long” labels, of arbitrary - length `l ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation - of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by l bits comprising the label itself. +A caret (`^`) preceding a type `X` means that instead of serializing a value of type `X` as a bitstring inside the current cell, we place this value into a separate cell, and add a reference to it into the current cell. Therefore `^X` means “the type of references to cells containing values of type `X`”. -* `hml_same` — Describes a way to serialize “long” labels, consisting of l - repetitions of the same bit v. Such a serialization consists of `11` (the - constructor tag of `hml_same`), followed by the bit `v`, followed by the - length l stored in `⌈log2(n + 1)⌉` bits as before. +Parametrized type `#<= p` with `p : #` (this notation means “p of type #”, i.e., a natural number) denotes the subtype of the natural numbers type `#`, consisting of integers `0 … p`; it is serialized into `⌈log2(p + 1)⌉` bits as an unsigned big-endian integer. Type `#` by itself is serialized as an unsigned 32-bit integer. Parametrized type `## b` with `b : #<=31` is equivalent to `#<= 2^b − 1` (i.e., it is an unsigned `b`-bit integer). -Each label can always be serialized in at least two different fashions, using -`hml_short` or `hml_long` constructors. Usually the shortest serialization (and -in the case of a tie—the lexicographically smallest among the shortest) is -preferred and is generated by TVM hashmap primitives, while the other -variants are still considered valid. +### 3.3.5 Application to the serialization of hashmaps -This label encoding scheme has been designed to be efficient for dictionaries -with “random” keys (e.g., hashes of some data), as well as for dictionaries with -“regular” keys (e.g., big-endian representations of integers in some range). +Let us explain the net result of applying the general rules described in [3.3.4](#3-3-4-brief-explanation-of-tl-b-schemes) to the TL-B scheme presented in [3.3.3](#3-3-3-serialization-of-hashmaps). ---- +Suppose we wish to serialize a value of type `HashmapE n X` for some integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with `n`-bit keys and values of type `X`, admitting an abstract representation as a Patricia tree (cf. [3.3.2](#3-3-2-hashmaps-as-patricia-trees))). + +First of all, if our dictionary is empty, it is serialized into a single binary `0`, which is the tag of nullary constructor `hme_empty`. Otherwise, its serialization consists of a binary `1` (the tag of `hme_root`), along with a reference to a cell containing the serialization of a value of type `Hashmap n X` (i.e., a necessarily non-empty dictionary). + +The only way to serialize a value of type `Hashmap n X` is given by the `hm_edge` constructor, which instructs us to serialize first the label `label` of the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel ~l n`, which means that it is a bitstring of length at most `n`, serialized in such a way that the true length `l` of the label, `0 ≤ l ≤ n`, becomes known from the serialization of the label. (This special serialization method is described separately in [3.3.6](#3-3-6-serialization-of-labels).) + +The label must be followed by the serialization of a node of type `HashmapNode m X`, where `m = n − l`. It corresponds to a vertex of the Patricia tree, representing a non-empty subdictionary of the original dictionary with `m`-bit keys, obtained by removing from all the keys of the original subdictionary their common prefix of length `l`. + +If `m = 0`, a value of type `HashmapNode 0 X` is given by the `hmn_leaf` constructor, which describes a leaf of the Patricia tree—or, equivalently, a subdictionary with `0`-bit keys. A leaf simply consists of the corresponding value of type `X` and is serialized accordingly. + +On the other hand, if `m > 0`, a value of type `HashmapNode m X` corresponds to a fork (i.e., an intermediate node) in the Patricia tree, and is given by the `hmn_fork` constructor. Its serialization consists of `left` and `right`, two references to cells containing values of type `Hashmap n X` **with `n` reduced by one** (i.e., `Hashmap (n − 1) X`), which correspond to the left and the right child of the intermediate node in question—or, equivalently, to the two subdictionaries of the original dictionary consisting of key-value pairs with keys beginning with a binary `0` or a binary `1`, respectively. Because the first bit of all keys in each of these subdictionaries is known and fixed, it is removed, and the resulting (necessarily non-empty) subdictionaries are recursively serialized as values of type `Hashmap (n − 1) X`. + +### 3.3.6 Serialization of labels -### 3.3.7. An example of dictionary serialization. +There are several ways to serialize a label of length at most `n`, if its exact length is `l ≤ n` (recall that the exact length must be deducible from the serialization of the label itself, while the upper bound `n` is known before the label is serialized or deserialized). These ways are described by the three constructors `hml_short`, `hml_long`, and `hml_same` of type `HmLabel ~l n`: -Consider a dictionary -with three 16-bit keys 13, 17, and 239 (considered as big-endian integers) -and corresponding 16-bit values 169, 289, and 57121. +* **`hml_short`** — Describes a way to serialize “short” labels, of small length `l ≤ n`. Such a serialization consists of a binary `0` (the constructor tag of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary representation of the length `l`), followed by `l` bits comprising the label itself. +* **`hml_long`** — Describes a way to serialize “long” labels, of arbitrary length `l ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by `l` bits comprising the label itself. +* **`hml_same`** — Describes a way to serialize “long” labels, consisting of `l` repetitions of the same bit `v`. Such a serialization consists of `11` (the constructor tag of `hml_same`), followed by the bit `v`, followed by the length `l` stored in `⌈log2(n + 1)⌉` bits as before. + +Each label can always be serialized in at least two different fashions, using `hml_short` or `hml_long` constructors. Usually the shortest serialization (and in the case of a tie—the lexicographically smallest among the shortest) is preferred and is generated by TVM hashmap primitives, while the other variants are still considered valid. + +This label encoding scheme has been designed to be efficient for dictionaries with “random” keys (e.g., hashes of some data), as well as for dictionaries with “regular” keys (e.g., big-endian representations of integers in some range). + +### 3.3.7 An example of dictionary serialization + +Consider a dictionary with three 16-bit keys `13`, `17`, and `239` (considered as big-endian integers) and corresponding 16-bit values `169`, `289`, and `57121`. In binary form: @@ -1395,45 +778,34 @@ In binary form: 0000000011101111 => 1101111100100001 ``` -The corresponding Patricia tree consists of a root `A`, two intermediate -nodes `B` and `C`, and three leaf nodes `D`, `E`, and `F`, corresponding to 13, 17, -and 239, respectively. The root `A` has only one child, `B`; the label on the -edge `AB` is `00000000 = 08`. The node `B` has two children: its left child is -an intermediate node `C` with the edge `BC` labelled by `(0)00`, while its right -child is the leaf `F` with `BF` labelled by `(1)1101111`. Finally, `C` has two leaf -children `D` and `E`, with `CD` labelled by `(0)1101` and `CE`—by `(1)0001`. +The corresponding Patricia tree consists of a root `A`, two intermediate nodes `B` and `C`, and three leaf nodes `D`, `E`, and `F`, corresponding to `13`, `17`, and `239`, respectively. The root `A` has only one child, `B`; the label on the edge `AB` is `00000000 = 0₈`. The node `B` has two children: its left child is an intermediate node `C` with the edge `BC` labelled by `(0)00`, while its right child is the leaf `F` with `BF` labelled by `(1)1101111`. Finally, `C` has two leaf children `D` and `E`, with `CD` labelled by `(0)1101` and `CE`—by `(1)0001`. -The corresponding value of type `HashmapE 16 (## 16)` may be written -in human-readable form as: +The corresponding value of type `HashmapE 16 (## 16)` may be written in human-readable form as: ``` (hme_root$1 - root:^(hm_edge label:(hml_same$11 v:0 n:8) node:(hm_fork - left:^(hm_edge label:(hml_short$0 len:$110 s:$00) node:(hm_fork - left:^(hm_edge label:(hml_long$10 n:4 s:$1101) - node:(hm_leaf value:169)) - right:^(hm_edge label:(hml_long$10 n:4 s:$0001) - node:(hm_leaf value:289)))) - right:^(hm_edge label:(hml_long$10 n:7 s:$1101111) - node:(hm_leaf value:57121))))) + root:^(hm_edge label:(hml_same$11 v:0 n:8) node:(hm_fork + left:^(hm_edge label:(hml_short$0 len:$110 s:$00) node:(hm_fork + left:^(hm_edge label:(hml_long$10 n:4 s:$1101) + node:(hm_leaf value:169)) + right:^(hm_edge label:(hml_long$10 n:4 s:$0001) + node:(hm_leaf value:289)))) + right:^(hm_edge label:(hml_long$10 n:7 s:$1101111) + node:(hm_leaf value:57121))))) ``` -The serialization of this data structure into a tree of cells consists of six -cells with the following binary data contained in them: +The serialization of this data structure into a tree of cells consists of six cells with the following binary data contained in them: ``` -A := 1 -A.0 := 11 0 01000 -A.0.0 := 0 110 00 -A.0.0.0 := 10 100 1101 0000000010101001 -A.0.0.1 := 10 100 0001 0000000100100001 -A.0.1 := 10 111 1101111 1101111100100001 +A := 1 +A.0 := 11 0 01000 +A.0.0 := 0 110 00 +A.0.0.0 := 10 100 1101 0000000010101001 +A.0.0.1 := 10 100 0001 0000000100100001 +A.0.1 := 10 111 1101111 1101111100100001 ``` -Here `A` is the root cell, `A.0` is the cell at the first reference of `A`, `A.1` is -the cell at the second reference of `A`, and so on. This tree of cells can be -represented more compactly using the hexadecimal notation described in 1.0, -using indentation to reflect the tree-of-cells structure: +Here `A` is the root cell, `A.0` is the cell at the first reference of `A`, `A.1` is the cell at the second reference of `A`, and so on. This tree of cells can be represented more compactly using the hexadecimal notation described in [1.0](#1-0-notation-for-bitstrings), using indentation to reflect the tree-of-cells structure: ``` C_ @@ -1444,157 +816,70 @@ A08090C_ BEFDF21 ``` -A total of 93 data bits and 5 references in 6 cells have been used to serialize -this dictionary. Notice that a straightforward representation of three 16- -bit keys and their corresponding 16-bit values would already require 96 bits -(albeit without any references), so this particular serialization turns out to -be quite efficient. +A total of 93 data bits and 5 references in 6 cells have been used to serialize this dictionary. Notice that a straightforward representation of three 16-bit keys and their corresponding 16-bit values would already require 96 bits (albeit without any references), so this particular serialization turns out to be quite efficient. ---- +### 3.3.8 Ways to describe the serialization of type X -### 3.3.8. Ways to describe the serialization of type X. - -Notice that the -built-in TVM primitives for dictionary manipulation need to know something -about the serialization of type `X`; otherwise, they would not be able to work -correctly with `Hashmap n X`, because values of type `X` are immediately -contained in the Patricia tree leaf cells. There are several options available -to describe the serialization of type `X`: - -* The simplest case is when `X = ^Y` for some other type `Y`. In this case - the serialization of `X` itself always consists of one reference to a cell, - which in fact must contain a value of type `Y`, something that is not - relevant for dictionary manipulation primitives. - -* Another simple case is when the serialization of any value of type `X` - always consists of `0 ≤ b ≤ 1023` data bits and `0 ≤ r ≤ 4` references. Integers `b` and `r` can then be passed to a dictionary manipulation primitive - as a simple description of `X`. (Notice that the previous case corresponds - to `b = 0, r = 1`.) - -* A more sophisticated case can be described by four integers - `1 ≤ b0, b1 ≤ 1023`, `0 ≤ r0, r1 ≤ 4`, with `bi` and `ri` used when the first bit of the - serialization equals `i`. When `b0 = b1` and `r0 = r1`, this case reduces to - the previous one. - -* Finally, the most general description of the serialization of a type `X` - is given by a splitting function `splitX` for `X`, which accepts one `Slice` - parameter `s`, and returns two `Slice`s, `s'` and `s''`, where `s'` - is the only prefix of `s` that is the serialization of a value of type `X`, and `s''` is - the remainder of `s`. If no such prefix exists, the splitting function is - expected to throw an exception. Notice that a compiler for a high-level - language, which supports some or all algebraic TL-B types, is likely to - automatically generate splitting functions for all types defined in the - program. +Notice that the built-in TVM primitives for dictionary manipulation need to know something about the serialization of type `X`; otherwise, they would not be able to work correctly with `Hashmap n X`, because values of type `X` are immediately contained in the Patricia tree leaf cells. There are several options available to describe the serialization of type `X`: ---- +* The simplest case is when `X = ^Y` for some other type `Y`. In this case the serialization of `X` itself always consists of one reference to a cell, which in fact must contain a value of type `Y`, something that is not relevant for dictionary manipulation primitives. +* Another simple case is when the serialization of any value of type `X` always consists of `0 ≤ b ≤ 1023` data bits and `0 ≤ r ≤ 4` references. Integers `b` and `r` can then be passed to a dictionary manipulation primitive as a simple description of `X`. (Notice that the previous case corresponds to `b = 0, r = 1`.) +* A more sophisticated case can be described by four integers `1 ≤ b0, b1 ≤ 1023`, `0 ≤ r0, r1 ≤ 4`, with `b_i` and `r_i` used when the first bit of the serialization equals `i`. When `b0 = b1` and `r0 = r1`, this case reduces to the previous one. +* Finally, the most general description of the serialization of a type `X` is given by a splitting function `split_X` for `X`, which accepts one `Slice` parameter `s`, and returns two `Slice`s, `s'` and `s''`, where `s'` is the only prefix of `s` that is the serialization of a value of type `X`, and `s''` is the remainder of `s`. If no such prefix exists, the splitting function is expected to throw an exception. Notice that a compiler for a high-level language, which supports some or all algebraic TL-B types, is likely to automatically generate splitting functions for all types defined in the program. -### 3.3.9. A simplifying assumption on the serialization of `X`. +### 3.3.9 A simplifying assumption on the serialization of X -One -may notice that values of type `X` always occupy the remaining part of an -`hm_edge`/`hme_leaf` cell inside the serialization of a `HashmapE n X`. Therefore, if we do not insist on strict validation of all dictionaries accessed, we -may assume that everything left unparsed in an `hm_edge`/`hme_leaf` cell after deserializing its label is a value of type `X`. This greatly simplifies the -creation of dictionary manipulation primitives, because in most cases they -turn out not to need any information about `X` at all. +One may notice that values of type `X` always occupy the remaining part of an `hm_edge/hmn_leaf` cell inside the serialization of a `HashmapE n X`. Therefore, if we do not insist on strict validation of all dictionaries accessed, we may assume that everything left unparsed in an `hm_edge/hmn_leaf` cell after deserializing its label is a value of type `X`. This greatly simplifies the creation of dictionary manipulation primitives, because in most cases they turn out not to need any information about `X` at all. ---- +### 3.3.10. Basic dictionary operations -### 3.3.10. Basic dictionary operations. - -Let us present a classification of -basic operations with dictionaries (i.e., values `D` of type `HashmapE n X`): - -* `Get(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns - the corresponding value `D[k] : X?` kept in `D`. -* `Set(D, k, x)` — Given `D : HashmapE(n, X)`, a key `k : n · bit`, and a - value `x : X`, sets `D0[k]` to `x` in a copy `D0` of `D`, and returns the resulting - dictionary `D0` (cf. 2.3.4). -* `Add(D, k, x)` — Similar to `Set`, but adds the key-value pair `(k, x)` to - `D` only if key `k` is absent in `D`. -* `Replace(D, k, x)` — Similar to `Set`, but changes `D0[k]` to `x` only if key - `k` is already present in `D`. -* `GetSet`, `GetAdd`, `GetReplace` — Similar to `Set`, `Add`, and `Replace`, - respectively, but returns the old value of `D[k]` as well. -* `Delete(D, k)` — Deletes key `k` from dictionary `D`, and returns the - resulting dictionary `D0`. -* `GetMin(D)`, `GetMax(D)` — Gets the minimal or maximal key `k` - from dictionary `D`, along with the associated value `x : X`. -* `RemoveMin(D)`, `RemoveMax(D)` — Similar to `GetMin` and `GetMax`, but also removes the key in question from dictionary `D`, and - returns the modified dictionary `D0`. May be used to iterate over all - elements of `D`, effectively using (a copy of) `D` itself as an iterator. -* `GetNext(D, k)` — Computes the minimal key `k0 > k` (or `k0 ≥ k` in a - variant) and returns it along with the corresponding value `x0 : X`. May - be used to iterate over all elements of `D`. -* `GetPrev(D, k)` — Computes the maximal key `k0 < k` (or `k0 ≤ k` in a - variant) and returns it along with the corresponding value `x0 : X`. -* `Empty(n)` — Creates an empty dictionary `D : HashmapE(n, X)`. -* `IsEmpty(D)` — Checks whether a dictionary is empty. -* `Create(n, {(ki , xi)})` — Given `n`, creates a dictionary from a list `(ki , xi)` - of key-value pairs passed in stack. -* `GetSubdict(D, l, k0)` — Given `D : HashmapE(n, X)` and some `l`-bit - string `k0 : l · bit` for `0 ≤ l ≤ n`, returns subdictionary `D0 = D/k0` of `D`, - consisting of keys beginning with `k0`. The result `D0` may be of either - type `HashmapE(n, X)` or type `HashmapE(n − l, X)`. -* `ReplaceSubdict(D, l, k0, D0)` — Given `D : HashmapE(n, X)`, `0 ≤ - l ≤ n`, `k0 : l · bit`, and `D0 : HashmapE(n − l, X)`, replaces with `D0` - the subdictionary `D/k0` of `D` consisting of keys beginning with `k0`, and - returns the resulting dictionary `D00 : HashmapE(n, X)`. Some variants - of `ReplaceSubdict` may also return the old value of the subdictionary - `D/k0` in question. -* `DeleteSubdict(D, l, k0)` — Equivalent to `ReplaceSubdict` with `D0` - being an empty dictionary. -* `Split(D)` — Given `D : HashmapE(n, X)`, returns `D0 := D/0` and - `D1 := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with 0 and 1, respectively. -* `Merge(D0, D1)` — Given `D0` and `D1 : HashmapE(n−1, X)`, computes - `D : HashmapE(n, X)`, such that `D/0 = D0` and `D/1 = D1`. -* `Foreach(D, f)` — Executes a function `f` with two arguments `k` and - `x`, with `(k, x)` running over all key-value pairs of a dictionary `D` in - lexicographical order.18 -* `ForeachRev(D, f)` — Similar to `Foreach`, but processes all keyvalue pairs in reverse order. -* `TreeReduce(D, o, f, g)` — Given `D : HashmapE(n, X)`, a value `o : X`, - and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree - reduction” of `D` by first applying `f` to all the leaves, and then using `g` - to compute the value corresponding to a fork starting from the values - assigned to its children.19 +Let us present a classification of basic operations with dictionaries (i.e., values D of type `HashmapE n X`): ---- - -### 3.3.11. Taxonomy of dictionary primitives. - -The dictionary primitives, -described in detail in A.10, can be classified according to the following categories: +- `GET(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns the corresponding value `D[k] : X?` kept in `D`. +- `SET(D, k, x)` — Given `D : HashmapE(n, X)`, a key `k : n·bit`, and a value `x : X`, sets `D′[k]` to `x` in a copy `D′` of `D`, and returns the resulting dictionary `D′` (cf. [2.3.4](#234-transparency-of-the-implementation-stack-values-are-values-not-references)). +- `ADD(D, k, x)` — Similar to `SET`, but adds the key-value pair `(k, x)` to `D` only if key `k` is absent in `D`. +- `REPLACE(D, k, x)` — Similar to `SET`, but changes `D′[k]` to `x` only if key `k` is already present in `D`. +- `GETSET`, `GETADD`, `GETREPLACE` — Similar to `SET`, `ADD`, and `REPLACE`, respectively, but returns the old value of `D[k]` as well. +- `DELETE(D, k)` — Deletes key `k` from dictionary `D`, and returns the resulting dictionary `D′`. +- `GETMIN(D)`, `GETMAX(D)` — Gets the minimal or maximal key `k` from dictionary `D`, along with the associated value `x : X`. +- `REMOVEMIN(D)`, `REMOVEMAX(D)` — Similar to `GETMIN` and `GETMAX`, but also removes the key in question from dictionary `D`, and returns the modified dictionary `D′`. May be used to iterate over all elements of `D`, effectively using (a copy of) `D` itself as an iterator. +- `GETNEXT(D, k)` — Computes the minimal key `k′ > k` (or `k′ ≥ k` in a variant) and returns it along with the corresponding value `x′ : X`. May be used to iterate over all elements of `D`. +- `GETPREV(D, k)` — Computes the maximal key `k′ < k` (or `k′ ≤ k` in a variant) and returns it along with the corresponding value `x′ : X`. +- `EMPTY(n)` — Creates an empty dictionary `D : HashmapE(n, X)`. +- `ISEMPTY(D)` — Checks whether a dictionary is empty. +- `CREATE(n, {(ki, xi)})` — Given `n`, creates a dictionary from a list `(ki, xi)` of key-value pairs passed in stack. +- `GETSUBDICT(D, l, k0)` — Given `D : HashmapE(n, X)` and some `l`-bit string `k0 : l·bit` for `0 ≤ l ≤ n`, returns subdictionary `D′ = D/k0` of `D`, consisting of keys beginning with `k0`. The result `D′` may be of either type `HashmapE(n, X)` or type `HashmapE(n − l, X)`. +- `REPLACESUBDICT(D, l, k0, D0)` — Given `D : HashmapE(n, X)`, `0 ≤ l ≤ n`, `k0 : l · bit`, and `D0 : HashmapE(n − l, X)`, replaces with `D0` the subdictionary `D/k0` of `D` consisting of keys beginning with `k0`, and returns the resulting dictionary `D′′ : HashmapE(n, X)`. Some variants of `REPLACESUBDICT` may also return the old value of the subdictionary `D/k0` in question. +- `DELETESUBDICT(D, l, k0)` — Equivalent to `REPLACESUBDICT` with `D0` being an empty dictionary. +- `SPLIT(D)` — Given `D : HashmapE(n, X)`, returns `D0 := D/0` and `D1 := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with `0` and `1`, respectively. +- `MERGE(D0, D1)` — Given `D0` and `D1 : HashmapE(n − 1, X)`, computes `D : HashmapE(n, X)`, such that `D/0 = D0` and `D/1 = D1`. +- `FOREACH(D, f)` — Executes a function `f` with two arguments `k` and `x`, with `(k, x)` running over all key-value pairs of a dictionary `D` in lexicographical order.[18](#footnote-18) +- `FOREACHREV(D, f)` — Similar to `FOREACH`, but processes all key-value pairs in reverse order. +- `TREEREDUCE(D, o, f, g)` — Given `D : HashmapE(n, X)`, a value `o : X`, and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree reduction” of `D` by first applying `f` to all the leaves, and then using `g` to compute the value corresponding to a fork starting from the values assigned to its children.[19](#footnote-19) -* Which dictionary operation (cf. 3.3.10) do they perform? -* Are they specialized for the case `X = ^Y`? If so, do they represent values of type `Y` by `Cells` or by `Slices`? (Generic versions always represent - values of type `X` as `Slices`.) -* Are the dictionaries themselves passed and returned as `Cells` or as - `Slices`? (Most primitives represent dictionaries as `Slices`.) -* Is the key length `n` fixed inside the primitive, or is it passed in the - stack? -* Are the keys represented by `Slices`, or by signed or unsigned `Integer`s? +### 3.3.11 Taxonomy of dictionary primitives -In addition, TVM includes special serialization/deserialization primitives, -such as `STDICT`, `LDDICT`, and `PLDDICT`. They can be used to extract a dictionary from a serialization of an encompassing object, or to insert a dictionary -into such a serialization. +The dictionary primitives, described in detail in [A.10](#a-10), can be classified according to the following categories: ---- +* Which dictionary operation (cf. [3.3.10](#3-3-10-basic-dictionary-operations)) do they perform? +* Are they specialized for the case `X = ^Y`? If so, do they represent values of type `Y` by `Cell`s or by `Slice`s? (Generic versions always represent values of type `X` as `Slice`s.) +* Are the dictionaries themselves passed and returned as `Cell`s or as `Slice`s? (Most primitives represent dictionaries as `Slice`s.) +* Is the key length `n` fixed inside the primitive, or is it passed in the stack? +* Are the keys represented by `Slice`s, or by signed or unsigned `Integer`s? -Great — here’s **3.4 Hashmaps with variable-length keys** in Markdown, text unchanged and with inline code backticked where needed: +In addition, TVM includes special serialization/deserialization primitives, such as `STDICT`, `LDDICT`, and `PLDDICT`. They can be used to extract a dictionary from a serialization of an encompassing object, or to insert a dictionary into such a serialization. --- -### 3.4 Hashmaps with variable-length keys +## 3.4 Hashmaps with variable-length keys -TVM provides some support for dictionaries, or hashmaps, with variablelength keys, in addition to its support for dictionaries with fixed-length keys -(as described in 3.3 above). +TVM provides some support for dictionaries, or hashmaps, with variable-length keys, in addition to its support for dictionaries with fixed-length keys (as described in [3.3](#33-hashmaps-or-dictionaries)). -#### 3.4.1. Serialization of dictionaries with variable-length keys. +### 3.4.1. Serialization of dictionaries with variable-length keys -The -serialization of a `VarHashmap` into a tree of cells (or, more generally, into a -`Slice`) is defined by a TL-B scheme, similar to that described in 3.3.3: +The serialization of a `VarHashmap` into a tree of cells (or, more generally, into a `Slice`) is defined by a TL-B scheme, similar to that described in [3.3.3](#333-serialization-of-hashmaps): -``` +```tl-b vhm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(VarHashmapNode m X) = VarHashmap n X; @@ -1617,328 +902,223 @@ vhme_empty$0 {n:#} {X:Type} = VarHashmapE n X; vhme_root$1 {n:#} {X:Type} root:^(VarHashmap n X) = VarHashmapE n X; ``` +--- + +### 3.4.2. Serialization of prefix codes + +One special case of a dictionary with variable-length keys is that of a **prefix code**, where the keys cannot be prefixes of each other. Values in such dictionaries may occur only in the leaves of a Patricia tree. + +The serialization of a prefix code is defined by the following TL-B scheme: + +```tl-b +phm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) +{n = (~m) + l} node:(PfxHashmapNode m X) += PfxHashmap n X; + +phmn_leaf$0 {n:#} {X:Type} value:X = PfxHashmapNode n X; + +phmn_fork$1 {n:#} {X:Type} left:^(PfxHashmap n X) +right:^(PfxHashmap n X) = PfxHashmapNode (n + 1) X; + +phme_empty$0 {n:#} {X:Type} = PfxHashmapE n X; + +phme_root$1 {n:#} {X:Type} root:^(PfxHashmap n X) += PfxHashmapE n X; +``` +--- # 4 Control flow, continuations, and exceptions -This chapter describes continuations, which may represent execution tokens -and exception handlers in TVM. Continuations are deeply involved with the -control flow of a TVM program; in particular, subroutine calls and conditional and iterated execution are implemented in TVM using special primitives that accept one or more continuations as their arguments. -We conclude this chapter with a discussion of the problem of recursion -and of families of mutually recursive functions, exacerbated by the fact that -cyclic references are not allowed in TVM data structures (including TVM -code). +This chapter describes continuations, which may represent execution tokens and exception handlers in TVM. Continuations are deeply involved with the control flow of a TVM program; in particular, subroutine calls and conditional and iterated execution are implemented in TVM using special primitives that accept one or more continuations as their arguments. + +We conclude this chapter with a discussion of the problem of recursion and of families of mutually recursive functions, exacerbated by the fact that cyclic references are not allowed in TVM data structures (including TVM code). + +--- ## 4.1 Continuations and subroutines -Recall (cf.1.1.3) that `Continuation` values represent “execution tokens” that -can be executed later—for example, by `EXECUTE=CALLX` (“execute” or “call -indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations -are responsible for the execution of the program, and are heavily used by -control flow primitives, enabling subroutine calls, conditional expressions, -loops, and so on. - -### 4.1.1. Ordinary continuations. - -The most common kind of continuations -are the ordinary continuations, containing the following data: -• A `Slice` code (cf. 1.1.3 and 3.2.2), containing (the remainder of) the -TVM code to be executed. -• A (possibly empty) `Stack` stack, containing the original contents of -the stack for the code to be executed. -• A (possibly empty) list `save` of pairs (`c(i)`, `vi`) (also called “savelist”), -containing the values of control registers to be restored before the execution of the code. -• A 16-bit integer value `cp`, selecting the TVM codepage used to interpret -the TVM code from code. -• An optional non-negative integer `nargs`, indicating the number of arguments expected by the continuation. - -### 4.1.2. Simple ordinary continuations. - -In most cases, the ordinary continuations are the simplest ones, having empty stack and `save`. They consist -essentially of a reference `code` to (the remainder of) the code to be executed, -and of the codepage `cp` to be used while decoding the instructions from this -code. - -### 4.1.3. Current continuation `cc`. - -The “current continuation” `cc` is an important part of the total state of TVM, representing the code being executed -right now (cf. 1.1). In particular, what we call “the current stack” (or simply -“the stack”) when discussing all other primitives is in fact the stack of the -current continuation. All other components of the total state of TVM may -be also thought of as parts of the current continuation `cc`; however, they -may be extracted from the current continuation and kept separately as part -of the total state for performance reasons. This is why we describe the stack, -the control registers, and the codepage as separate parts of the TVM state -in 1.4. - -### 4.1.4. Normal work of TVM, or the main loop. - -TVM usually performs -the following operations: -If the current continuation `cc` is an ordinary one, it decodes the first -instruction from the `Slice` `code`, similarly to the way other cells are deserialized by TVM `LD*` primitives (cf. 3.2 and 3.2.11): it decodes the opcode -first, and then the parameters of the instruction (e.g., 4-bit fields indicating -“stack registers” involved for stack manipulation primitives, or constant values for “push constant” or “literal” primitives). The remainder of the `Slice` -is then put into the `code` of the new `cc`, and the decoded operation is executed on the current stack. This entire process is repeated until there are no -operations left in `cc.code`. -If the code is empty (i.e., contains no bits of data and no references), or if -a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, -the current continuation is discarded, and the “return continuation” from -control register `c0` is loaded into `cc` instead (this process is discussed in -more detail starting in 4.1.6).20 Then the execution continues by parsing -operations from the new current continuation. - -### 4.1.5. Extraordinary continuations. - -In addition to the ordinary continuations considered so far (cf. 4.1.1), TVM includes some extraordinary continuations, representing certain less common states. Examples of extraordinary -continuations include: -• The continuation `ec_quit` with its parameter set to zero, which represents the end of the work of TVM. This continuation is the original -value of `c0` when TVM begins executing the code of a smart contract. -• The continuation `ec_until`, which contains references to two other -continuations (ordinary or not) representing the body of the loop being -executed and the code to be executed after the loop. -Execution of an extraordinary continuation by TVM depends on its specific -class, and differs from the operations for ordinary continuations described in -4.1.4. -21 - -### 4.1.6. Switching to another continuation: `JMP` and `RET`. - -The process of -switching to another continuation `c` may be performed by such instructions -as `JMPX` (which takes `c` from the stack) or `RET` (which uses `c0` as `c`). This -process is slightly more complex than simply setting the value of `cc` to `c`: -before doing this, either all values or the top `n` values in the current stack -are moved to the stack of the continuation `c`, and only then is the remainder -of the current stack discarded. -If all values need to be moved (the most common case), and if the continuation `c` has an empty stack (also the most common case; notice that -extraordinary continuations are assumed to have an empty stack), then the -new stack of `c` equals the stack of the current continuation, so we can simply -transfer the current stack in its entirety to `c`. (If we keep the current stack -as a separate part of the total state of TVM, we have to do nothing at all.) - -### 4.1.7. Determining the number `n` of arguments passed to the next continuation `c`. - -By default, `n` equals the depth of the current stack. However, if `c` has an explicit value of `nargs` (number of arguments to be provided), -then `n` is computed as `n0`, equal to `c.nargs` minus the current depth of `c`’s -stack. -Furthermore, there are special forms of `JMPX` and `RET` that provide an -explicit value `n00`, the number of parameters from the current stack to be -passed to continuation `c`. If `n00` is provided, it must be less than or equal to -the depth of the current stack, or else a stack underflow exception occurs. If -both `n0` and `n00` are provided, we must have `n0 ≤ n00`, in which case `n = n0` is -used. If `n00` is provided and `n0` -is not, then `n = n00` is used. -One could also imagine that the default value of `n00` equals the depth of -the original stack, and that `n00` values are always removed from the top of -the original stack even if only `n0` of them are actually moved to the stack of -the next continuation `c`. Even though the remainder of the current stack is -discarded afterwards, this description will become useful later. - -### 4.1.8. Restoring control registers from the new continuation `c`. - -After -the new stack is computed, the values of control registers present in `c.save` -are restored accordingly, and the current codepage `cp` is also set to `c.cp`. -Only then does TVM set `cc` equal to the new `c` and begin its execution.22 - -### 4.1.9. Subroutine calls: `CALLX` or `EXECUTE` primitives. - -The execution -of continuations as subroutines is slightly more complicated than switching -to continuations. -Consider the `CALLX` or `EXECUTE` primitive, which takes a continuation `c` -from the (current) stack and executes it as a subroutine. -Apart from doing the stack manipulations described in 4.1.6 and 4.1.7 -and setting the new control registers and codepage as described in 4.1.8, -these primitives perform several additional steps: - -1. After the top `n00` values are removed from the current stack (cf. 4.1.7), - the (usually empty) remainder is not discarded, but instead is stored - in the (old) current continuation `cc`. -2. The old value of the special register `c0` is saved into the (previously - empty) savelist `cc.save`. -3. The continuation `cc` thus modified is not discarded, but instead is set - as the new `c0`, which performs the role of “next continuation” or “return - continuation” for the subroutine being called. -4. After that, the switching to `c` continues as before. In particular, some - control registers are restored from `c.save`, potentially overwriting the - value of `c0` set in the previous step. (Therefore, a good optimization - would be to check that `c0` is present in `c.save` from the very beginning, - and skip the three previous steps as useless in this case.) - In this way, the called subroutine can return control to the caller by - switching the current continuation to the return continuation saved in `c0`. - Nested subroutine calls work correctly because the previous value of `c0` ends - up saved into the new `c0`’s control register savelist `c0.save`, from which it is - restored later. - -### 4.1.10. Determining the number of arguments passed to and/or return values accepted from a subroutine. - -Similarly to `JMPX` and `RET`, -`CALLX` also has special (rarely used) forms, which allow us to explicitly specify -the number `n00` of arguments passed from the current stack to the called -subroutine (by default, `n00` equals the depth of the current stack, i.e., it is -passed in its entirety). Furthermore, a second number `n000` can be specified, -used to set `nargs` of the modified `cc` continuation before storing it into the -new `c0`; the new `nargs` equals the depth of the old stack minus `n00` plus `n000`. -This means that the caller is willing to pass exactly `n00` arguments to the -called subroutine, and is willing to accept exactly `n000` results in their stead. -Such forms of `CALLX` and `RET` are mostly intended for library functions -that accept functional arguments and want to invoke them safely. Another -application is related to the “virtualization support” of TVM, which enables -TVM code to run other TVM code inside a “virtual TVM machine”. Such -virtualization techniques might be useful for implementing sophisticated payment channels in the TON Blockchain (cf. \[1, 5]). - -### 4.1.11. `CALLCC`: call with current continuation. - -Notice that TVM supports a form of the “call with current continuation” primitive. Namely, primitive `CALLCC` is similar to `CALLX` or `JMPX` in that it takes a continuation `c` from -the stack and switches to it; however, `CALLCC` does not discard the previous -current continuation `c0` -(as `JMPX` does) and does not write `c0` -to `c0` (as `CALLX` -does), but rather pushes `c0` -into the (new) stack as an extra argument to `c`. -The primitive `JMPXDATA` does a similar thing, but pushes only the (remainder -of the) code of the previous current continuation as a `Slice`. - -## 4.2 Control flow primitives: conditional and iterated - -execution - -### 4.2.1. Conditional execution: `IF`, `IFNOT`, `IFELSE`. - -An important modification of `EXECUTE` (or `CALLX`) consists in its conditional forms. For example, -`IF` accepts an integer `x` and a continuation `c`, and executes `c` (in the same -way as `EXECUTE` would do it) only if `x` is non-zero; otherwise both values -are simply discarded from the stack. Similarly, `IFNOT` accepts `x` and `c`, but -executes `c` only if `x = 0`. Finally, `IFELSE` accepts `x`, `c`, and `c0`, removes these -values from the stack, and executes `c` if `x 6= 0` or `c0` if `x = 0`. - -### 4.2.2. Iterated execution and loops. - -More sophisticated modifications -of `EXECUTE` include: -• `REPEAT` — Takes an integer `n` and a continuation `c`, and executes `c` `n` -times.23 -• `WHILE` — Takes `c0` and `c00`, executes `c0`, and then takes the top value `x` -from the stack. If `x` is non-zero, it executes `c00` and then begins a new -loop by executing `c0` again; if `x` is zero, it stops. -• `UNTIL` — Takes `c`, executes it, and then takes the top integer `x` from -the stack. If `x` is zero, a new iteration begins; if `x` is non-zero, the -previously executed code is resumed. - -### 4.2.3. Constant, or literal, continuations. - -We see that we can create -arbitrarily complex conditional expressions and loops in the TVM code, provided we have a means to push constant continuations into the stack. In fact, -TVM includes special versions of “literal” or “constant” primitives that cut -the next `n` bytes or bits from the remainder of the current code `cc.code` into -a cell slice, and then push it into the stack not as a `Slice` (as a `PUSHSLICE` -does) but as a simple ordinary `Continuation` (which has only `code` and `cp`). -The simplest of these primitives is `PUSHCONT`, which has an immediate -argument `n` describing the number of subsequent bytes (in a byte-oriented -version of TVM) or bits to be converted into a simple continuation. Another -primitive is `PUSHREFCONT`, which removes the first cell reference from the -current continuation `cc.code`, converts the cell referred to into a cell slice, -and finally converts the cell slice into a simple continuation. - -### 4.2.4. Constant continuations combined with conditional or iterated execution primitives. - -Because constant continuations are very often -used as arguments to conditional or iterated execution primitives, combined -versions of these primitives (e.g., `IFCONT` or `UNTILREFCONT`) may be defined -in a future revision of TVM, which combine a `PUSHCONT` or `PUSHREFCONT` -with another primitive. If one inspects the resulting code, `IFCONT` looks very -much like the more customary “conditional-branch-forward” instruction. +Recall (cf. [1.1.3](#113-preliminary-list-of-value-types)) that Continuation values represent “execution tokens” that can be executed later—for example, by `EXECUTE` = `CALLX` (“execute” or “call indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations are responsible for the execution of the program, and are heavily used by control flow primitives, enabling subroutine calls, conditional expressions, loops, and so on. -## 4.3 Operations with continuations +### 4.1.1 Ordinary continuations + +The most common kind of continuations are the ordinary continuations, containing the following data: + +* A Slice `code` (cf. [1.1.3](#113-preliminary-list-of-value-types) and [3.2.2](#322-builder-and-slice-values)), containing (the remainder of) the TVM code to be executed. +* A (possibly empty) Stack `stack`, containing the original contents of the stack for the code to be executed. +* A (possibly empty) list `save` of pairs `(c(i), vi)` (also called “savelist”), containing the values of control registers to be restored before the execution of the code. +* A 16-bit integer value `cp`, selecting the TVM codepage used to interpret the TVM code from `code`. +* An optional non-negative integer `nargs`, indicating the number of arguments expected by the continuation. + +### 4.1.2 Simple ordinary continuations + +In most cases, the ordinary continuations are the simplest ones, having empty `stack` and `save`. They consist essentially of a reference `code` to (the remainder of) the code to be executed, and of the codepage `cp` to be used while decoding the instructions from this code. + +### 4.1.3 Current continuation cc + +The “current continuation” `cc` is an important part of the total state of TVM, representing the code being executed right now (cf. [1.1](#1-1-tvm-is-a-stack-machine)). In particular, what we call “the current stack” (or simply “the stack”) when discussing all other primitives is in fact the stack of the current continuation. All other components of the total state of TVM may be also thought of as parts of the current continuation `cc`; however, they may be extracted from the current continuation and kept separately as part of the total state for performance reasons. This is why we describe the stack, the control registers, and the codepage as separate parts of the TVM state in [1.4](#14-total-state-of-tvm-scccg). + +### 4.1.4 Normal work of TVM, or the main loop + +TVM usually performs the following operations: + +If the current continuation `cc` is an ordinary one, it decodes the first instruction from the Slice `code`, similarly to the way other cells are deserialized by TVM `LD*` primitives (cf. [3.2](#3-2-data-manipulation-instructions-and-cells) and [3.2.11](#3-2-11-taxonomy-of-cell-deserialisation-primitives)): it decodes the opcode first, and then the parameters of the instruction (e.g., 4-bit fields indicating “stack registers” involved for stack manipulation primitives, or constant values for “push constant” or “literal” primitives). The remainder of the Slice is then put into the code of the new `cc`, and the decoded operation is executed on the current stack. This entire process is repeated until there are no operations left in `cc.code`. + +If the code is empty (i.e., contains no bits of data and no references), or if a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, the current continuation is discarded, and the “return continuation” from control register `c0` is loaded into `cc` instead (this process is discussed in more detail starting in [4.1.6](#416-switching-to-another-continuation-jmp-and-ret)).[20](#footnote-20) Then the execution continues by parsing operations from the new current continuation. + +### 4.1.5 Extraordinary continuations + +In addition to the ordinary continuations considered so far (cf. [4.1.1](#4-1-1-ordinary-continuations)), TVM includes some extraordinary continuations, representing certain less common states. Examples of extraordinary continuations include: + +* The continuation `ec_quit` with its parameter set to zero, which represents the end of the work of TVM. This continuation is the original value of `c0` when TVM begins executing the code of a smart contract. +* The continuation `ec_until`, which contains references to two other continuations (ordinary or not) representing the body of the loop being executed and the code to be executed after the loop. + +Execution of an extraordinary continuation by TVM depends on its specific class, and differs from the operations for ordinary continuations described in [4.1.4](#4-1-4-normal-work-of-tvm-or-the-main-loop).[21](#footnote-21) -### 4.3.1. Continuations are opaque. - -Notice that all continuations are opaque, -at least in the current version of TVM, meaning that there is no way to -modify a continuation or inspect its internal data. Almost the only use of a -continuation is to supply it to a control flow primitive. -While there are some arguments in favor of including support for nonopaque continuations in TVM (along with opaque continuations, which are -required for virtualization), the current revision offers no such support. - -### 4.3.2. Allowed operations with continuations. - -However, some operations with opaque continuations are still possible, mostly because they are -equivalent to operations of the kind “create a new continuation, which will -do something special, and then invoke the original continuation”. Allowed -operations with continuations include: -• Push one or several values into the stack of a continuation `c` (thus -creating a partial application of a function, or a closure). -• Set the saved value of a control register `c(i)` inside the savelist `c.save` -of a continuation `c`. If there is already a value for the control register -in question, this operation silently does nothing. - -### 4.3.3. Example: operations with control registers. - -TVM has some -primitives to set and inspect the values of control registers. The most important of them are `PUSH c(i)` (pushes the current value of `c(i)` into the stack) -and `POP c(i)` (sets the value of `c(i)` from the stack, if the supplied value is -of the correct type). However, there is also a modified version of the latter -instruction, called `POPSAVE c(i)`, which saves the old value of `c(i)` (for `i > 0`) -into the continuation at `c0` as described in 4.3.2 before setting the new value. - -### 4.3.4. Example: setting the number of arguments to a function in its code. - -The primitive `LEAVEARGS n` demonstrates another application of -continuations in an operation: it leaves only the top `n` values of the current stack, and moves the remainder to the stack of the continuation in `c0`. -This primitive enables a called function to “return” unneeded arguments to -its caller’s stack, which is useful in some situations (e.g., those related to -exception handling). - -### 4.3.5. Boolean circuits. - -A continuation `c` may be thought of as a piece -of code with two optional exit points kept in the savelist of `c`: the principal -exit point given by `c.c0 := c.save(c0)`, and the auxiliary exit point given -by `c.c1 := c.save(c1)`. If executed, a continuation performs whatever action -it was created for, and then (usually) transfers control to the principal exit -point, or, on some occasions, to the auxiliary exit point. We sometimes say -that a continuation `c` with both exit points `c.c0` and `c.c1` defined is a two-exit -continuation, or a boolean circuit, especially if the choice of the exit point -depends on some internally-checked condition. - -### 4.3.6. Composition of continuations. - -One can compose two continuations `c` and `c0` simply by setting `c.c0` or `c.c1` to `c0`. This creates a new -continuation denoted by `c ◦0 c0` or `c ◦1 c0`, which differs from `c` in its savelist. -(Recall that if the savelist of `c` already has an entry corresponding to the control register in question, such an operation silently does nothing as explained -in 4.3.2). -By composing continuations, one can build chains or other graphs, possibly with loops, representing the control flow. In fact, the resulting graph -resembles a flow chart, with the boolean circuits corresponding to the “condition nodes” (containing code that will transfer control either to `c0` or to `c1` -depending on some condition), and the one-exit continuations corresponding -to the “action nodes”. - -### 4.3.7. Basic continuation composition primitives. - -Two basic primitives for composing continuations are `COMPOS` (also known as `SETCONT c0` and -`BOOLAND`) and `COMPOSALT` (also known as `SETCONT c1` and `BOOLOR`), which -take `c` and `c0` from the stack, set `c.c0` or `c.c1` to `c0`, and return the resulting continuation `c00 = c ◦0 c0` or `c ◦1 c0`. All other continuation composition -operations can be expressed in terms of these two primitives. +### 4.1.6 Switching to another continuation: JMP and RET + +The process of switching to another continuation `c` may be performed by such instructions as `JMPX` (which takes `c` from the stack) or `RET` (which uses `c0` as `c`). This process is slightly more complex than simply setting the value of `cc` to `c`: before doing this, either all values or the top `n` values in the current stack are moved to the stack of the continuation `c`, and only then is the remainder of the current stack discarded. + +If all values need to be moved (the most common case), and if the continuation `c` has an empty stack (also the most common case; notice that extraordinary continuations are assumed to have an empty stack), then the new stack of `c` equals the stack of the current continuation, so we can simply transfer the current stack in its entirety to `c`. (If we keep the current stack as a separate part of the total state of TVM, we have to do nothing at all.) + +### 4.1.7 Determining the number n of arguments passed to the next continuation c + +By default, `n` equals the depth of the current stack. However, if `c` has an explicit value of `nargs` (number of arguments to be provided), then `n` is computed as `n'`, equal to `c.nargs` minus the current depth of `c`’s stack. + +Furthermore, there are special forms of `JMPX` and `RET` that provide an explicit value `n''`, the number of parameters from the current stack to be passed to continuation `c`. If `n''` is provided, it must be less than or equal to the depth of the current stack, or else a stack underflow exception occurs. If both `n'` and `n''` are provided, we must have `n' ≤ n''`, in which case `n = n'` is used. If `n''` is provided and `n'` is not, then `n = n''` is used. + +One could also imagine that the default value of `n''` equals the depth of the original stack, and that `n''` values are always removed from the top of the original stack even if only `n'` of them are actually moved to the stack of the next continuation `c`. Even though the remainder of the current stack is discarded afterwards, this description will become useful later. + +### 4.1.8 Restoring control registers from the new continuation c + +After the new stack is computed, the values of control registers present in `c.save` are restored accordingly, and the current codepage `cp` is also set to `c.cp`. Only then does TVM set `cc` equal to the new `c` and begin its execution.[22](#footnote-22) + +### 4.1.9 Subroutine calls: CALLX or EXECUTE primitives + +The execution of continuations as subroutines is slightly more complicated than switching to continuations. + +Consider the `CALLX` or `EXECUTE` primitive, which takes a continuation `c` from the (current) stack and executes it as a subroutine. + +Apart from doing the stack manipulations described in [4.1.6](#4-1-6-switching-to-another-continuation-jmp-and-ret) and [4.1.7](#417-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c) and setting the new control registers and codepage as described in [4.1.8](#4-1-8-restoring-control-registers-from-the-new-continuation-c), these primitives perform several additional steps: + +1. After the top `n''` values are removed from the current stack (cf. [4.1.7](#4-1-7-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c)), the (usually empty) remainder is not discarded, but instead is stored in the (old) current continuation `cc`. +2. The old value of the special register `c0` is saved into the (previously empty) savelist `cc.save`. +3. The continuation `cc` thus modified is not discarded, but instead is set as the new `c0`, which performs the role of “next continuation” or “return continuation” for the subroutine being called. +4. After that, the switching to `c` continues as before. In particular, some control registers are restored from `c.save`, potentially overwriting the value of `c0` set in the previous step. (Therefore, a good optimization would be to check that `c0` is present in `c.save` from the very beginning, and skip the three previous steps as useless in this case.) + +In this way, the called subroutine can return control to the caller by switching the current continuation to the return continuation saved in `c0`. Nested subroutine calls work correctly because the previous value of `c0` ends up saved into the new `c0`’s control register savelist `c0.save`, from which it is restored later. + +### 4.1.10 Determining the number of arguments passed to and/or return values accepted from a subroutine + +Similarly to `JMPX` and `RET`, `CALLX` also has special (rarely used) forms, which allow us to explicitly specify the number `n''` of arguments passed from the current stack to the called subroutine (by default, `n''` equals the depth of the current stack, i.e., it is passed in its entirety). Furthermore, a second number `n'''` can be specified, used to set `nargs` of the modified `cc` continuation before storing it into the new `c0`; the new `nargs` equals the depth of the old stack minus `n''` plus `n'''`. + +This means that the caller is willing to pass exactly `n''` arguments to the called subroutine, and is willing to accept exactly `n'''` results in their stead. + +Such forms of `CALLX` and `RET` are mostly intended for library functions that accept functional arguments and want to invoke them safely. Another application is related to the “virtualization support” of TVM, which enables TVM code to run other TVM code inside a “virtual TVM machine”. Such virtualization techniques might be useful for implementing sophisticated payment channels in the TON Blockchain (cf. [1, 5](#reference-1)). + +### 4.1.11 CALLCC: call with current continuation + +Notice that TVM supports a form of the “call with current continuation” primitive. Namely, primitive `CALLCC` is similar to `CALLX` or `JMPX` in that it takes a continuation `c` from the stack and switches to it; however, `CALLCC` does not discard the previous current continuation `c'` (as `JMPX` does) and does not write `c'` to `c0` (as `CALLX` does), but rather pushes `c'` into the (new) stack as an extra argument to `c`. + +The primitive `JMPXDATA` does a similar thing, but pushes only the (remainder of the) code of the previous current continuation as a Slice. --- -### 4.3.8. Advanced continuation composition primitives. +## 4.2 Control flow primitives: conditional and iterated execution + +### 4.2.1 Conditional execution: IF, IFNOT, IFELSE + +An important modification of `EXECUTE` (or `CALLX`) consists in its conditional forms. For example, `IF` accepts an integer `x` and a continuation `c`, and executes `c` (in the same way as `EXECUTE` would do it) only if `x` is non-zero; otherwise both values are simply discarded from the stack. Similarly, `IFNOT` accepts `x` and `c`, but executes `c` only if `x = 0`. Finally, `IFELSE` accepts `x`, `c`, and `c'`, removes these values from the stack, and executes `c` if `x ≠ 0` or `c'` if `x = 0`. + +### 4.2.2 Iterated execution and loops + +More sophisticated modifications of `EXECUTE` include: + +* **REPEAT** — Takes an integer `n` and a continuation `c`, and executes `c` `n` times.[23](#footnote-23) +* **WHILE** — Takes `c'` and `c''`, executes `c'`, and then takes the top value `x` from the stack. If `x` is non-zero, it executes `c''` and then begins a new loop by executing `c'` again; if `x` is zero, it stops. +* **UNTIL** — Takes `c`, executes it, and then takes the top integer `x` from the stack. If `x` is zero, a new iteration begins; if `x` is non-zero, the previously executed code is resumed. + +### 4.2.3 Constant, or literal, continuations + +We see that we can create arbitrarily complex conditional expressions and loops in the TVM code, provided we have a means to push constant continuations into the stack. In fact, TVM includes special versions of “literal” or “constant” primitives that cut the next `n` bytes or bits from the remainder of the current code `cc.code` into a cell slice, and then push it into the stack not as a Slice (as a `PUSHSLICE` does) but as a simple ordinary Continuation (which has only `code` and `cp`). + +The simplest of these primitives is `PUSHCONT`, which has an immediate argument `n` describing the number of subsequent bytes (in a byte-oriented version of TVM) or bits to be converted into a simple continuation. Another primitive is `PUSHREFCONT`, which removes the first cell reference from the current continuation `cc.code`, converts the cell referred to into a cell slice, and finally converts the cell slice into a simple continuation. + +### 4.2.4 Constant continuations combined with conditional or iterated execution primitives + +Because constant continuations are very often used as arguments to conditional or iterated execution primitives, combined versions of these primitives (e.g., `IFCONT` or `UNTILREFCONT`) may be defined in a future revision of TVM, which combine a `PUSHCONT` or `PUSHREFCONT` with another primitive. If one inspects the resulting code, `IFCONT` looks very much like the more customary “conditional-branch-forward” instruction. + +--- + +# 4 Control flow, continuations, and exceptions + +## 4.3 Operations with continuations + +### 4.3.1 Continuations are opaque + +Notice that all continuations are opaque, at least in the current version of TVM, meaning that there is no way to modify a continuation or inspect its internal data. Almost the only use of a continuation is to supply it to a control flow primitive. + +While there are some arguments in favor of including support for non-opaque continuations in TVM (along with opaque continuations, which are required for virtualization), the current revision offers no such support. + +### 4.3.2 Allowed operations with continuations + +However, some operations with opaque continuations are still possible, mostly because they are equivalent to operations of the kind “create a new continuation, which will do something special, and then invoke the original continuation”. Allowed operations with continuations include: + +* Push one or several values into the stack of a continuation `c` (thus creating a partial application of a function, or a closure). +* Set the saved value of a control register `c(i)` inside the savelist `c.save` of a continuation `c`. If there is already a value for the control register in question, this operation silently does nothing. + +### 4.3.3 Example: operations with control registers + +TVM has some primitives to set and inspect the values of control registers. The most important of them are `PUSH c(i)` (pushes the current value of `c(i)` into the stack) and `POP c(i)` (sets the value of `c(i)` from the stack, if the supplied value is of the correct type). However, there is also a modified version of the latter instruction, called `POPSAVE c(i)`, which saves the old value of `c(i)` (for i > 0) into the continuation at `c0` as described in [4.3.2](#4-3-2-allowed-operations-with-continuations) before setting the new value. + +### 4.3.4 Example: setting the number of arguments to a function in its code + +The primitive `LEAVEARGS n` demonstrates another application of continuations in an operation: it leaves only the top `n` values of the current stack, and moves the remainder to the stack of the continuation in `c0`. + +This primitive enables a called function to “return” unneeded arguments to its caller’s stack, which is useful in some situations (e.g., those related to exception handling). + +### 4.3.5 Boolean circuits + +A continuation `c` may be thought of as a piece of code with two optional exit points kept in the savelist of `c`: + +* the principal exit point given by `c.c0 := c.save(c0)` +* the auxiliary exit point given by `c.c1 := c.save(c1)` + +If executed, a continuation performs whatever action it was created for, and then (usually) transfers control to the principal exit point, or, on some occasions, to the auxiliary exit point. + +We sometimes say that a continuation `c` with both exit points `c.c0` and `c.c1` defined is a two-exit continuation, or a boolean circuit, especially if the choice of the exit point depends on some internally-checked condition. + +### 4.3.6 Composition of continuations + +One can compose two continuations `c` and `c'` simply by setting `c.c0` or `c.c1` to `c'`. This creates a new continuation denoted by `c ◦0 c'` or `c ◦1 c'`, which differs from `c` in its savelist. (Recall that if the savelist of `c` already has an entry corresponding to the control register in question, such an operation silently does nothing as explained in [4.3.2](#4-3-2-allowed-operations-with-continuations)). + +By composing continuations, one can build chains or other graphs, possibly with loops, representing the control flow. In fact, the resulting graph resembles a flow chart, with the boolean circuits corresponding to the “condition nodes” (containing code that will transfer control either to `c0` or to `c1` depending on some condition), and the one-exit continuations corresponding to the “action nodes”. + +### 4.3.7 Basic continuation composition primitives + +Two basic primitives for composing continuations are `COMPOS` (also known as `SETCONT c0` and `BOOLAND`) and `COMPOSALT` (also known as `SETCONT c1` and `BOOLOR`), which take `c` and `c'` from the stack, set `c.c0` or `c.c1` to `c'`, and return the resulting continuation `c'' = c ◦0 c'` or `c ◦1 c'`. All other continuation composition operations can be expressed in terms of these two primitives. + +### 4.3.8 Advanced continuation composition primitives However, TVM can compose continuations not only taken from stack, but also taken from `c0` or `c1`, or from the current continuation `cc`; likewise, the result may be pushed into the stack, stored into either `c0` or `c1`, or used as the new current continuation (i.e., the control may be transferred to it). Furthermore, TVM can define conditional composition primitives, performing some of the above actions only if an integer value taken from the stack is non-zero. -For instance, `EXECUTE` can be described as `cc ← c ◦0 cc`, with continuation `c` taken from the original stack. Similarly, `JMPX` is `cc ← c`, and `RET` (also known as `RETTRUE` in a boolean circuit context) is `cc ← c0`. Other interesting primitives include `THENRET` (`c0 ← c ◦0 c0`) and `ATEXIT` (`c0 ← c ◦0 c0`). +For instance: -Finally, some “experimental” primitives also involve `c1` and `◦1`. For example: +* `EXECUTE` can be described as `cc ← c ◦0 cc`, with continuation `c` taken from the original stack. +* `JMPX` is `cc ← c`. +* `RET` (also known as `RETTRUE` in a boolean circuit context) is `cc ← c0`. +* Other interesting primitives include `THENRET (c0 ← c ◦0 c0)` and `ATEXIT (c0 ← c ◦0 c0)`. + +Some “experimental” primitives also involve `c1` and `◦1`. For example: * `RETALT` or `RETFALSE` does `cc ← c1`. -* Conditional versions of `RET` and `RETALT` may also be useful: `RETBOOL` takes an integer `x` from the stack, and performs `RETTRUE` if `x 6= 0`, `RETFALSE` otherwise. +* Conditional versions of `RET` and `RETALT` may also be useful: `RETBOOL` takes an integer `x` from the stack, and performs `RETTRUE` if `x ≠ 0`, `RETFALSE` otherwise. * `INVERT` does `c0 ↔ c1`; if the two continuations in `c0` and `c1` represent the two branches we should select depending on some boolean expression, `INVERT` negates this expression on the outer level. * `INVERTCONT` does `c.c0 ↔ c.c1` to a continuation `c` taken from the stack. -* Variants of `ATEXIT` include `ATEXITALT` (`c1 ← c ◦1 c1`) and `SETEXITALT` (`c1 ← (c ◦0 c0) ◦1 c1`). +* Variants of `ATEXIT` include `ATEXITALT (c1 ← c ◦1 c1)` and `SETEXITALT (c1 ← (c ◦0 c0) ◦1 c1)`. * `BOOLEVAL` takes a continuation `c` from the stack and does: ``` - cc ← ((c ◦0 (PUSH − 1)) ◦1 (PUSH0)) ◦0 cc + cc ← (c ◦0 (PUSH −1)) ◦1 (PUSH0) ◦0 cc ``` If `c` represents a boolean circuit, the net effect is to evaluate it and push either `−1` or `0` into the stack before continuing. @@ -1947,175 +1127,97 @@ Finally, some “experimental” primitives also involve `c1` and `◦1`. For ex ## 4.4 Continuations as objects -### 4.4.1. Representing objects using continuations. - -Object-oriented programming in Smalltalk (or Objective C) style may be implemented with the -aid of continuations. For this, an object is represented by a special continuation `o`. If it has any data fields, they can be kept in the stack of `o`, making -`o` a partial application (i.e., a continuation with a non-empty stack). -When somebody wants to invoke a method `m` of `o` with arguments `x1, x2, -. . . , xn`, she pushes the arguments into the stack, then pushes a magic number -corresponding to the method `m`, and then executes `o` passing `n+1` arguments -(cf. 4.1.10). Then `o` uses the top-of-stack integer `m` to select the branch with -5 - -### 4.5. Exception handling - -the required method, and executes it. If `o` needs to modify its state, it simply -computes a new continuation `o0` of the same sort (perhaps with the same code -as `o`, but with a different initial stack). The new continuation `o0` -is returned -to the caller along with whatever other return values need to be returned. - -### 4.4.2. Serializable objects. - -Another way of representing Smalltalk-style -objects as continuations, or even as trees of cells, consists in using the -`JMPREFDATA` primitive (a variant of `JMPXDATA`, cf. 4.1.11), which takes the -first cell reference from the code of the current continuation, transforms the -cell referred to into a simple ordinary continuation, and transfers control to -it, first pushing the remainder of the current continuation as a `Slice` into the -stack. In this way, an object might be represented by a cell `o˜` that contains -`JMPREFDATA` at the beginning of its data, and the actual code of the object -in the first reference (one might say that the first reference of cell `o˜` is the -class of object `o˜`). Remaining data and references of this cell will be used for -storing the fields of the object. -Such objects have the advantage of being trees of cells, and not just -continuations, meaning that they can be stored into the persistent storage of -a TON smart contract. - -### 4.4.3. Unique continuations and capabilities. - -It might make sense (in -a future revision of TVM) to mark some continuations as unique, meaning -that they cannot be copied, even in a delayed manner, by increasing their -reference counter to a value greater than one. If an opaque continuation is -unique, it essentially becomes a capability, which can either be used by its -owner exactly once or be transferred to somebody else. -For example, imagine a continuation that represents the output stream to -a printer (this is an example of a continuation used as an object, cf. 4.4.1). -When invoked with one integer argument `n`, this continuation outputs the -character with code `n` to the printer, and returns a new continuation of -the same kind reflecting the new state of the stream. Obviously, copying -such a continuation and using the two copies in parallel would lead to some -unintended side effects; marking it as unique would prohibit such adverse -usage. - -## 4.5 Exception handling - -TVM’s exception handling is quite simple and consists in a transfer of control -to the continuation kept in control register `c2`. - -### 4.5.1. Two arguments of the exception handler: exception parameter and exception number. - -Every exception is characterized by two -arguments: the exception number (an `Integer`) and the exception parameter -(any value, most often a zero `Integer`). Exception numbers 0–31 are reserved -for TVM, while all other exception numbers are available for user-defined -exceptions. - -### 4.5.2. Primitives for throwing an exception. - -There are several special primitives used for throwing an exception. The most general of them, -`THROWANY`, takes two arguments, `v` and `0 ≤ n < 2^16`, from the stack, and -throws the exception with number `n` and value `v`. There are variants of -this primitive that assume `v` to be a zero integer, store `n` as a literal value, -and/or are conditional on an integer value taken from the stack. User-defined -exceptions may use arbitrary values as `v` (e.g., trees of cells) if needed. - -### 4.5.3. Exceptions generated by TVM. - -Of course, some exceptions are -generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit -into a signed 257-bit integer. In such cases, the arguments of the exception, -`v` and `n`, are determined by TVM itself. - -### 4.5.4. Exception handling. - -The exception handling itself consists in a -control transfer to the exception handler—i.e., the continuation specified in -control register `c2`, with `v` and `n` supplied as the two arguments to this -continuation, as if a `JMP` to `c2` had been requested with `n00 = 2` arguments -(cf. 4.1.7 and 4.1.6). As a consequence, `v` and `n` end up in the top of the -stack of the exception handler. The remainder of the old stack is discarded. -Notice that if the continuation in `c2` has a value for `c2` in its savelist, it -will be used to set up the new value of `c2` before executing the exception -handler. In particular, if the exception handler invokes `THROWANY`, it will rethrow the original exception with the restored value of `c2`. This trick enables -the exception handler to handle only some exceptions, and pass the rest to -an outer exception handler. - -### 4.5.5. Default exception handler. - -When an instance of TVM is created, -`c2` contains a reference to the “default exception handler continuation”, which -is an `ec_fatal` extraordinary continuation (cf. 4.1.5). Its execution leads -to the termination of the execution of TVM, with the arguments `v` and `n` -of the exception returned to the outside caller. In the context of the TON -Blockchain, `n` will be stored as a part of the transaction’s result. -59 - -### 4.5.6. `TRY` primitive. - -A `TRY` primitive can be used to implement C++-like -exception handling. This primitive accepts two continuations, `c` and `c0`. It -stores the old value of `c2` into the savelist of `c0`, sets `c2` to `c0`, and executes `c` -just as `EXECUTE` would, but additionally saving the old value of `c2` into the -savelist of the new `c0` as well. Usually a version of the `TRY` primitive with an -explicit number of arguments `n00` passed to the continuation `c` is used. -The net result is roughly equivalent to C++’s `try { c } catch(...) { c0 }` operator. +### 4.4.1 Representing objects using continuations -### 4.5.7. List of predefined exceptions +Object-oriented programming in Smalltalk (or Objective C) style may be implemented with the aid of continuations. For this, an object is represented by a special continuation `o`. If it has any data fields, they can be kept in the stack of `o`, making `o` a partial application (i.e., a continuation with a non-empty stack). -Predefined exceptions of TVM correspond to exception numbers `n` in the range `0–31`. They include: +When somebody wants to invoke a method `m` of `o` with arguments `x1, x2, …, xn`, she pushes the arguments into the stack, then pushes a magic number corresponding to the method `m`, and then executes `o` passing `n+1` arguments (cf. [4.1.10](#4-1-10-determining-the-number-of-arguments-passed-to-andor-return-values-accepted-from-a-subroutine)). Then `o` uses the top-of-stack integer `m` to select the branch with the required method, and executes it. -* **Normal termination (`n = 0`)** — Should never be generated, but it is useful for some tricks. -* **Alternative termination (`n = 1`)** — Again, should never be generated. -* **Stack underflow (`n = 2`)** — Not enough arguments in the stack for a primitive. -* **Stack overflow (`n = 3`)** — More values have been stored on a stack than allowed by this version of TVM. -* **Integer overflow (`n = 4`)** — Integer does not fit into `−2^256 ≤ x < 2^256`, or a division by zero has occurred. -* **Range check error (`n = 5`)** — Integer out of expected range. -* **Invalid opcode (`n = 6`)** — Instruction or its immediate arguments cannot be decoded. -* **Type check error (`n = 7`)** — An argument to a primitive is of incorrect value type. -* **Cell overflow (`n = 8`)** — Error in one of the serialization primitives. -* **Cell underflow (`n = 9`)** — Deserialization error. -* **Dictionary error (`n = 10`)** — Error while deserializing a dictionary object. -* **Unknown error (`n = 11`)** — Unknown error, may be thrown by user programs. -* **Fatal error (`n = 12`)** — Thrown by TVM in situations deemed impossible. -* **Out of gas (`n = 13`)** — Thrown by TVM when the remaining gas (`gr`) becomes negative. This exception usually cannot be caught and leads to an immediate termination of TVM. +If `o` needs to modify its state, it simply computes a new continuation `o'` of the same sort (perhaps with the same code as `o`, but with a different initial stack). The new continuation `o'` is returned to the caller along with whatever other return values need to be returned. -Most of these exceptions have no parameter (i.e., use a zero integer instead). -The order in which these exceptions are checked is outlined below in **4.5.8**. +### 4.4.2 Serializable objects ---- +Another way of representing Smalltalk-style objects as continuations, or even as trees of cells, consists in using the `JMPREFDATA` primitive (a variant of `JMPXDATA`, cf. [4.1.11](#4-1-11-callcc-call-with-current-continuation)), which takes the first cell reference from the code of the current continuation, transforms the cell referred to into a simple ordinary continuation, and transfers control to it, first pushing the remainder of the current continuation as a Slice into the stack. -### 4.5.8. Order of stack underflow, type check, and range check exceptions. - -All TVM primitives first check whether the stack contains the -required number of arguments, generating a stack underflow exception if this -is not the case. Only then are the type tags of the arguments and their ranges -(e.g., if a primitive expects an argument not only to be an `Integer`, but also -to be in the range from 0 to 256) checked, starting from the value in the top -of the stack (the last argument) and proceeding deeper into the stack. If an -argument’s type is incorrect, a type-checking exception is generated; if the -type is correct, but the value does not fall into the expected range, a range -check exception is generated. -Some primitives accept a variable number of arguments, depending on the -values of some small fixed subset of arguments located near the top of the -stack. In this case, the above procedure is first run for all arguments from -this small subset. Then it is repeated for the remaining arguments, once -their number and types have been determined from the arguments already -processed. +In this way, an object might be represented by a cell `o~` that contains `JMPREFDATA` at the beginning of its data, and the actual code of the object in the first reference (one might say that the first reference of cell `o~` is the class of object `o~`). Remaining data and references of this cell will be used for storing the fields of the object. +Such objects have the advantage of being trees of cells, and not just continuations, meaning that they can be stored into the persistent storage of a TON smart contract. + +### 4.4.3 Unique continuations and capabilities + +It might make sense (in a future revision of TVM) to mark some continuations as unique, meaning that they cannot be copied, even in a delayed manner, by increasing their reference counter to a value greater than one. If an opaque continuation is unique, it essentially becomes a capability, which can either be used by its owner exactly once or be transferred to somebody else. + +For example, imagine a continuation that represents the output stream to a printer (this is an example of a continuation used as an object, cf. [4.4.1](#4-4-1-representing-objects-using-continuations)). When invoked with one integer argument `n`, this continuation outputs the character with code `n` to the printer, and returns a new continuation of the same kind reflecting the new state of the stream. Obviously, copying such a continuation and using the two copies in parallel would lead to some unintended side effects; marking it as unique would prohibit such adverse usage. --- -# 4.6 Functions, recursion, and dictionaries +# 4.5 Exception handling + +TVM’s exception handling is quite simple and consists in a transfer of control to the continuation kept in control register c2. + +## 4.5.1. Two arguments of the exception handler: exception parameter and exception number + +Every exception is characterized by two arguments: the exception number (an Integer) and the exception parameter (any value, most often a zero Integer). Exception numbers 0–31 are reserved for TVM, while all other exception numbers are available for user-defined exceptions. + +## 4.5.2. Primitives for throwing an exception + +There are several special primitives used for throwing an exception. The most general of them, THROWANY, takes two arguments, v and 0 ≤ n < 2^16, from the stack, and throws the exception with number n and value v. There are variants of this primitive that assume v to be a zero integer, store n as a literal value, and/or are conditional on an integer value taken from the stack. User-defined exceptions may use arbitrary values as v (e.g., trees of cells) if needed. + +## 4.5.3. Exceptions generated by TVM + +Of course, some exceptions are generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit into a signed 257-bit integer. In such cases, the arguments of the exception, v and n, are determined by TVM itself. + +## 4.5.4. Exception handling + +The exception handling itself consists in a control transfer to the exception handler—i.e., the continuation specified in control register c2, with v and n supplied as the two arguments to this continuation, as if a JMP to c2 had been requested with n00 = 2 arguments (cf. [4.1.7](#4-1-7-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c) and [4.1.6](#4-1-6-switching-to-another-continuation-jmp-and-ret)). As a consequence, v and n end up in the top of the stack of the exception handler. The remainder of the old stack is discarded. + +Notice that if the continuation in c2 has a value for c2 in its savelist, it will be used to set up the new value of c2 before executing the exception handler. In particular, if the exception handler invokes THROWANY, it will rethrow the original exception with the restored value of c2. This trick enables the exception handler to handle only some exceptions, and pass the rest to an outer exception handler. + +## 4.5.5. Default exception handler + +When an instance of TVM is created, c2 contains a reference to the “default exception handler continuation”, which is an ec_fatal extraordinary continuation (cf. [4.1.5](#4-1-5-extraordinary-continuations)). Its execution leads to the termination of the execution of TVM, with the arguments v and n of the exception returned to the outside caller. In the context of the TON Blockchain, n will be stored as a part of the transaction’s result. + +## 4.5.6. TRY primitive + +A TRY primitive can be used to implement C++-like exception handling. This primitive accepts two continuations, c and c0. It stores the old value of c2 into the savelist of c0, sets c2 to c0, and executes c just as EXECUTE would, but additionally saving the old value of c2 into the savelist of the new c0 as well. Usually a version of the TRY primitive with an explicit number of arguments n00 passed to the continuation c is used. + +The net result is roughly equivalent to C++’s `try { c } catch(...) { c0 }` operator. -### 4.6.1. The problem of recursion. +## 4.5.7. List of predefined exceptions -The conditional and iterated execution primitives described in 4.2—along with the unconditional branch, call, and return primitives described in 4.1— enable one to implement more or less arbitrary code with nested loops and conditional expressions, with one notable exception: one can only create new constant continuations from parts of the current continuation. (In particular, one cannot invoke a subroutine from itself in this way.) Therefore, the code being executed—i.e., the current continuation—gradually becomes smaller and smaller. +Predefined exceptions of TVM correspond to exception numbers n in the range 0–31. They include: -### 4.6.2. Y -combinator solution: pass a continuation as an argument to itself. +- **Normal termination (n = 0)** — Should never be generated, but it is useful for some tricks. +- **Alternative termination (n = 1)** — Again, should never be generated. +- **Stack underflow (n = 2)** — Not enough arguments in the stack for a primitive. +- **Stack overflow (n = 3)** — More values have been stored on a stack than allowed by this version of TVM. +- **Integer overflow (n = 4)** — Integer does not fit into −2^256 ≤ x < 2^256, or a division by zero has occurred. +- **Range check error (n = 5)** — Integer out of expected range. +- **Invalid opcode (n = 6)** — Instruction or its immediate arguments cannot be decoded. +- **Type check error (n = 7)** — An argument to a primitive is of incorrect value type. +- **Cell overflow (n = 8)** — Error in one of the serialization primitives. +- **Cell underflow (n = 9)** — Deserialization error. +- **Dictionary error (n = 10)** — Error while deserializing a dictionary object. +- **Unknown error (n = 11)** — Unknown error, may be thrown by user programs. +- **Fatal error (n = 12)** — Thrown by TVM in situations deemed impossible. +- **Out of gas (n = 13)** — Thrown by TVM when the remaining gas (gr) becomes negative. This exception usually cannot be caught and leads to an immediate termination of TVM. +Most of these exceptions have no parameter (i.e., use a zero integer instead). The order in which these exceptions are checked is outlined below in 4.5.8. + +## 4.5.8. Order of stack underflow, type check, and range check exceptions + +All TVM primitives first check whether the stack contains the required number of arguments, generating a stack underflow exception if this is not the case. Only then are the type tags of the arguments and their ranges (e.g., if a primitive expects an argument not only to be an Integer, but also to be in the range from 0 to 256) checked, starting from the value in the top of the stack (the last argument) and proceeding deeper into the stack. If an argument’s type is incorrect, a type-checking exception is generated; if the type is correct, but the value does not fall into the expected range, a range check exception is generated. + +Some primitives accept a variable number of arguments, depending on the values of some small fixed subset of argument + +--- + +# 4.6 Functions, recursion, and dictionaries + +## 4.6.1 The problem of recursion +The conditional and iterated execution primitives described in [4.2](#4-2-control-flow-primitives-conditional-and-iterated-execution)—along with the unconditional branch, call, and return primitives described in [4.1](#4-1-continuations-and-subroutines)—enable one to implement more or less arbitrary code with nested loops and conditional expressions, with one notable exception: one can only create new constant continuations from parts of the current continuation. (In particular, one cannot invoke a subroutine from itself in this way.) Therefore, the code being executed—i.e., the current continuation—gradually becomes smaller and smaller.[24](#footnote-24) + +## 4.6.2 Y-combinator solution: pass a continuation as an argument to itself One way of dealing with the problem of recursion is by passing a copy of the continuation representing the body of a recursive function as an extra argument to itself. Consider, for example, the following code for a factorial function: ``` @@ -2140,17 +1242,17 @@ D8 EXECUTE 31 NIP ``` -This roughly corresponds to defining an auxiliary function body with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, n·x, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. +This roughly corresponds to defining an auxiliary function `body` with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, n·x, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. -### 4.6.3. A variant of Y -combinator solution. +## 4.6.3 A variant of Y-combinator solution +Another way of recursively computing the factorial, more closely following the classical recursive definition: -Another way of recursively computing the factorial, more closely following the classical recursive definition - -``` -fact(n) := ( -1 if n < 2, -n · fact(n − 1) otherwise -) +```math +\text{fact}(n) := +\begin{cases} +1 & \text{if } n < 2, \\ +n \cdot \text{fact}(n - 1) & \text{otherwise} +\end{cases} ``` is as follows: @@ -2177,7 +1279,7 @@ D9 JMPX This definition of the factorial function is two bytes shorter than the previous one, but it uses general recursion instead of tail recursion, so it cannot be easily transformed into a loop. -### 4.6.4. Comparison: non-recursive definition of the factorial function. +## 4.6.4 Comparison: non-recursive definition of the factorial function Incidentally, a non-recursive definition of the factorial with the aid of a `REPEAT` loop is also possible, and it is much shorter than both recursive definitions: @@ -2195,442 +1297,180 @@ E4 REPEAT 30 DROP ``` -### 4.6.5. Several mutually recursive functions. +## 4.6.5 Several mutually recursive functions -If one has a collection `f1, . . . , fn` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fi}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. +If one has a collection `f1, …, fn` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fi}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. -### 4.6.6. Combining several functions into one tuple. +## 4.6.6 Combining several functions into one tuple -One might also combine a collection of continuations representing functions `f1, . . . , fn` into a “tuple” `f := (f1, . . . , fn)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fi`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. +One might also combine a collection of continuations representing functions `f1, …, fn` into a “tuple” `f := (f1, …, fn)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fi`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. -### 4.6.7. Combining several functions into a selector function. +## 4.6.7 Combining several functions into a selector function -Another approach is to combine several functions `f1, . . . , fn` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fi` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. +Another approach is to combine several functions `f1, …, fn` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fi` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. -### 4.6.8. Using a dedicated register to keep the selector function. +## 4.6.8 Using a dedicated register to keep the selector function However, even if we use one of the two previous approaches to combine all functions into one extra argument, passing this argument to all mutually recursive functions is still quite cumbersome and requires a lot of additional stack manipulation operations. Because this argument changes very rarely, one might use a dedicated register to keep it and transparently pass it to all functions called. This is the approach used by TVM by default. -### 4.6.9. Special register c3 for the selector function. +## 4.6.9 Special register c3 for the selector function -In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. A.8.7) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. +In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. [A.8.7](#a-8-7)) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). -In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). - -### 4.6.10. Initialization of c3. +## 4.6.10 Initialization of c3 A TVM program might initialize `c3` by means of a `POP c3` instruction. However, because this usually is the very first action undertaken by a program (e.g., a smart contract), TVM makes some provisions for the automatic initialization of `c3`. Namely, `c3` is initialized by the code (the initial value of `cc`) of the program itself, and an extra zero (or, in some cases, some other predefined number `s`) is pushed into the stack before the program’s execution. This is approximately equivalent to invoking `JMPDICT 0` (or `JMPDICT s`) at the very beginning of a program—i.e., the function with index zero is effectively the `main()` function for the program. -### 4.6.11. Creating selector functions and switch statements. - -TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. A.8.2). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. - -Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. A.7.2). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. +## 4.6.11 Creating selector functions and switch statements -### 4.6.12. Alternative: using a hashmap to select the correct function. +TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. [A.8.2](#a-8-2)). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. -Yet another alternative is to use a `Hashmap` (cf. 3.3) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. A.10) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. A.8.5) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. A.10.11). This approach may be more efficient for larger programs and switch statements. +Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. [A.7.2](#a-7-2)). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. +## 4.6.12 Alternative: using a hashmap to select the correct function -Got it ✅ — here’s **Chapter 5: Codepages and instruction encoding** converted cleanly into Markdown. -I kept the **text exactly as-is** (no paraphrasing), just formatted with proper Markdown: headings, subheadings, inline backticks for mnemonics/opcodes, and bullet lists where appropriate. +Yet another alternative is to use a Hashmap (cf. [3.3](#3-3-hashmaps-or-dictionaries)) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. [A.10](#a-10-dictionary-manipulation-primitives)) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. [A.8.5](#a-8-5)) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. [A.10.11](#a-10-11)). --- # 5 Codepages and instruction encoding -This chapter describes the codepage mechanism, which allows TVM to be -flexible and extendable while preserving backward compatibility with respect -to previously generated code. -We also discuss some general considerations about instruction encodings -(applicable to arbitrary machine code, not just TVM), as well as the implications of these considerations for TVM and the choices made while designing -TVM’s (experimental) codepage zero. The instruction encodings themselves -are presented later in Appendix A. +This chapter describes the codepage mechanism, which allows TVM to be flexible and extendable while preserving backward compatibility with respect to previously generated code. -## 5.1 Codepages and interoperability of different TVM versions - -The codepages are an essential mechanism of backward compatibility and -of future extensions to TVM. They enable transparent execution of code -written for different revisions of TVM, with transparent interaction between -instances of such code. The mechanism of the codepages, however, is general -and powerful enough to enable some other originally unintended applications. - -### 5.1.1. Codepages in continuations - -Every ordinary continuation contains -a 16-bit codepage field `cp` (cf. 4.1.1), which determines the codepage that -will be used to execute its code. If a continuation is created by a `PUSHCONT` -(cf. 4.2.3) or similar primitive, it usually inherits the current codepage (i.e., -the codepage of `cc`).25 - -### 5.1.2. Current codepage - -The current codepage `cp` (cf. 1.4) is the codepage of the current continuation `cc`. It determines the way the next instruction will be decoded from `cc.code`, the remainder of the current continuation’s code. Once the instruction has been decoded and executed, it -determines the next value of the current codepage. In most cases, the current codepage is left unchanged. - -On the other hand, all primitives that switch the current continuation -load the new value of `cp` from the new current continuation. In this way, all -code in continuations is always interpreted exactly as it was intended to be. - ---- - -### 5.1.3. Different versions of TVM may use different codepages - -Different versions of TVM may use different codepages for their code. For -example, the original version of TVM might use codepage zero. A newer -version might use codepage one, which contains all the previously defined -opcodes, along with some newly defined ones, using some of the previously -unused opcode space. A subsequent version might use yet another codepage, -and so on. - -However, a newer version of TVM will execute old code for codepage zero -exactly as before. If the old code contained an opcode used for some new -operations that were undefined in the original version of TVM, it will still -generate an invalid opcode exception, because the new operations are absent -in codepage zero. - ---- +We also discuss some general considerations about instruction encodings (applicable to arbitrary machine code, not just TVM), as well as the implications of these considerations for TVM and the choices made while designing TVM’s (experimental) codepage zero. The instruction encodings themselves are presented later in Appendix A. -### 5.1.4. Changing the behavior of old operations +## 5.1 Codepages and interoperability of different TVM versions -New codepages can -also change the effects of some operations present in the old codepages while -preserving their opcodes and mnemonics. +The codepages are an essential mechanism of backward compatibility and of future extensions to TVM. They enable transparent execution of code written for different revisions of TVM, with transparent interaction between instances of such code. The mechanism of the codepages, however, is general and powerful enough to enable some other originally unintended applications. -For example, imagine a future 513-bit upgrade of TVM (replacing the -current 257-bit design). It might use a 513-bit Integer type within the same -arithmetic primitives as before. However, while the opcodes and instructions -in the new codepage would look exactly like the old ones, they would work -differently, accepting 513-bit integer arguments and results. On the other -hand, during the execution of the same code in codepage zero, the new -machine would generate exceptions whenever the integers used in arithmetic -and other primitives do not fit into 257 bits.26 In this way, the upgrade would -not change the behavior of the old code. +### 5.1.1 Codepages in continuations +Every ordinary continuation contains a 16-bit codepage field `cp` (cf. [4.1.1](#4-1-1-ordinary-continuations)), which determines the codepage that will be used to execute its code. If a continuation is created by a `PUSHCONT` (cf. [4.2.3](#4-2-3-constant-or-literal-continuations)) or similar primitive, it usually inherits the current codepage (i.e., the codepage of `cc`).[25](#footnote-25) ---- +### 5.1.2 Current codepage +The current codepage `cp` (cf. [1.4](#1-4-total-state-of-tvm)) is the codepage of the current continuation `cc`. It determines the way the next instruction will be decoded from `cc.code`, the remainder of the current continuation’s code. Once the instruction has been decoded and executed, it determines the next value of the current codepage. In most cases, the current codepage is left unchanged. -### 5.1.5. Improving instruction encoding +On the other hand, all primitives that switch the current continuation load the new value of `cp` from the new current continuation. In this way, all code in continuations is always interpreted exactly as it was intended to be. -Another application for codepages is to change instruction encodings, reflecting improved knowledge of -the actual frequencies of such instructions in the code base. In this case, -the new codepage will have exactly the same instructions as the old one, but -with different encodings, potentially of differing lengths. +### 5.1.3 Different versions of TVM may use different codepages +Different versions of TVM may use different codepages for their code. -For example, one -might create an experimental version of the first version of TVM, using a -(prefix) bitcode instead of the original bytecode, aiming to achieve higher -code density. +For example, the original version of TVM might use codepage zero. A newer version might use codepage one, which contains all the previously defined opcodes, along with some newly defined ones, using some of the previously unused opcode space. A subsequent version might use yet another codepage, and so on. ---- +However, a newer version of TVM will execute old code for codepage zero exactly as before. If the old code contained an opcode used for some new operations that were undefined in the original version of TVM, it will still generate an invalid opcode exception, because the new operations are absent in codepage zero. -### 5.1.6. Making instruction encoding context-dependent +### 5.1.4 Changing the behavior of old operations +New codepages can also change the effects of some operations present in the old codepages while preserving their opcodes and mnemonics. -Another way -of using codepages to improve code density is to use several codepages with -different subsets of the whole instruction set defined in each of them, or with -the whole instruction set defined, but with different length encodings for the -same instructions in different codepages. +For example, imagine a future 513-bit upgrade of TVM (replacing the current 257-bit design). It might use a 513-bit Integer type within the same arithmetic primitives as before. However, while the opcodes and instructions in the new codepage would look exactly like the old ones, they would work differently, accepting 513-bit integer arguments and results. On the other hand, during the execution of the same code in codepage zero, the new machine would generate exceptions whenever the integers used in arithmetic and other primitives do not fit into 257 bits.[26](#footnote-26) -Imagine, for instance, a “stack manipulation” codepage, where stack manipulation primitives have short encodings at the expense of all other operations, and a “data processing” codepage, where all other operations are -shorter at the expense of stack manipulation operations. If stack manipulation operations tend to come one after another, we can automatically -switch to “stack manipulation” codepage after executing any such instruction. When a data processing instruction occurs, we switch back to “data -processing” codepage. +In this way, the upgrade would not change the behavior of the old code. -If conditional probabilities of the class of the next instruction depending on the class of the previous instruction are considerably -different from corresponding unconditional probabilities, this technique— -automatically switching into stack manipulation mode to rearrange the stack -with shorter instructions, then switching back—might considerably improve -the code density. +### 5.1.5 Improving instruction encoding +Another application for codepages is to change instruction encodings, reflecting improved knowledge of the actual frequencies of such instructions in the code base. In this case, the new codepage will have exactly the same instructions as the old one, but with different encodings, potentially of differing lengths. ---- +For example, one might create an experimental version of the first version of TVM, using a (prefix) bitcode instead of the original bytecode, aiming to achieve higher code density. -### 5.1.7. Using codepages for status and control flags +### 5.1.6 Making instruction encoding context-dependent +Another way of using codepages to improve code density is to use several codepages with different subsets of the whole instruction set defined in each of them, or with the whole instruction set defined, but with different length encodings for the same instructions in different codepages. -Another potential -application of multiple codepages inside the same revision of TVM consists in -switching between several codepages depending on the result of the execution -of some instructions. +Imagine, for instance, a “stack manipulation” codepage, where stack manipulation primitives have short encodings at the expense of all other operations, and a “data processing” codepage, where all other operations are shorter at the expense of stack manipulation operations. If stack manipulation operations tend to come one after another, we can automatically switch to “stack manipulation” codepage after executing any such instruction. When a data processing instruction occurs, we switch back to “data processing” codepage. -For example, imagine a version of TVM that uses two new codepages, `2` -and `3`. Most operations do not change the current codepage. However, the -integer comparison operations will switch to codepage `2` if the condition is -false, and to codepage `3` if it is true. Furthermore, a new operation `?EXECUTE`, -similar to `EXECUTE`, will indeed be equivalent to `EXECUTE` in codepage `3`, but -will instead be a `DROP` in codepage `2`. Such a trick effectively uses bit 0 of -the current codepage as a status flag. +If conditional probabilities of the class of the next instruction depending on the class of the previous instruction are considerably different from corresponding unconditional probabilities, this technique—automatically switching into stack manipulation mode to rearrange the stack with shorter instructions, then switching back—might considerably improve the code density. -Alternatively, one might create a couple of codepages—say, `4` and `5`— -which differ only in their cell deserialisation primitives. For instance, in -codepage `4` they might work as before, while in codepage `5` they might deserialize data not from the beginning of a Slice, but from its end. Two new -instructions—say, `CLD` and `STD`—might be used for switching to codepage `4` -or codepage `5`. Clearly, we have now described a status flag, affecting the -execution of some instructions in a certain new manner. +### 5.1.7 Using codepages for status and control flags +Another potential application of multiple codepages inside the same revision of TVM consists in switching between several codepages depending on the result of the execution of some instructions. ---- - -### 5.1.8. Setting the codepage in the code itself +For example, imagine a version of TVM that uses two new codepages, 2 and 3. Most operations do not change the current codepage. However, the integer comparison operations will switch to codepage 2 if the condition is false, and to codepage 3 if it is true. Furthermore, a new operation `?EXECUTE`, similar to `EXECUTE`, will indeed be equivalent to `EXECUTE` in codepage 3, but will instead be a `DROP` in codepage 2. Such a trick effectively uses bit 0 of the current codepage as a status flag. -For convenience, we -reserve some opcode in all codepages—say, `FF n`—for the instruction `SETCP n`, -with `n` from 0 to 255 (cf. A.13). Then by inserting such an instruction -into the very beginning of (the main function of) a program (e.g., a TON -Blockchain smart contract) or a library function, we can ensure that the code -will always be executed in the intended codepage. +Alternatively, one might create a couple of codepages—say, 4 and 5—which differ only in their cell deserialisation primitives. For instance, in codepage 4 they might work as before, while in codepage 5 they might deserialize data not from the beginning of a Slice, but from its end. Two new instructions—say, `CLD` and `STD`—might be used for switching to codepage 4 or codepage 5. Clearly, we have now described a status flag, affecting the execution of some instructions in a certain new manner. ---- +### 5.1.8 Setting the codepage in the code itself +For convenience, we reserve some opcode in all codepages—say, `FF n`—for the instruction `SETCP n`, with `n` from 0 to 255 (cf. [A.13](#a-13)). Then by inserting such an instruction into the very beginning of (the main function of) a program (e.g., a TON Blockchain smart contract) or a library function, we can ensure that the code will always be executed in the intended codepage. ## 5.2 Instruction encoding -This section discusses the general principles of instruction encoding valid for -all codepages and all versions of TVM. Later, 5.3 discusses the choices made -for the experimental “codepage zero”. +This section discusses the general principles of instruction encoding valid for all codepages and all versions of TVM. Later, [5.3](#5-3-instruction-encoding-in-codepage-zero) discusses the choices made for the experimental “codepage zero”. -### 5.2.1. Instructions are encoded by a binary prefix code +### 5.2.1 Instructions are encoded by a binary prefix code +All complete instructions (i.e., instructions along with all their parameters, such as the names of stack registers `s(i)` or other embedded constants) of a TVM codepage are encoded by a binary prefix code. This means that a (finite) binary string (i.e., a bitstring) corresponds to each complete instruction, in such a way that binary strings corresponding to different complete instructions do not coincide, and no binary string among the chosen subset is a prefix of another binary string from this subset. -All complete instructions (i.e., instructions along with all their parameters, such as -the names of stack registers `s(i)` or other embedded constants) of a TVM -codepage are encoded by a **binary prefix code**. This means that a (finite) -binary string (i.e., a bitstring) corresponds to each complete instruction, in -such a way that binary strings corresponding to different complete instructions do not coincide, and no binary string among the chosen subset is a -prefix of another binary string from this subset. +### 5.2.2 Determining the first instruction from a code stream +As a consequence of this encoding method, any binary string admits at most one prefix, which is an encoding of some complete instruction. In particular, the code `cc.code` of the current continuation (which is a Slice, and thus a bitstring along with some cell references) admits at most one such prefix, which corresponds to the (uniquely determined) instruction that TVM will execute first. After execution, this prefix is removed from the code of the current continuation, and the next instruction can be decoded. ---- - -### 5.2.2. Determining the first instruction from a code stream +### 5.2.3 Invalid opcode +If no prefix of `cc.code` encodes a valid instruction in the current codepage, an invalid opcode exception is generated (cf. [4.5.7](#4-5-7-list-of-predefined-exceptions)). However, the case of an empty `cc.code` is treated separately as explained in [4.1.4](#4-1-4-normal-work-of-tvm-or-the-main-loop) (the exact behavior may depend on the current codepage). -As a consequence of this encoding method, any binary string admits at most one -prefix, which is an encoding of some complete instruction. In particular, -the code `cc.code` of the current continuation (which is a Slice, and thus a -bitstring along with some cell references) admits at most one such prefix, -which corresponds to the (uniquely determined) instruction that TVM will -execute first. After execution, this prefix is removed from the code of the -current continuation, and the next instruction can be decoded. - ---- +### 5.2.4 Special case: end-of-code padding +As an exception to the above rule, some codepages may accept some values of `cc.code` that are too short to be valid instruction encodings as additional variants of `NOP`, thus effectively using the same procedure for them as for an empty `cc.code`. Such bitstrings may be used for padding the code near its end. -### 5.2.3. Invalid opcode +For example, if binary string `00000000` (i.e., `0x00`, cf. [1.0.3](#1-0-3-hexadecimal-notation)) is used in a codepage to encode `NOP`, its proper prefixes cannot encode any instructions. So this codepage may accept `0`, `00`, `000`, …, `0000000` as variants of `NOP` if this is all that is left in `cc.code`, instead of generating an invalid opcode exception. -If no prefix of `cc.code` encodes a valid instruction -in the current codepage, an invalid opcode exception is generated (cf. 4.5.7). - -However, the case of an empty `cc.code` is treated separately as explained -in 4.1.4 (the exact behavior may depend on the current codepage). - ---- +Such a padding may be useful, for example, if the `PUSHCONT` primitive (cf. [4.2.3](#4-2-3-constant-or-literal-continuations)) creates only continuations with code consisting of an integral number of bytes, but not all instructions are encoded by an integral number of bytes. -### 5.2.4. Special case: end-of-code padding +### 5.2.5 TVM code is a bitcode, not a bytecode +Recall that TVM is a bit-oriented machine in the sense that its Cells (and Slices) are naturally considered as sequences of bits, not just of octets (bytes), cf. [3.2.5](#3-2-5-cells-and-cell-primitives-are-bit-oriented-not-byte-oriented). Because the TVM code is also kept in cells (cf. [3.1.9](#3-1-9-tvm-code-is-a-tree-of-cells) and [4.1.4](#4-1-4-normal-work-of-tvm-or-the-main-loop)), there is no reason to use only bitstrings of length divisible by eight as encodings of complete instructions. In other words, generally speaking, the TVM code is a bitcode, not a bytecode. -As an exception to the above -rule, some codepages may accept some values of `cc.code` that are too short -to be valid instruction encodings as additional variants of `NOP`, thus effectively -using the same procedure for them as for an empty `cc.code`. Such bitstrings -may be used for padding the code near its end. +That said, some codepages (such as our experimental codepage zero) may opt to use a bytecode (i.e., to use only encodings consisting of an integral number of bytes)—either for simplicity, or for the ease of debugging and of studying memory (i.e., cell) dumps.[27](#footnote-27) -For example, if binary string `00000000` (i.e., `x00`, cf. 1.0.3) is used in a -codepage to encode `NOP`, its proper prefixes cannot encode any instructions. -So this codepage may accept `0`, `00`, `000`, …, `0000000` as variants of `NOP` if -this is all that is left in `cc.code`, instead of generating an invalid opcode -exception. - -Such a padding may be useful, for example, if the `PUSHCONT` primitive -(cf. 4.2.3) creates only continuations with code consisting of an integral -number of bytes, but not all instructions are encoded by an integral number -of bytes. - ---- - -### 5.2.5. TVM code is a bitcode, not a bytecode - -Recall that TVM is -a bit-oriented machine in the sense that its Cells (and Slices) are naturally -considered as sequences of bits, not just of octets (bytes), cf. 3.2.5. Because -the TVM code is also kept in cells (cf. 3.1.9 and 4.1.4), there is no reason -to use only bitstrings of length divisible by eight as encodings of complete -instructions. In other words, generally speaking, the TVM code is a **bitcode**, -not a **bytecode**. - -That said, some codepages (such as our experimental codepage zero) may -opt to use a bytecode (i.e., to use only encodings consisting of an integral -number of bytes)—either for simplicity, or for the ease of debugging and of -studying memory (i.e., cell) dumps.27 - ---- - -### 5.2.6. Opcode space used by a complete instruction - -Recall from coding theory that the lengths of bitstrings `li` used in a binary prefix code satisfy -Kraft–McMillan inequality: +### 5.2.6 Opcode space used by a complete instruction +Recall from coding theory that the lengths of bitstrings `li` used in a binary prefix code satisfy Kraft–McMillan inequality: +```math +\sum_i 2^{-l_i} \leq 1 ``` -Σ 2^(-li) ≤ 1 -``` - -This is applicable in particular to -the (complete) instruction encoding used by a TVM codepage. We say that -a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2^(-l)` of the opcode space, if it is encoded -by an `l`-bit string. One can see that all complete instructions together utilize -at most 1 (i.e., “at most the whole opcode space”). - ---- - -### 5.2.7. Opcode space used by an instruction, or a class of instructions - -The above terminology is extended to instructions (considered with -all admissible values of their parameters), or even classes of instructions (e.g., -all arithmetic instructions). We say that an (incomplete) instruction, or a -class of instructions, occupies portion `α` of the opcode space, if `α` is the sum -of the portions of the opcode space occupied by all complete instructions -belonging to that class. - ---- - -### 5.2.8. Opcode space for bytecodes - -A useful approximation of the above -definitions is as follows: - -Consider all 256 possible values for the first byte of -an instruction encoding. Suppose that `k` of these values correspond to the -specific instruction or class of instructions we are considering. Then this -instruction or class of instructions occupies approximately the portion `k/256` -of the opcode space. - -This approximation shows why all instructions cannot occupy together -more than the portion `256/256 = 1` of the opcode space, at least without -compromising the uniqueness of instruction decoding. - ---- - -### 5.2.9. Almost optimal encodings - -Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete -instruction (`2^(-l)`, if the complete instruction is encoded in `l` bits) should be -approximately equal to the probability or frequency of its occurrence in real -programs.28 The same should hold for (incomplete) instructions, or primitives -(i.e., generic instructions without specified values of parameters), and -for classes of instructions. - ---- - -### 5.2.10. Example: stack manipulation primitives - -For instance, if stack -manipulation instructions constitute approximately half of all instructions in -a typical TVM program, one should allocate approximately half of the opcode -space for encoding stack manipulation instructions. - -One might reserve the -first bytes (“opcodes”) `0x00–0x7f` for such instructions. If a quarter of these -instructions are `XCHG`, it would make sense to reserve `0x00–0x1f` for `XCHG`s. -Similarly, if half of all `XCHG`s involve the top of stack `s0`, it would make sense -to use `0x00–0x0f` to encode `XCHG s0,s(i)`. - ---- - -### 5.2.11. Simple encodings of instructions -In most cases, simple encodings of complete instructions are used. Simple encodings begin with a fixed -bitstring called the opcode of the instruction, followed by, say, 4-bit fields -containing the indices `i` of stack registers `s(i)` specified in the instruction, followed by all other constant (literal, immediate) parameters included in the -complete instruction. +This is applicable in particular to the (complete) instruction encoding used by a TVM codepage. We say that a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2^-l` of the opcode space, if it is encoded by an `l`-bit string. One can see that all complete instructions together utilize at most 1 (i.e., “at most the whole opcode space”). -While simple encodings may not be exactly optimal, -they admit short descriptions, and their decoding and encoding can be easily -implemented. +### 5.2.7 Opcode space used by an instruction, or a class of instructions +The above terminology is extended to instructions (considered with all admissible values of their parameters), or even classes of instructions (e.g., all arithmetic instructions). We say that an (incomplete) instruction, or a class of instructions, occupies portion `α` of the opcode space, if `α` is the sum of the portions of the opcode space occupied by all complete instructions belonging to that class. -If a (generic) instruction uses a simple encoding with an `l`-bit opcode, then -the instruction will utilize `2^(-l)` portion of the opcode space. This observation -might be useful for considerations described in 5.2.9 and 5.2.10. +### 5.2.8 Opcode space for bytecodes +A useful approximation of the above definitions is as follows: Consider all 256 possible values for the first byte of an instruction encoding. Suppose that `k` of these values correspond to the specific instruction or class of instructions we are considering. Then this instruction or class of instructions occupies approximately the portion `k/256` of the opcode space. ---- +This approximation shows why all instructions cannot occupy together more than the portion `256/256 = 1` of the opcode space, at least without compromising the uniqueness of instruction decoding. -### 5.2.12. Optimizing code density further: Huffman codes +### 5.2.9 Almost optimal encodings +Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete instruction (`2^-l`, if the complete instruction is encoded in `l` bits) should be approximately equal to the probability or frequency of its occurrence in real programs.[28](#footnote-28) The same should hold for (incomplete) instructions, or primitives (i.e., generic instructions without specified values of parameters), and for classes of instructions. -One might -construct optimally dense binary code for the set of all complete instructions, -provided their probabilities or frequencies in real code are known. This is the -well-known **Huffman code** (for the given probability distribution). However, -such code would be highly unsystematic and hard to decode. +### 5.2.10 Example: stack manipulation primitives +For instance, if stack manipulation instructions constitute approximately half of all instructions in a typical TVM program, one should allocate approximately half of the opcode space for encoding stack manipulation instructions. One might reserve the first bytes (“opcodes”) `0x00–0x7f` for such instructions. If a quarter of these instructions are `XCHG`, it would make sense to reserve `0x00–0x1f` for `XCHG`s. Similarly, if half of all `XCHG`s involve the top of stack `s0`, it would make sense to use `0x00–0x0f` to encode `XCHG s0,s(i)`. ---- +### 5.2.11 Simple encodings of instructions +In most cases, simple encodings of complete instructions are used. Simple encodings begin with a fixed bitstring called the opcode of the instruction, followed by, say, 4-bit fields containing the indices `i` of stack registers `s(i)` specified in the instruction, followed by all other constant (literal, immediate) parameters included in the complete instruction. While simple encodings may not be exactly optimal, they admit short descriptions, and their decoding and encoding can be easily implemented. -### 5.2.13. Practical instruction encodings +If a (generic) instruction uses a simple encoding with an `l`-bit opcode, then the instruction will utilize `2^-l` portion of the opcode space. This observation might be useful for considerations described in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives). -In practice, instruction encodings used in TVM and other virtual machines offer a compromise between -code density and ease of encoding and decoding. Such a compromise may -be achieved by selecting simple encodings (cf. 5.2.11) for all instructions -(maybe with separate simple encodings for some often used variants, such -as `XCHG s0,s(i)` among all `XCHG s(i),s(j)`), and allocating opcode space for -such simple encodings using the heuristics outlined in 5.2.9 and 5.2.10; this -is the approach currently used in TVM. +### 5.2.12 Optimizing code density further: Huffman codes +One might construct optimally dense binary code for the set of all complete instructions, provided their probabilities or frequences in real code are known. This is the well-known Huffman code (for the given probability distribution). However, such code would be highly unsystematic and hard to decode. ---- +### 5.2.13 Practical instruction encodings +In practice, instruction encodings used in TVM and other virtual machines offer a compromise between code density and ease of encoding and decoding. Such a compromise may be achieved by selecting simple encodings (cf. [5.2.11](#5-2-11-simple-encodings-of-instructions)) for all instructions (maybe with separate simple encodings for some often used variants, such as `XCHG s0,s(i)` among all `XCHG s(i),s(j)`), and allocating opcode space for such simple encodings using the heuristics outlined in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives); this is the approach currently used in TVM. ## 5.3 Instruction encoding in codepage zero -This section provides details about the experimental instruction encoding -for codepage zero, as described elsewhere in this document (cf. Appendix A) -and used in the preliminary test version of TVM. +This section provides details about the experimental instruction encoding for codepage zero, as described elsewhere in this document (cf. [Appendix A](#appendix-a)) and used in the preliminary test version of TVM. -### 5.3.1. Upgradability +### 5.3.1 Upgradability +First of all, even if this preliminary version somehow gets into the production version of the TON Blockchain, the codepage mechanism (cf. [5.1](#51-codepages-and-interoperability-of-different-tvm-versions)) enables us to introduce better versions later without compromising backward compatibility.[29](#footnote-29) So in the meantime, we are free to experiment. -First of all, even if this preliminary version somehow gets into the production version of the TON Blockchain, the codepage -mechanism (cf. 5.1) enables us to introduce better versions later without -compromising backward compatibility.29 So in the meantime, we are free to -experiment. +### 5.3.2 Choice of instructions +We opted to include many “experimental” and not strictly necessary instructions in codepage zero just to see how they might be used in real code. For example, we have both the basic (cf. [2.2.1](#2-2-1-basic-stack-manipulation-primitives)) and the compound (cf. [2.2.3](#2-2-3-compound-stack-manipulation-primitives)) stack manipulation primitives, as well as some “unsystematic” ones such as `ROT` (mostly borrowed from Forth). If such primitives are rarely used, their inclusion just wastes some part of the opcode space and makes the encodings of other instructions slightly less effective, something we can afford at this stage of TVM’s development. ---- +### 5.3.3 Using experimental instructions +Some of these experimental instructions have been assigned quite long opcodes, just to fit more of them into the opcode space. One should not be afraid to use them just because they are long; if these instructions turn out to be useful, they will receive shorter opcodes in future revisions. Codepage zero is not meant to be fine-tuned in this respect. -### 5.3.2. Choice of instructions +### 5.3.4 Choice of bytecode +We opted to use a bytecode (i.e., to use encodings of complete instructions of lengths divisible by eight). While this may not produce optimal code density, because such a length restriction makes it more difficult to match portions of opcode space used for the encoding of instructions with estimated frequencies of these instructions in TVM code (cf. [5.2.11](#5-2-11-simple-encodings-of-instructions) and [5.2.9](#5-2-9-almost-optimal-encodings)), such an approach has its advantages: it admits a simpler instruction decoder and simplifies debugging (cf. [5.2.5](#5-2-5-tvm-code-is-a-bitcode-not-a-bytecode)). -We opted to include many “experimental” -and not strictly necessary instructions in codepage zero just to see how they -might be used in real code. For example, we have both the basic (cf. 2.2.1) -and the compound (cf. 2.2.3) stack manipulation primitives, as well as some -“unsystematic” ones such as `ROT` (mostly borrowed from Forth). If such -primitives are rarely used, their inclusion just wastes some part of the opcode -space and makes the encodings of other instructions slightly less effective, -something we can afford at this stage of TVM’s development. +After all, we do not have enough data on the relative frequencies of different instructions right now, so our code density optimizations are likely to be very approximate at this stage. The ease of debugging and experimenting and the simplicity of implementation are more important at this point. ---- - -### 5.3.3. Using experimental instructions +### 5.3.5 Simple encodings for all instructions +For similar reasons, we opted to use simple encodings for all instructions (cf. [5.2.11](#5-2-11-simple-encodings-of-instructions) and [5.2.13](#5-2-13-practical-instruction-encodings)), with separate simple encodings for some very frequently used subcases as outlined in [5.2.13](#5-2-13-practical-instruction-encodings). That said, we tried to distribute opcode space using the heuristics described in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives). -Some of these experimental -instructions have been assigned quite long opcodes, just to fit more of them -into the opcode space. One should not be afraid to use them just because -they are long; if these instructions turn out to be useful, they will receive -shorter opcodes in future revisions. Codepage zero is not meant to be fine -tuned in this respect. - ---- - -### 5.3.4. Choice of bytecode. - -We opted to use a bytecode (i.e., to use encodings of complete instructions of lengths divisible by eight). While this may not produce optimal code density, because such a length restriction makes it more difficult to match portions of opcode space used for the encoding of instructions with estimated frequencies of these instructions in TVM code -(cf. 5.2.11 and 5.2.9), such an approach has its advantages: it admits a -simpler instruction decoder and simplifies debugging (cf. 5.2.5). - -After all, we do not have enough data on the relative frequencies of different instructions right now, so our code density optimizations are likely to -be very approximate at this stage. The ease of debugging and experimenting -and the simplicity of implementation are more important at this point. - -### 5.3.5. Simple encodings for all instructions. - -For similar reasons, we -opted to use simple encodings for all instructions (cf. 5.2.11 and 5.2.13), -with separate simple encodings for some very frequently used subcases as -outlined in 5.2.13. That said, we tried to distribute opcode space using the -heuristics described in 5.2.9 and 5.2.10. - -### 5.3.6. Lack of context-dependent encodings. - -This version of TVM also -does not use context-dependent encodings (cf. 5.1.6). They may be added -at a later stage, if deemed useful. - -### 5.3.7. The list of all instructions. +### 5.3.6 Lack of context-dependent encodings +This version of TVM also does not use context-dependent encodings (cf. [5.1.6](#5-1-6-making-instruction-encoding-context-dependent)). They may be added at a later stage, if deemed useful. +### 5.3.7 The list of all instructions The list of all instructions available in codepage zero, along with their encodings and (in some cases) short descriptions, may be found in Appendix A. --- @@ -2645,6 +1485,7 @@ category (e.g., arithmetic primitives) have neighboring opcodes. So we first list a number of stack manipulation primitives, then constant primitives, arithmetic primitives, comparison primitives, cell primitives, continuation primitives, dictionary primitives, and finally application-specific primitives. + We use hexadecimal notation (cf. 1.0) for bitstrings. Stack registers `s(i)` usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, @@ -2683,6 +1524,7 @@ compound stack manipulation primitives, such as `XCPU` or `XCHG2`, turn out to have the same length as an equivalent sequence of simpler operations. We have included these primitives regardless, so that they can easily be allocated shorter opcodes in a future revision of TVM—or removed for good. + Some stack manipulation instructions have two mnemonics: one Forth- style (e.g., `-ROT`), the other conforming to the usual rules for identifiers (e.g., `ROTREV`). Whenever a stack manipulation primitive (e.g., `PICK`) accepts an @@ -2691,70 +1533,72 @@ otherwise a range check exception happens before any further checks. ### A.2.1. Basic stack manipulation primitives. -* `00` — **NOP**, does nothing. -* `01` — **XCHG s1**, also known as **SWAP**. -* `0i` — **XCHG s(i)** or **XCHG s0,s(i)**, interchanges the top of the stack with `s(i)`, `1 ≤ i ≤ 15`. -* `10ij` — **XCHG s(i),s(j)**, `1 ≤ i < j ≤ 15`, interchanges `s(i)` with `s(j)`. -* `11ii` — **XCHG s0,s(ii)**, with `0 ≤ ii ≤ 255`. -* `1i` — **XCHG s1,s(i)**, `2 ≤ i ≤ 15`. -* `2i` — **PUSH s(i)**, `0 ≤ i ≤ 15`, pushes a copy of the old `s(i)` into the stack. -* `20` — **PUSH s0**, also known as **DUP**. -* `21` — **PUSH s1**, also known as **OVER**. -* `3i` — **POP s(i)**, `0 ≤ i ≤ 15`, pops the old top-of-stack value into the old `s(i)`. -* `30` — **POP s0**, also known as **DROP**, discards the top-of-stack value. -* `31` — **POP s1**, also known as **NIP**. +* `00` — `NOP`, does nothing. +* `01` — `XCHG s1`, also known as `SWAP`. +* `0i` — `XCHG s(i)` or `XCHG s0,s(i)`, interchanges the top of the stack with `s(i)`, `1 ≤ i ≤ 15`. +* `10ij` — `XCHG s(i),s(j)`, `1 ≤ i < j ≤ 15`, interchanges `s(i)` with `s(j)`. +* `11ii` — `XCHG s0,s(ii)`, with `0 ≤ ii ≤ 255`. +* `1i` — `XCHG s1,s(i)`, `2 ≤ i ≤ 15`. +* `2i` — `PUSH s(i)`, `0 ≤ i ≤ 15`, pushes a copy of the old `s(i)` into the stack. +* `20` — `PUSH s0`, also known as `DUP`. +* `21` — `PUSH s1`, also known as `OVER`. +* `3i` — `POP s(i)`, `0 ≤ i ≤ 15`, pops the old top-of-stack value into the old `s(i)`. +* `30` — `POP s0`, also known as `DROP`, discards the top-of-stack value. +* `31` — `POP s1`, also known as `NIP`. ### A.2.2. Compound stack manipulation primitives. Parameters `i`, `j`, and `k` of the following primitives all are 4-bit integers in the range `0 . . . 15`. -* `4ijk` — **XCHG3 s(i),s(j),s(k)**, equivalent to **XCHG s2,s(i); XCHG s1,s(j); XCHG s0,s(k)**, with `0 ≤ i, j, k ≤ 15`. -* `50ij` — **XCHG2 s(i),s(j)**, equivalent to **XCHG s1,s(i); XCHG s(j)**. -* `51ij` — **XCPU s(i),s(j)**, equivalent to **XCHG s(i); PUSH s(j)**. -* `52ij` — **PUXC s(i),s(j − 1)**, equivalent to **PUSH s(i); SWAP; XCHG s(j)**. -* `53ij` — **PUSH2 s(i),s(j)**, equivalent to **PUSH s(i); PUSH s(j + 1)**. -* `540ijk` — **XCHG3 s(i),s(j),s(k)** (long form). -* `541ijk` — **XC2PU s(i),s(j),s(k)**, equivalent to **XCHG2 s(i),s(j); PUSH s(k)**. -* `542ijk` — **XCPUXC s(i),s(j),s(k−1)**, equivalent to **XCHG s1,s(i); PUXC s(j),s(k − 1)**. -* `543ijk` — **XCPU2 s(i),s(j),s(k)**, equivalent to **XCHG s(i); PUSH2 s(j),s(k)**. -* `544ijk` — **PUXC2 s(i),s(j − 1),s(k − 1)**, equivalent to **PUSH s(i); XCHG s2; XCHG2 s(j),s(k)**. -* `545ijk` — **PUXCPU s(i),s(j−1),s(k−1)**, equivalent to **PUXC s(i),s(j− 1); PUSH s(k)**. -* `546ijk` — **PU2XC s(i),s(j−1),s(k−2)**, equivalent to **PUSH s(i); SWAP; PUXC s(j),s(k − 1)**. -* `547ijk` — **PUSH3 s(i),s(j),s(k)**, equivalent to **PUSH s(i); PUSH2 s(j + 1),s(k + 1)**. -* `54C_` — **unused**. + +* `4ijk` — `XCHG3 s(i),s(j),s(k)`, equivalent to `XCHG s2,s(i); XCHG s1,s(j); XCHG s0,s(k)`, with `0 ≤ i, j, k ≤ 15`. +* `50ij` — `XCHG2 s(i),s(j)`, equivalent to `XCHG s1,s(i); XCHG s(j)`. +* `51ij` — `XCPU s(i),s(j)`, equivalent to `XCHG s(i); PUSH s(j)`. +* `52ij` — `PUXC s(i),s(j − 1)`, equivalent to `PUSH s(i); SWAP; XCHG s(j)`. +* `53ij` — `PUSH2 s(i),s(j)`, equivalent to `PUSH s(i); PUSH s(j + 1)`. +* `540ijk` — `XCHG3 s(i),s(j),s(k)` (long form). +* `541ijk` — `XC2PU s(i),s(j),s(k)`, equivalent to `XCHG2 s(i),s(j); PUSH s(k)`. +* `542ijk` — `XCPUXC s(i),s(j),s(k−1)`, equivalent to `XCHG s1,s(i); PUXC s(j),s(k − 1)`. +* `543ijk` — `XCPU2 s(i),s(j),s(k)`, equivalent to `XCHG s(i); PUSH2 s(j),s(k)`. +* `544ijk` — `PUXC2 s(i),s(j − 1),s(k − 1)`, equivalent to `PUSH s(i); XCHG s2; XCHG2 s(j),s(k)`. +* `545ijk` — `PUXCPU s(i),s(j−1),s(k−1)`, equivalent to `PUXC s(i),s(j−1); PUSH s(k)`. +* `546ijk` — `PU2XC s(i),s(j−1),s(k−2)`, equivalent to `PUSH s(i); SWAP; PUXC s(j),s(k − 1)`. +* `547ijk` — `PUSH3 s(i),s(j),s(k)`, equivalent to `PUSH s(i); PUSH2 s(j + 1),s(k + 1)`. +* `54C_` — `unused`. + ### A.2.3. Exotic stack manipulation primitives. -* `55ij` — **BLKSWAP i+1,j+1**, permutes two blocks `s(j + i + 1)…s(j + 1)` and `s(j)…s0`, for `0 ≤ i, j ≤ 15`. Equivalent to **REVERSE i+1,j+1; REVERSE j+1,0; REVERSE i+j+2,0**. -* `5513` — **ROT2** or **2ROT** (`a b c d e f – c d e f a b`), rotates the three topmost pairs of stack entries. -* `550i` — **ROLL i+1**, rotates the top `i+1` stack entries. Equivalent to **BLKSWAP 1,i+1**. -* `55i0` — **ROLLREV i+1** or **-ROLL i+1**, rotates the top `i+1` stack entries in the other direction. Equivalent to **BLKSWAP i+1,1**. -* `56ii` — **PUSH s(ii)** for `0 ≤ ii ≤ 255`. -* `57ii` — **POP s(ii)** for `0 ≤ ii ≤ 255`. -* `58` — **ROT** (`a b c – b c a`), equivalent to **BLKSWAP 1,2** or to **XCHG2 s2,s1**. -* `59` — **ROTREV** or **-ROT** (`a b c – c a b`), equivalent to **BLKSWAP 2,1** or to **XCHG2 s2,s2**. -* `5A` — **SWAP2** or **2SWAP** (`a b c d – c d a b`), equivalent to **BLKSWAP 2,2** or to **XCHG2 s3,s2**. -* `5B` — **DROP2** or **2DROP** (`a b –`), equivalent to **DROP; DROP**. -* `5C` — **DUP2** or **2DUP** (`a b – a b a b`), equivalent to **PUSH2 s1,s0**. -* `5D` — **OVER2** or **2OVER** (`a b c d – a b c d a b`), equivalent to **PUSH2 s3,s2**. -* `5Eij` — **REVERSE i+2,j**, reverses the order of `s(j+i+1)…s(j)` for `0 ≤ i, j ≤ 15`; equivalent to a sequence of `⌊i/2⌋+1` **XCHG**s. -* `5F0i` — **BLKDROP i**, equivalent to **DROP** performed `i` times. -* `5Fij` — **BLKPUSH i,j**, equivalent to **PUSH s(j)** performed `i` times, `1 ≤ i ≤ 15`, `0 ≤ j ≤ 15`. -* `60` — **PICK** or **PUSHX**, pops integer `i` from the stack, then performs **PUSH s(i)**. -* `61` — **ROLLX**, pops integer `i` from the stack, then performs **BLKSWAP 1,i**. -* `62` — **-ROLLX** or **ROLLREVX**, pops integer `i` from the stack, then performs **BLKSWAP i,1**. -* `63` — **BLKSWX**, pops integers `i,j` from the stack, then performs **BLKSWAP i,j**. -* `64` — **REVX**, pops integers `i,j` from the stack, then performs **REVERSE i,j**. -* `65` — **DROPX**, pops integer `i` from the stack, then performs **BLKDROP i**. -* `66` — **TUCK** (`a b – b a b`), equivalent to **SWAP; OVER** or to **XCPU s1,s1**. -* `67` — **XCHGX**, pops integer `i` from the stack, then performs **XCHG s(i)**. -* `68` — **DEPTH**, pushes the current depth of the stack. -* `69` — **CHKDEPTH**, pops integer `i` from the stack, then checks whether there are at least `i` elements, generating a stack underflow exception otherwise. -* `6A` — **ONLYTOPX**, pops integer `i` from the stack, then removes all but the top `i` elements. -* `6B` — **ONLYX**, pops integer `i` from the stack, then leaves only the bottom `i` elements. Approximately equivalent to **DEPTH; SWAP; SUB; DROPX**. -* `6C00–6C0F` — **reserved** for stack operations. -* `6Cij` — **BLKDROP2 i,j**, drops `i` stack elements under the top `j` elements, where `1 ≤ i ≤ 15` and `0 ≤ j ≤ 15`. Equivalent to **REVERSE i+j,0; BLKDROP i; REVERSE j,0**. +* `55ij` — `BLKSWAP i+1,j+1`, permutes two blocks `s(j+i+1)…s(j+1)` and `s(j)…s0`, for `0 ≤ i, j ≤ 15`. Equivalent to `REVERSE i+1,j+1; REVERSE j+1,0; REVERSE i+j+2,0`. +* `5513` — `ROT2` or `2ROT` (`a b c d e f – c d e f a b`), rotates the three topmost pairs of stack entries. +* `550i` — `ROLL i+1`, rotates the top `i+1` stack entries. Equivalent to `BLKSWAP 1,i+1`. +* `55i0` — `ROLLREV i+1` or `-ROLL i+1`, rotates the top `i+1` stack entries in the other direction. Equivalent to `BLKSWAP i+1,1`. +* `56ii` — `PUSH s(ii)` for `0 ≤ ii ≤ 255`. +* `57ii` — `POP s(ii)` for `0 ≤ ii ≤ 255`. +* `58` — `ROT` (`a b c – b c a`), equivalent to `BLKSWAP 1,2` or to `XCHG2 s2,s1`. +* `59` — `ROTREV` or `-ROT` (`a b c – c a b`), equivalent to `BLKSWAP 2,1` or to `XCHG2 s2,s2`. +* `5A` — `SWAP2` or `2SWAP` (`a b c d – c d a b`), equivalent to `BLKSWAP 2,2` or to `XCHG2 s3,s2`. +* `5B` — `DROP2` or `2DROP` (`a b –`), equivalent to `DROP; DROP`. +* `5C` — `DUP2` or `2DUP` (`a b – a b a b`), equivalent to `PUSH2 s1,s0`. +* `5D` — `OVER2` or `2OVER` (`a b c d – a b c d a b`), equivalent to `PUSH2 s3,s2`. +* `5Eij` — `REVERSE i+2,j`, reverses the order of `s(j+i+1)…s(j)` for `0 ≤ i, j ≤ 15`; equivalent to a sequence of `⌊i/2⌋+1` `XCHG`s. +* `5F0i` — `BLKDROP i`, equivalent to `DROP` performed `i` times. +* `5Fij` — `BLKPUSH i,j`, equivalent to `PUSH s(j)` performed `i` times, `1 ≤ i ≤ 15`, `0 ≤ j ≤ 15`. +* `60` — `PICK` or `PUSHX`, pops integer `i` from the stack, then performs `PUSH s(i)`. +* `61` — `ROLLX`, pops integer `i` from the stack, then performs `BLKSWAP 1,i`. +* `62` — `-ROLLX` or `ROLLREVX`, pops integer `i` from the stack, then performs `BLKSWAP i,1`. +* `63` — `BLKSWX`, pops integers `i,j` from the stack, then performs `BLKSWAP i,j`. +* `64` — `REVX`, pops integers `i,j` from the stack, then performs `REVERSE i,j`. +* `65` — `DROPX`, pops integer `i` from the stack, then performs `BLKDROP i`. +* `66` — `TUCK` (`a b – b a b`), equivalent to `SWAP; OVER` or to `XCPU s1,s1`. +* `67` — `XCHGX`, pops integer `i` from the stack, then performs `XCHG s(i)`. +* `68` — `DEPTH`, pushes the current depth of the stack. +* `69` — `CHKDEPTH`, pops integer `i` from the stack, then checks whether there are at least `i` elements, generating a stack underflow exception otherwise. +* `6A` — `ONLYTOPX`, pops integer `i` from the stack, then removes all but the top `i` elements. +* `6B` — `ONLYX`, pops integer `i` from the stack, then leaves only the bottom `i` elements. Approximately equivalent to `DEPTH; SWAP; SUB; DROPX`. +* `6C00–6C0F` — `reserved` for stack operations. +* `6Cij` — `BLKDROP2 i,j`, drops `i` stack elements under the top `j` elements, where `1 ≤ i ≤ 15` and `0 ≤ j ≤ 15`. Equivalent to `REVERSE i+j,0; BLKDROP i; REVERSE j,0`. ## A.3 Tuple, List, and Null primitives @@ -3368,81 +2212,104 @@ All these primitives first check whether there is enough space in the Builder, a ## A.8 Continuation and control flow primitives +### A.8.1. Unconditional control flow primitives. + +* `D8` — `EXECUTE` or `CALLX` `(c – )`, calls or executes continuation `c` (i.e., `cc ← c ◦0 cc`). +* `D9` — `JMPX` `(c – )`, jumps, or transfers control, to continuation `c` (i.e., `cc ← c ◦0 c0, or rather cc ← (c ◦0 c0) ◦1 c1`). The remainder of the previous current continuation `cc` is discarded. +* `DApr` — `CALLXARGS p,r` `(c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. +* `DB0p` — `CALLXARGS p,−1` `(c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. +* `DB1p` — `JMPXARGS p` `(c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). +* `DB2r` — `RETARGS r`, returns to `c0`, with `0 ≤ r ≤ 15` return values taken from the current stack. +* `DB30` — `RET` or `RETTRUE`, returns to the continuation at `c0` (i.e., performs `cc ← c0`). The remainder of the current continuation `cc` is discarded. Approximately equivalent to `PUSH c0; JMPX`. +* `DB31` — `RETALT` or `RETFALSE`, returns to the continuation at `c1` (i.e., `cc ← c1`). Approximately equivalent to `PUSH c1; JMPX`. +* `DB32` — `BRANCH` or `RETBOOL` `(f – )`, performs `RETTRUE` if integer `f ≠ 0`, or `RETFALSE` if `f = 0`. +* `DB34` — `CALLCC` `(c – )`, call with current continuation, transfers control to `c`, pushing the old value of `cc` into `c`’s stack (instead of discarding it or writing it into new `c0`). +* `DB35` — `JMPXDATA` `(c – )`, similar to `CALLCC`, but the remainder of the current continuation (the old value of `cc`) is converted into a Slice before pushing it into the stack of `c`. +* `DB36pr` — `CALLCCARGS p,r` `(c – )`, similar to `CALLXARGS`, but pushes the old value of `cc` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `cc.nargs` to `−1 ≤ r ≤ 14`. +* `DB38` — `CALLXVARARGS` `(c p r – )`, similar to `CALLXARGS`, but takes `−1 ≤ p, r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1 . . . 254`. +* `DB39` — `RETVARARGS` `(p r – )`, similar to `RETARGS`. +* `DB3A` — `JMPXVARARGS` `(c p r – )`, similar to `JMPXARGS`. +* `DB3B` — `CALLCCVARARGS` `(c p r – )`, similar to `CALLCCARGS`. +* `DB3C` — `CALLREF`, equivalent to `PUSHREFCONT; CALLX`. +* `DB3D` — `JMPREF`, equivalent to `PUSHREFCONT; JMPX`. +* `DB3E` — `JMPREFDATA`, equivalent to `PUSHREFCONT; JMPXDATA`. +* `DB3F` — `RETDATA`, equivalent to `PUSH c0; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. + + ### A.8.2. Conditional control flow primitives -* `DC` — **IFRET** `(f – )`, performs a **RET**, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. -* `DD` — **IFNOTRET** `(f – )`, performs a **RET**, but only if integer `f` is zero. -* `DE` — **IF** `(f c – )`, performs **EXECUTE** for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. -* `DF` — **IFNOT** `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. -* `E0` — **IFJMP** `(f c – )`, jumps to `c` (similarly to **JMPX**), but only if `f` is non-zero. -* `E1` — **IFNOTJMP** `(f c – )`, jumps to `c` (similarly to **JMPX**), but only if `f` is zero. -* `E2` — **IFELSE** `(f c c0 – )`, if integer `f` is non-zero, executes `c`, otherwise executes `c0`. Equivalent to `CONDSELCHK; EXECUTE`. -* `E300` — **IFREF** `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. -* `E301` — **IFNOTREF** `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. -* `E302` — **IFJMPREF** `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. -* `E303` — **IFNOTJMPREF** `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. -* `E304` — **CONDSEL** `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. -* `E305` — **CONDSELCHK** `(f x y – x or y)`, same as **CONDSEL**, but first checks whether `x` and `y` have the same type. -* `E308` — **IFRETALT** `(f – )`, performs **RETALT** if integer `f ≠ 0`. -* `E309` — **IFNOTRETALT** `(f – )`, performs **RETALT** if integer `f = 0`. -* `E30D` — **IFREFELSE** `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. -* `E30E` — **IFELSEREF** `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. -* `E30F` — **IFREFELSEREF** `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. +* `DC` — `IFRET` `(f – )`, performs a `RET`, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. +* `DD` — `IFNOTRET` `(f – )`, performs a `RET`, but only if integer `f` is zero. +* `DE` — `IF` `(f c – )`, performs `EXECUTE` for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. +* `DF` — `IFNOT` `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. +* `E0` — `IFJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is non-zero. +* `E1` — `IFNOTJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is zero. +* `E2` — `IFELSE` `(f c c0 – )`, if integer `f` is non-zero, executes `c`, otherwise executes `c0`. Equivalent to `CONDSELCHK; EXECUTE`. +* `E300` — `IFREF` `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. +* `E301` — `IFNOTREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. +* `E302` — `IFJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. +* `E303` — `IFNOTJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. +* `E304` — `CONDSEL` `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. +* `E305` — `CONDSELCHK` `(f x y – x or y)`, same as `CONDSEL`, but first checks whether `x` and `y` have the same type. +* `E308` — `IFRETALT` `(f – )`, performs `RETALT` if integer `f ≠ 0`. +* `E309` — `IFNOTRETALT` `(f – )`, performs `RETALT` if integer `f = 0`. +* `E30D` — `IFREFELSE` `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. +* `E30E` — `IFELSEREF` `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. +* `E30F` — `IFREFELSEREF` `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. * `E310–E31F` — reserved for loops with break operators (cf. A.8.3). -* `E39_n` — **IFBITJMP n** `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs **JMPX** to continuation `c`. Value `x` is left in the stack. -* `E3B_n` — **IFNBITJMP n** `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. -* `E3D_n` — **IFBITJMPREF n** `(x – x)`, performs a **JMPREF** if bit `0 ≤ n ≤ 31` is set in integer `x`. -* `E3F_n` — **IFNBITJMPREF n** `(x – x)`, performs a **JMPREF** if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `E39_n` — `IFBITJMP n` `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs `JMPX` to continuation `c`. Value `x` is left in the stack. +* `E3B_n` — `IFNBITJMP n` `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `E3D_n` — `IFBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is set in integer `x`. +* `E3F_n` — `IFNBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is not set in integer `x`. ---- ### A.8.3. Control flow primitives: loops -Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. 4.1.5), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have \*BRK versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for \*ENDBRK versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for \*ENDBRK versions). - -* `E4` — **REPEAT** `(n c – )`, executes continuation `c` `n` times, if integer `n` is non-negative. If `n ≥ 2^31` or `n < −2^31`, generates a range check exception. Notice that a **RET** inside the code of `c` works as a continue, not as a break. One should use either alternative (experimental) loops or alternative **RETALT** (along with a **SETEXITALT** before the loop) to break out of a loop. -* `E5` — **REPEATEND** `(n – )`, similar to **REPEAT**, but it is applied to the current continuation `cc`. -* `E6` — **UNTIL** `(c – )`, executes continuation `c`, then pops an integer `x` from the resulting stack. If `x` is zero, performs another iteration of this loop. Implemented with extraordinary continuation `ec_until`. -* `E7` — **UNTILEND** `( – )`, similar to **UNTIL**, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs a **RET**. -* `E8` — **WHILE** `(c0 c – )`, executes `c0` and pops an integer `x` from the resulting stack. If `x = 0`, exits the loop and transfers control to the original `cc`. If `x ≠ 0`, executes `c`, and then begins a new iteration. -* `E9` — **WHILEEND** `(c0 – )`, similar to **WHILE**, but uses the current continuation `cc` as the loop body. -* `EA` — **AGAIN** `(c – )`, similar to **REPEAT**, but executes `c` infinitely many times. A **RET** only begins a new iteration of the infinite loop, which can be exited only by an exception, or a **RETALT** (or an explicit **JMPX**). -* `EB` — **AGAINEND** `( – )`, similar to **AGAIN**, but performed with respect to the current continuation `cc`. -* `E314` — **REPEATBRK** `(n c – )`, similar to **REPEAT**, but also sets `c1` to the original `cc` after saving the old value of `c1` into the savelist of the original `cc`. In this way **RETALT** could be used to break out of the loop body. -* `E315` — **REPEATENDBRK** `(n – )`, similar to **REPEATEND**, but also sets `c1` to the original `c0` after saving the old value of `c1` into the savelist of the original `c0`. Equivalent to `SAMEALTSAVE; REPEATEND`. -* `E316` — **UNTILBRK** `(c – )`, similar to **UNTIL**, but also modifies `c1` in the same way as **REPEATBRK**. -* `E317` — **UNTILENDBRK** `( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. -* `E318` — **WHILEBRK** `(c0 c – )`, similar to **WHILE**, but also modifies `c1` in the same way as **REPEATBRK**. -* `E319` — **WHILEENDBRK** `(c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. -* `E31A` — **AGAINBRK** `(c – )`, similar to **AGAIN**, but also modifies `c1` in the same way as **REPEATBRK**. -* `E31B` — **AGAINENDBRK** `( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. +Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. 4.1.5), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have `*BRK` versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for `*ENDBRK` versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for `*ENDBRK` versions). + +* `E4` — `REPEAT` `(n c – )`, executes continuation `c` `n` times, if integer `n` is non-negative. If `n ≥ 2^31` or `n < −2^31`, generates a range check exception. Notice that a `RET` inside the code of `c` works as a continue, not as a break. One should use either alternative (experimental) loops or alternative `RETALT` (along with a `SETEXITALT` before the loop) to break out of a loop. +* `E5` — `REPEATEND` `(n – )`, similar to `REPEAT`, but it is applied to the current continuation `cc`. +* `E6` — `UNTIL` `(c – )`, executes continuation `c`, then pops an integer `x` from the resulting stack. If `x` is zero, performs another iteration of this loop. Implemented with extraordinary continuation `ec_until`. +* `E7` — `UNTILEND` `( – )`, similar to `UNTIL`, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs a `RET`. +* `E8` — `WHILE` `(c0 c – )`, executes `c0` and pops an integer `x` from the resulting stack. If `x = 0`, exits the loop and transfers control to the original `cc`. If `x ≠ 0`, executes `c`, and then begins a new iteration. +* `E9` — `WHILEEND` `(c0 – )`, similar to `WHILE`, but uses the current continuation `cc` as the loop body. +* `EA` — `AGAIN` `(c – )`, similar to `REPEAT`, but executes `c` infinitely many times. A `RET` only begins a new iteration of the infinite loop, which can be exited only by an exception, or a `RETALT` (or an explicit `JMPX`). +* `EB` — `AGAINEND` `( – )`, similar to `AGAIN`, but performed with respect to the current continuation `cc`. +* `E314` — `REPEATBRK` `(n c – )`, similar to `REPEAT`, but also sets `c1` to the original `cc` after saving the old value of `c1` into the savelist of the original `cc`. In this way `RETALT` could be used to break out of the loop body. +* `E315` — `REPEATENDBRK` `(n – )`, similar to `REPEATEND`, but also sets `c1` to the original `c0` after saving the old value of `c1` into the savelist of the original `c0`. Equivalent to `SAMEALTSAVE; REPEATEND`. +* `E316` — `UNTILBRK` `(c – )`, similar to `UNTIL`, but also modifies `c1` in the same way as `REPEATBRK`. +* `E317` — `UNTILENDBRK` `( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. +* `E318` — `WHILEBRK` `(c0 c – )`, similar to `WHILE`, but also modifies `c1` in the same way as `REPEATBRK`. +* `E319` — `WHILEENDBRK` `(c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. +* `E31A` — `AGAINBRK` `(c – )`, similar to `AGAIN`, but also modifies `c1` in the same way as `REPEATBRK`. +* `E31B` — `AGAINENDBRK` `( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. ---- -### A.9 Exception generating and handling primitives +--- +## A.9 Exception generating and handling primitives -#### A.9.1. Throwing exceptions +### A.9.1. Throwing exceptions -* `F22_nn` — **THROW nn** `( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. -* `F26_nn` — **THROWIF nn** `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. -* `F2A_nn` — **THROWIFNOT nn** `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. -* `F2C4_nn` — **THROW nn** for `0 ≤ nn < 2^11`, an encoding of **THROW nn** for larger values. -* `F2CC_nn` — **THROWARG nn** `(x – x nn)`, throws exception `0 ≤ nn < 2^11` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. -* `F2D4_nn` — **THROWIF nn** `(f – )` for `0 ≤ nn < 2^11`. -* `F2DC_nn` — **THROWARGIF nn** `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f ≠ 0`. -* `F2E4_nn` — **THROWIFNOT nn** `(f – )` for `0 ≤ nn < 2^11`. -* `F2EC_nn` — **THROWARGIFNOT nn** `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f = 0`. -* `F2F0` — **THROWANY** `(n – 0 n)`, throws exception `0 ≤ n < 2^16` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. -* `F2F1` — **THROWARGANY** `(x n – x n)`, throws exception `0 ≤ n < 2^16` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. -* `F2F2` — **THROWANYIF** `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f ≠ 0`. -* `F2F3` — **THROWARGANYIF** `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f ≠ 0`. -* `F2F4` — **THROWANYIFNOT** `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f = 0`. -* `F2F5` — **THROWARGANYIFNOT** `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f = 0`. +* `F22_nn` — `THROW nn` `( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. +* `F26_nn` — `THROWIF nn` `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. +* `F2A_nn` — `THROWIFNOT nn` `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. +* `F2C4_nn` — `THROW nn` for `0 ≤ nn < 2^11`, an encoding of `THROW nn` for larger values. +* `F2CC_nn` — `THROWARG nn` `(x – x nn)`, throws exception `0 ≤ nn < 2^11` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. +* `F2D4_nn` — `THROWIF nn` `(f – )` for `0 ≤ nn < 2^11`. +* `F2DC_nn` — `THROWARGIF nn` `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f ≠ 0`. +* `F2E4_nn` — `THROWIFNOT nn` `(f – )` for `0 ≤ nn < 2^11`. +* `F2EC_nn` — `THROWARGIFNOT nn` `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f = 0`. +* `F2F0` — `THROWANY` `(n – 0 n)`, throws exception `0 ≤ n < 2^16` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. +* `F2F1` — `THROWARGANY` `(x n – x n)`, throws exception `0 ≤ n < 2^16` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. +* `F2F2` — `THROWANYIF` `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f ≠ 0`. +* `F2F3` — `THROWARGANYIF` `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f ≠ 0`. +* `F2F4` — `THROWANYIFNOT` `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f = 0`. +* `F2F5` — `THROWARGANYIFNOT` `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f = 0`. -#### A.9.2. Catching and handling exceptions +### A.9.2. Catching and handling exceptions -* `F2FF` — **TRY** `(c c0 – )`, sets `c2` to `c0`, saving the old value of `c2` both into the savelist of `c0` and into the savelist of the current continuation. Then runs `c`. If `c` does not throw any exceptions, the original value of `c2` is restored. If an exception occurs, execution is transferred to `c0`. -* `F3pr` — **TRYARGS p,r** `(c c0 – )`, similar to **TRY**, but with **CALLARGS p,r** internally used instead of **EXECUTE**. +* `F2FF` — `TRY` `(c c0 – )`, sets `c2` to `c0`, saving the old value of `c2` both into the savelist of `c0` and into the savelist of the current continuation. Then runs `c`. If `c` does not throw any exceptions, the original value of `c2` is restored. If an exception occurs, execution is transferred to `c0`. +* `F3pr` — `TRYARGS p,r` `(c c0 – )`, similar to `TRY`, but with `CALLARGS p,r` internally used instead of `EXECUTE`. --- @@ -3462,319 +2329,310 @@ Most of the dictionary primitives listed below accept and return dictionaries in Opcodes starting with `F4` and `F5` are reserved for dictionary operations. -## A.10.1. Dictionary creation. +### A.10.1. Dictionary creation. -* `6D` — **NEWDICT** `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for **PUSHNULL**, cf. A.3.1. -* `6E` — **DICTEMPTY** `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for **ISNULL**, cf. A.3.1. +* `6D` — `NEWDICT` `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for `PUSHNULL`, cf. A.3.1. +* `6E` — `DICTEMPTY` `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for `ISNULL`, cf. A.3.1. -## A.10.2. Dictionary serialization and deserialization. +--- + +### A.10.2. Dictionary serialization and deserialization. + +* `CE` — `STDICTS` `(s b – b 0)`, stores a `Slice`-represented dictionary `s` into `Builder` `b`. It is actually a synonym for `STSLICE`. +* `F400` — `STDICT` or `STOPTREF` `(D b – b 0)`, stores dictionary `D` into `Builder` `b`, returing the resulting `Builder` `b 0`. In other words, if `D` is a cell, performs `STONE` and `STREF`; if `D` is `Null`, performs `NIP` and `STZERO`; otherwise throws a type checking exception. +* `F401` — `SKIPDICT` or `SKIPOPTREF` `(s – s 0)`, equivalent to `LDDICT`; `NIP` +* `F402` — `LDDICTS` `(s – s 0 s 00)`, loads (parses) a (`Slice`-represented) dictionary `s 0` from `Slice` `s`, and returns the remainder of `s` as `s 00`. This is a “split function” for all `HashmapE(n, X)` dictionary types. +* `F403` — `PLDDICTS` `(s – s 0)`, preloads a (`Slice`-represented) dictionary `s 0` from `Slice` `s`. Approximately equivalent to `LDDICTS`; `DROP`. +* `F404` — `LDDICT` or `LDOPTREF` `(s – D s0)`, loads (parses) a dictionary `D` from `Slice` `s`, and returns the remainder of `s` as `s 0`. May be applied to dictionaries or to values of arbitrary `(ˆY ) ?` types. +* `F405` — `PLDDICT` or `PLDOPTREF` `(s – D)`, preloads a dictionary `D` from `Slice` `s`. Approximately equivalent to `LDDICT`; `DROP`. +* `F406` — `LDDICTQ` `(s – D s0 −1 or s 0)`, a quiet version of `LDDICT`. +* `F407` — `PLDDICTQ` `(s – D −1 or 0)`, a quiet version of `PLDDICT`. -* `CE` — **STDICTS** `(s b – b 0)`, stores a `Slice`-represented dictionary `s` into `Builder` `b`. It is actually a synonym for **STSLICE**. -* `F400` — **STDICT** or **STOPTREF** `(D b – b 0)`, stores dictionary `D` into `Builder` `b`, returing the resulting `Builder` `b 0`. In other words, if `D` is a cell, performs **STONE** and **STREF**; if `D` is `Null`, performs **NIP** and **STZERO**; otherwise throws a type checking exception. -* `F401` — **SKIPDICT** or **SKIPOPTREF** `(s – s 0)`, equivalent to **LDDICT**; **NIP** -* `F402` — **LDDICTS** `(s – s 0 s 00)`, loads (parses) a (`Slice`-represented) dictionary `s 0` from `Slice` `s`, and returns the remainder of `s` as `s 00`. This is a “split function” for all `HashmapE(n, X)` dictionary types. -* `F403` — **PLDDICTS** `(s – s 0)`, preloads a (`Slice`-represented) dictionary `s 0` from `Slice` `s`. Approximately equivalent to **LDDICTS**; **DROP**. -* `F404` — **LDDICT** or **LDOPTREF** `(s – D s0)`, loads (parses) a dictionary `D` from `Slice` `s`, and returns the remainder of `s` as `s 0`. May be applied to dictionaries or to values of arbitrary `(ˆY ) ?` types. -* `F405` — **PLDDICT** or **PLDOPTREF** `(s – D)`, preloads a dictionary `D` from `Slice` `s`. Approximately equivalent to **LDDICT**; **DROP**. -* `F406` — **LDDICTQ** `(s – D s0 −1 or s 0)`, a quiet version of **LDDICT**. -* `F407` — **PLDDICTQ** `(s – D −1 or 0)`, a quiet version of **PLDDICT**. -## A.10.3. Get dictionary operations. +### A.10.3. Get dictionary operations. + +* `F40A` — `DICTGET` `(k D n – x −1 or 0)`, looks up key `k` (represented by a `Slice`, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the value found as a `Slice` `x`. +* `F40B` — `DICTGETREF` `(k D n – c −1 or 0)`, similar to `DICTGET`, but with a `LDREF`; `ENDS` applied to `x` on success. This operation is useful for dictionaries of type `HashmapE(n, ˆY )`. +* `F40C` — `DICTIGET` `(i D n – x −1 or 0)`, similar to `DICTGET`, but with a signed (big-endian) n-bit `Integer` `i` as a key. If `i` does not fit into n bits, returns `0`. If `i` is a `NaN`, throws an integer overflow exception. +* `F40D` — `DICTIGETREF` `(i D n – c −1 or 0)`, combines `DICTIGET` with `DICTGETREF`: it uses signed n-bit `Integer` `i` as a key and returns a `Cell` instead of a `Slice` on success. +* `F40E` — `DICTUGET` `(i D n – x −1 or 0)`, similar to `DICTIGET`, but with unsigned (big-endian) n-bit `Integer` `i` used as a key. +* `F40F` — `DICTUGETREF` `(i D n – c −1 or 0)`, similar to `DICTIGETREF`, but with an unsigned n-bit `Integer` key `i`. -* `F40A` — **DICTGET** `(k D n – x −1 or 0)`, looks up key `k` (represented by a `Slice`, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the value found as a `Slice` `x`. -* `F40B` — **DICTGETREF** `(k D n – c −1 or 0)`, similar to **DICTGET**, but with a **LDREF**; **ENDS** applied to `x` on success. This operation is useful for dictionaries of type `HashmapE(n, ˆY )`. -* `F40C` — **DICTIGET** `(i D n – x −1 or 0)`, similar to **DICTGET**, but with a signed (big-endian) n-bit `Integer` `i` as a key. If `i` does not fit into n bits, returns `0`. If `i` is a `NaN`, throws an integer overflow exception. -* `F40D` — **DICTIGETREF** `(i D n – c −1 or 0)`, combines **DICTIGET** with **DICTGETREF**: it uses signed n-bit `Integer` `i` as a key and returns a `Cell` instead of a `Slice` on success. -* `F40E` — **DICTUGET** `(i D n – x −1 or 0)`, similar to **DICTIGET**, but with unsigned (big-endian) n-bit `Integer` `i` used as a key. -* `F40F` — **DICTUGETREF** `(i D n – c −1 or 0)`, similar to **DICTIGETREF**, but with an unsigned n-bit `Integer` key `i`. - 117 - A.10. Dictionary manipulation primitives ## A.10.4. Set/Replace/Add dictionary operations. The mnemonics of the following dictionary primitives are constructed in a systematic fashion according to the regular expression `DICT[, I, U](SET, REPLACE, ADD)[GET][REF]` depending on the type of the key used (a `Slice` or a signed or unsigned `Integer`), the dictionary operation to be performed, and the way the values are accepted and returned (as `Cells` or as `Slices`). Therefore, we provide a detailed description only for some primitives, assuming that this information is sufficient for the reader to understand the precise action of the remaining primitives. -* `F412` — **DICTSET** `(x k D n – D0)`, sets the value associated with n-bit key `k` (represented by a `Slice` as in **DICTGET**) in dictionary `D` (also represented by a `Slice`) to value `x` (again a `Slice`), and returns the resulting dictionary as `D0`. -* `F413` — **DICTSETREF** `(c k D n – D0)`, similar to **DICTSET**, but with the value set to a reference to `Cell` `c`. -* `F414` — **DICTISET** `(x i D n – D0)`, similar to **DICTSET**, but with the key represented by a (big-endian) signed n-bit integer `i`. If `i` does not fit into n bits, a range check exception is generated. -* `F415` — **DICTISETREF** `(c i D n – D0)`, similar to **DICTSETREF**, but with the key a signed n-bit integer as in **DICTISET**. -* `F416` — **DICTUSET** `(x i D n – D0)`, similar to **DICTISET**, but with `i` an unsigned n-bit integer. -* `F417` — **DICTUSETREF** `(c i D n – D0)`, similar to **DICTISETREF**, but with `i` unsigned. -* `F41A` — **DICTSETGET** `(x k D n – D0 y −1 or D0 0)`, combines **DICTSET** with **DICTGET**: it sets the value corresponding to key `k` to `x`, but also returns the old value `y` associated with the key in question, if present. -* `F41B` — **DICTSETGETREF** `(c k D n – D0 c 0 −1 or D0 0)`, combines **DICTSETREF** with **DICTGETREF** similarly to **DICTSETGET**. -* `F41C` — **DICTISETGET** `(x i D n – D0 y −1 or D0 0)`, similar to **DICTSETGET**, but with the key represented by a big-endian signed n-bit `Integer` `i` -* `F41D` — **DICTISETGETREF** `(c i D n – D0 c 0 −1 or D0 0)`, a version of **DICTSETGETREF** with signed `Integer` `i` as a key. -* `F41E` — **DICTUSETGET** `(x i D n – D0 y −1 or D0 0)`, similar to **DICTISETGET**, but with `i` an unsigned n-bit integer. -* `F41F` — **DICTUSETGETREF** `(c i D n – D0 c 0 −1 or D0 0)`. -* `F422` — **DICTREPLACE** `(x k D n – D0 −1 or D 0)`, a Replace operation, which is similar to **DICTSET**, but sets the value of key `k` in dictionary `D` to `x` only if the key `k` was already present in `D`. -* `F423` — **DICTREPLACEREF** `(c k D n – D0 −1 or D 0)`, a Replace counterpart of **DICTSETREF**. -* `F424` — **DICTIREPLACE** `(x i D n – D0 −1 or D 0)`, a version of **DICTREPLACE** with signed n-bit `Integer` `i` used as a key. -* `F425` — **DICTIREPLACEREF** `(c i D n – D0 −1 or D 0)`. -* `F426` — **DICTUREPLACE** `(x i D n – D0 −1 or D 0)`. -* `F427` — **DICTUREPLACEREF** `(c i D n – D0 −1 or D 0)`. -* `F42A` — **DICTREPLACEGET** `(x k D n – D0 y −1 or D 0)`, a Replace counterpart of **DICTSETGET**: on success, also returns the old value associated with the key in question. -* `F42B` — **DICTREPLACEGETREF** `(c k D n – D0 c 0 −1 or D 0)`. -* `F42C` — **DICTIREPLACEGET** `(x i D n – D0 y −1 or D 0)`. -* `F42D` — **DICTIREPLACEGETREF** `(c i D n – D0 c 0 −1 or D 0)`. -* `F42E` — **DICTUREPLACEGET** `(x i D n – D0 y −1 or D 0)`. -* `F42F` — **DICTUREPLACEGETREF** `(c i D n – D0 c 0 −1 or D 0)`. -* `F432` — **DICTADD** `(x k D n – D0 −1 or D 0)`, an Add counterpart of **DICTSET**: sets the value associated with key `k` in dictionary `D` to `x`, but only if it is not already present in `D`. -* `F433` — **DICTADDREF** `(c k D n – D0 −1 or D 0)`. - 119 - A.10. Dictionary manipulation primitives -* `F434` — **DICTIADD** `(x i D n – D0 −1 or D 0)`. -* `F435` — **DICTIADDREF** `(c i D n – D0 −1 or D 0)`. -* `F436` — **DICTUADD** `(x i D n – D0 −1 or D 0)`. -* `F437` — **DICTUADDREF** `(c i D n – D0 −1 or D 0)`. -* `F43A` — **DICTADDGET** `(x k D n – D0 −1 or D y 0)`, an Add counterpart of **DICTSETGET**: sets the value associated with key `k` in dictionary `D` to `x`, but only if key `k` is not already present in `D`. Otherwise, just returns the old value `y` without changing the dictionary. -* `F43B` — **DICTADDGETREF** `(c k D n – D0 −1 or D c0 0)`, an Add counterpart of **DICTSETGETREF**. -* `F43C` — **DICTIADDGET** `(x i D n – D0 −1 or D y 0)`. -* `F43D` — **DICTIADDGETREF** `(c i D n – D0 −1 or D c0 0)`. -* `F43E` — **DICTUADDGET** `(x i D n – D0 −1 or D y 0)`. -* `F43F` — **DICTUADDGETREF** `(c i D n – D0 −1 or D c0 0)`. - -## A.10.5. Builder-accepting variants of Set dictionary operations. - -The following primitives accept the new value as a `Builder` `b` instead of a `Slice` `x`, which often is more convenient if the value needs to be serialized from several components computed in the stack. (This is reflected by appending a `B` to the mnemonics of the corresponding Set primitives that work with `Slices`.) The net effect is roughly equivalent to converting `b` into a `Slice` by **ENDC**; **CTOS** and executing the corresponding primitive listed in A.10.4. - -* `F441` — **DICTSETB** `(b k D n – D0)`. -* `F442` — **DICTISETB** `(b i D n – D0)`. -* `F443` — **DICTUSETB** `(b i D n – D0)`. -* `F445` — **DICTSETGETB** `(b k D n – D0 y −1 or D0 0)`. -* `F446` — **DICTISETGETB** `(b i D n – D0 y −1 or D0 0)`. -* `F447` — **DICTUSETGETB** `(b i D n – D0 y −1 or D0 0)`. -* `F449` — **DICTREPLACEB** `(b k D n – D0 −1 or D 0)`. -* `F44A` — **DICTIREPLACEB** `(b i D n – D0 −1 or D 0)`. -* `F44B` — **DICTUREPLACEB** `(b i D n – D0 −1 or D 0)`. -* `F44D` — **DICTREPLACEGETB** `(b k D n – D0 y −1 or D 0)`. -* `F44E` — **DICTIREPLACEGETB** `(b i D n – D0 y −1 or D 0)`. -* `F44F` — **DICTUREPLACEGETB** `(b i D n – D0 y −1 or D 0)`. -* `F451` — **DICTADDB** `(b k D n – D0 −1 or D 0)`. -* `F452` — **DICTIADDB** `(b i D n – D0 −1 or D 0)`. -* `F453` — **DICTUADDB** `(b i D n – D0 −1 or D 0)`. -* `F455` — **DICTADDGETB** `(b k D n – D0 −1 or D y 0)`. -* `F456` — **DICTIADDGETB** `(b i D n – D0 −1 or D y 0)`. -* `F457` — **DICTUADDGETB** `(b i D n – D0 −1 or D y 0)`. - -## A.10.6. Delete dictionary operations. - -* `F459` — **DICTDEL** `(k D n – D0 −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0` and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. -* `F45A` — **DICTIDEL** `(i D n – D0 ?)`, a version of **DICTDEL** with the key represented by a signed n-bit `Integer` `i`. If `i` does not fit into n bits, simply returns `D 0` (“key not found, dictionary unmodified”). -* `F45B` — **DICTUDEL** `(i D n – D0 ?)`, similar to **DICTIDEL**, but with `i` an unsigned n-bit integer. -* `F462` — **DICTDELGET** `(k D n – D0 x −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0`, the original value `x` associated with the key `k` (represented by a `Slice`), and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. - 121 - A.10. Dictionary manipulation primitives -* `F463` — **DICTDELGETREF** `(k D n – D0 c −1 or D 0)`, similar to **DICTDELGET**, but with **LDREF**; **ENDS** applied to `x` on success, so that the value returned `c` is a `Cell`. -* `F464` — **DICTIDELGET** `(i D n – D0 x −1 or D 0)`, a variant of primitive **DICTDELGET** with signed n-bit integer `i` as a key. -* `F465` — **DICTIDELGETREF** `(i D n – D0 c −1 or D 0)`, a variant of primitive **DICTIDELGET** returning a `Cell` instead of a `Slice`. -* `F466` — **DICTUDELGET** `(i D n – D0 x −1 or D 0)`, a variant of primitive **DICTDELGET** with unsigned n-bit integer `i` as a key. -* `F467` — **DICTUDELGETREF** `(i D n – D0 c −1 or D 0)`, a variant of primitive **DICTUDELGET** returning a `Cell` instead of a `Slice`. - -## A.10.7. “Maybe reference” dictionary operations. +* `F412` — `DICTSET` `(x k D n – D0)`, sets the value associated with n-bit key `k` (represented by a `Slice` as in `DICTGET`) in dictionary `D` (also represented by a `Slice`) to value `x` (again a `Slice`), and returns the resulting dictionary as `D0`. +* `F413` — `DICTSETREF` `(c k D n – D0)`, similar to `DICTSET`, but with the value set to a reference to `Cell` `c`. +* `F414` — `DICTISET` `(x i D n – D0)`, similar to `DICTSET`, but with the key represented by a (big-endian) signed n-bit integer `i`. If `i` does not fit into n bits, a range check exception is generated. +* `F415` — `DICTISETREF` `(c i D n – D0)`, similar to `DICTSETREF`, but with the key a signed n-bit integer as in `DICTISET`. +* `F416` — `DICTUSET` `(x i D n – D0)`, similar to `DICTISET`, but with `i` an unsigned n-bit integer. +* `F417` — `DICTUSETREF` `(c i D n – D0)`, similar to `DICTISETREF`, but with `i` unsigned. +* `F41A` — `DICTSETGET` `(x k D n – D0 y −1 or D0 0)`, combines `DICTSET` with `DICTGET`: it sets the value corresponding to key `k` to `x`, but also returns the old value `y` associated with the key in question, if present. +* `F41B` — `DICTSETGETREF` `(c k D n – D0 c 0 −1 or D0 0)`, combines `DICTSETREF` with `DICTGETREF` similarly to `DICTSETGET`. +* `F41C` — `DICTISETGET` `(x i D n – D0 y −1 or D0 0)`, similar to `DICTSETGET`, but with the key represented by a big-endian signed n-bit `Integer` `i` +* `F41D` — `DICTISETGETREF` `(c i D n – D0 c 0 −1 or D0 0)`, a version of `DICTSETGETREF` with signed `Integer` `i` as a key. +* `F41E` — `DICTUSETGET` `(x i D n – D0 y −1 or D0 0)`, similar to `DICTISETGET`, but with `i` an unsigned n-bit integer. +* `F41F` — `DICTUSETGETREF` `(c i D n – D0 c 0 −1 or D0 0)`. +* `F422` — `DICTREPLACE` `(x k D n – D0 −1 or D 0)`, a Replace operation, which is similar to `DICTSET`, but sets the value of key `k` in dictionary `D` to `x` only if the key `k` was already present in `D`. +* `F423` — `DICTREPLACEREF` `(c k D n – D0 −1 or D 0)`, a Replace counterpart of `DICTSETREF`. +* `F424` — `DICTIREPLACE` `(x i D n – D0 −1 or D 0)`, a version of `DICTREPLACE` with signed n-bit `Integer` `i` used as a key. +* `F425` — `DICTIREPLACEREF` `(c i D n – D0 −1 or D 0)`. +* `F426` — `DICTUREPLACE` `(x i D n – D0 −1 or D 0)`. +* `F427` — `DICTUREPLACEREF` `(c i D n – D0 −1 or D 0)`. +* `F42A` — `DICTREPLACEGET` `(x k D n – D0 y −1 or D 0)`, a Replace counterpart of `DICTSETGET`: on success, also returns the old value associated with the key in question. +* `F42B` — `DICTREPLACEGETREF` `(c k D n – D0 c 0 −1 or D 0)`. +* `F42C` — `DICTIREPLACEGET` `(x i D n – D0 y −1 or D 0)`. +* `F42D` — `DICTIREPLACEGETREF` `(c i D n – D0 c 0 −1 or D 0)`. +* `F42E` — `DICTUREPLACEGET` `(x i D n – D0 y −1 or D 0)`. +* `F42F` — `DICTUREPLACEGETREF` `(c i D n – D0 c 0 −1 or D 0)`. +* `F432` — `DICTADD` `(x k D n – D0 −1 or D 0)`, an Add counterpart of `DICTSET`: sets the value associated with key `k` in dictionary `D` to `x`, but only if it is not already present in `D`. +* `F433` — `DICTADDREF` `(c k D n – D0 −1 or D 0)`. +* `F434` — `DICTIADD` `(x i D n – D0 −1 or D 0)`. +* `F435` — `DICTIADDREF` `(c i D n – D0 −1 or D 0)`. +* `F436` — `DICTUADD` `(x i D n – D0 −1 or D 0)`. +* `F437` — `DICTUADDREF` `(c i D n – D0 −1 or D 0)`. +* `F43A` — `DICTADDGET` `(x k D n – D0 −1 or D y 0)`, an Add counterpart of `DICTSETGET`: sets the value associated with key `k` in dictionary `D` to `x`, but only if key `k` is not already present in `D`. Otherwise, just returns the old value `y` without changing the dictionary. +* `F43B` — `DICTADDGETREF` `(c k D n – D0 −1 or D c0 0)`, an Add counterpart of `DICTSETGETREF`. +* `F43C` — `DICTIADDGET` `(x i D n – D0 −1 or D y 0)`. +* `F43D` — `DICTIADDGETREF` `(c i D n – D0 −1 or D c0 0)`. +* `F43E` — `DICTUADDGET` `(x i D n – D0 −1 or D y 0)`. +* `F43F` — `DICTUADDGETREF` `(c i D n – D0 −1 or D c0 0)`. + + +### A.10.5. Builder-accepting variants of Set dictionary operations. + +The following primitives accept the new value as a `Builder` `b` instead of a `Slice` `x`, which often is more convenient if the value needs to be serialized from several components computed in the stack. (This is reflected by appending a `B` to the mnemonics of the corresponding Set primitives that work with `Slices`.) The net effect is roughly equivalent to converting `b` into a `Slice` by `ENDC`; `CTOS` and executing the corresponding primitive listed in A.10.4. + +* `F441` — `DICTSETB` `(b k D n – D0)`. +* `F442` — `DICTISETB` `(b i D n – D0)`. +* `F443` — `DICTUSETB` `(b i D n – D0)`. +* `F445` — `DICTSETGETB` `(b k D n – D0 y −1 or D0 0)`. +* `F446` — `DICTISETGETB` `(b i D n – D0 y −1 or D0 0)`. +* `F447` — `DICTUSETGETB` `(b i D n – D0 y −1 or D0 0)`. +* `F449` — `DICTREPLACEB` `(b k D n – D0 −1 or D 0)`. +* `F44A` — `DICTIREPLACEB` `(b i D n – D0 −1 or D 0)`. +* `F44B` — `DICTUREPLACEB` `(b i D n – D0 −1 or D 0)`. +* `F44D` — `DICTREPLACEGETB` `(b k D n – D0 y −1 or D 0)`. +* `F44E` — `DICTIREPLACEGETB` `(b i D n – D0 y −1 or D 0)`. +* `F44F` — `DICTUREPLACEGETB` `(b i D n – D0 y −1 or D 0)`. +* `F451` — `DICTADDB` `(b k D n – D0 −1 or D 0)`. +* `F452` — `DICTIADDB` `(b i D n – D0 −1 or D 0)`. +* `F453` — `DICTUADDB` `(b i D n – D0 −1 or D 0)`. +* `F455` — `DICTADDGETB` `(b k D n – D0 −1 or D y 0)`. +* `F456` — `DICTIADDGETB` `(b i D n – D0 −1 or D y 0)`. +* `F457` — `DICTUADDGETB` `(b i D n – D0 −1 or D y 0)`. + +--- + +### A.10.6. Delete dictionary operations. + +* `F459` — `DICTDEL` `(k D n – D0 −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0` and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. +* `F45A` — `DICTIDEL` `(i D n – D0 ?)`, a version of `DICTDEL` with the key represented by a signed n-bit `Integer` `i`. If `i` does not fit into n bits, simply returns `D 0` (“key not found, dictionary unmodified”). +* `F45B` — `DICTUDEL` `(i D n – D0 ?)`, similar to `DICTIDEL`, but with `i` an unsigned n-bit integer. +* `F462` — `DICTDELGET` `(k D n – D0 x −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0`, the original value `x` associated with the key `k` (represented by a `Slice`), and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. +* `F463` — `DICTDELGETREF` `(k D n – D0 c −1 or D 0)`, similar to `DICTDELGET`, but with `LDREF`; `ENDS` applied to `x` on success, so that the value returned `c` is a `Cell`. +* `F464` — `DICTIDELGET` `(i D n – D0 x −1 or D 0)`, a variant of primitive `DICTDELGET` with signed n-bit integer `i` as a key. +* `F465` — `DICTIDELGETREF` `(i D n – D0 c −1 or D 0)`, a variant of primitive `DICTIDELGET` returning a `Cell` instead of a `Slice`. +* `F466` — `DICTUDELGET` `(i D n – D0 x −1 or D 0)`, a variant of primitive `DICTDELGET` with unsigned n-bit integer `i` as a key. +* `F467` — `DICTUDELGETREF` `(i D n – D0 c −1 or D 0)`, a variant of primitive `DICTUDELGET` returning a `Cell` instead of a `Slice`. + + +### A.10.7. “Maybe reference” dictionary operations. The following operations assume that a dictionary is used to store values `c ?` of type `Cell ?` (“Maybe `Cell`”), which can be used in particular to store dictionaries as values in other dictionaries. The representation is as follows: if `c ?` is a `Cell`, it is stored as a value with no data bits and exactly one reference to this `Cell`. If `c ?` is `Null`, then the corresponding key must be absent from the dictionary altogether. -* `F469` — **DICTGETOPTREF** `(k D n – c ? )`, a variant of **DICTGETREF** that returns `Null` instead of the value `c ?` if the key `k` is absent from dictionary `D`. -* `F46A` — **DICTIGETOPTREF** `(i D n – c ? )`, similar to **DICTGETOPTREF**, but with the key given by signed n-bit `Integer` `i`. If the key `i` is out of range, also returns `Null`. -* `F46B` — **DICTUGETOPTREF** `(i D n – c ? )`, similar to **DICTGETOPTREF**, but with the key given by unsigned n-bit `Integer` `i`. -* `F46D` — **DICTSETGETOPTREF** `(c ? k D n – D0 c˜ ? )`, a variant of both **DICTGETOPTREF** and **DICTSETGETREF** that sets the value corresponding to key `k` in dictionary `D` to `c ?` (if `c ?` is `Null`, then the key is deleted instead), and returns the old value `c˜ ?` (if the key `k` was absent before, returns `Null` instead). -* `F46E` — **DICTISETGETOPTREF** `(c ? i D n – D0 c˜ ? )`, similar to primitive **DICTSETGETOPTREF**, but using signed n-bit `Integer` `i` as a key. If `i` does not fit into n bits, throws a range checking exception. -* `F46F` — **DICTUSETGETOPTREF** `(c ? i D n – D0 c˜ ? )`, similar to primitive **DICTSETGETOPTREF**, but using unsigned n-bit `Integer` `i` as a key. +* `F469` — `DICTGETOPTREF` `(k D n – c ? )`, a variant of `DICTGETREF` that returns `Null` instead of the value `c ?` if the key `k` is absent from dictionary `D`. +* `F46A` — `DICTIGETOPTREF` `(i D n – c ? )`, similar to `DICTGETOPTREF`, but with the key given by signed n-bit `Integer` `i`. If the key `i` is out of range, also returns `Null`. +* `F46B` — `DICTUGETOPTREF` `(i D n – c ? )`, similar to `DICTGETOPTREF`, but with the key given by unsigned n-bit `Integer` `i`. +* `F46D` — `DICTSETGETOPTREF` `(c ? k D n – D0 c˜ ? )`, a variant of both `DICTGETOPTREF` and `DICTSETGETREF` that sets the value corresponding to key `k` in dictionary `D` to `c ?` (if `c ?` is `Null`, then the key is deleted instead), and returns the old value `c˜ ?` (if the key `k` was absent before, returns `Null` instead). +* `F46E` — `DICTISETGETOPTREF` `(c ? i D n – D0 c˜ ? )`, similar to primitive `DICTSETGETOPTREF`, but using signed n-bit `Integer` `i` as a key. If `i` does not fit into n bits, throws a range checking exception. +* `F46F` — `DICTUSETGETOPTREF` `(c ? i D n – D0 c˜ ? )`, similar to primitive `DICTSETGETOPTREF`, but using unsigned n-bit `Integer` `i` as a key. + -## A.10.8. Prefix code dictionary operations. +### A.10.8. Prefix code dictionary operations. These are some basic operations for constructing prefix code dictionaries (cf. 3.4.2). The primary application for prefix code dictionaries is deserializing TL-B serialized data structures, or, more generally, parsing prefix codes. Therefore, most prefix code dictionaries will be constant and created at compile time, not by the following primitives. Some Get operations for prefix code dictionaries may be found in A.10.11. Other prefix code dictionary operations include: -* `F470` — **PFXDICTSET** `(x k D n – D0 −1 or D 0)`. -* `F471` — **PFXDICTREPLACE** `(x k D n – D0 −1 or D 0)`. -* `F472` — **PFXDICTADD** `(x k D n – D0 −1 or D 0)`. -* `F473` — **PFXDICTDEL** `(k D n – D0 −1 or D 0)`. - -These primitives are completely similar to their non-prefix code counterparts **DICTSET** etc (cf. A.10.4), with the obvious difference that even a Set may fail in a prefix code dictionary, so a success flag must be returned by **PFXDICTSET** as well. - -## A.10.9. Variants of GetNext and GetPrev operations. - -* `F474` — **DICTGETNEXT** `(k D n – x 0 k 0 −1 or 0)`, computes the minimal key `k 0` in dictionary `D` that is lexicographically greater than `k`, and returns `k 0` (represented by a `Slice`) along with associated value `x 0` (also represented by a `Slice`). -* `F475` — **DICTGETNEXTEQ** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETNEXT**, but computes the minimal key `k 0` that is lexicographically greater than or equal to `k`. -* `F476` — **DICTGETPREV** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETNEXT**, but computes the maximal key `k 0` lexicographically smaller than `k`. - 123 - A.10. Dictionary manipulation primitives -* `F477` — **DICTGETPREVEQ** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETPREV**, but computes the maximal key `k 0` lexicographically smaller than or equal to `k`. -* `F478` — **DICTIGETNEXT** `(i D n – x 0 i 0 −1 or 0)`, similar to **DICTGETNEXT**, but interprets all keys in dictionary `D` as big-endian signed n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits). -* `F479` — **DICTIGETNEXTEQ** `(i D n – x 0 i 0 −1 or 0)`. -* `F47A` — **DICTIGETPREV** `(i D n – x 0 i 0 −1 or 0)`. -* `F47B` — **DICTIGETPREVEQ** `(i D n – x 0 i 0 −1 or 0)`. -* `F47C` — **DICTUGETNEXT** `(i D n – x 0 i 0 −1 or 0)`, similar to **DICTGETNEXT**, but interprets all keys in dictionary `D` as big-endian unsigned n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits, and is not necessarily nonnegative). -* `F47D` — **DICTUGETNEXTEQ** `(i D n – x 0 i 0 −1 or 0)`. -* `F47E` — **DICTUGETPREV** `(i D n – x 0 i 0 −1 or 0)`. -* `F47F` — **DICTUGETPREVEQ** `(i D n – x 0 i 0 −1 or 0)`. - -## A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. - -* `F482` — **DICTMIN** `(D n – x k −1 or 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. -* `F483` — **DICTMINREF** `(D n – c k −1 or 0)`, similar to **DICTMIN**, but returns the only reference in the value as a `Cell` `c`. -* `F484` — **DICTIMIN** `(D n – x i −1 or 0)`, somewhat similar to **DICTMIN**, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by **DICTMIN** and **DICTUMIN** -* `F485` — **DICTIMINREF** `(D n – c i −1 or 0)`. -* `F486` — **DICTUMIN** `(D n – x i −1 or 0)`, similar to **DICTMIN**, but returns the key as an unsigned n-bit `Integer` `i`. -* `F487` — **DICTUMINREF** `(D n – c i −1 or 0)`. -* `F48A` — **DICTMAX** `(D n – x k −1 or 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. -* `F48B` — **DICTMAXREF** `(D n – c k −1 or 0)`. -* `F48C` — **DICTIMAX** `(D n – x i −1 or 0)`. -* `F48D` — **DICTIMAXREF** `(D n – c i −1 or 0)`. -* `F48E` — **DICTUMAX** `(D n – x i −1 or 0)`. -* `F48F` — **DICTUMAXREF** `(D n – c i −1 or 0)`. -* `F492` — **DICTREMMIN** `(D n – D0 x k −1 or D 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. -* `F493` — **DICTREMMINREF** `(D n – D0 c k −1 or D 0)`, similar to **DICTREMMIN**, but returns the only reference in the value as a `Cell` `c`. -* `F494` — **DICTIREMMIN** `(D n – D0 x i −1 or D 0)`, somewhat similar to **DICTREMMIN**, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by **DICTREMMIN** and **DICTUREMMIN**. -* `F495` — **DICTIREMMINREF** `(D n – D0 c i −1 or D 0)`. -* `F496` — **DICTUREMMIN** `(D n – D0 x i −1 or D 0)`, similar to **DICTREMMIN**, but returns the key as an unsigned n-bit `Integer` `i`. -* `F497` — **DICTUREMMINREF** `(D n – D0 c i −1 or D 0)`. - 125 - A.10. Dictionary manipulation primitives -* `F49A` — **DICTREMMAX** `(D n – D0 x k −1 or D 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. -* `F49B` — **DICTREMMAXREF** `(D n – D0 c k −1 or D 0)`. -* `F49C` — **DICTIREMMAX** `(D n – D0 x i −1 or D 0)`. -* `F49D` — **DICTIREMMAXREF** `(D n – D0 c i −1 or D 0)`. -* `F49E` — **DICTUREMMAX** `(D n – D0 x i −1 or D 0)`. -* `F49F` — **DICTUREMMAXREF** `(D n – D0 c i −1 or D 0)`. - -## A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. - -* `F4A0` — **DICTIGETJMP** `(i D n – )`, similar to **DICTIGET** (cf. A.10.12), but with `x` **BLESS**ed into a continuation with a subsequent **JMPX** to it on success. On failure, does nothing. This is useful for implementing switch/case constructions. -* `F4A1` — **DICTUGETJMP** `(i D n – )`, similar to **DICTIGETJMP**, but performs **DICTUGET** instead of **DICTIGET**. -* `F4A2` — **DICTIGETEXEC** `(i D n – )`, similar to **DICTIGETJMP**, but with **EXECUTE** instead of **JMPX**. -* `F4A3` — **DICTUGETEXEC** `(i D n – )`, similar to **DICTUGETJMP**, but with **EXECUTE** instead of **JMPX**. -* `F4A6_n` — **DICTPUSHCONST n** `( – D n)`, pushes a non-empty constant dictionary `D` (as a `Cell ?`) along with its key length `0 ≤ n ≤ 1023`, stored as a part of the instruction. The dictionary itself is created from the first of remaining references of the current continuation. In this way, the complete **DICTPUSHCONST** instruction can be obtained by first serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and a cell reference), and then the unsigned 10-bit integer `n` (as if by a **STU 10** instruction). An empty dictionary can be pushed by a **NEWDICT** primitive (cf. A.10.1) instead. -* `F4A8` — **PFXDICTGETQ** `(s D n – s 0 x s00 −1 or s 0)`, looks up the unique prefix of `Slice` `s` present in the prefix code dictionary (cf. 3.4.2) represented by `Cell ?` `D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is returned as `s 0`, and the corresponding value (also a `Slice`) as `x`. The remainder of `s` is returned as a `Slice` `s 00`. If no prefix of `s` is a key in prefix code dictionary `D`, returns the unchanged `s` and a zero flag to indicate failure. -* `F4A9` — **PFXDICTGET** `(s D n – s 0 x s00)`, similar to **PFXDICTGET**, but throws a cell deserialization failure exception on failure. -* `F4AA` — **PFXDICTGETJMP** `(s D n – s 0 s 00 or s)`, similar to **PFXDICTGETQ**, but on success **BLESS**es the value `x` into a `Continuation` and transfers control to it as if by a **JMPX**. On failure, returns `s` unchanged and continues execution. -* `F4AB` — **PFXDICTGETEXEC** `(s D n – s 0 s 00)`, similar to **PFXDICTGETJMP**, but **EXEC**utes the continuation found instead of jumping to it. On failure, throws a cell deserialization exception. -* `F4AE_n` — **PFXDICTCONSTGETJMP n** or **PFXDICTSWITCH n** `(s – s 0 s 00 or s)`, combines **DICTPUSHCONST n** for `0 ≤ n ≤ 1023` with **PFXDICTGETJMP**. -* `F4BC` — **DICTIGETJMPZ** `(i D n – i or nothing)`, a variant of **DICTIGETJMP** that returns index `i` on failure. -* `F4BD` — **DICTUGETJMPZ** `(i D n – i or nothing)`, a variant of **DICTUGETJMP** that returns index `i` on failure. -* `F4BE` — **DICTIGETEXECZ** `(i D n – i or nothing)`, a variant of **DICTIGETEXEC** that returns index `i` on failure. -* `F4BF` — **DICTUGETEXECZ** `(i D n – i or nothing)`, a variant of **DICTUGETEXEC** that returns index `i` on failure. - -## A.10.12. SubDict dictionary operations. - -* `F4B1` — **SUBDICTGET** `(k l D n – D0)`, constructs a subdictionary consisting of all keys beginning with prefix `k` (represented by a `Slice`, the first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, - 127 - A.11. Application-specific primitives - returns the new subdictionary of the same type `HashmapE(n, X)` as a `Slice` `D0`. -* `F4B2` — **SUBDICTIGET** `(x l D n – D0)`, variant of **SUBDICTGET** with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. -* `F4B3` — **SUBDICTUGET** `(x l D n – D0)`, variant of **SUBDICTGET** with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. -* `F4B5` — **SUBDICTRPGET** `(k l D n – D0)`, similar to **SUBDICTGET**, but removes the common prefix `k` from all keys of the new dictionary `D0`, which becomes of type `HashmapE(n − l, X)`. -* `F4B6` — **SUBDICTIRPGET** `(x l D n – D0)`, variant of **SUBDICTRPGET** with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. -* `F4B7` — **SUBDICTURPGET** `(x l D n – D0)`, variant of **SUBDICTRPGET** with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. -* `F4BC–F4BF` — used by **DICT...Z** primitives in A.10.11. +* `F470` — `PFXDICTSET` `(x k D n – D0 −1 or D 0)`. +* `F471` — `PFXDICTREPLACE` `(x k D n – D0 −1 or D 0)`. +* `F472` — `PFXDICTADD` `(x k D n – D0 −1 or D 0)`. +* `F473` — `PFXDICTDEL` `(k D n – D0 −1 or D 0)`. + +These primitives are completely similar to their non-prefix code counterparts `DICTSET` etc (cf. A.10.4), with the obvious difference that even a Set may fail in a prefix code dictionary, so a success flag must be returned by `PFXDICTSET` as well. + +### A.10.9. Variants of GetNext and GetPrev operations. + +* `F474` — `DICTGETNEXT` `(k D n – x 0 k 0 −1 or 0)`, computes the minimal key `k 0` in dictionary `D` that is lexicographically greater than `k`, and returns `k 0` (represented by a `Slice`) along with associated value `x 0` (also represented by a `Slice`). +* `F475` — `DICTGETNEXTEQ` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETNEXT`, but computes the minimal key `k 0` that is lexicographically greater than or equal to `k`. +* `F476` — `DICTGETPREV` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETNEXT`, but computes the maximal key `k 0` lexicographically smaller than `k`. +* `F477` — `DICTGETPREVEQ` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETPREV`, but computes the maximal key `k 0` lexicographically smaller than or equal to `k`. +* `F478` — `DICTIGETNEXT` `(i D n – x 0 i 0 −1 or 0)`, similar to `DICTGETNEXT`, but interprets all keys in dictionary `D` as big-endian signed n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits). +* `F479` — `DICTIGETNEXTEQ` `(i D n – x 0 i 0 −1 or 0)`. +* `F47A` — `DICTIGETPREV` `(i D n – x 0 i 0 −1 or 0)`. +* `F47B` — `DICTIGETPREVEQ` `(i D n – x 0 i 0 −1 or 0)`. +* `F47C` — `DICTUGETNEXT` `(i D n – x 0 i 0 −1 or 0)`, similar to `DICTGETNEXT`, but interprets all keys in dictionary `D` as big-endian unsigned n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits, and is not necessarily nonnegative). +* `F47D` — `DICTUGETNEXTEQ` `(i D n – x 0 i 0 −1 or 0)`. +* `F47E` — `DICTUGETPREV` `(i D n – x 0 i 0 −1 or 0)`. +* `F47F` — `DICTUGETPREVEQ` `(i D n – x 0 i 0 −1 or 0)`. + +### A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. + +* `F482` — `DICTMIN` `(D n – x k −1 or 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. +* `F483` — `DICTMINREF` `(D n – c k −1 or 0)`, similar to `DICTMIN`, but returns the only reference in the value as a `Cell` `c`. +* `F484` — `DICTIMIN` `(D n – x i −1 or 0)`, somewhat similar to `DICTMIN`, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by `DICTMIN` and `DICTUMIN` +* `F485` — `DICTIMINREF` `(D n – c i −1 or 0)`. +* `F486` — `DICTUMIN` `(D n – x i −1 or 0)`, similar to `DICTMIN`, but returns the key as an unsigned n-bit `Integer` `i`. +* `F487` — `DICTUMINREF` `(D n – c i −1 or 0)`. +* `F48A` — `DICTMAX` `(D n – x k −1 or 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. +* `F48B` — `DICTMAXREF` `(D n – c k −1 or 0)`. +* `F48C` — `DICTIMAX` `(D n – x i −1 or 0)`. +* `F48D` — `DICTIMAXREF` `(D n – c i −1 or 0)`. +* `F48E` — `DICTUMAX` `(D n – x i −1 or 0)`. +* `F48F` — `DICTUMAXREF` `(D n – c i −1 or 0)`. +* `F492` — `DICTREMMIN` `(D n – D0 x k −1 or D 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. +* `F493` — `DICTREMMINREF` `(D n – D0 c k −1 or D 0)`, similar to `DICTREMMIN`, but returns the only reference in the value as a `Cell` `c`. +* `F494` — `DICTIREMMIN` `(D n – D0 x i −1 or D 0)`, somewhat similar to `DICTREMMIN`, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by `DICTREMMIN` and `DICTUREMMIN`. +* `F495` — `DICTIREMMINREF` `(D n – D0 c i −1 or D 0)`. +* `F496` — `DICTUREMMIN` `(D n – D0 x i −1 or D 0)`, similar to `DICTREMMIN`, but returns the key as an unsigned n-bit `Integer` `i`. +* `F497` — `DICTUREMMINREF` `(D n – D0 c i −1 or D 0)`. +* `F49A` — `DICTREMMAX` `(D n – D0 x k −1 or D 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. +* `F49B` — `DICTREMMAXREF` `(D n – D0 c k −1 or D 0)`. +* `F49C` — `DICTIREMMAX` `(D n – D0 x i −1 or D 0)`. +* `F49D` — `DICTIREMMAXREF` `(D n – D0 c i −1 or D 0)`. +* `F49E` — `DICTUREMMAX` `(D n – D0 x i −1 or D 0)`. +* `F49F` — `DICTUREMMAXREF` `(D n – D0 c i −1 or D 0)`. + +### A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. + +* `F4A0` — `DICTIGETJMP` `(i D n – )`, similar to `DICTIGET` (cf. A.10.12), but with `x` `BLESS`ed into a continuation with a subsequent `JMPX` to it on success. On failure, does nothing. This is useful for implementing switch/case constructions. +* `F4A1` — `DICTUGETJMP` `(i D n – )`, similar to `DICTIGETJMP`, but performs `DICTUGET` instead of `DICTIGET`. +* `F4A2` — `DICTIGETEXEC` `(i D n – )`, similar to `DICTIGETJMP`, but with `EXECUTE` instead of `JMPX`. +* `F4A3` — `DICTUGETEXEC` `(i D n – )`, similar to `DICTUGETJMP`, but with `EXECUTE` instead of `JMPX`. +* `F4A6_n` — `DICTPUSHCONST n` `( – D n)`, pushes a non-empty constant dictionary `D` (as a `Cell ?`) along with its key length `0 ≤ n ≤ 1023`, stored as a part of the instruction. The dictionary itself is created from the first of remaining references of the current continuation. In this way, the complete `DICTPUSHCONST` instruction can be obtained by first serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and a cell reference), and then the unsigned 10-bit integer `n` (as if by a `STU 10` instruction). An empty dictionary can be pushed by a `NEWDICT` primitive (cf. A.10.1) instead. +* `F4A8` — `PFXDICTGETQ` `(s D n – s 0 x s00 −1 or s 0)`, looks up the unique prefix of `Slice` `s` present in the prefix code dictionary (cf. 3.4.2) represented by `Cell ?` `D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is returned as `s 0`, and the corresponding value (also a `Slice`) as `x`. The remainder of `s` is returned as a `Slice` `s 00`. If no prefix of `s` is a key in prefix code dictionary `D`, returns the unchanged `s` and a zero flag to indicate failure. +* `F4A9` — `PFXDICTGET` `(s D n – s 0 x s00)`, similar to `PFXDICTGET`, but throws a cell deserialization failure exception on failure. +* `F4AA` — `PFXDICTGETJMP` `(s D n – s 0 s 00 or s)`, similar to `PFXDICTGETQ`, but on success `BLESS`es the value `x` into a `Continuation` and transfers control to it as if by a `JMPX`. On failure, returns `s` unchanged and continues execution. +* `F4AB` — `PFXDICTGETEXEC` `(s D n – s 0 s 00)`, similar to `PFXDICTGETJMP`, but `EXEC`utes the continuation found instead of jumping to it. On failure, throws a cell deserialization exception. +* `F4AE_n` — `PFXDICTCONSTGETJMP n` or `PFXDICTSWITCH n` `(s – s 0 s 00 or s)`, combines `DICTPUSHCONST n` for `0 ≤ n ≤ 1023` with `PFXDICTGETJMP`. +* `F4BC` — `DICTIGETJMPZ` `(i D n – i or nothing)`, a variant of `DICTIGETJMP` that returns index `i` on failure. +* `F4BD` — `DICTUGETJMPZ` `(i D n – i or nothing)`, a variant of `DICTUGETJMP` that returns index `i` on failure. +* `F4BE` — `DICTIGETEXECZ` `(i D n – i or nothing)`, a variant of `DICTIGETEXEC` that returns index `i` on failure. +* `F4BF` — `DICTUGETEXECZ` `(i D n – i or nothing)`, a variant of `DICTUGETEXEC` that returns index `i` on failure. + +### A.10.12. SubDict dictionary operations. + +* `F4B1` — `SUBDICTGET` `(k l D n – D0)`, constructs a subdictionary consisting of all keys beginning with prefix `k` (represented by a `Slice`, the first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the new subdictionary of the same type `HashmapE(n, X)` as a `Slice` `D0`. +* `F4B2` — `SUBDICTIGET` `(x l D n – D0)`, variant of `SUBDICTGET` with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. +* `F4B3` — `SUBDICTUGET` `(x l D n – D0)`, variant of `SUBDICTGET` with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. +* `F4B5` — `SUBDICTRPGET` `(k l D n – D0)`, similar to `SUBDICTGET`, but removes the common prefix `k` from all keys of the new dictionary `D0`, which becomes of type `HashmapE(n − l, X)`. +* `F4B6` — `SUBDICTIRPGET` `(x l D n – D0)`, variant of `SUBDICTRPGET` with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. +* `F4B7` — `SUBDICTURPGET` `(x l D n – D0)`, variant of `SUBDICTRPGET` with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. +* `F4BC–F4BF` — used by `DICT...Z` primitives in A.10.11. --- + # A.11 Application-specific primitives Opcode range `F8...FB` is reserved for the application-specific primitives. When TVM is used to execute TON Blockchain smart contracts, these application-specific primitives are in fact TON Blockchain-specific. -## A.11.1. External actions and access to blockchain configuration data. +### A.11.1. External actions and access to blockchain configuration data. Some of the primitives listed below pretend to produce some externally visible actions, such as sending a message to another smart contract. In fact, the execution of a smart contract in TVM never has any effect apart from a modification of the TVM state. All external actions are collected into a linked list stored in special register `c5` (“output actions”). Additionally, some primitives use the data kept in the first component of the Tuple stored in `c7` (“root of temporary data”, cf. 1.3.2). Smart contracts are free to modify any other data kept in the cell `c7`, provided the first reference remains intact (otherwise some application-specific primitives would be likely to throw exceptions when invoked). Most of the primitives listed below use 16-bit opcodes. -A.11. Application-specific primitives - -## A.11.2. Gas-related primitives. +### A.11.2. Gas-related primitives. Of the following primitives, only the first two are “pure” in the sense that they do not use `c5` or `c7`. -* `F800` — **ACCEPT**, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. 1.4), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence no gas) with themselves. -* `F801` — **SETGASLIMIT** `(g – )`, sets current gas limit `gl` to the minimum of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed so far (including the present instruction) exceeds the resulting value of `gl`, an (unhandled) out of gas exception is thrown before setting new gas limits. Notice that **SETGASLIMIT** with an argument `g ≥ 2^63 − 1` is equivalent to **ACCEPT**. -* `F802` — **BUYGAS** `(x – )`, computes the amount of gas that can be bought for `x` nanograms, and sets `gl` accordingly in the same way as **SETGASLIMIT**. -* `F804` — **GRAMTOGAS** `(x – g)`, computes the amount of gas that can be bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `2^63−1`, it is replaced with this value. -* `F805` — **GASTOGRAM** `(g – x)`, computes the price of `g` gas in nanograms. +* `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. 1.4), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence no gas) with themselves. +* `F801` — `SETGASLIMIT` `(g – )`, sets current gas limit `gl` to the minimum of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed so far (including the present instruction) exceeds the resulting value of `gl`, an (unhandled) out of gas exception is thrown before setting new gas limits. Notice that `SETGASLIMIT` with an argument `g ≥ 2^63 − 1` is equivalent to `ACCEPT`. +* `F802` — `BUYGAS` `(x – )`, computes the amount of gas that can be bought for `x` nanograms, and sets `gl` accordingly in the same way as `SETGASLIMIT`. +* `F804` — `GRAMTOGAS` `(x – g)`, computes the amount of gas that can be bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `2^63−1`, it is replaced with this value. +* `F805` — `GASTOGRAM` `(g – x)`, computes the price of `g` gas in nanograms. * `F806–F80E` — Reserved for gas-related primitives. -* `F80F` — **COMMIT** `( – )`, commits the current state of registers `c4` (“persistent data”) and `c5` (“actions”) so that the current execution is considered “successful” with the saved values even if an exception is thrown later. +* `F80F` — `COMMIT` `( – )`, commits the current state of registers `c4` (“persistent data”) and `c5` (“actions”) so that the current execution is considered “successful” with the saved values even if an exception is thrown later. + +--- -## A.11.3. Pseudo-random number generator primitives. +### A.11.3. Pseudo-random number generator primitives. The pseudo-random number generator uses the random seed (parameter `#6`, cf. A.11.4), an unsigned 256-bit `Integer`, and (sometimes) other data kept in `c7`. -The initial value of the random seed before a smart contract is executed in TON Blockchain is a hash of the smart contract address and the global block random seed. If there are several runs of the same smart contract inside a block, then all of these runs will have the same random seed. This can be fixed, for example, by running **LTIME**; **ADDRAND** before using the pseudo-random number generator for the first time. +The initial value of the random seed before a smart contract is executed in TON Blockchain is a hash of the smart contract address and the global block random seed. If there are several runs of the same smart contract inside a block, then all of these runs will have the same random seed. This can be fixed, for example, by running `LTIME`; `ADDRAND` before using the pseudo-random number generator for the first time. -* `F810` — **RANDU256** `( – x)`, generates a new pseudo-random unsigned 256-bit `Integer` `x`. The algorithm is as follows: if `r` is the old value of the random seed, considered as a 32-byte array (by constructing the big-endian representation of an unsigned 256-bit integer), then its `sha512(r)` is computed; the first 32 bytes of this hash are stored as the new value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`. -* `F811` — **RAND** `(y – z)`, generates a new pseudo-random integer `z` in the range `0 ... y − 1` (or `y ... − 1`, if `y < 0`). More precisely, an unsigned random value `x` is generated as in **RAND256U**; then `z := ⌊x·y/2^256⌋` is computed. Equivalent to **RANDU256**; **MULRSHIFT** `256`. -* `F814` — **SETRAND** `(x – )`, sets the random seed to unsigned 256-bit `Integer` `x`. -* `F815` — **ADDRAND** `(x – )`, mixes unsigned 256-bit `Integer` `x` into the random seed `r` by setting the random seed to `sha256` of the concatenation of two 32-byte strings: the first with the big-endian representation of the old seed `r`, and the second with the big-endian representation of `x`. +* `F810` — `RANDU256` `( – x)`, generates a new pseudo-random unsigned 256-bit `Integer` `x`. The algorithm is as follows: if `r` is the old value of the random seed, considered as a 32-byte array (by constructing the big-endian representation of an unsigned 256-bit integer), then its `sha512(r)` is computed; the first 32 bytes of this hash are stored as the new value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`. +* `F811` — `RAND` `(y – z)`, generates a new pseudo-random integer `z` in the range `0 ... y − 1` (or `y ... − 1`, if `y < 0`). More precisely, an unsigned random value `x` is generated as in `RAND256U`; then `z := ⌊x·y/2^256⌋` is computed. Equivalent to `RANDU256`; `MULRSHIFT` `256`. +* `F814` — `SETRAND` `(x – )`, sets the random seed to unsigned 256-bit `Integer` `x`. +* `F815` — `ADDRAND` `(x – )`, mixes unsigned 256-bit `Integer` `x` into the random seed `r` by setting the random seed to `sha256` of the concatenation of two 32-byte strings: the first with the big-endian representation of the old seed `r`, and the second with the big-endian representation of `x`. * `F810–F81F` — Reserved for pseudo-random number generator primitives. - `129` - A.11. Application-specific primitives -## A.11.4. Configuration primitives. +--- + +### A.11.4. Configuration primitives. The following primitives read configuration data provided in the Tuple stored in the first component of the Tuple at `c7`. Whenever TVM is invoked for executing TON Blockchain smart contracts, this Tuple is initialized by a `SmartContractInfo` structure; configuration primitives assume that it has remained intact. -* `F82i` — **GETPARAM** `i` `( – x)`, returns the `i`-th parameter from the Tuple provided at `c7` for `0 ≤ i < 16`. Equivalent to **PUSH** `c7`; **FIRST**; **INDEX** `i`. If one of these internal operations fails, throws an appropriate type checking or range checking exception -* `F823` — **NOW** `( – x)`, returns the current Unix time as an `Integer`. If it is impossible to recover the requested value starting from `c7`, throws a type checking or range checking exception as appropriate. Equivalent to **GETPARAM** `3`. -* `F824` — **BLOCKLT** `( – x)`, returns the starting logical time of the current block. Equivalent to **GETPARAM** `4`. -* `F825` — **LTIME** `( – x)`, returns the logical time of the current transaction. Equivalent to **GETPARAM** `5`. -* `F826` — **RANDSEED** `( – x)`, returns the current random seed as an unsigned 256-bit `Integer`. Equivalent to **GETPARAM** `6`. -* `F827` — **BALANCE** `( – t)`, returns the remaining balance of the smart contract as a `Tuple` consisting of an `Integer` (the remaining Gram balance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys representing the balance of “extra currencies”). Equivalent to **GETPARAM** `7`. Note that RAW primitives such as **SENDRAWMSG** do not update this field. -* `F828` — **MYADDR** `( – s)`, returns the internal address of the current smart contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed further using primitives such as **PARSESTDADDR** or **REWRITESTDADDR**. Equivalent to **GETPARAM** `8`. -* `F829` — **CONFIGROOT** `( – D)`, returns the `Maybe Cell` `D` with the current global configuration dictionary. Equivalent to **GETPARAM** `9`. -* `F830` — **CONFIGDICT** `( – D 32)`, returns the global configuration dictionary along with its key length (`32`). Equivalent to **CONFIGROOT**; **PUSHINT** `32`. -* `F832` — **CONFIGPARAM** `(i – c −1 or 0)`, returns the value of the global configuration parameter with integer index `i` as a `Cell` `c`, and a flag to indicate success. Equivalent to **CONFIGDICT**; **DICTIGETREF**. -* `F833` — **CONFIGOPTPARAM** `(i – c ? )`, returns the value of the global configuration parameter with integer index `i` as a `Maybe Cell` `c ?`. Equivalent to **CONFIGDICT**; **DICTIGETOPTREF**. +* `F82i` — `GETPARAM` `i` `( – x)`, returns the `i`-th parameter from the Tuple provided at `c7` for `0 ≤ i < 16`. Equivalent to `PUSH` `c7`; `FIRST`; `INDEX` `i`. If one of these internal operations fails, throws an appropriate type checking or range checking exception +* `F823` — `NOW` `( – x)`, returns the current Unix time as an `Integer`. If it is impossible to recover the requested value starting from `c7`, throws a type checking or range checking exception as appropriate. Equivalent to `GETPARAM` `3`. +* `F824` — `BLOCKLT` `( – x)`, returns the starting logical time of the current block. Equivalent to `GETPARAM` `4`. +* `F825` — `LTIME` `( – x)`, returns the logical time of the current transaction. Equivalent to `GETPARAM` `5`. +* `F826` — `RANDSEED` `( – x)`, returns the current random seed as an unsigned 256-bit `Integer`. Equivalent to `GETPARAM` `6`. +* `F827` — `BALANCE` `( – t)`, returns the remaining balance of the smart contract as a `Tuple` consisting of an `Integer` (the remaining Gram balance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys representing the balance of “extra currencies”). Equivalent to `GETPARAM` `7`. Note that RAW primitives such as `SENDRAWMSG` do not update this field. +* `F828` — `MYADDR` `( – s)`, returns the internal address of the current smart contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed further using primitives such as `PARSESTDADDR` or `REWRITESTDADDR`. Equivalent to `GETPARAM` `8`. +* `F829` — `CONFIGROOT` `( – D)`, returns the `Maybe Cell` `D` with the current global configuration dictionary. Equivalent to `GETPARAM` `9`. +* `F830` — `CONFIGDICT` `( – D 32)`, returns the global configuration dictionary along with its key length (`32`). Equivalent to `CONFIGROOT`; `PUSHINT` `32`. +* `F832` — `CONFIGPARAM` `(i – c −1 or 0)`, returns the value of the global configuration parameter with integer index `i` as a `Cell` `c`, and a flag to indicate success. Equivalent to `CONFIGDICT`; `DICTIGETREF`. +* `F833` — `CONFIGOPTPARAM` `(i – c ? )`, returns the value of the global configuration parameter with integer index `i` as a `Maybe Cell` `c ?`. Equivalent to `CONFIGDICT`; `DICTIGETOPTREF`. * `F820–F83F` — Reserved for configuration primitives. - `131` - A.11. Application-specific primitives - -## A.11.5. Global variable primitives. -The “global variables” may be helpful in implementing some high-level smart-contract languages. They are in fact stored as components of the Tuple at `c7`: the `k`-th global variable simply is the `k`-th component of this Tuple, for `1 ≤ k ≤ 254`. By convention, the `0`-th component is used for the “configuration parameters” of A.11.4, so it is not available as a global variable. - -* `F840` — **GETGLOBVAR** `(k – x)`, returns the `k`-th global variable for `0 ≤ k < 255`. Equivalent to **PUSH** `c7`; **SWAP**; **INDEXVARQ** (cf. A.3.2). -* `F85_k` — **GETGLOB** `k` `( – x)`, returns the `k`-th global variable for `1 ≤ k ≤ 31`. Equivalent to **PUSH** `c7`; **INDEXQ** `k`. -* `F860` — **SETGLOBVAR** `(x k – )`, assigns `x` to the `k`-th global variable for `0 ≤ k < 255`. Equivalent to **PUSH** `c7`; **ROTREV**; **SETINDEXVARQ**; **POP** `c7`. -* `F87_k` — **SETGLOB** `k` `(x – )`, assigns `x` to the `k`-th global variable for `1 ≤ k ≤ 31`. Equivalent to **PUSH** `c7`; **SWAP**; **SETINDEXQ** `k`; **POP** `c7`. +--- -## A.11.6. Hashing and cryptography primitives. +### A.11.6. Hashing and cryptography primitives. -* `F900` — **HASHCU** `(c – x)`, computes the representation hash (cf. 3.1.5) of a `Cell` `c` and returns it as a 256-bit unsigned integer `x`. Useful for signing and checking signatures of arbitrary entities represented by a tree of cells. -* `F901` — **HASHSU** `(s – x)`, computes the hash of a `Slice` `s` and returns it as a 256-bit unsigned integer `x`. The result is the same as if an ordinary cell containing only data and references from `s` had been created and its hash computed by **HASHCU**. -* `F902` — **SHA256U** `(s – x)`, computes `sha256` of the data bits of `Slice` `s`. If the bit length of `s` is not divisible by eight, throws a cell underflow exception. The hash value is returned as a 256-bit unsigned integer `x`. -* `F910` — **CHKSIGNU** `(h s k – ? )`, checks the Ed25519-signature `s` of a hash `h` (a 256-bit unsigned integer, usually computed as the hash of some data) using public key `k` (also represented by a 256-bit unsigned integer). The signature `s` must be a `Slice` containing at least 512 databits; only the first 512 bits are used. The result is `−1` if the signature is valid, `0` otherwise. Notice that **CHKSIGNU** is equivalent to **ROT**; **NEWB**; **STU** `256`; **ENDB**; **NEWC**; **ROTREV**; **CHKSIGNS**, i.e., to **CHKSIGNS** with the first argument `d` set to 256-bit `Slice` containing `h`. Therefore, if `h` is computed as the hash of some data, these data are hashed twice, the second hashing occurring inside **CHKSIGNS**. -* `F911` — **CHKSIGNS** `(d s k – ? )`, checks whether `s` is a valid Ed25519-signature of the data portion of `Slice` `d` using public key `k`, similarly to **CHKSIGNU**. If the bit length of `Slice` `d` is not divisible by eight, throws a cell underflow exception. The verification of Ed25519 signatures is the standard one, with `sha256` used to reduce `d` to the 256-bit number that is actually signed. +* `F900` — `HASHCU` `(c – x)`, computes the representation hash (cf. 3.1.5) of a `Cell` `c` and returns it as a 256-bit unsigned integer `x`. Useful for signing and checking signatures of arbitrary entities represented by a tree of cells. +* `F901` — `HASHSU` `(s – x)`, computes the hash of a `Slice` `s` and returns it as a 256-bit unsigned integer `x`. The result is the same as if an ordinary cell containing only data and references from `s` had been created and its hash computed by `HASHCU`. +* `F902` — `SHA256U` `(s – x)`, computes `sha256` of the data bits of `Slice` `s`. If the bit length of `s` is not divisible by eight, throws a cell underflow exception. The hash value is returned as a 256-bit unsigned integer `x`. +* `F910` — `CHKSIGNU` `(h s k – ? )`, checks the Ed25519-signature `s` of a hash `h` (a 256-bit unsigned integer, usually computed as the hash of some data) using public key `k` (also represented by a 256-bit unsigned integer). The signature `s` must be a `Slice` containing at least 512 databits; only the first 512 bits are used. The result is `−1` if the signature is valid, `0` otherwise. Notice that `CHKSIGNU` is equivalent to `ROT`; `NEWB`; `STU` `256`; `ENDB`; `NEWC`; `ROTREV`; `CHKSIGNS`, i.e., to `CHKSIGNS` with the first argument `d` set to 256-bit `Slice` containing `h`. Therefore, if `h` is computed as the hash of some data, these data are hashed twice, the second hashing occurring inside `CHKSIGNS`. +* `F911` — `CHKSIGNS` `(d s k – ? )`, checks whether `s` is a valid Ed25519-signature of the data portion of `Slice` `d` using public key `k`, similarly to `CHKSIGNU`. If the bit length of `Slice` `d` is not divisible by eight, throws a cell underflow exception. The verification of Ed25519 signatures is the standard one, with `sha256` used to reduce `d` to the 256-bit number that is actually signed. * `F912–F93F` — Reserved for hashing and cryptography primitives. -## A.11.7. Miscellaneous primitives. +--- + +### A.11.7. Miscellaneous primitives. -* `F940` — **CDATASIZEQ** `(c n – x y z −1 or 0)`, recursively computes the count of distinct cells `x`, data bits `y`, and cell references `z` in the dag rooted at `Cell` `c`, effectively returning the total storage used by this dag taking into account the identification of equal cells. The values of `x`, `y`, and `z` are computed by a depth-first traversal of this dag, with a hash table of visited cell hashes used to prevent visits of already-visited cells. The total count of visited cells `x` cannot exceed non-negative `Integer` `n`; otherwise the computation is aborted before visiting the `(n + 1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, returns `x = y = z = 0`. -* `F941` — **CDATASIZE** `(c n – x y z)`, a non-quiet version of **CDATASIZEQ** that throws a cell overflow exception (8) on failure. -* `F942` — **SDATASIZEQ** `(s n – x y z −1 or 0)`, similar to **CDATASIZEQ**, but accepting a `Slice` `s` instead of a `Cell`. The returned value of `x` does not take into account the cell that contains the slice `s` itself; however, the data bits and the cell references of `s` are accounted for in `y` and `z`. -* `F943` — **SDATASIZE** `(s n – x y z)`, a non-quiet version of **SDATASIZEQ** that throws a cell overflow exception (8) on failure. +* `F940` — `CDATASIZEQ` `(c n – x y z −1 or 0)`, recursively computes the count of distinct cells `x`, data bits `y`, and cell references `z` in the dag rooted at `Cell` `c`, effectively returning the total storage used by this dag taking into account the identification of equal cells. The values of `x`, `y`, and `z` are computed by a depth-first traversal of this dag, with a hash table of visited cell hashes used to prevent visits of already-visited cells. The total count of visited cells `x` cannot exceed non-negative `Integer` `n`; otherwise the computation is aborted before visiting the `(n + 1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, returns `x = y = z = 0`. +* `F941` — `CDATASIZE` `(c n – x y z)`, a non-quiet version of `CDATASIZEQ` that throws a cell overflow exception (8) on failure. +* `F942` — `SDATASIZEQ` `(s n – x y z −1 or 0)`, similar to `CDATASIZEQ`, but accepting a `Slice` `s` instead of a `Cell`. The returned value of `x` does not take into account the cell that contains the slice `s` itself; however, the data bits and the cell references of `s` are accounted for in `y` and `z`. +* `F943` — `SDATASIZE` `(s n – x y z)`, a non-quiet version of `SDATASIZEQ` that throws a cell overflow exception (8) on failure. * `F944–F97F` — Reserved for miscellaneous TON-specific primitives that do not fall into any other specific category. - `133` - A.11. Application-specific primitives -## A.11.8. Currency manipulation primitives. +--- + +### A.11.8. Currency manipulation primitives. -* `FA00` — **LDGRAMS** or **LDVARUINT16** `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to **LDU** `4`; **SWAP**; **LSHIFT** `3`; **LDUX**. -* `FA01` — **LDVARINT16** `(s – x s0)`, similar to **LDVARUINT16**, but loads a signed `Integer` `x`. Approximately equivalent to **LDU** `4`; **SWAP**; **LSHIFT** `3`; **LDIX**. -* `FA02` — **STGRAMS** or **STVARUINT16** `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2^120−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2^(8l)`, followed by an `8l`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. -* `FA03` — **STVARINT16** `(b x – b 0)`, similar to **STVARUINT16**, but serializes a signed `Integer` `x` in the range `−2^119 ... 2^119 − 1`. -* `FA04` — **LDVARUINT32** `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2^248`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to **LDU** `5`; **SWAP**; **SHIFT** `3`; **LDUX**. -* `FA05` — **LDVARINT32** `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2^247 ≤ x < 2^247`. -* `FA06` — **STVARUINT32** `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2^248` as a `VarUInteger 32`. -* `FA07` — **STVARINT32** `(b x – b 0)`, serializes an `Integer` `−2^247 ≤ x < 2^247` as a `VarInteger 32`. +* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU` `4`; `SWAP`; `LSHIFT` `3`; `LDUX`. +* `FA01` — `LDVARINT16` `(s – x s0)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU` `4`; `SWAP`; `LSHIFT` `3`; `LDIX`. +* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2^120−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2^(8l)`, followed by an `8l`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. +* `FA03` — `STVARINT16` `(b x – b 0)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2^119 ... 2^119 − 1`. +* `FA04` — `LDVARUINT32` `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2^248`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU` `5`; `SWAP`; `SHIFT` `3`; `LDUX`. +* `FA05` — `LDVARINT32` `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2^247 ≤ x < 2^247`. +* `FA06` — `STVARUINT32` `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2^248` as a `VarUInteger 32`. +* `FA07` — `STVARINT32` `(b x – b 0)`, serializes an `Integer` `−2^247 ≤ x < 2^247` as a `VarInteger 32`. * `FA08–FA1F` — Reserved for currency manipulation primitives. -## A.11.9. Message and address manipulation primitives. + +### A.11.9. Message and address manipulation primitives. The message and address manipulation primitives listed below serialize and deserialize values according to the following TL-B scheme (cf. 3.3.4): ``` addr_none$00 = MsgAddressExt; addr_extern$01 len:(## 8) external_address:(bits len) = MsgAddressExt; -anycast_info$_ depth:(#<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; +anycast_info$_ depth:(<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt; addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) workchain_id:int32 address:(bits addr_len) = MsgAddressInt; _ _:MsgAddressInt = MsgAddress; @@ -3800,74 +2658,71 @@ A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: The following primitives, which use the above conventions, are defined: -* `FA40` — **LDMSGADDR** `(s – s 0 s 00)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s 0` and the remainder `s 00` of `s` as `CellSlices`. -* `FA41` — **LDMSGADDRQ** `(s – s 0 s 00 −1 or s 0)`, a quiet version of **LDMSGADDR**: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. -* `FA42` — **PARSEMSGADDR** `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. -* `FA43` — **PARSEMSGADDRQ** `(s – t −1 or 0)`, a quiet version of **PARSEMSGADDR**: returns a zero on error instead of throwing an exception. -* `FA44` — **REWRITESTDADDR** `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. -* `FA45` — **REWRITESTDADDRQ** `(s – x y −1 or 0)`, a quiet version of primitive **REWRITESTDADDR**. -* `FA46` — **REWRITEVARADDR** `(s – x s0)`, a variant of **REWRITESTDADDR** that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). -* `FA47` — **REWRITEVARADDRQ** `(s – x s0 −1 or 0)`, a quiet version of primitive **REWRITEVARADDR**. +### A.11.9. Message and address manipulation primitives. + +* `FA40` — `LDMSGADDR` `(s – s 0 s 00)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s 0` and the remainder `s 00` of `s` as `CellSlices`. +* `FA41` — `LDMSGADDRQ` `(s – s 0 s 00 −1 or s 0)`, a quiet version of `LDMSGADDR`: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. +* `FA42` — `PARSEMSGADDR` `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. +* `FA43` — `PARSEMSGADDRQ` `(s – t −1 or 0)`, a quiet version of `PARSEMSGADDR`: returns a zero on error instead of throwing an exception. +* `FA44` — `REWRITESTDADDR` `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. +* `FA45` — `REWRITESTDADDRQ` `(s – x y −1 or 0)`, a quiet version of primitive `REWRITESTDADDR`. +* `FA46` — `REWRITEVARADDR` `(s – x s0)`, a variant of `REWRITESTDADDR` that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). +* `FA47` — `REWRITEVARADDRQ` `(s – x s0 −1 or 0)`, a quiet version of primitive `REWRITEVARADDR`. * `FA48–FA5F` — Reserved for message and address manipulation primitives. -## A.11.10. Outbound message and output action primitives. +### A.11.10. Outbound message and output action primitives. -* `FB00` — **SENDRAWMSG** `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. -* `FB02` — **RAWRESERVE** `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. -* `FB03` — **RAWRESERVEX** `(x D y – )`, similar to **RAWRESERVE**, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. - `137` - A.12. Debug primitives -* `FB04` — **SETCODE** `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. -* `FB06` — **SETLIBCODE** `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. -* `FB07` — **CHANGELIB** `(h x – )`, creates an output action similarly to **SETLIBCODE**, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. +* `FB00` — `SENDRAWMSG` `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. +* `FB02` — `RAWRESERVE` `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. +* `FB03` — `RAWRESERVEX` `(x D y – )`, similar to `RAWRESERVE`, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. +* `FB04` — `SETCODE` `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. +* `FB06` — `SETLIBCODE` `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. +* `FB07` — `CHANGELIB` `(h x – )`, creates an output action similarly to `SETLIBCODE`, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. * `FB08–FB3F` — Reserved for output action primitives. --- -# A.12 Debug primitives -Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) **NOP** operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. +## A.12 Debug primitives -## A.12.1. Debug primitives as multibyte NOPs. +Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) `NOP` operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. -`138` -A.12. Debug primitives +### A.12.1. Debug primitives as multibyte NOPs. -* `FEnn` — **DEBUG** `nn`, for `0 ≤ nn < 240`, is a two-byte **NOP**. -* `FEFnssss` — **DEBUGSTR** `ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte **NOP**, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. +* `FEnn` — `DEBUG nn`, for `0 ≤ nn < 240`, is a two-byte `NOP`. +* `FEFnssss` — `DEBUGSTR ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte `NOP`, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. -## A.12.2. Debug primitives as operations without side-effect. +### A.12.2. Debug primitives as operations without side-effect. -Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte **NOP**s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as **NOP**s, but they cannot throw exceptions. +Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte `NOP`s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as `NOP`s, but they cannot throw exceptions. -* `FE00` — **DUMPSTK**, dumps the stack (at most the top 255 values) and shows the total stack depth. -* `FE0n` — **DUMPSTKTOP** `n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. -* `FE10` — **HEXDUMP**, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. -* `FE11` — **HEXPRINT**, similar to **HEXDUMP**, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. -* `FE12` — **BINDUMP**, dumps `s0` in binary form, similarly to **HEXDUMP**. -* `FE13` — **BINPRINT**, outputs the binary representation of `s0` to a text buffer. -* `FE14` — **STRDUMP**, dumps the `Slice` at `s0` as an UTF-8 string. -* `FE15` — **STRPRINT**, similar to **STRDUMP**, but outputs the string into a text buffer (without carriage return). -* `FE1E` — **DEBUGOFF**, disables all debug output until it is re-enabled by a **DEBUGON**. More precisely, this primitive increases an internal counter, which disables all debug operations (except **DEBUGOFF** and **DEBUGON**) when strictly positive. - `139` - A.13. Codepage primitives -* `FE1F` — **DEBUGON**, enables debug output (in a debug version of TVM). -* `FE2n` — **DUMP s(n)**, `0 ≤ n < 15`, dumps `s(n)`. -* `FE3n` — **PRINT s(n)**, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. +* `FE00` — `DUMPSTK`, dumps the stack (at most the top 255 values) and shows the total stack depth. +* `FE0n` — `DUMPSTKTOP n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. +* `FE10` — `HEXDUMP`, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. +* `FE11` — `HEXPRINT`, similar to `HEXDUMP`, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. +* `FE12` — `BINDUMP`, dumps `s0` in binary form, similarly to `HEXDUMP`. +* `FE13` — `BINPRINT`, outputs the binary representation of `s0` to a text buffer. +* `FE14` — `STRDUMP`, dumps the `Slice` at `s0` as an UTF-8 string. +* `FE15` — `STRPRINT`, similar to `STRDUMP`, but outputs the string into a text buffer (without carriage return). +* `FE1E` — `DEBUGOFF`, disables all debug output until it is re-enabled by a `DEBUGON`. More precisely, this primitive increases an internal counter, which disables all debug operations (except `DEBUGOFF` and `DEBUGON`) when strictly positive. +* `FE1F` — `DEBUGON`, enables debug output (in a debug version of TVM). +* `FE2n` — `DUMP s(n)`, `0 ≤ n < 15`, dumps `s(n)`. +* `FE3n` — `PRINT s(n)`, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. * `FEC0–FEEF` — Use these opcodes for custom/experimental debug operations. -* `FEFnssss` — **DUMPTOSFMT** `ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). -* `FEFn00ssss` — **LOGSTR** `ssss`, string `ssss` is `n` bytes long. -* `FEF000` — **LOGFLUSH**, flushes all pending debug output from the buffer into the debug log. -* `FEFn01ssss` — **PRINTSTR** `ssss`, string `ssss` is `n` bytes long. +* `FEFnssss` — `DUMPTOSFMT ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). +* `FEFn00ssss` — `LOGSTR ssss`, string `ssss` is `n` bytes long. +* `FEF000` — `LOGFLUSH`, flushes all pending debug output from the buffer into the debug log. +* `FEFn01ssss` — `PRINTSTR ssss`, string `ssss` is `n` bytes long. -# A.13 Codepage primitives +--- -The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. 5.1.8). +## A.13 Codepage primitives -* `FFnn` — **SETCP** `nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. -* `FF00` — **SETCP0**, selects TVM (test) codepage zero as described in this document -* `FFFz` — **SETCP** `z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 . . . − 1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in B.2.6. Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. -* `FFF0` — **SETCPX** `(c – )`, selects codepage `c` with `−2^15 ≤ c < 2^15` passed in the top of the stack. +The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. 5.1.8). +* `FFnn` — `SETCP nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. +* `FF00` — `SETCP0`, selects TVM (test) codepage zero as described in this document. +* `FFFz` — `SETCP z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 ... −1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in B.2.6. Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. +* `FFF0` — `SETCPX` `(c – )`, selects codepage `c` with `−2^15 ≤ c < 2^15` passed in the top of the stack. --- # B Formal properties and specifications of TVM @@ -4013,7 +2868,7 @@ Codepage `−1` of TVM is reserved for the stripped-down version of TVM. Its mai ### B.2.7. Codepage −2. -This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage `−2`”. All 64-bit arithmetic used in codepage `−1` would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage `−1`. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer. +This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage −2”. All 64-bit arithmetic used in codepage −1 would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage −1. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer.[30](#footnote-30) --- @@ -4031,7 +2886,7 @@ We start with a comparison of machine code generated by an (imaginary) optimizin The source file we consider contains one function f that takes six (integer) arguments, a, b, c, d, e, f, and returns two (integer) values, x and y, which are the solutions of the system of two linear equations -``` +```math ( ax + by = e cx + dy = f @@ -4040,17 +2895,16 @@ cx + dy = f The source code of the function, in a programming language similar to C, might look as follows: -```c -(int, int) f(int a, int b, int c, int d, int e, int f) { -int D = a*d - b*c; -int Dx = e*d - b*f; -int Dy = a*f - e*c; -147 -C.1. Sample leaf function -return (Dx / D, Dy / D); + +```math +(int, int) f(int a, int b, int c, int d, int e, int f) \\ +{ \\ + int D = a*d - b*c; \\ + int Dx = e*d - b*f; \\ + int Dy = a*f - e*c; \\ + return (Dx / D, Dy / D); \\ } ``` - We assume (cf. 2.1) that the register machines we consider accept the six parameters a. . . f in registers r0. . . r5, and return the two values x and y in r0 and r1. We also assume that the register machines have 16 registers, and that the stack machine can directly access s0 to s15 by its stack manipulation primitives; the stack machine will accept the parameters in s5 to s0, and return the two values in s0 and s1, somewhat similarly to the register machine. Finally, we assume at first that the register machine is allowed to destroy values in all registers (which is slightly unfair towards the stack machine); this assumption will be revisited later. ### C.1.2. Three-address register machine. @@ -4097,7 +2951,7 @@ IDIV r1,r6 // r1 := Dy/D RET ``` -We have used 16 operations; optimistically assuming each of them (with the exception of RET) can be encoded by two bytes, this code would require 31 bytes.31 +We have used 16 operations; optimistically assuming each of them (with the exception of RET) can be encoded by two bytes, this code would require 31 bytes.[31](#footnote-31) ### C.1.4. One-address register machine. @@ -4382,7 +3236,7 @@ Table 4: A summary of machine code properties for hypothetical 3-address, 2-addr This section compares the machine code for different register machines for a sample non-leaf function. Again, we assume that either m = 0, m = 8, or m = 16 registers are preserved by called functions, with m = 8 representing the compromise made by most modern compilers and operating systems. -## C.3.1. Sample source code for a non-leaf function. +### C.3.1. Sample source code for a non-leaf function. A sample source file may be obtained by replacing the built-in integer type with a custom Rational type, represented by a pointer to an object in memory, in our function for solving systems of two linear equations (cf. C.1.1): @@ -4407,11 +3261,11 @@ Rational numbers will now be represented by pointers, addresses, or references, We assume that subroutines (or functions) are called by a special CALL instruction, which is encoded by three bytes, including the specification of the function to be called (e.g., the index in a “global function table”). -## C.3.2. Three-address and two-address register machines, m = 0 preserved registers. +### C.3.2. Three-address and two-address register machines, m = 0 preserved registers. Because our sample function does not use built-in arithmetic instructions at all, compilers for our hypothetical three-address and two-address register machines will produce the same machine code. Apart from the previously introduced PUSH r(i) and POP r(i) one-byte instructions, we assume that our two- and three-address machines support the following two-byte instructions: MOV r(i),s(j), MOV s(j),r(i), and XCHG r(i),s(j), for 0 ≤ i, j ≤ 15. Such instructions occupy only 3/256 of the opcode space, so their addition seems quite natural. -We first assume that m = 0 (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for r\_f does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. A size-optimizing compiler might produce the following code: +We first assume that m = 0 (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for `r_f` does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. A size-optimizing compiler might produce the following code: ``` PUSH r4 // STACK: e @@ -4459,9 +3313,9 @@ POP r0 // x ; .. RET ``` -We have used 41 instructions: 17 one-byte (eight PUSH/POP pairs and one RET), 13 two-byte (MOV and XCHG; out of them 11 “new” ones, involving the stack),and 11 three-byte (CALL), for a total of 17 · 1 + 13 · 2 + 11 · 3 = 76 bytes. +We have used 41 instructions: 17 one-byte (eight PUSH/POP pairs and one RET), 13 two-byte (MOV and XCHG; out of them 11 “new” ones, involving the stack),and 11 three-byte (CALL), for a total of 17 · 1 + 13 · 2 + 11 · 3 = 76 bytes.[32](#footnote-32) -## C.3.3. Three-address and two-address register machines, m = 8 preserved registers. +### C.3.3. Three-address and two-address register machines, m = 8 preserved registers. Now we have eight registers, r8 to r15, that are preserved by subroutine calls. We might keep some intermediate values there instead of pushing them into the stack. However, the penalty for doing so consists in a PUSH/POP pair for every such register that we choose to use, because our function is also required to preserve its original value. It seems that using these registers under such a penalty does not improve the density of the code, so the optimal code for three- and two-address machines for m = 8 preserved registers is the same as that provided in C.3.2, with a total of 42 instructions and 74 code bytes. @@ -4517,7 +3371,7 @@ RET We have used 39 instructions: 11 one-byte, 17 two-byte (among them 5 “new” instructions), and 11 three-byte, for a total of 11 · 1 + 17 · 2 + 11 · 3 = 78 bytes. Somewhat paradoxically, the code size in bytes is slightly longer than in the previous case (cf. C.3.2), contrary to what one might have expected. This is partially due to the fact that we have assumed two-byte encodings for “new” MOV and XCHG instructions involving the stack, similarly to the “old” instructions. Most existing architectures (such as x86-64) use longer encodings (maybe even twice as long) for their counterparts of our “new” move and exchange instructions compared to the “usual” register-register ones. Taking this into account, we see that we would have obtained here 83 bytes (versus 87 for the code in C.3.2) assuming three-byte encodings of new operations, and 88 bytes (versus 98) assuming four-byte encodings. This shows that, for two-address architectures without optimized encodings for register-stackmove and exchange operations, m = 16 preserved registers might result in slightly shorter code for some non-leaf functions, at the expense of leaf functions (cf. C.2.3 and C.2.4), which would become considerably longer. -## C.3.5. One-address register machine, m = 0 preserved registers. +### C.3.5. One-address register machine, m = 0 preserved registers. For our one-address register machine, we assume that new register-stack instructions work through the accumulator only. Therefore, we have three new instructions, LD s(j) (equivalent to MOV r0,s(j) of two-address machines), ST s(j) (equivalent to MOV s(j),r0), and XCHG s(j) (equivalent to XCHG r0,s(j)). To make the comparison with two-address machines more interesting, we assume one-byte encodings for these new instructions, even though this would consume 48/256 = 3/16 of the opcode space. @@ -4575,11 +3429,11 @@ RET We have used 45 instructions: 34 one-byte and 11 three-byte, for a total of 67 bytes. Compared to the 76 bytes used by two- and three-address machines in C.3.2, we see that, again, the one-address register machine code may be denser than that of two-register machines, at the expense of utilizing more opcode space (just as shown in C.2). However, this time the extra 3/16 of the opcode space was used for data manipulation instructions, which do not depend on specific arithmetic operations or user functions invoked. -## C.3.6. One-address register machine, m = 8 preserved registers. +### C.3.6. One-address register machine, m = 8 preserved registers. As explained in C.3.3, the preservation of r8–r15 between subroutine calls does not improve the size of our previously written code, so the one-address machine will use for m = 8 the same code provided in C.3.5. -## C.3.7. One-address register machine, m = 16 preserved registers. +### C.3.7. One-address register machine, m = 16 preserved registers. We simply adapt the code provided in C.3.4 to the one-address register machine: @@ -4629,7 +3483,7 @@ RET We have used 40 instructions: 18 one-byte, 11 two-byte, and 11 three-byte, for a total of 18 · 1 + 11 · 2 + 11 · 3 = 73 bytes. -## C.3.8. Stack machine with basic stack primitives. +### C.3.8. Stack machine with basic stack primitives. We reuse the code provided in C.1.5, simply replacing arithmetic primitives (VM instructions) with subroutine calls. The only substantive modification is the insertion of the previously optional XCHG s1 before the third multiplication, because even an optimizing compiler cannot now know whether CALL r\_mul is a commutative operation. We have also used the “tail recursion optimization” by replacing the final CALL r\_div followed by RET with JMP r\_div. @@ -4667,7 +3521,7 @@ JMP r_div // x y We have used 29 instructions; assuming one-byte encodings for all stack operations, and three-byte encodings for CALL and JMP instructions, we end up with 51 bytes. -## C.3.9. Stack machine with compound stack primitives. +### C.3.9. Stack machine with compound stack primitives. We again reuse the code provided in C.1.7, replacing arithmetic primitives with subroutine calls and making the tail recursion optimization: @@ -4760,7 +3614,9 @@ For example, the very popular two-address register architecture x86-64 produces An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in 2.2.2 and 2.2.5. The only exception is the unimportant “manual” XCHG3 optimization described in C.1.7, which enabled us to shorten the code by one more byte. By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. +## References + [1] N. Durov, *Telegram Open Network*, 2017. ## Footnotes @@ -4768,4 +3624,62 @@ By contrast, the heavily optimized (with respect to size) code for register mach **2.** The production version will likely require some tweaks and modifications prior to launch, which will become apparent only after using the experimental version in the test environment for some time. [Back ↑](#1-introduction) - **3.** A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. [Back ↑](#11-tvm-is-a-stack-machine) + **3.** A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. [Back ↑](#1-1-tvm-is-a-stack-machine) + + **4.** In the TON Blockchain context, `c7` is initialized with a singleton `Tuple`, the only component of which is a `Tuple` containing blockchain-specific data. The smart contract is free to modify `c7` to store its temporary data provided the first component of this `Tuple` remains intact. [Back ↑](#1-3-2-list-of-control-registers) + + **5.** Strictly speaking, there is also the current library context, which consists of a dictionary with 256-bit keys and cell values, used to load library reference cells of 3.1.7. [Back ↑](#1-4-total-state-of-tvm-scccg) + + **6.** Our inclusion of `r0` here creates a minor conflict with our assumption that the accumulator register, if present, is also `r0`; for simplicity, we will resolve this problem by assuming that the first argument to a function is passed in the accumulator. [Back ↑](#2-1-5-register-calling-conventions) + + **7.** For instance, if one writes a function for extracting square roots, this function will always accept its argument and return its result in the same registers, in contrast with a hypothetical built-in square root instruction, which could allow the programmer to arbitrarily choose the source and destination registers. Therefore, a user-defined function is tremendously less flexible than a built-in instruction on a register machine. [Back ↑](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines) + + **8.** Of course, if the second option is used, this will destroy the original arrangement of `x` in the top of the stack. In this case, one should either issue a `SWAP` before `XCHG s(j₀)`, or replace the previous operation `XCHG s(i)` with `XCHG s1, s(i)`, so that `x` is exchanged with `s1` from the beginning. [Back ↑](#2-2-2-basic-stack-manipulation-primitives-suffice) + + **9.** Notice that the most common `XCHG s(i)` operation is not really required here if we do not insist on keeping the same temporary value or variable always in the same stack location, but rather keep track of its subsequent locations. We will move it to some other location while preparing the arguments to the next primitive or function call. [Back ↑](#2-2-2-basic-stack-manipulation-primitives-suffice) + + **10.** An alternative, arguably better, translation of `PU O₀ s(i₁), …, s(iγ)` consists of the translation of `O₀ s(i₂), …, s(iγ)`, followed by `PUSH s(i₁ + α − 1); XCHG s(γ − 1)`. [Back ↑](#2-2-5-semantics-of-compound-stack-operations) + + **11.** From the perspective of low-level cell operations, these data bits and cell references are not intermixed. In other words, an (ordinary) cell essentially is a couple consisting of a list of up to 1023 bits and of a list of up to four cell references, without prescribing an order in which the references and the data bits should be deserialized, even though TL-B schemes appear to suggest such an order. [Back ↑](#3-1-1-tvm-memory-and-persistent-storage-consist-of-cells) + + **12.** From a theoretical perspective, we might say that a cell `c` has an infinite sequence of hashes `Hashᵢ(c)` (`i ≥ 1`), which eventually stabilizes: `Hashᵢ(c) → Hash∞(c)`. Then the level `l` is simply the largest index `i`, such that `Hashᵢ(c) ≠ Hash∞(c)`. [Back ↑](#3-1-7-types-of-exotic-cells) + + **13.** A pruned branch cell `c₀` of level `l` is bound by a Merkle (proof or update) cell `c` if there are exactly `l` Merkle cells on the path from `c` to its descendant `c₀`, including `c`. [Back ↑](#3-1-7-types-of-exotic-cells) + + **14.** Negative numbers are represented using two’s complement. For instance, integer `−17` is serialized by instruction `STI 8` into bitstring `xEF`. [Back ↑](#3-2-8-integers-in-cells-are-big-endian-by-default) + + **15.** A description of an older version of TL may be found at https://core.telegram.org/mtproto/TL. [Back ↑](#3-3-3-serialization-of-hashmaps) + + **16.** The field’s name is useful for representing values of the type being defined in human-readable form, but it does not affect the binary serialization. [Back ↑](#3-3-4-brief-explanation-of-tl-b-schemes) + + **17.** This is the “linear negation” operation `(-)^⊥` of linear logic, hence the notation `~`. [Back ↑](#3-3-4-brief-explanation-of-tl-b-schemes) + + **18.** In fact, `f` may receive `m` extra arguments and return `m` modified values, which are passed to the next invocation of `f`. This may be used to implement “map” and “reduce” operations with dictionaries. [Back ↑](#3-3-10-basic-dictionary-operations) + + **19.** Versions of this operation may be introduced where `f` and `g` receive an additional bitstring argument, equal to the key (for leaves) or to the common prefix of all keys (for forks) in the corresponding subtree. [Back ↑](#3-3-10-basic-dictionary-operations) + + **20.** If there are no bits of data left in `code`, but there is still exactly one reference, an implicit `JMP` to the cell at that reference is performed instead of an implicit `RET`. [Back ↑](#414-normal-work-of-tvm-or-the-main-loop) + + **21.** Technically, TVM may simply invoke a virtual method `run()` of the continuation currently in `cc`. [Back ↑](#415-extraordinary-continuations) + + **22.** The already used savelist `cc.save` of the new `cc` is emptied before the execution starts. [Back ↑](#418-restoring-control-registers-from-the-new-continuation-c) + + **23.** The implementation of REPEAT involves an extraordinary continuation that remembers the remaining number of iterations, the body of the loop c, and the return continuation c'. (The latter term represents the remainder of the body of the function that invoked REPEAT, which would be normally stored in c0 of the new cc.) [Back ↑](#422-iterated-execution-and-loops) + + **24.** An important point here is that the tree of cells representing a TVM program cannot have cyclic references, so using `CALLREF` along with a reference to a cell higher up the tree would not work. [Back ↑](#4-6-1-the-problem-of-recursion) + + **25.** This is not exactly true. A more precise statement is that usually the codepage of the newly-created continuation is a known function of the current codepage. [Back ↑](#5-1-1-codepages-in-continuations) + + **26.** This is another important mechanism of backward compatibility. All values of newly-added types, as well as values belonging to extended original types that do not belong to the original types (e.g., 513-bit integers that do not fit into 257 bits in the example above), are treated by all instructions (except stack manipulation instructions, which are naturally polymorphic, cf. [2.2.6](#2-2-6-stack-manipulation-instructions-are-polymorphic)) in the old codepages as “values of incorrect type”, and generate type-checking exceptions accordingly. [Back ↑](#5-1-4-changing-the-behavior-of-old-operations) + + **27.** If the cell dumps are hexadecimal, encodings consisting of an integral number of hexadecimal digits (i.e., having length divisible by four bits) might be equally convenient. [Back ↑](#5-2-5-tvm-code-is-a-bitcode-not-a-bytecode) + + **28.** Notice that it is the probability of occurrence in the code that counts, not the probability of being executed. An instruction occurring in the body of a loop executed a million times is still counted only once. [Back ↑](#5-2-9-almost-optimal-encodings) + + **29.** Notice that any modifications after launch cannot be done unilaterally; rather they would require the support of at least two-thirds of validators. [Back ↑](#5-3-1-upgradability) + + **30.** The preliminary version of TVM does not use codepage −2 for this purpose. This may change in the future. [Back ↑](#b27-codepage-2) + + **31.** It is interesting to compare this code with that generated by optimizing C compilers for the x86-64 architecture. First of all, the integer division operation for x86-64 uses the one-address form, with the (double-length) dividend to be supplied in accumulator pair `r2:r0`. The quotient is also returned in `r0`. As a consequence, two single-to-double extension operations (**CDQ** or **CQO**) and at least one move operation need to be added. Secondly, the encoding used for arithmetic and move operations is less optimistic than in our example above, requiring about three bytes per operation on average. As a result, we obtain a total of 43 bytes for 32-bit integers, and 68 bytes for 64-bit integers. [Back ↑](#c13-two-address-register-machine) + + **32.** Code produced for this function by an optimizing compiler for x86-64 architecture. [Back ↑](#c32-three-address-and-two-address-register-machines-m--0-preserved-registers) \ No newline at end of file From 438a6d2287217bc3e1ff4d63585e7140a84904f6 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Tue, 9 Sep 2025 03:18:51 +0100 Subject: [PATCH 04/18] more markdown updates --- ton/tvm.mdx | 3018 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 1965 insertions(+), 1053 deletions(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 75fedb0c..aa704237 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -104,7 +104,7 @@ All type tags attached to values processed by TVM will always have expected valu A preliminary list of value types supported by TVM is as follows: -- **Integer** — Signed 257-bit integers, representing integer numbers in the range `−2^256 … 2^256 − 1`, as well as a special “not-a-number” value `NaN`. +- **Integer** — Signed 257-bit integers, representing integer numbers in the range `−2²⁵⁶ … 2²⁵⁶ − 1`, as well as a special “not-a-number” value `NaN`. - **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. [1](#reference-1) 2.5.14]). - **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. - **Null** — A type with exactly one value `⊥`, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. @@ -179,7 +179,7 @@ Also notice that there are no general-purpose registers, because TVM is a stack ## 1.5 Integer arithmetic -All arithmetic primitives of TVM operate on several arguments of type `Integer`, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that `Integer` represents all integer values in the range `−2^256 ≤ x < 2^256`, and additionally contains a special value `NaN` (“not-a-number”). +All arithmetic primitives of TVM operate on several arguments of type `Integer`, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that `Integer` represents all integer values in the range `−2²⁵⁶ ≤ x < 2²⁵⁶`, and additionally contains a special value `NaN` (“not-a-number”). If one of the results does not fit into the supported range of integers—or if one of the arguments is a `NaN`—then this result or all of the results are replaced by a `NaN`, and (by default) an integer overflow exception is generated. However, special “quiet” versions of arithmetic operations will simply produce `NaN`s and keep going. If these `NaN`s end up being used in a “non-quiet” arithmetic operation, or in a non-arithmetic operation, an integer overflow exception will occur. @@ -191,11 +191,11 @@ Notice that TVM `Integer`s are “mathematical” integers, and not 257-bit stri Notice that all TVM arithmetic primitives perform overflow checks of the results. If a result does not fit into the `Integer` type, it is replaced by a `NaN`, and (usually) an exception occurs. -In particular, the result is not automatically reduced modulo `2^256` or `2^257`, as is common for most hardware machine code architectures. +In particular, the result is not automatically reduced modulo `−2²⁵⁶` or `2²⁵⁷`, as is common for most hardware machine code architectures. ### 1.5.3 Custom overflow checks -In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. These primitives check whether the value on (the top of) the stack is an integer `x` in the range `−2^(n−1) ≤ x < 2^(n−1)` or `0 ≤ x < 2^n`, respectively, and replace the value with a `NaN` and (optionally) generate an integer overflow exception if this is not the case. +In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. These primitives check whether the value on (the top of) the stack is an integer `x` in the range `−2ⁿ⁻¹ ≤ x < 2ⁿ⁻¹` or `0 ≤ x < 2ⁿ`, respectively, and replace the value with a `NaN` and (optionally) generate an integer overflow exception if this is not the case. This greatly simplifies the implementation of arbitrary n-bit integer types, signed or unsigned: the programmer or the compiler must insert appropriate `FITS` or `UFITS` primitives either after each arithmetic operation (which is more reasonable, but requires more checks) or before storing computed values and returning them from functions. @@ -203,7 +203,7 @@ This is important for smart contracts, where unexpected integer overflows happen ### 1.5.4 Reduction modulo 2ⁿ -TVM also has a primitive `MODPOW2 n`, which reduces the integer at the top of the stack modulo `2^n`, with the result ranging from `0` to `2^n − 1`. +TVM also has a primitive MODPOW2 n, which reduces the integer at the top of the stack modulo `2ⁿ`, with the result ranging from `0` to `2ⁿ − 1`. ### 1.5.5 Integer is 257-bit, not 256-bit @@ -233,7 +233,7 @@ If `c` is zero or if the quotient does not fit into `Integer`, either two `NaN`s # 2 The stack -This chapter contains a general discussion and comparison of register and stack machines, expanded further in [Appendix C](#appendix-c), and describes the two main classes of stack manipulation primitives employed by TVM: the basic and the compound stack manipulation primitives. An informal explanation of their sufficiency for all stack reordering required for correctly invoking other primitives and user-defined functions is also provided. Finally, the problem of efficiently implementing TVM stack manipulation primitives is discussed in [2.3](#2-3-...). +This chapter contains a general discussion and comparison of register and stack machines, expanded further in [Appendix C](#c-code-density-of-stack-and-register-machines), and describes the two main classes of stack manipulation primitives employed by TVM: the basic and the compound stack manipulation primitives. An informal explanation of their sufficiency for all stack reordering required for correctly invoking other primitives and user-defined functions is also provided. Finally, the problem of efficiently implementing TVM stack manipulation primitives is discussed in [2.3](#2-3-...). ## 2.1 Stack calling conventions @@ -271,7 +271,7 @@ For simplicity, we will assume that up to `m ≤ n` function arguments are passe ### 2.1.6 Order of function arguments -If a function or primitive requires `m` arguments `x1, …, xm`, they are pushed by the caller into the stack in the same order, starting from `x1`. Therefore, when the function or primitive is invoked, its first argument `x1` is in `s(m − 1)`, its second argument `x2` is in `s(m − 2)`, and so on. The last argument `xm` is in `s0` (i.e., at the top of the stack). It is the called function or primitive’s responsibility to remove its arguments from the stack. +If a function or primitive requires `m` arguments `x₁, …, xₘ`, they are pushed by the caller into the stack in the same order, starting from `x1`. Therefore, when the function or primitive is invoked, its first argument `x₁` is in `s(m − 1)`, its second argument `x₂` is in `s(m − 2)`, and so on. The last argument `xₘ` is in `s0` (i.e., at the top of the stack). It is the called function or primitive’s responsibility to remove its arguments from the stack. In this respect the TVM stack calling conventions—obeyed, at least, by TMV primitives—match those of Pascal and Forth, and are the opposite of those of C (in which the arguments are pushed into the stack in the reverse order, and are removed by the caller after it regains control, not the callee). @@ -307,13 +307,13 @@ In this respect TVM, again, faithfully observes Forth calling conventions. ### 2.1.10 Stack notation -When a stack of depth `n` contains values `z1, …, zn`, in that order, with `z1` the deepest element and `zn` the top of the stack, the contents of the stack are often represented by a list `z1 z2 … zn`, in that order. When a primitive transforms the original stack state `S₀` into a new state `S₀₀`, this is often written as `S₀ – S₀₀`; this is the so-called **stack notation**. +When a stack of depth n contains values `z₁, …, zₙ`, in that order, with z₁ the deepest element and `zₙ` the top of the stack, the contents of the stack are often represented by a list `z₁ z₂ … zₙ`, in that order.. When a primitive transforms the original stack state `S′` into a new state `S′′`, this is often written as `S′ – S′′`; this is the so-called **stack notation**. For example, the action of the division primitive `DIV` can be described by `S x y – S ⌊x/y⌋`, where `S` is any list of values. This is usually abbreviated as `x y – ⌊x/y⌋`, tacitly assuming that all other values deeper in the stack remain intact. -Alternatively, one can describe `DIV` as a primitive that runs on a stack `S₀` of depth `n ≥ 2`, divides `s1` by `s0`, and returns the floor-rounded quotient as `s0` of the new stack `S₀₀` of depth `n − 1`. The new value of `s(i)` equals the old value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `… x y` into `… ⌊x/y⌋`, is more concise. +Alternatively, one can describe `DIV` as a primitive that runs on a stack `S′′` of depth `n ≥ 2`, divides `s1` by `S0`, and returns the floor-rounded quotient as `s0` of the new stack `S′′` of depth `n − 1`. The new value of `s(i)` equals the old value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `… x y` into `… ⌊x/y⌋`, is more concise. -The stack notation is extensively used throughout [Appendix A](#appendix-a), where all currently defined TVM primitives are listed. +The stack notation is extensively used throughout [Appendix A](#a-instructions-and-opcodes), where all currently defined TVM primitives are listed. ### 2.1.11 Explicitly defining the number of arguments to a function @@ -325,7 +325,7 @@ Such argument-checking mechanisms might be useful, for example, for a library fu ## 2.2 Stack manipulation primitives -A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, so that they become located near the top of the stack in correct order. This section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some examples of code using these primitives can be found in [Appendix C](#appendix-c). +A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, so that they become located near the top of the stack in correct order. This section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some examples of code using these primitives can be found in [Appendix C](#c-code-density-of-stack-and-register-machines). ### 2.2.1 Basic stack manipulation primitives @@ -340,9 +340,9 @@ Some other “unsystematic” stack manipulation operations might be also define ### 2.2.2 Basic stack manipulation primitives suffice -A compiler or a human TVM-code programmer might use the basic stack primitives as follows. Suppose that the function or primitive to be invoked is to be passed, say, three arguments `x, y, z`, currently located in stack registers `s(i)`, `s(j)`, and `s(k)`. In this circumstance, the compiler (or programmer) might issue operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) or `XCHG s(i)` (if it will not be needed thereafter) to put the first argument `x` into the top of the stack. Then, the compiler (or programmer) could use either `PUSH s(j₀)` or `XCHG s(j₀)`, where `j₀ = j` or `j + 1`, to put `y` into the new top of the stack.[8](#footnote-8) +A compiler or a human TVM-code programmer might use the basic stack primitives as follows. Suppose that the function or primitive to be invoked is to be passed, say, three arguments `x, y, z`, currently located in stack registers `s(i)`, `s(j)`, and `s(k)`. In this circumstance, the compiler (or programmer) might issue operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) or `XCHG s(i)` (if it will not be needed thereafter) to put the first argument `x` into the top of the stack. Then, the compiler (or programmer) could use either `PUSH s(j′)` or `XCHG s(j′)`, where `j′ = j` or `j + 1`, to put `y` into the new top of the stack.[8](#footnote-8) -Proceeding in this manner, we see that we can put the original values of `x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using a sequence of push and exchange operations (cf. [2.2.4](#2-2-4-mnemonics-of-compound-stack-operations) and [2.2.5](#2-2-5-... ) for a more detailed explanation). In order to generate this sequence, the compiler will need to know only the three values `i, j, k`, describing the old locations of variables or temporary values in question, and some flags describing whether each value will be needed thereafter or is needed only for this primitive or function call. The locations of other variables and temporary values will be affected in the process, but a compiler (or a human programmer) can easily track their new locations. +Proceeding in this manner, we see that we can put the original values of `x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using a sequence of push and exchange operations (cf. [2.2.4](#2-2-4-mnemonics-of-compound-stack-operations) and [2.2.5](#2-2-5-semantics-of-compound-stack-operations) for a more detailed explanation). In order to generate this sequence, the compiler will need to know only the three values `i, j, k`, describing the old locations of variables or temporary values in question, and some flags describing whether each value will be needed thereafter or is needed only for this primitive or function call. The locations of other variables and temporary values will be affected in the process, but a compiler (or a human programmer) can easily track their new locations. Similarly, if the results returned from a function need to be discarded or moved to other stack registers, a suitable sequence of exchange and pop operations will do the job. In the typical case of one return value in `s0`, this is achieved either by an `XCHG s(i)` or a `POP s(i)` (in most cases, a `DROP`) operation.[9](#footnote-9) @@ -361,15 +361,15 @@ In order to improve the density of the TVM code and simplify development of comp Of course, such operations make sense only if they admit a more compact encoding than the equivalent sequence of basic operations. For example, if all top-of-stack exchanges, `XCHG s1,s(i)` exchanges, and push and pop operations admit one-byte encodings, the only compound stack operations suggested above that might merit inclusion in the set of stack manipulation primitives are `PUXC`, `XCHG3`, and `PUSH3`. -These compound stack operations essentially augment other primitives (instructions) in the code with the “true” locations of their operands, somewhat similarly to what happens with two-address or three-address register machine code. However, instead of encoding these locations inside the opcode of the arithmetic or another instruction, as is customary for register machines, we indicate these locations in a preceding compound stack manipulation operation. As already described in [2.1.7](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines), the advantage of such an approach is that user-defined functions (or rarely used specific primitives added in a future version of TVM) can benefit from it as well (cf. [C.3](#c-3-...) for a more detailed discussion with examples). +These compound stack operations essentially augment other primitives (instructions) in the code with the “true” locations of their operands, somewhat similarly to what happens with two-address or three-address register machine code. However, instead of encoding these locations inside the opcode of the arithmetic or another instruction, as is customary for register machines, we indicate these locations in a preceding compound stack manipulation operation. As already described in [2.1.7](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines), the advantage of such an approach is that user-defined functions (or rarely used specific primitives added in a future version of TVM) can benefit from it as well (cf. [C.3](#c-3-sample-non-leaf-function) for a more detailed discussion with examples). ### 2.2.4 Mnemonics of compound stack operations The mnemonics of compound stack operations, some examples of which have been provided in [2.2.3](#2-2-3-compound-stack-manipulation-primitives), are created as follows. -The `γ ≥ 2` formal arguments `s(i₁), …, s(i_γ)` to such an operation `O` represent the values in the original stack that will end up in `s(γ − 1), …, s0` after the execution of this compound operation, at least if all `iν`, `1 ≤ ν ≤ γ`, are distinct and at least `γ`. The mnemonic itself of the operation `O` is a sequence of `γ` two-letter strings `PU` and `XC`, with `PU` meaning that the corresponding argument is to be **PU**shed (i.e., a copy is to be created), and `XC` meaning that the value is to be **eX**Changed (i.e., no other copy of the original value is created). Sequences of several `PU` or `XC` strings may be abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, we write `PUXC2PU` instead of `PUXCXCPU`.) +The `γ ≥ 2` formal arguments `s(i₁), …, s(iγ)` to such an operation `O` represent the values in the original stack that will end up in `s(γ − 1), …, s₀` after the execution of this compound operation, at least if all `iᵥ, 1 ≤ ν ≤ γ`, are distinct and at least `γ`. The mnemonic itself of the operation `O` is a sequence of `γ` two-letter strings `PU` and `XC`, with `PU` meaning that the corresponding argument is to be PUshed (i.e., a copy is to be created), and `XC` meaning that the value is to be eXChanged (i.e., no other copy of the original value is created). Sequences of several `PU` or `XC` strings may be abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, we write `PUXC2PU` instead of `PUXCXCPU`.) -As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, so that the compound operation is equivalent to a sequence of `m` `PUSH`es or `eXCHanGe`s, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. +As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, so that the compound operation is equivalent to a sequence of `m` `PUSH`es or eXCHanGEs, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. ### 2.2.5 Semantics of compound stack operations @@ -379,11 +379,11 @@ Each compound γ-ary operation `O s(i₁), …, s(iγ)` is translated into an eq - Equivalently, we might begin the induction from γ = 1. Then `PU s(i)` corresponds to the sequence consisting of one basic operation `PUSH s(i)`, and `XC s(i)` corresponds to the one-element sequence consisting of `XCHG s(i)`. - For γ ≥ 1 (or for γ ≥ 2, if we use γ = 1 as induction base), there are two subcases: - 1. `O s(i₁), …, s(iγ)`, with `O = XC O₀`, where `O₀` is a compound operation of arity γ − 1 (i.e., the mnemonic of `O₀` consists of γ − 1 strings `XC` and `PU`). - Let α be the total quantity of **PU**shes in `O`, and β be that of eXChanges, so that α + β = γ. Then the original operation is translated into `XCHG s(β − 1), s(i₁)`, followed by the translation of `O₀ s(i₂), …, s(iγ)`, defined by the induction hypothesis. + 1. `O s(i₁), …, s(iγ)`, with `O = XC O′`, where `O′` is a compound operation of arity γ − 1 (i.e., the mnemonic of `O′` consists of γ − 1 strings `XC` and `PU`). + Let α be the total quantity of **PU**shes in `O`, and β be that of eXChanges, so that α + β = γ. Then the original operation is translated into `XCHG s(β − 1), s(i₁)`, followed by the translation of `O′ s(i₂), …, s(iγ)`, defined by the induction hypothesis. - 2. `O s(i₁), …, s(iγ)`, with `O = PU O₀`, where `O₀` is a compound operation of arity γ − 1. - Then the original operation is translated into `PUSH s(i₁); XCHG s(β)`, followed by the translation of `O₀ s(i₂ + 1), …, s(iγ + 1)`, defined by the induction hypothesis.[10](#footnote-10) + 2. `O s(i₁), …, s(iγ)`, with `O = PU O′`, where `O′` is a compound operation of arity γ − 1. + Then the original operation is translated into `PUSH s(i₁); XCHG s(β)`, followed by the translation of `O′s(i₂ + 1), …, s(iγ + 1)`, defined by the induction hypothesis.[10](#footnote-10) --- @@ -429,7 +429,7 @@ In other words, the programmer should always act as if the objects themselves we One might attempt to create a circular reference between two cells, `A` and `B`, as follows: first create `A` and write some data into it; then create `B` and write some data into it, along with a reference to previously constructed cell `A`; finally, add a reference to `B` into `A`. -While it may seem that after this sequence of operations we obtain a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. In fact, we obtain a new cell `A₀`, which contains a copy of the data originally stored into cell `A` along with a reference to cell `B`, which contains a reference to (the original) cell `A`. +While it may seem that after this sequence of operations we obtain a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. In fact, we obtain a new cell `A′`, which contains a copy of the data originally stored into cell `A` along with a reference to cell `B`, which contains a reference to (the original) cell `A`. In this way the transparent copy-on-write mechanism and the “everything is a value” paradigm enable us to create new cells using only previously constructed cells, thus forbidding the appearance of circular references. @@ -461,33 +461,33 @@ The type of an exotic cell is stored as the first eight bits of its data. If an ### 3.1.3 The level of a cell -Every cell `c` has another attribute `Lvl(c)` called its (de Brujn) **level**, which currently takes integer values in the range 0…3. +Every cell `c` has another attribute `Lvl(c)` called its (_de Brujn_) **level**, which currently takes integer values in the range 0…3. The level of an ordinary cell is always equal to the maximum of the levels of all its children `ci`: ```math Lvl(c) = max_{1 ≤ i ≤ r} Lvl(ci) -```` +``` -for an ordinary cell `c` containing `r` references to cells `c1, …, cr`. +For an ordinary cell `c` containing `r` references to cells `c₁, …, cᵣ`. If `r = 0`, then `Lvl(c) = 0`. Exotic cells may have different rules for setting their level. -A cell’s level affects the number of higher hashes it has. More precisely, a level `l` cell has `l` higher hashes `Hash₁(c), …, Hash_l(c)` in addition to its representation hash `Hash(c) = Hash∞(c)`. +A cell’s level affects the number of higher hashes it has. More precisely, a level `ℓ` cell has `ℓ` higher hashes `Hash₁(c), …, Hashℓ(c)` in addition to its representation hash `Hash(c) = Hash∞(c)`. Cells of non-zero level appear inside Merkle proofs and Merkle updates, after some branches of the tree of cells representing a value of an abstract data type are pruned. + ### 3.1.4 Standard cell representation When a cell needs to be transferred by a network protocol or stored in a disk file, it must be serialized. The standard representation `CellRepr(c) = CellRepr∞(c)` of a cell `c` as an octet (byte) sequence is constructed as follows: -1. Two descriptor bytes `d1` and `d2` are serialized first. - - * `d1 = r + 8s + 32l`, where `0 ≤ r ≤ 4` is the number of cell references contained in the cell, `0 ≤ l ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is 1 for exotic cells and 0 for ordinary cells. - * `d2 = ⌊b/8⌋ + ⌈b/8⌉`, where `0 ≤ b ≤ 1023` is the number of data bits in `c`. +1. Two descriptor bytes `d₁` and `d₂` are serialized first. + * Byte `d₁` equals `r + 8s + 32ℓ`, where `0 ≤ r ≤ 4` is the quantity of cell references contained in the cell, `0 ≤ ℓ ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is `1` for exotic cells and `0` for ordinary cells. + * Byte `d₂` equals `⌊b / 8⌋ + ⌈b / 8⌉`, where `0 ≤ b ≤ 1023` is the quantity of data bits in `c`. 2. Then the data bits are serialized as `⌈b/8⌉` 8-bit octets (bytes). If `b` is not a multiple of eight, a binary `1` and up to six binary `0`s are appended to the data bits. After that, the data is split into `⌈b/8⌉` eight-bit groups, and each group is interpreted as an unsigned big-endian integer 0…255 and stored into an octet. -3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(ci)` (explained in [3.1.5](#3-1-5-the-representation-hash-of-a-cell)) of the cell `ci` referred to. +3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(cᵢ)` (explained in [3.1.5](#3-1-5-the-representation-hash-of-a-cell)) of the cell `cᵢ` referred to. In this way, `2 + ⌈b/8⌉ + 32r` bytes of `CellRepr(c)` are obtained. @@ -503,14 +503,9 @@ Notice that cyclic cell references are not allowed and cannot be created by mean ### 3.1.6 The higher hashes of a cell -Recall that a cell `c` of level `l` has `l` higher hashes `Hashᵢ(c), 1 ≤ i ≤ l`, as well. Exotic cells have their own rules for computing their higher hashes. +Recall that a cell `c` of level `ℓ` has `ℓ` higher hashes `Hashᵢ(c)`, `1 ≤ i ≤ ℓ`, as well. Exotic cells have their own rules for computing their higher hashes. Higher hashes `Hashᵢ(c)` of an ordinary cell `c` are computed similarly to its representation hash, but using the higher hashes `Hashᵢ(cⱼ)` of its children `cⱼ` instead of their representation hashes `Hash(cⱼ)`. -Higher hashes `Hashᵢ(c)` of an ordinary cell `c` are computed similarly to its representation hash, but using the higher hashes `Hashᵢ(cj)` of its children `cj` instead of their representation hashes `Hash(cj)`. - -By convention: - -* `Hash∞(c) := Hash(c)` -* `Hashᵢ(c) := Hash∞(c) = Hash(c)` for all `i > l`. +By convention, we set `Hash∞(c) := Hash(c)`, and `Hashᵢ(c) := Hash∞(c) = Hash(c)` for all `i > ℓ`.[12](#footnote-13) ### 3.1.7 Types of exotic cells @@ -518,15 +513,15 @@ TVM currently supports the following cell types: * **Type −1: Ordinary cell** — Contains up to 1023 bits of data and up to four cell references. -* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ l ≤ 3`. - Contains exactly `8 + 256l` data bits: first an 8-bit integer equal to `1` (the cell’s type), then its `l` higher hashes `Hash₁(c), …, Hash_l(c)`. - The level `l` may be called its **de Brujn index**, because it determines the outer Merkle proof or Merkle update during which the branch has been pruned. +* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ ℓ ≤ 3`. + Contains exactly `8 + 256ℓ` data bits: first an 8-bit integer equal to `1` (the cell’s type), then its `ℓ` higher hashes `Hash₁(c), …, Hashℓ(c)`. + The level `ℓ` may be called its **de Brujn index**, because it determines the outer Merkle proof or Merkle update during which the branch has been pruned. An attempt to load a pruned branch cell usually leads to an exception. * **Type 2: Library reference cell** — Always has level 0, and contains `8 + 256` data bits, including its 8-bit type integer `2` and the representation hash `Hash(c₀)` of the library cell being referred to. When loaded, a library reference cell may be transparently replaced by the cell it refers to, if found in the current library context. -* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c₁` and level `0 ≤ l ≤ 3`, which must be one less than the level of its only child `c₁`: +* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c₁` and level `0 ≤ ℓ ≤ 3`, which must be one less than the level of its only child `c₁`: ```math Lvl(c) = max(Lvl(c₁) − 1, 0) @@ -537,7 +532,7 @@ TVM currently supports the following cell types: The higher hashes `Hashᵢ(c)` of `c` are computed similarly to the higher hashes of an ordinary cell, but with `Hashᵢ₊₁(c₁)` used instead of `Hashᵢ(c₁)`. When loaded, a Merkle proof cell is replaced by `c₁`. -* **Type 4: Merkle update cell `c`** — Has two children `c₁` and `c₂`. Its level `0 ≤ l ≤ 3` is given by: +* **Type 4: Merkle update cell `c`** — Has two children `c₁` and `c₂`. Its level `0 ≤ ℓ ≤ 3` is given by: ```math Lvl(c) = max(Lvl(c₁) − 1, Lvl(c₂) − 1, 0) @@ -621,7 +616,7 @@ The mnemonics of cell serialization primitives usually begin with `ST`. Subseque - The source of the field width in bits to be used (e.g., `X` for integer serialization instructions means that the bit width `n` is supplied in the stack; otherwise it has to be embedded into the instruction as an immediate value). - The action to be performed if the operation cannot be completed (by default, an exception is generated; “quiet” versions of serialization instructions are marked by a `Q` letter in their mnemonics). -This classification scheme is used to create a more complete taxonomy of cell serialization primitives, which can be found in [A.7.1](#a-7-1). +This classification scheme is used to create a more complete taxonomy of cell serialization primitives, which can be found in [A.7.1](#a-7-1-cell-serialization-primitives). ### 3.2.7 Integer serialization primitives @@ -629,10 +624,10 @@ Integer serialization primitives can be classified according to the above taxono - There are signed and unsigned (big-endian) integer serialization primitives. - The size `n` of the bit field to be used (`1 ≤ n ≤ 257` for signed integers, `0 ≤ n ≤ 256` for unsigned integers) can either come from the top of stack or be embedded into the instruction itself. -- If the integer `x` to be serialized is not in the range `−2^(n−1) ≤ x < 2^(n−1)` (for signed integer serialization) or `0 ≤ x < 2^n` (for unsigned integer serialization), a range check exception is usually generated, and if `n` bits cannot be stored into the provided Builder, a cell overflow exception is generated. +- If the integer x to be serialized is not in the range `−2ⁿ⁻¹ ≤ x < 2ⁿ⁻¹` (for signed integer serialization) or `0 ≤ x < 2ⁿ` (for unsigned integer serialization), a range check exception is usually generated, and if n bits cannot be stored into the provided Builder, a cell overflow exception is generated. - Quiet versions of serialization instructions do not throw exceptions; instead, they push `-1` on top of the resulting Builder upon success, or return the original Builder with `0` on top of it to indicate failure. -Integer serialization instructions have mnemonics like `STU 20` (“store an unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of variable length provided in the stack”). The full list of these instructions—including their mnemonics, descriptions, and opcodes—is provided in [A.7.1](#a-7-1). +Integer serialization instructions have mnemonics like `STU 20` (“store an unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of variable length provided in the stack”). The full list of these instructions—including their mnemonics, descriptions, and opcodes—is provided in [A.7.1](#a-7-1-cell-serialization-primitives). ### 3.2.8 Integers in cells are big-endian by default @@ -657,7 +652,7 @@ Cell parsing, or deserialization, primitives can be classified as described in [ For example, an unsigned big-endian 20-bit integer previously serialized into a cell by a `STU 20` instruction is likely to be deserialized later by a matching `LDU 20` instruction. -Again, more detailed information about these instructions is provided in [A.7.2](#a-7-2). +Again, more detailed information about these instructions is provided in [A.7.2](#a-7-2-cell-deserialization-primitives). ### 3.2.12 Other cell slice primitives @@ -687,7 +682,7 @@ Hashmaps, or dictionaries, are a specific data structure represented by a tree o The two most basic hashmap types predefined in TVM are `HashmapE n X` or `HashmapE(n, X)`, which represents a partially defined map from `n`-bit strings (called keys) for some fixed `0 ≤ n ≤ 1023` into values of some type `X`, and `Hashmap(n, X)`, which is similar to `HashmapE(n, X)` but is not allowed to be empty (i.e., it must contain at least one key-value pair). -Other hashmap types are also available—for example, one with keys of arbitrary length up to some predefined bound (up to 1023 bits). +Other hashmap types are also available — for example, one with keys of arbitrary length up to some predefined bound (up to `1023` bits). ### 3.3.2 Hashmaps as Patricia trees @@ -695,11 +690,11 @@ The abstract representation of a hashmap in TVM is a Patricia tree, or a compact It is easy to see that any collection of key-value pairs (with distinct keys) is represented by a unique Patricia tree. -### 3.3.3 Serialization of hashmaps +### 3.3.3 Serialization of hashmaps The serialization of a hashmap into a tree of cells (or, more generally, into a `Slice`) is defined by the following TL-B scheme:[15](#footnote-15) -```tlb +```c bit#_ _:(## 1) = Bit; hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(HashmapNode m X) = Hashmap n X; @@ -728,7 +723,7 @@ The left-hand side of each equation describes a way to define, or even to serial The constructor and its optional tag are followed by field definitions. Each field definition is of the form `ident : type-expr`, where ident is an identifier with the name of the field[16](#footnote-16) (replaced by an underscore for anonymous fields), and `type-expr` is the field’s type. The type provided here is a type expression, which may include simple types or parametrized types with suitable parameters. Variables—i.e., the (identifiers of the) previously defined fields of types `#` (natural numbers) or `Type` (type of types)—may be used as parameters for the parametrized types. The serialization process recursively serializes each field according to its type, and the serialization of a value ultimately consists of the concatenation of bitstrings representing the constructor (i.e., the constructor tag) and the field values. -Some fields may be implicit. Their definitions are surrounded by curly braces, which indicate that the field is not actually present in the serialization, but that its value must be deduced from other data (usually the parameters of the type being serialized). +Some fields may be _implicit_. Their definitions are surrounded by curly braces, which indicate that the field is not actually present in the serialization, but that its value must be deduced from other data (usually the parameters of the type being serialized). Some occurrences of “variables” (i.e., already-defined fields) are prefixed by a tilde. This indicates that the variable’s occurrence is used in the opposite way of the default behavior: in the left-hand side of the equation, it means that the variable will be deduced (computed) based on this occurrence, instead of substituting its previously computed value; in the right-hand side, conversely, it means that the variable will not be deduced from the type being serialized, but rather that it will be computed during the deserialization process. In other words, a tilde transforms an “input argument” into an “output argument”, and vice versa.[17](#footnote-17) @@ -740,15 +735,16 @@ Parametrized type `#<= p` with `p : #` (this notation means “p of type #”, i ### 3.3.5 Application to the serialization of hashmaps -Let us explain the net result of applying the general rules described in [3.3.4](#3-3-4-brief-explanation-of-tl-b-schemes) to the TL-B scheme presented in [3.3.3](#3-3-3-serialization-of-hashmaps). +Let us explain the net result of applying the general rules described in `3.3.4` to the TL-B scheme presented in [3.3.3](#3-3-3-serialization-of-hashmaps). -Suppose we wish to serialize a value of type `HashmapE n X` for some integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with `n`-bit keys and values of type `X`, admitting an abstract representation as a Patricia tree (cf. [3.3.2](#3-3-2-hashmaps-as-patricia-trees))). +Suppose we wish to serialize a value of type `HashmapE n X` for some integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with `n`-bit keys and values of type `X`, admitting an abstract representation as a Patricia tree, (cf. [3.3.2](#3-3-2-hashmaps-as-patricia-trees))). First of all, if our dictionary is empty, it is serialized into a single binary `0`, which is the tag of nullary constructor `hme_empty`. Otherwise, its serialization consists of a binary `1` (the tag of `hme_root`), along with a reference to a cell containing the serialization of a value of type `Hashmap n X` (i.e., a necessarily non-empty dictionary). -The only way to serialize a value of type `Hashmap n X` is given by the `hm_edge` constructor, which instructs us to serialize first the label `label` of the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel ~l n`, which means that it is a bitstring of length at most `n`, serialized in such a way that the true length `l` of the label, `0 ≤ l ≤ n`, becomes known from the serialization of the label. (This special serialization method is described separately in [3.3.6](#3-3-6-serialization-of-labels).) +The only way to serialize a value of type `Hashmap n X` is given by the `hm_edge` constructor, which instructs us to serialize first the label `label` of the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel_ℓ^n`, which means that it is a bitstring of length at most `n`, serialized in such a way that the true length `ℓ` of the label, `0 ≤ ℓ ≤ n`, becomes known from its serialization. + -The label must be followed by the serialization of a node of type `HashmapNode m X`, where `m = n − l`. It corresponds to a vertex of the Patricia tree, representing a non-empty subdictionary of the original dictionary with `m`-bit keys, obtained by removing from all the keys of the original subdictionary their common prefix of length `l`. +The label must be followed by the serialization of a node of type `HashmapNode m X`, where `m = n − ℓ`. It corresponds to a vertex of the Patricia tree, representing a non-empty subdictionary of the original dictionary with `m`-bit keys, obtained by removing from all the keys of the original subdictionary their common prefix of length `l`. If `m = 0`, a value of type `HashmapNode 0 X` is given by the `hmn_leaf` constructor, which describes a leaf of the Patricia tree—or, equivalently, a subdictionary with `0`-bit keys. A leaf simply consists of the corresponding value of type `X` and is serialized accordingly. @@ -756,11 +752,11 @@ On the other hand, if `m > 0`, a value of type `HashmapNode m X` corresponds to ### 3.3.6 Serialization of labels -There are several ways to serialize a label of length at most `n`, if its exact length is `l ≤ n` (recall that the exact length must be deducible from the serialization of the label itself, while the upper bound `n` is known before the label is serialized or deserialized). These ways are described by the three constructors `hml_short`, `hml_long`, and `hml_same` of type `HmLabel ~l n`: +There are several ways to serialize a label of length at most `n`, if its exact length is `ℓ ≤ n` (recall that the exact length must be deducible from the serialization of the label itself, while the upper bound `n` is known before the label is serialized or deserialized). These ways are described by the three constructors `hml_short`, `hml_long`, and `hml_same` of type `HmLabel ~l n`: -* **`hml_short`** — Describes a way to serialize “short” labels, of small length `l ≤ n`. Such a serialization consists of a binary `0` (the constructor tag of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary representation of the length `l`), followed by `l` bits comprising the label itself. -* **`hml_long`** — Describes a way to serialize “long” labels, of arbitrary length `l ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by `l` bits comprising the label itself. -* **`hml_same`** — Describes a way to serialize “long” labels, consisting of `l` repetitions of the same bit `v`. Such a serialization consists of `11` (the constructor tag of `hml_same`), followed by the bit `v`, followed by the length `l` stored in `⌈log2(n + 1)⌉` bits as before. +* **`hml_short`** — Describes a way to serialize “short” labels, of small length `ℓ ≤ n`. Such a serialization consists of a binary `0` (the constructor tag of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary representation of the length `l`), followed by `l` bits comprising the label itself. +* **`hml_long`** — Describes a way to serialize “long” labels, of arbitrary length `ℓ ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by `l` bits comprising the label itself. +* **`hml_same`** — Describes a way to serialize “long” labels, consisting of `ℓ` repetitions of the same bit `v`. Such a serialization consists of `11` (the constructor tag of `hml_same`), followed by the bit `v`, followed by the length `l` stored in `⌈log2(n + 1)⌉` bits as before. Each label can always be serialized in at least two different fashions, using `hml_short` or `hml_long` constructors. Usually the shortest serialization (and in the case of a tie—the lexicographically smallest among the shortest) is preferred and is generated by TVM hashmap primitives, while the other variants are still considered valid. @@ -772,7 +768,7 @@ Consider a dictionary with three 16-bit keys `13`, `17`, and `239` (considered a In binary form: -``` +```asm 0000000000001101 => 0000000010101001 0000000000010001 => 0000000100100001 0000000011101111 => 1101111100100001 @@ -782,7 +778,7 @@ The corresponding Patricia tree consists of a root `A`, two intermediate nodes ` The corresponding value of type `HashmapE 16 (## 16)` may be written in human-readable form as: -``` +```c (hme_root$1 root:^(hm_edge label:(hml_same$11 v:0 n:8) node:(hm_fork left:^(hm_edge label:(hml_short$0 len:$110 s:$00) node:(hm_fork @@ -796,7 +792,7 @@ The corresponding value of type `HashmapE 16 (## 16)` may be written in human-re The serialization of this data structure into a tree of cells consists of six cells with the following binary data contained in them: -``` +```asm A := 1 A.0 := 11 0 01000 A.0.0 := 0 110 00 @@ -807,7 +803,7 @@ A.0.1 := 10 111 1101111 1101111100100001 Here `A` is the root cell, `A.0` is the cell at the first reference of `A`, `A.1` is the cell at the second reference of `A`, and so on. This tree of cells can be represented more compactly using the hexadecimal notation described in [1.0](#1-0-notation-for-bitstrings), using indentation to reflect the tree-of-cells structure: -``` +```asm C_ C8 62_ @@ -824,9 +820,10 @@ Notice that the built-in TVM primitives for dictionary manipulation need to know * The simplest case is when `X = ^Y` for some other type `Y`. In this case the serialization of `X` itself always consists of one reference to a cell, which in fact must contain a value of type `Y`, something that is not relevant for dictionary manipulation primitives. * Another simple case is when the serialization of any value of type `X` always consists of `0 ≤ b ≤ 1023` data bits and `0 ≤ r ≤ 4` references. Integers `b` and `r` can then be passed to a dictionary manipulation primitive as a simple description of `X`. (Notice that the previous case corresponds to `b = 0, r = 1`.) -* A more sophisticated case can be described by four integers `1 ≤ b0, b1 ≤ 1023`, `0 ≤ r0, r1 ≤ 4`, with `b_i` and `r_i` used when the first bit of the serialization equals `i`. When `b0 = b1` and `r0 = r1`, this case reduces to the previous one. +* A more sophisticated case can be described by four integers `1 ≤ b₀, b₁ ≤ 1023`, `0 ≤ r₀, r₁ ≤ 4`, with `bᵢ` and `rᵢ` used when the first bit of the serialization equals `i`. When `b₀ = b₁` and `r₀ = r₁`, this case reduces to the previous one. * Finally, the most general description of the serialization of a type `X` is given by a splitting function `split_X` for `X`, which accepts one `Slice` parameter `s`, and returns two `Slice`s, `s'` and `s''`, where `s'` is the only prefix of `s` that is the serialization of a value of type `X`, and `s''` is the remainder of `s`. If no such prefix exists, the splitting function is expected to throw an exception. Notice that a compiler for a high-level language, which supports some or all algebraic TL-B types, is likely to automatically generate splitting functions for all types defined in the program. + ### 3.3.9 A simplifying assumption on the serialization of X One may notice that values of type `X` always occupy the remaining part of an `hm_edge/hmn_leaf` cell inside the serialization of a `HashmapE n X`. Therefore, if we do not insist on strict validation of all dictionaries accessed, we may assume that everything left unparsed in an `hm_edge/hmn_leaf` cell after deserializing its label is a value of type `X`. This greatly simplifies the creation of dictionary manipulation primitives, because in most cases they turn out not to need any information about `X` at all. @@ -835,7 +832,7 @@ One may notice that values of type `X` always occupy the remaining part of an `h Let us present a classification of basic operations with dictionaries (i.e., values D of type `HashmapE n X`): -- `GET(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns the corresponding value `D[k] : X?` kept in `D`. +- `GET(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns the corresponding value `D[k] : Xˀ` kept in `D`. - `SET(D, k, x)` — Given `D : HashmapE(n, X)`, a key `k : n·bit`, and a value `x : X`, sets `D′[k]` to `x` in a copy `D′` of `D`, and returns the resulting dictionary `D′` (cf. [2.3.4](#234-transparency-of-the-implementation-stack-values-are-values-not-references)). - `ADD(D, k, x)` — Similar to `SET`, but adds the key-value pair `(k, x)` to `D` only if key `k` is absent in `D`. - `REPLACE(D, k, x)` — Similar to `SET`, but changes `D′[k]` to `x` only if key `k` is already present in `D`. @@ -847,15 +844,16 @@ Let us present a classification of basic operations with dictionaries (i.e., val - `GETPREV(D, k)` — Computes the maximal key `k′ < k` (or `k′ ≤ k` in a variant) and returns it along with the corresponding value `x′ : X`. - `EMPTY(n)` — Creates an empty dictionary `D : HashmapE(n, X)`. - `ISEMPTY(D)` — Checks whether a dictionary is empty. -- `CREATE(n, {(ki, xi)})` — Given `n`, creates a dictionary from a list `(ki, xi)` of key-value pairs passed in stack. -- `GETSUBDICT(D, l, k0)` — Given `D : HashmapE(n, X)` and some `l`-bit string `k0 : l·bit` for `0 ≤ l ≤ n`, returns subdictionary `D′ = D/k0` of `D`, consisting of keys beginning with `k0`. The result `D′` may be of either type `HashmapE(n, X)` or type `HashmapE(n − l, X)`. -- `REPLACESUBDICT(D, l, k0, D0)` — Given `D : HashmapE(n, X)`, `0 ≤ l ≤ n`, `k0 : l · bit`, and `D0 : HashmapE(n − l, X)`, replaces with `D0` the subdictionary `D/k0` of `D` consisting of keys beginning with `k0`, and returns the resulting dictionary `D′′ : HashmapE(n, X)`. Some variants of `REPLACESUBDICT` may also return the old value of the subdictionary `D/k0` in question. -- `DELETESUBDICT(D, l, k0)` — Equivalent to `REPLACESUBDICT` with `D0` being an empty dictionary. -- `SPLIT(D)` — Given `D : HashmapE(n, X)`, returns `D0 := D/0` and `D1 := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with `0` and `1`, respectively. -- `MERGE(D0, D1)` — Given `D0` and `D1 : HashmapE(n − 1, X)`, computes `D : HashmapE(n, X)`, such that `D/0 = D0` and `D/1 = D1`. -- `FOREACH(D, f)` — Executes a function `f` with two arguments `k` and `x`, with `(k, x)` running over all key-value pairs of a dictionary `D` in lexicographical order.[18](#footnote-18) -- `FOREACHREV(D, f)` — Similar to `FOREACH`, but processes all key-value pairs in reverse order. -- `TREEREDUCE(D, o, f, g)` — Given `D : HashmapE(n, X)`, a value `o : X`, and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree reduction” of `D` by first applying `f` to all the leaves, and then using `g` to compute the value corresponding to a fork starting from the values assigned to its children.[19](#footnote-19) +- `CREATE(n, {(kᵢ, xᵢ)})` — Given `n`, creates a dictionary from a list `(kᵢ, xᵢ)` of key–value pairs passed in stack. +* **`GETSUBDICT(D, ℓ, k₀)`** — Given `D : HashmapE(n, X)` and some `ℓ`-bit string `k₀ : ℓ·bit` for `0 ≤ ℓ ≤ n`, returns subdictionary `D′ = D/k₀` of `D`, consisting of keys beginning with `k₀`. The result `D′` may be of either type `HashmapE(n, X)` or type `HashmapE(n − ℓ, X)`. +* **`REPLACESUBDICT(D, ℓ, k₀, D₀)`** — Given `D : HashmapE(n, X)`, `0 ≤ ℓ ≤ n`, `k₀ : ℓ·bit`, and `D₀ : HashmapE(n − ℓ, X)`, replaces with `D₀` the subdictionary `D/k₀` of `D` consisting of keys beginning with `k₀`, and returns the resulting dictionary `D′′ : HashmapE(n, X)`. Some variants of `REPLACESUBDICT` may also return the old value of the subdictionary `D/k₀` in question. +* **`DELETESUBDICT(D, ℓ, k₀)`** — Equivalent to `REPLACESUBDICT` with `D₀` being an empty dictionary. +* **`SPLIT(D)`** — Given `D : HashmapE(n, X)`, returns `D₀ := D/0` and `D₁ := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with `0` and `1`, respectively. +* **`MERGE(D₀, D₁)`** — Given `D₀` and `D₁ : HashmapE(n − 1, X)`, computes `D : HashmapE(n, X)` such that `D/0 = D₀` and `D/1 = D₁`. +* **`FOREACH(D, f)`** — Executes a function `f` with two arguments `k` and `x`, with `(k, x)` running over all key–value pairs of a dictionary `D` in lexicographical order. +* **`FOREACHREV(D, f)`** — Similar to `FOREACH`, but processes all key–value pairs in reverse order. +* **`TREEREDUCE(D, o, f, g)`** — Given `D : HashmapE(n, X)`, a value `o : X`, and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree reduction” of `D` by first applying `f` to all the leaves, and then using `g` to compute the value corresponding to a fork starting from the values assigned to its children. + ### 3.3.11 Taxonomy of dictionary primitives @@ -873,13 +871,13 @@ In addition, TVM includes special serialization/deserialization primitives, such ## 3.4 Hashmaps with variable-length keys -TVM provides some support for dictionaries, or hashmaps, with variable-length keys, in addition to its support for dictionaries with fixed-length keys (as described in [3.3](#33-hashmaps-or-dictionaries)). +TVM provides some support for dictionaries, or hashmaps, with variable-length keys, in addition to its support for dictionaries with fixed-length keys (as described in [3.3](#3-3-hashmaps%2C-or-dictionaries)). ### 3.4.1. Serialization of dictionaries with variable-length keys -The serialization of a `VarHashmap` into a tree of cells (or, more generally, into a `Slice`) is defined by a TL-B scheme, similar to that described in [3.3.3](#333-serialization-of-hashmaps): +The serialization of a `VarHashmap` into a tree of cells (or, more generally, into a `Slice`) is defined by a TL-B scheme, similar to that described in [3.3.3](#3-3-3-serialization-of-hashmaps): -```tl-b +```c vhm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(VarHashmapNode m X) = VarHashmap n X; @@ -910,7 +908,7 @@ One special case of a dictionary with variable-length keys is that of a **prefix The serialization of a prefix code is defined by the following TL-B scheme: -```tl-b +```c phm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(PfxHashmapNode m X) = PfxHashmap n X; @@ -937,15 +935,15 @@ We conclude this chapter with a discussion of the problem of recursion and of fa ## 4.1 Continuations and subroutines -Recall (cf. [1.1.3](#113-preliminary-list-of-value-types)) that Continuation values represent “execution tokens” that can be executed later—for example, by `EXECUTE` = `CALLX` (“execute” or “call indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations are responsible for the execution of the program, and are heavily used by control flow primitives, enabling subroutine calls, conditional expressions, loops, and so on. +Recall (cf. [1.1.3](#1-1-3-preliminary-list-of-value-types)) that Continuation values represent “execution tokens” that can be executed later—for example, by `EXECUTE` = `CALLX` (“execute” or “call indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations are responsible for the execution of the program, and are heavily used by control flow primitives, enabling subroutine calls, conditional expressions, loops, and so on. ### 4.1.1 Ordinary continuations The most common kind of continuations are the ordinary continuations, containing the following data: -* A Slice `code` (cf. [1.1.3](#113-preliminary-list-of-value-types) and [3.2.2](#322-builder-and-slice-values)), containing (the remainder of) the TVM code to be executed. +* A Slice `code` (cf. [1.1.3](#1-1-3-preliminary-list-of-value-types) and [3.2.2](#3-2-2-builder-and-slice-values)), containing (the remainder of) the TVM code to be executed. * A (possibly empty) Stack `stack`, containing the original contents of the stack for the code to be executed. -* A (possibly empty) list `save` of pairs `(c(i), vi)` (also called “savelist”), containing the values of control registers to be restored before the execution of the code. +* A (possibly empty) list `save` of pairs `(c(i), vᵢ)` (also called “savelist”), containing the values of control registers to be restored before the execution of the code. * A 16-bit integer value `cp`, selecting the TVM codepage used to interpret the TVM code from `code`. * An optional non-negative integer `nargs`, indicating the number of arguments expected by the continuation. @@ -963,7 +961,7 @@ TVM usually performs the following operations: If the current continuation `cc` is an ordinary one, it decodes the first instruction from the Slice `code`, similarly to the way other cells are deserialized by TVM `LD*` primitives (cf. [3.2](#3-2-data-manipulation-instructions-and-cells) and [3.2.11](#3-2-11-taxonomy-of-cell-deserialisation-primitives)): it decodes the opcode first, and then the parameters of the instruction (e.g., 4-bit fields indicating “stack registers” involved for stack manipulation primitives, or constant values for “push constant” or “literal” primitives). The remainder of the Slice is then put into the code of the new `cc`, and the decoded operation is executed on the current stack. This entire process is repeated until there are no operations left in `cc.code`. -If the code is empty (i.e., contains no bits of data and no references), or if a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, the current continuation is discarded, and the “return continuation” from control register `c0` is loaded into `cc` instead (this process is discussed in more detail starting in [4.1.6](#416-switching-to-another-continuation-jmp-and-ret)).[20](#footnote-20) Then the execution continues by parsing operations from the new current continuation. +If the code is empty (i.e., contains no bits of data and no references), or if a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, the current continuation is discarded, and the “return continuation” from control register `c0` is loaded into `cc` instead (this process is discussed in more detail starting in [4.1.6](#4-1-6-switching-to-another-continuation%3A-jmp-and-ret)).[20](#footnote-20) Then the execution continues by parsing operations from the new current continuation. ### 4.1.5 Extraordinary continuations @@ -1049,8 +1047,6 @@ Because constant continuations are very often used as arguments to conditional o --- -# 4 Control flow, continuations, and exceptions - ## 4.3 Operations with continuations ### 4.3.1 Continuations are opaque @@ -1114,14 +1110,8 @@ Some “experimental” primitives also involve `c1` and `◦1`. For example: * Conditional versions of `RET` and `RETALT` may also be useful: `RETBOOL` takes an integer `x` from the stack, and performs `RETTRUE` if `x ≠ 0`, `RETFALSE` otherwise. * `INVERT` does `c0 ↔ c1`; if the two continuations in `c0` and `c1` represent the two branches we should select depending on some boolean expression, `INVERT` negates this expression on the outer level. * `INVERTCONT` does `c.c0 ↔ c.c1` to a continuation `c` taken from the stack. -* Variants of `ATEXIT` include `ATEXITALT (c1 ← c ◦1 c1)` and `SETEXITALT (c1 ← (c ◦0 c0) ◦1 c1)`. -* `BOOLEVAL` takes a continuation `c` from the stack and does: - - ``` - cc ← (c ◦0 (PUSH −1)) ◦1 (PUSH0) ◦0 cc - ``` - - If `c` represents a boolean circuit, the net effect is to evaluate it and push either `−1` or `0` into the stack before continuing. +* Variants of `ATEXIT` include `ATEXITALT (c1 ← c◦₁ c1)` and `SETEXITALT (c1 ← (c◦₀ c0) ◦₁ c1)`. +* `BOOLEVAL` takes a continuation `c` from the stack and does `cc ← (c◦₀ (PUSH−1))◦₁ (PUSH0)◦₀ cc`. If `c` represents a boolean circuit, the net effect is to evaluate it and push either `−1` or `0` into the stack before continuing. --- @@ -1131,7 +1121,7 @@ Some “experimental” primitives also involve `c1` and `◦1`. For example: Object-oriented programming in Smalltalk (or Objective C) style may be implemented with the aid of continuations. For this, an object is represented by a special continuation `o`. If it has any data fields, they can be kept in the stack of `o`, making `o` a partial application (i.e., a continuation with a non-empty stack). -When somebody wants to invoke a method `m` of `o` with arguments `x1, x2, …, xn`, she pushes the arguments into the stack, then pushes a magic number corresponding to the method `m`, and then executes `o` passing `n+1` arguments (cf. [4.1.10](#4-1-10-determining-the-number-of-arguments-passed-to-andor-return-values-accepted-from-a-subroutine)). Then `o` uses the top-of-stack integer `m` to select the branch with the required method, and executes it. +When somebody wants to invoke a method `m` of `o` with arguments `x₁, x₂, …, xₙ`, she pushes the arguments into the stack, then pushes a magic number corresponding to the method `m`, and then executes `o` passing `n+1` arguments (cf. [4.1.10](#4-1-10-determining-the-number-of-arguments-passed-to-andor-return-values-accepted-from-a-subroutine)). Then `o` uses the top-of-stack integer `m` to select the branch with the required method, and executes it. If `o` needs to modify its state, it simply computes a new continuation `o'` of the same sort (perhaps with the same code as `o`, but with a different initial stack). The new continuation `o'` is returned to the caller along with whatever other return values need to be returned. @@ -1151,39 +1141,45 @@ For example, imagine a continuation that represents the output stream to a print --- -# 4.5 Exception handling +## 4.5 Exception handling TVM’s exception handling is quite simple and consists in a transfer of control to the continuation kept in control register c2. -## 4.5.1. Two arguments of the exception handler: exception parameter and exception number +### 4.5.1. Two arguments of the exception handler: exception parameter and exception number + +Every exception is characterized by two arguments: the **exception number** (an `Integer`) and the **exception parameter** (any value, most often a zero `Integer`). Exception numbers `0–31` are reserved for TVM, while all other exception numbers are available for user-defined exceptions. -Every exception is characterized by two arguments: the exception number (an Integer) and the exception parameter (any value, most often a zero Integer). Exception numbers 0–31 are reserved for TVM, while all other exception numbers are available for user-defined exceptions. +### 4.5.2. Primitives for throwing an exception -## 4.5.2. Primitives for throwing an exception +There are several special primitives used for throwing an exception. The most general of them, `THROWANY`, takes two arguments, `v` and `0 ≤ n < 2¹⁶` from the stack, and throws the exception with number `n` and value `v`. -There are several special primitives used for throwing an exception. The most general of them, THROWANY, takes two arguments, v and 0 ≤ n < 2^16, from the stack, and throws the exception with number n and value v. There are variants of this primitive that assume v to be a zero integer, store n as a literal value, and/or are conditional on an integer value taken from the stack. User-defined exceptions may use arbitrary values as v (e.g., trees of cells) if needed. +There are variants of this primitive that assume `v` to be a zero integer, store `n` as a literal value, and/or are conditional on an integer value taken from the stack. User-defined exceptions may use arbitrary values as `v` (e.g., trees of cells) if needed. -## 4.5.3. Exceptions generated by TVM +### 4.5.3. Exceptions generated by TVM -Of course, some exceptions are generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit into a signed 257-bit integer. In such cases, the arguments of the exception, v and n, are determined by TVM itself. +Some exceptions are generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit into a signed 257-bit integer. In such cases, the arguments of the exception, `v` and `n`, are determined by TVM itself. -## 4.5.4. Exception handling +### 4.5.4. Exception handling -The exception handling itself consists in a control transfer to the exception handler—i.e., the continuation specified in control register c2, with v and n supplied as the two arguments to this continuation, as if a JMP to c2 had been requested with n00 = 2 arguments (cf. [4.1.7](#4-1-7-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c) and [4.1.6](#4-1-6-switching-to-another-continuation-jmp-and-ret)). As a consequence, v and n end up in the top of the stack of the exception handler. The remainder of the old stack is discarded. +Exception handling consists in a control transfer to the exception handler — i.e., the continuation specified in control register `c₂`, with `v` and `n` supplied as the two arguments to this continuation, as if a `JMP` to `c2` had been requested with `n′′ = 2` arguments (cf. [4.1.7](#4-1-7-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c) and [4.1.6](#4-1-6-switching-to-another-continuation-jmp-and-ret)). -Notice that if the continuation in c2 has a value for c2 in its savelist, it will be used to set up the new value of c2 before executing the exception handler. In particular, if the exception handler invokes THROWANY, it will rethrow the original exception with the restored value of c2. This trick enables the exception handler to handle only some exceptions, and pass the rest to an outer exception handler. +As a consequence, `v` and `n` end up on top of the stack of the exception handler. The remainder of the old stack is discarded. -## 4.5.5. Default exception handler +Notice that if the continuation in `c2` has a value for `c2` in its savelist, it will be used to set up the new value of `c2` before executing the exception handler. In particular, if the exception handler invokes `THROWANY`, it will rethrow the original exception with the restored value of `c2`. This trick enables the exception handler to handle only some exceptions, and pass the rest to an outer exception handler. -When an instance of TVM is created, c2 contains a reference to the “default exception handler continuation”, which is an ec_fatal extraordinary continuation (cf. [4.1.5](#4-1-5-extraordinary-continuations)). Its execution leads to the termination of the execution of TVM, with the arguments v and n of the exception returned to the outside caller. In the context of the TON Blockchain, n will be stored as a part of the transaction’s result. +### 4.5.5. Default exception handler -## 4.5.6. TRY primitive +When an instance of TVM is created, `c2` contains a reference to the “default exception handler continuation”, which is an **`ec_fatal`** extraordinary continuation (cf. [4.1.5](#4-1-5-extraordinary-continuations)). -A TRY primitive can be used to implement C++-like exception handling. This primitive accepts two continuations, c and c0. It stores the old value of c2 into the savelist of c0, sets c2 to c0, and executes c just as EXECUTE would, but additionally saving the old value of c2 into the savelist of the new c0 as well. Usually a version of the TRY primitive with an explicit number of arguments n00 passed to the continuation c is used. +Its execution leads to the termination of the execution of TVM, with the arguments `v` and `n` of the exception returned to the outside caller. In the context of the TON Blockchain, `n` will be stored as a part of the transaction’s result. -The net result is roughly equivalent to C++’s `try { c } catch(...) { c0 }` operator. +### 4.5.6. `TRY` primitive -## 4.5.7. List of predefined exceptions +A **`TRY`** primitive can be used to implement C++-like exception handling. This primitive accepts two continuations, `c` and `c′`. It stores the old value of `c2` into the savelist of `c′`, sets `c₂` to `c′`, and executes `c` just as `EXECUTE` would, but additionally saving the old value of `C2` into the savelist of the new `c′` as well. Usually, a version of the `TRY` primitive with an explicit number of arguments `n′′` passed to the continuation `c` is used. + +The net result is roughly equivalent to C++’s `try { c } catch(...) { c′ }` operator. + +### 4.5.7. List of predefined exceptions Predefined exceptions of TVM correspond to exception numbers n in the range 0–31. They include: @@ -1191,7 +1187,7 @@ Predefined exceptions of TVM correspond to exception numbers n in the range 0– - **Alternative termination (n = 1)** — Again, should never be generated. - **Stack underflow (n = 2)** — Not enough arguments in the stack for a primitive. - **Stack overflow (n = 3)** — More values have been stored on a stack than allowed by this version of TVM. -- **Integer overflow (n = 4)** — Integer does not fit into −2^256 ≤ x < 2^256, or a division by zero has occurred. +- **Integer overflow (n = 4)** — Integer does not fit into `−2²⁵⁶ ≤ x < 2²⁵⁶`, or a division by zero has occurred. - **Range check error (n = 5)** — Integer out of expected range. - **Invalid opcode (n = 6)** — Instruction or its immediate arguments cannot be decoded. - **Type check error (n = 7)** — An argument to a primitive is of incorrect value type. @@ -1204,7 +1200,7 @@ Predefined exceptions of TVM correspond to exception numbers n in the range 0– Most of these exceptions have no parameter (i.e., use a zero integer instead). The order in which these exceptions are checked is outlined below in 4.5.8. -## 4.5.8. Order of stack underflow, type check, and range check exceptions +### 4.5.8. Order of stack underflow, type check, and range check exceptions All TVM primitives first check whether the stack contains the required number of arguments, generating a stack underflow exception if this is not the case. Only then are the type tags of the arguments and their ranges (e.g., if a primitive expects an argument not only to be an Integer, but also to be in the range from 0 to 256) checked, starting from the value in the top of the stack (the last argument) and proceeding deeper into the stack. If an argument’s type is incorrect, a type-checking exception is generated; if the type is correct, but the value does not fall into the expected range, a range check exception is generated. @@ -1212,15 +1208,15 @@ Some primitives accept a variable number of arguments, depending on the values o --- -# 4.6 Functions, recursion, and dictionaries +## 4.6 Functions, recursion, and dictionaries -## 4.6.1 The problem of recursion +### 4.6.1 The problem of recursion The conditional and iterated execution primitives described in [4.2](#4-2-control-flow-primitives-conditional-and-iterated-execution)—along with the unconditional branch, call, and return primitives described in [4.1](#4-1-continuations-and-subroutines)—enable one to implement more or less arbitrary code with nested loops and conditional expressions, with one notable exception: one can only create new constant continuations from parts of the current continuation. (In particular, one cannot invoke a subroutine from itself in this way.) Therefore, the code being executed—i.e., the current continuation—gradually becomes smaller and smaller.[24](#footnote-24) -## 4.6.2 Y-combinator solution: pass a continuation as an argument to itself +### 4.6.2 Y-combinator solution: pass a continuation as an argument to itself One way of dealing with the problem of recursion is by passing a copy of the continuation representing the body of a recursive function as an extra argument to itself. Consider, for example, the following code for a factorial function: -``` +```asm 71 PUSHINT 1 9C PUSHCONT { 22 PUSH s2 @@ -1242,9 +1238,9 @@ D8 EXECUTE 31 NIP ``` -This roughly corresponds to defining an auxiliary function `body` with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, n·x, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. +This roughly corresponds to defining an auxiliary function `body` with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, nx, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. -## 4.6.3 A variant of Y-combinator solution +### 4.6.3 A variant of Y-combinator solution Another way of recursively computing the factorial, more closely following the classical recursive definition: ```math @@ -1257,7 +1253,7 @@ n \cdot \text{fact}(n - 1) & \text{otherwise} is as follows: -``` +```asm 9D PUSHCONT { 21 OVER C102 LESSINT 2 @@ -1279,11 +1275,11 @@ D9 JMPX This definition of the factorial function is two bytes shorter than the previous one, but it uses general recursion instead of tail recursion, so it cannot be easily transformed into a loop. -## 4.6.4 Comparison: non-recursive definition of the factorial function +### 4.6.4 Comparison: non-recursive definition of the factorial function Incidentally, a non-recursive definition of the factorial with the aid of a `REPEAT` loop is also possible, and it is much shorter than both recursive definitions: -``` +```asm 71 PUSHINT 1 01 SWAP 20 DUP @@ -1297,39 +1293,39 @@ E4 REPEAT 30 DROP ``` -## 4.6.5 Several mutually recursive functions +### 4.6.5 Several mutually recursive functions -If one has a collection `f1, …, fn` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fi}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. +If one has a collection `f₁, …, fₙ` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fᵢ}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. -## 4.6.6 Combining several functions into one tuple +### 4.6.6 Combining several functions into one tuple -One might also combine a collection of continuations representing functions `f1, …, fn` into a “tuple” `f := (f1, …, fn)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fi`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. +One might also combine a collection of continuations representing functions `f₁, …, fₙ` into a “tuple” `f := (f₁, …, fₙ)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fᵢ`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. -## 4.6.7 Combining several functions into a selector function +### 4.6.7 Combining several functions into a selector function -Another approach is to combine several functions `f1, …, fn` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fi` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. +Another approach is to combine several functions `f₁, …, fₙ` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fᵢ` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. -## 4.6.8 Using a dedicated register to keep the selector function +### 4.6.8 Using a dedicated register to keep the selector function However, even if we use one of the two previous approaches to combine all functions into one extra argument, passing this argument to all mutually recursive functions is still quite cumbersome and requires a lot of additional stack manipulation operations. Because this argument changes very rarely, one might use a dedicated register to keep it and transparently pass it to all functions called. This is the approach used by TVM by default. -## 4.6.9 Special register c3 for the selector function +### 4.6.9 Special register c3 for the selector function -In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. [A.8.7](#a-8-7)) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). +In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. [A.8.7](#a-8-7-dictionary-subroutine-calls-and-jumps)) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). -## 4.6.10 Initialization of c3 +### 4.6.10 Initialization of c3 A TVM program might initialize `c3` by means of a `POP c3` instruction. However, because this usually is the very first action undertaken by a program (e.g., a smart contract), TVM makes some provisions for the automatic initialization of `c3`. Namely, `c3` is initialized by the code (the initial value of `cc`) of the program itself, and an extra zero (or, in some cases, some other predefined number `s`) is pushed into the stack before the program’s execution. This is approximately equivalent to invoking `JMPDICT 0` (or `JMPDICT s`) at the very beginning of a program—i.e., the function with index zero is effectively the `main()` function for the program. -## 4.6.11 Creating selector functions and switch statements +### 4.6.11 Creating selector functions and switch statements -TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. [A.8.2](#a-8-2)). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. +TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. [A.8.2](#a-8-2-conditional-control-flow-primitives)). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. -Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. [A.7.2](#a-7-2)). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. +Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. [A.7.2](#a-7-2-cell-deserialization-primitives)). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. ## 4.6.12 Alternative: using a hashmap to select the correct function -Yet another alternative is to use a Hashmap (cf. [3.3](#3-3-hashmaps-or-dictionaries)) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. [A.10](#a-10-dictionary-manipulation-primitives)) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. [A.8.5](#a-8-5)) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. [A.10.11](#a-10-11)). +Yet another alternative is to use a Hashmap (cf. [3.3](#3-3-hashmaps%2C-or-dictionaries)) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. [A.10](#a-10-dictionary-manipulation-primitives)) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. [A.8.5](#a-8-5-creating-simple-continuations-and-closures)) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. [A.10.11](#a-10-10-getmin%2C-getmax%2C-removemin%2C-removemax-operations)). This approach may be more efficient for larger programs and switch statements. --- @@ -1413,13 +1409,13 @@ Recall that TVM is a bit-oriented machine in the sense that its Cells (and Slice That said, some codepages (such as our experimental codepage zero) may opt to use a bytecode (i.e., to use only encodings consisting of an integral number of bytes)—either for simplicity, or for the ease of debugging and of studying memory (i.e., cell) dumps.[27](#footnote-27) ### 5.2.6 Opcode space used by a complete instruction -Recall from coding theory that the lengths of bitstrings `li` used in a binary prefix code satisfy Kraft–McMillan inequality: +Recall from coding theory that the lengths of bitstrings `ℓᵢ` used in a binary prefix code satisfy Kraft–McMillan inequality: ```math \sum_i 2^{-l_i} \leq 1 ``` -This is applicable in particular to the (complete) instruction encoding used by a TVM codepage. We say that a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2^-l` of the opcode space, if it is encoded by an `l`-bit string. One can see that all complete instructions together utilize at most 1 (i.e., “at most the whole opcode space”). +This is applicable in particular to the (complete) instruction encoding used by a TVM codepage. We say that a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2⁻ˡ` of the opcode space, if it is encoded by an `ℓ`-bit string. One can see that all complete instructions together utilize at most `1` (i.e., “at most the whole opcode space”). ### 5.2.7 Opcode space used by an instruction, or a class of instructions The above terminology is extended to instructions (considered with all admissible values of their parameters), or even classes of instructions (e.g., all arithmetic instructions). We say that an (incomplete) instruction, or a class of instructions, occupies portion `α` of the opcode space, if `α` is the sum of the portions of the opcode space occupied by all complete instructions belonging to that class. @@ -1430,7 +1426,7 @@ A useful approximation of the above definitions is as follows: Consider all 256 This approximation shows why all instructions cannot occupy together more than the portion `256/256 = 1` of the opcode space, at least without compromising the uniqueness of instruction decoding. ### 5.2.9 Almost optimal encodings -Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete instruction (`2^-l`, if the complete instruction is encoded in `l` bits) should be approximately equal to the probability or frequency of its occurrence in real programs.[28](#footnote-28) The same should hold for (incomplete) instructions, or primitives (i.e., generic instructions without specified values of parameters), and for classes of instructions. +Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete instruction (`2⁻ℓ`, if the complete instruction is encoded in `ℓ` bits) should be approximately equal to the probability or frequency of its occurrence in real programs.[28](#footnote-28) The same should hold for (incomplete) instructions, or primitives (i.e., generic instructions without specified values of parameters), and for classes of instructions. ### 5.2.10 Example: stack manipulation primitives For instance, if stack manipulation instructions constitute approximately half of all instructions in a typical TVM program, one should allocate approximately half of the opcode space for encoding stack manipulation instructions. One might reserve the first bytes (“opcodes”) `0x00–0x7f` for such instructions. If a quarter of these instructions are `XCHG`, it would make sense to reserve `0x00–0x1f` for `XCHG`s. Similarly, if half of all `XCHG`s involve the top of stack `s0`, it would make sense to use `0x00–0x0f` to encode `XCHG s0,s(i)`. @@ -1438,7 +1434,7 @@ For instance, if stack manipulation instructions constitute approximately half o ### 5.2.11 Simple encodings of instructions In most cases, simple encodings of complete instructions are used. Simple encodings begin with a fixed bitstring called the opcode of the instruction, followed by, say, 4-bit fields containing the indices `i` of stack registers `s(i)` specified in the instruction, followed by all other constant (literal, immediate) parameters included in the complete instruction. While simple encodings may not be exactly optimal, they admit short descriptions, and their decoding and encoding can be easily implemented. -If a (generic) instruction uses a simple encoding with an `l`-bit opcode, then the instruction will utilize `2^-l` portion of the opcode space. This observation might be useful for considerations described in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives). +If a (generic) instruction uses a simple encoding with an `ℓ`-bit opcode, then the instruction will utilize `2⁻ℓ` portion of the opcode space. This observation might be useful for considerations described in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives). ### 5.2.12 Optimizing code density further: Huffman codes One might construct optimally dense binary code for the set of all complete instructions, provided their probabilities or frequences in real code are known. This is the well-known Huffman code (for the given probability distribution). However, such code would be highly unsystematic and hard to decode. @@ -1476,27 +1472,22 @@ The list of all instructions available in codepage zero, along with their encodi --- # A Instructions and opcodes +This appendix lists all instructions available in the (experimental) codepage zero of TVM, as explained in [5.3](#5-3-instruction-encoding-in-codepage-zero). +We list the instructions in lexicographical opcode order. However, the opcode space is distributed in such way as to make all instructions in each category (e.g., arithmetic primitives) have neighboring opcodes. So we first list a number of stack manipulation primitives, then constant primitives, arithmetic primitives, comparison primitives, cell primitives, continuation primitives, dictionary primitives, and finally application-specific primitives. + +We use hexadecimal notation (cf. [1.0](#1-0-notation-for-bitstrings)) for bitstrings. Stack registers `s(i)` usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, 8-bit, or variable length. + +The stack notation described in [2.1.10](#2-1-10-stack-notation) is extensively used throughout this appendix. -This appendix lists all instructions available in the (experimental) codepage -zero of TVM, as explained in 5.3. -We list the instructions in lexicographical opcode order. However, the -opcode space is distributed in such way as to make all instructions in each -category (e.g., arithmetic primitives) have neighboring opcodes. So we first -list a number of stack manipulation primitives, then constant primitives, -arithmetic primitives, comparison primitives, cell primitives, continuation -primitives, dictionary primitives, and finally application-specific primitives. - -We use hexadecimal notation (cf. 1.0) for bitstrings. Stack registers `s(i)` -usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare -occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, -8-bit, or variable length. -The stack notation described in 2.1.10 is extensively used throughout -this appendix. ## A.1 Gas prices The gas price for most primitives equals the basic gas price, computed as -`Pb := 10 + b + 5r`, where `b` is the instruction length in bits and `r` is the + +```math +P_{b} := 10 + b + 5r +``` +where `b` is the instruction length in bits and `r` is the number of cell references included in the instruction. When the gas price of an instruction differs from this basic price, it is indicated in parentheses after its mnemonics, either as `(x)`, meaning that the total gas price equals @@ -1514,11 +1505,15 @@ expressions may appear: * `Cw` — The total price of creating new `Cell`s from `Builder`s. Currently equal to 500 gas units per cell. -By default, the gas price of an instruction equals `P := Pb + Cr + L + Bw + Cw`. +By default, the gas price of an instruction equals + +```math +P := P_{b} + C_{r} + L + B_{w} + C_{w} +``` ## A.2 Stack manipulation primitives -This section includes both the basic (cf. 2.2.1) and the compound (cf. 2.2.3) +This section includes both the basic (cf. [2.2.1](#2-2-1-basic-stack-manipulation-primitives)) and the compound (cf. [2.2.3](#2-2-3-compound-stack-manipulation-primitives)) stack manipulation primitives, as well as some “unsystematic” ones. Some compound stack manipulation primitives, such as `XCPU` or `XCHG2`, turn out to have the same length as an equivalent sequence of simpler operations. We @@ -1531,6 +1526,7 @@ style (e.g., `-ROT`), the other conforming to the usual rules for identifiers (e integer parameter `n` from the stack, it must be within the range `0 . . . 255`; otherwise a range check exception happens before any further checks. + ### A.2.1. Basic stack manipulation primitives. * `00` — `NOP`, does nothing. @@ -1608,10 +1604,12 @@ arbitrary types (not necessarily the same). Tuple primitives create, modify, and unpack Tuples; they manipulate values of arbitrary types in the process, similarly to the stack primitives. We do not recommend using Tuples of more than 15 elements. -When a Tuple `t` contains elements `x1, . . . , xn` (in that order), we write -`t = (x1, . . . , xn)`; number `n ≥ 0` is the length of Tuple `t`. It is also denoted + +When a Tuple `t` contains elements `x₁, ..., xₙ` (in that order), we write +`t = (x₁, ..., xₙ)`; number `n ≥ 0` is the length of Tuple `t`. It is also denoted by `|t|`. Tuples of length two are called pairs, and Tuples of length three are triples. + Lisp-style lists are represented with the aid of pairs, i.e., tuples consisting of exactly two elements. An empty list is represented by a `Null` value, and a non-empty list is represented by pair `(h, t)`, where `h` is the first element of @@ -1631,7 +1629,7 @@ more efficient and costs less gas. ### A.3.2. Tuple primitives. -* `6F0n` — `TUPLE n` `(x1 . . . xn – t)`, creates a new Tuple `t = (x1, . . . , xn)` +* `6F0n` — `TUPLE n` `(x₁, ..., xₙ – t)`, creates a new Tuple `t = (x₁, ..., xₙ)` containing `n` values `x1, . . . , xn`, where `0 ≤ n ≤ 15`. * `6F00` — `NIL` `( – t)`, pushes the only Tuple `t = ()` of length zero. * `6F01` — `SINGLE` `(x – t)`, creates a singleton `t := (x)`, i.e., a Tuple of @@ -1639,12 +1637,12 @@ more efficient and costs less gas. * `6F02` — `PAIR` or `CONS` `(x y – t)`, creates pair `t := (x, y)`. * `6F03` — `TRIPLE` `(x y z – t)`, creates triple `t := (x, y, z)`. * `6F1k` — `INDEX k` `(t – x)`, returns the `k`-th element of a Tuple `t`, where - `0 ≤ k ≤ 15`. In other words, returns `xk+1` if `t = (x1, . . . , xn)`. If `k ≥ n`, + `0 ≤ k ≤ 15`. In other words, returns `xk+1` if `t = (x₁, ..., xₙ)`. If `k ≥ n`, throws a range check exception. * `6F10` — `FIRST` or `CAR` `(t – x)`, returns the first element of a Tuple. * `6F11` — `SECOND` or `CDR` `(t – y)`, returns the second element of a Tuple. * `6F12` — `THIRD` `(t – z)`, returns the third element of a Tuple -* `6F2n` — `UNTUPLE n` `(t – x1 . . . xn)`, unpacks a Tuple `t = (x1, . . . , xn)` of +* `6F2n` — `UNTUPLE n` `(t – x1 . . . xn)`, unpacks a Tuple `t = (x₁, ..., xₙ)` of length equal to `0 ≤ n ≤ 15`. If `t` is not a Tuple, of if `|t| 6= n`, a type check exception is thrown. * `6F21` — `UNSINGLE` `(t – x)`, unpacks a singleton `t = (x)`. @@ -1676,13 +1674,13 @@ more efficient and costs less gas. If `t` is not `Null` or `Tuple`, throws an exception. If `x` is `Null` and either `|t| ≤ k` or `t` is `Null`, then always returns `t' = t` (and does not consume tuple creation gas). -* `6F80` — `TUPLEVAR` `(x1 . . . xn n – t)`, creates a new Tuple `t` of length `n` +* `6F80` — `TUPLEVAR` `(x₁, ..., xₙ n – t)`, creates a new Tuple `t` of length `n` similarly to `TUPLE`, but with `0 ≤ n ≤ 255` taken from the stack. * `6F81` — `INDEXVAR` `(t k – x)`, similar to `INDEX k`, but with `0 ≤ k ≤ 254` taken from the stack. -* `6F82` — `UNTUPLEVAR` `(t n – x1 . . . xn)`, similar to `UNTUPLE n`, but with +* `6F82` — `UNTUPLEVAR` `(t n – x₁, ..., xₙ)`, similar to `UNTUPLE n`, but with `0 ≤ n ≤ 255` taken from the stack. -* `6F83` — `UNPACKFIRSTVAR` `(t n – x1 . . . xn)`, similar to `UNPACKFIRST n`, +* `6F83` — `UNPACKFIRSTVAR` `(t n – x₁, ..., xₙ)`, similar to `UNPACKFIRST n`, but with `0 ≤ n ≤ 255` taken from the stack. * `6F84` — `EXPLODEVAR` `(t n – x1 . . . xm m)`, similar to `EXPLODE n`, but with `0 ≤ n ≤ 255` taken from the stack. @@ -1728,14 +1726,15 @@ more efficient and costs less gas. * `6FA7` — `NULLROTRIFNOT2` `(x y – x y or ⊥ ⊥ x y)`, pushes two `Null`s under the second stack entry from the top, but only if the topmost Integer `y` is zero. Equivalent to `NULLROTRIFNOT; NULLROTRIFNOT`. -* `6FBij` — `INDEX2 i,j` `(t – x)`, recovers `x = (ti+1)j+1` for `0 ≤ i, j ≤ 3`. +* `6FBij` — `INDEX2 i,j` `(t – x)`, recovers `x = (tᵢ₊₁)ⱼ₊₁` for `0 ≤ i, j ≤ 3`. Equivalent to `INDEX i; INDEX j`. -* `6FB4` — `CADR` `(t – x)`, recovers `x = (t2)1`. -* `6FB5` — `CDDR` `(t – x)`, recovers `x = (t2)2`. -* `6FE_ijk` — `INDEX3 i,j,k` `(t – x)`, recovers `x = ((ti+1)j+1)k+1` for `0 ≤ +* `6FB4` — `CADR` `(t – x)`, recovers `x = (t₂)₁`. +* `6FB5` — `CDDR` `(t – x)`, recovers `x = (t₂)₂`. +* `6FE_ijk` — `INDEX3 i,j,k` `(t – x)`, recovers `x = (tᵢ₊₁)ⱼ₊₁ₖ₊₁` for `0 ≤ i, j, k ≤ 3`. Equivalent to `INDEX2 i,j; INDEX k`. -* `6FD4` — `CADDR` `(t – x)`, recovers `x = ((t2)2)1`. -* `6FD5` — `CDDDR` `(t – x)`, recovers `x = ((t2)2)2`. +* `6FD4` — `CADDR` `(t – x)`, recovers `x = (t₂)₂₁`. +* `6FD5` — `CDDDR` `(t – x)`, recovers `x = (t₂)₂₂`. + ## A.4 Constant, or literal primitives @@ -1746,31 +1745,44 @@ instruction. Therefore, if the immediate argument is absent or too short, an ### A.4.1. Integer and boolean constants. -* `7i` — `PUSHINT x` with `−5 ≤ x ≤ 10`, pushes integer `x` into the stack; - here `i` equals four lower-order bits of `x` (i.e., `i = x mod 16`). -* `70` — `ZERO`, `FALSE`, or `PUSHINT 0`, pushes a zero. -* `71` — `ONE` or `PUSHINT 1`. -* `72` — `TWO` or `PUSHINT 2`. -* `7A` — `TEN` or `PUSHINT 10`. -* `7F` — `TRUE` or `PUSHINT -1`. -* `80xx` — `PUSHINT xx` with `−128 ≤ xx ≤ 127`. -* `81xxxx` — `PUSHINT xxxx` with `−2^15 ≤ xxxx < 2^15` a signed 16-bit - big-endian integer. -* `81FC18` — `PUSHINT −1000`. -* `82lxxx` — `PUSHINT xxx`, where 5-bit `0 ≤ l ≤ 30` determines the length - `n = 8l + 19` of signed big-endian integer `xxx`. The total length of this - instruction is `l + 4` bytes or `n + 13 = 8l + 32` bits. -* `821005F5E100` — `PUSHINT 1088`. -* `83xx` — `PUSHPOW2 xx + 1`, (quietly) pushes `2^(xx+1)` for `0 ≤ xx ≤ 255`. -* `83FF` — `PUSHNAN`, pushes a `NaN`. -* `84xx` — `PUSHPOW2DEC xx + 1`, pushes `2^(xx+1) − 1` for `0 ≤ xx ≤ 255`. -* `85xx` — `PUSHNEGPOW2 xx + 1`, pushes `−2^(xx+1)` for `0 ≤ xx ≤ 255`. -* `86, 87` — reserved for integer constants. +* `7i` — `PUSHINT x` with `−5 ≤ x ≤ 10`, pushes integer `x` into the stack; + here `i` equals four lower-order bits of `x` (i.e., `i = x mod 16`). + +* `70` — `ZERO`, `FALSE`, or `PUSHINT 0`, pushes a zero. + +* `71` — `ONE` or `PUSHINT 1`. + +* `72` — `TWO` or `PUSHINT 2`. + +* `7A` — `TEN` or `PUSHINT 10`. + +* `7F` — `TRUE` or `PUSHINT −1`. + +* `80xx` — `PUSHINT xx` with `−128 ≤ xx ≤ 127`. + +* `81xxxx` — `PUSHINT xxxx` with `−2¹⁵ ≤ xxxx < 2¹⁵`, a signed 16-bit big-endian integer. + +* `81FC18` — `PUSHINT −1000`. + +* `82lxxx` — `PUSHINT xxx`, where 5-bit `0 ≤ ℓ ≤ 30` determines the length + `n = 8ℓ + 19` of signed big-endian integer `xxx`. + The total length of this instruction is `ℓ + 4` bytes or `n + 13 = 8ℓ + 32` bits. + +* `821005F5E100` — `PUSHINT 10⁸`. + +* `83xx` — `PUSHPOW2 xx + 1`, (quietly) pushes `2ˣˣ⁺¹` for `0 ≤ xx ≤ 255`. + +* `83FF` — `PUSHNAN`, pushes a `NaN`. + +* `84xx` — `PUSHPOW2DEC xx + 1`, pushes `2ˣˣ⁺¹ − 1` for `0 ≤ xx ≤ 255`. + +* `85xx` — `PUSHNEGPOW2 xx + 1`, pushes `−2ˣˣ⁺¹` for `0 ≤ xx ≤ 255`. + +* `86, 87` — reserved for integer constants. ### A.4.2. Constant slices, continuations, cells, and references. -Most -of the instructions listed below push literal slices, continuations, cells, and +Most of the instructions listed below push literal slices, continuations, cells, and cell references, stored as immediate arguments to the instruction. Therefore, if the immediate argument is absent or too short, an “invalid or too short opcode” exception (code `6`) is thrown. @@ -1808,7 +1820,7 @@ opcode” exception (code `6`) is thrown. * `A1` — `SUB` `(x y – x − y)`. * `A2` — `SUBR` `(x y – y − x)`, equivalent to `SWAP; SUB`. * `A3` — `NEGATE` `(x – −x)`, equivalent to `MULCONST −1` or to `ZERO; SUBR`. - Notice that it triggers an integer overflow exception if `x = −2^256`. + Notice that it triggers an integer overflow exception if `x = −2²⁵⁶`. * `A4` — `INC` `(x – x + 1)`, equivalent to `ADDCONST 1`. * `A5` — `DEC` `(x – x − 1)`, equivalent to `ADDCONST −1`. * `A6cc` — `ADDCONST cc` `(x – x + cc)`, `−128 ≤ cc ≤ 127`. @@ -1835,31 +1847,31 @@ operation and its variants), possibly replaced by a left shift. * `1 ≤ d ≤ 3` — Indicates which results of division are required: `1`—only the quotient, `2`—only the remainder, `3`—both. * `0 ≤ f ≤ 2` — Rounding mode: `0`—floor, `1`—nearest integer, `2`—ceiling - (cf. 1.5.6). + (cf. [1.5.6](#1-5-2-automatic-overflow-checks)). Examples: -* `A904` — `DIV` `(x y – q := ⌊x/y⌋)`. -* `A905` — `DIVR` `(x y – q' := ⌊x/y + 1/2⌋)`. -* `A906` — `DIVC` `(x y – q'' := ⌈x/y⌉)`. -* `A908` — `MOD` `(x y – r)`, where `q := ⌊x/y⌋`, `r := x mod y := x − yq`. -* `A90C` — `DIVMOD` `(x y – q r)`, where `q := ⌊x/y⌋`, `r := x − yq`. -* `A90D` — `DIVMODR` `(x y – q' r')`, where `q' := ⌊x/y + 1/2⌋`, `r' := x − yq'`. -* `A90E` — `DIVMODC` `(x y – q'' r'')`, where `q'' := ⌈x/y⌉`, `r'' := x − yq''`. -* `A924` — same as `RSHIFT`: `(x y – ⌊x · 2^(−y)⌋)` for `0 ≤ y ≤ 256`. -* `A934tt` — same as `RSHIFT tt + 1`: `(x – ⌊x · 2^(−tt−1)⌋)`. -* `A938tt` — `MODPOW2 tt + 1`: `(x – x mod 2^(tt+1))`. -* `A985` — `MULDIVR` `(x y z – q')`, where `q' = ⌊xy/z + 1/2⌋`. -* `A98C` — `MULDIVMOD` `(x y z – q r)`, where `q := ⌊x · y/z⌋`, `r := x · y mod z` - (same as `*/MOD` in Forth). -* `A9A4` — `MULRSHIFT` `(x y z – ⌊xy · 2^(−z)⌋)` for `0 ≤ z ≤ 256`. -* `A9A5` — `MULRSHIFTR` `(x y z – ⌊xy · 2^(−z) + 1/2⌋)` for `0 ≤ z ≤ 256`. -* `A9B4tt` — `MULRSHIFT tt + 1` `(x y – ⌊xy · 2^(−tt−1)⌋)`. -* `A9B5tt` — `MULRSHIFTR tt + 1` `(x y – ⌊xy · 2^(−tt−1) + 1/2⌋)`. -* `A9C4` — `LSHIFTDIV` `(x y z – ⌊2^z x/y⌋)` for `0 ≤ z ≤ 256`. -* `A9C5` — `LSHIFTDIVR` `(x y z – ⌊2^z x/y + 1/2⌋)` for `0 ≤ z ≤ 256`. -* `A9D4tt` — `LSHIFTDIV tt + 1` `(x y – ⌊2^(tt+1) x/y⌋)`. -* `A9D5tt` — `LSHIFTDIVR tt + 1` `(x y – ⌊2^(tt+1) x/y + 1/2⌋)`. +* `A904` — `DIV (x y – q := ⌊x/y⌋)`. +* `A905` — `DIVR (x y – q′ := ⌊x/y + 1/2⌋)`. +* `A906` — `DIVC (x y – q″ := ⌈x/y⌉)`. +* `A908` — `MOD (x y – r)`, where `q := ⌊x/y⌋`, `r := x mod y := x − yq`. +* `A90C` — `DIVMOD (x y – q r)`, where `q := ⌊x/y⌋`, `r := x − yq`. +* `A90D` — `DIVMODR (x y – q′ r′)`, where `q′ := ⌊x/y + 1/2⌋`, `r′ := x − yq′`. +* `A90E` — `DIVMODC (x y – q″ r″)`, where `q″ := ⌈x/y⌉`, `r″ := x − yq″`. +* `A924` — same as `RSHIFT`: `(x y – ⌊x · 2⁻ʸ⌋)` for `0 ≤ y ≤ 256`. +* `A934tt` — same as `RSHIFT tt + 1`: `(x – ⌊x · 2⁻ᵗᵗ⁻¹⌋)`. +* `A938tt` — `MODPOW2 tt + 1`: `(x – x mod 2ᵗᵗ⁺¹)`. +* `A985` — `MULDIVR (x y z – q′)`, where `q′ = ⌊xy/z + 1/2⌋`. +* `A98C` — `MULDIVMOD (x y z – q r)`, where `q := ⌊x · y/z⌋`, `r := x · y mod z` (same as `*/MOD` in Forth). +* `A9A4` — `MULRSHIFT (x y z – ⌊xy · 2⁻ᶻ⌋)` for `0 ≤ z ≤ 256`. +* `A9A5` — `MULRSHIFTR (x y z – ⌊xy · 2⁻ᶻ + 1/2⌋)` for `0 ≤ z ≤ 256`. +* `A9B4tt` — `MULRSHIFT tt + 1 (x y – ⌊xy · 2⁻ᵗᵗ⁻¹⌋)`. +* `A9B5tt` — `MULRSHIFTR tt + 1 (x y – ⌊xy · 2⁻ᵗᵗ⁻¹ + 1/2⌋)`. +* `A9C4` — `LSHIFTDIV (x y z – ⌊2ᶻx/y⌋)` for `0 ≤ z ≤ 256`. +* `A9C5` — `LSHIFTDIVR (x y z – ⌊2ᶻx/y + 1/2⌋)` for `0 ≤ z ≤ 256`. +* `A9D4tt` — `LSHIFTDIV tt + 1 (x y – ⌊2ᵗᵗ⁺¹x/y⌋)`. +* `A9D5tt` — `LSHIFTDIVR tt + 1 (x y – ⌊2ᵗᵗ⁺¹x/y + 1/2⌋)`. + The most useful of these operations are `DIV`, `DIVMOD`, `MOD`, `DIVR`, `DIVC`, `MODPOW2 t`, and `RSHIFTR t` (for integer arithmetic); and `MULDIVMOD`, `MULDIV`, @@ -1867,50 +1879,50 @@ The most useful of these operations are `DIV`, `DIVMOD`, `MOD`, `DIVR`, `DIVC`, ### A.5.3. Shifts, logical operations. -* `AAcc` — `LSHIFT cc + 1` `(x – x · 2^(cc+1))`, `0 ≤ cc ≤ 255`. +* `AAcc` — `LSHIFT cc + 1 (x – x · 2ᶜᶜ⁺¹)`, `0 ≤ cc ≤ 255`. * `AA00` — `LSHIFT 1`, equivalent to `MULCONST 2` or to Forth’s `2*`. -* `ABcc` — `RSHIFT cc + 1` `(x – ⌊x · 2^(−cc−1)⌋)`, `0 ≤ cc ≤ 255`. -* `AC` — `LSHIFT` `(x y – x · 2^y)`, `0 ≤ y ≤ 1023`. -* `AD` — `RSHIFT` `(x y – ⌊x · 2^(−y)⌋)`, `0 ≤ y ≤ 1023`. -* `AE` — `POW2` `(y – 2^y)`, `0 ≤ y ≤ 1023`, equivalent to `ONE; SWAP; LSHIFT`. +* `ABcc` — `RSHIFT cc + 1 (x – ⌊x · 2⁻ᶜᶜ⁻¹⌋)`, `0 ≤ cc ≤ 255`. +* `AC` — `LSHIFT (x y – x · 2ʸ)`, `0 ≤ y ≤ 1023`. +* `AD` — `RSHIFT (x y – ⌊x · 2⁻ʸ⌋)`, `0 ≤ y ≤ 1023`. +* `AE` — `POW2 (y – 2ʸ)`, `0 ≤ y ≤ 1023`, equivalent to `ONE; SWAP; LSHIFT`. * `AF` — reserved. -* `B0` — `AND` `(x y – x&y)`, bitwise “and” of two signed integers `x` and `y`, +* `B0` — `AND (x y – x&y)`, bitwise “and” of two signed integers `x` and `y`, sign-extended to infinity. -* `B1` — `OR` `(x y – x ∨ y)`, bitwise “or” of two integers. -* `B2` — `XOR` `(x y – x ⊕ y)`, bitwise “xor” of two integers. -* `B3` — `NOT` `(x – x ⊕ −1 = −1 − x)`, bitwise “not” of an integer. -* `B4cc` — `FITS cc + 1` `(x – x)`, checks whether `x` is a `cc + 1`-bit signed - integer for `0 ≤ cc ≤ 255` (i.e., whether `−2^cc ≤ x < 2^cc`). If not, either +* `B1` — `OR (x y – x ∨ y)`, bitwise “or” of two integers. +* `B2` — `XOR (x y – x ⊕ y)`, bitwise “xor” of two integers. +* `B3` — `NOT (x – x ⊕ −1 = −1 − x)`, bitwise “not” of an integer. +* `B4cc` — `FITS cc + 1 (x – x)`, checks whether `x` is a `cc + 1`-bit signed + integer for `0 ≤ cc ≤ 255` (i.e., whether `−2ᶜᶜ ≤ x < 2ᶜᶜ`). If not, either triggers an integer overflow exception, or replaces `x` with a `NaN` (quiet version). -* `B400` — `FITS 1` or `CHKBOOL` `(x – x)`, checks whether `x` is a “boolean +* `B400` — `FITS 1` or `CHKBOOL (x – x)`, checks whether `x` is a “boolean value” (i.e., either `0` or `-1`). -* `B5cc` — `UFITS cc + 1` `(x – x)`, checks whether `x` is a `cc + 1`-bit unsigned - integer for `0 ≤ cc ≤ 255` (i.e., whether `0 ≤ x < 2^(cc+1)`). +* `B5cc` — `UFITS cc + 1 (x – x)`, checks whether `x` is a `cc + 1`-bit unsigned + integer for `0 ≤ cc ≤ 255` (i.e., whether `0 ≤ x < 2ᶜᶜ⁺¹`). * `B500` — `UFITS 1` or `CHKBIT`, checks whether `x` is a binary digit (i.e., zero or one). -* `B600` — `FITSX` `(x c – x)`, checks whether `x` is a `c`-bit signed integer for +* `B600` — `FITSX (x c – x)`, checks whether `x` is a `c`-bit signed integer for `0 ≤ c ≤ 1023`. -* `B601` — `UFITSX` `(x c – x)`, checks whether `x` is a `c`-bit unsigned integer +* `B601` — `UFITSX (x c – x)`, checks whether `x` is a `c`-bit unsigned integer for `0 ≤ c ≤ 1023`. -* `B602` — `BITSIZE` `(x – c)`, computes smallest `c ≥ 0` such that `x` fits into - a `c`-bit signed integer (`−2^(c−1) ≤ c < 2^(c−1)`). -* `B603` — `UBITSIZE` `(x – c)`, computes smallest `c ≥ 0` such that `x` fits - into a `c`-bit unsigned integer (`0 ≤ x < 2^c`), or throws a range check +* `B602` — `BITSIZE (x – c)`, computes smallest `c ≥ 0` such that `x` fits into + a `c`-bit signed integer (`−2ᶜ⁻¹ ≤ x < 2ᶜ⁻¹`). +* `B603` — `UBITSIZE (x – c)`, computes smallest `c ≥ 0` such that `x` fits + into a `c`-bit unsigned integer (`0 ≤ x < 2ᶜ`), or throws a range check exception. -* `B608` — `MIN` `(x y – x or y)`, computes the minimum of two integers `x` +* `B608` — `MIN (x y – x or y)`, computes the minimum of two integers `x` and `y`. -* `B609` — `MAX` `(x y – x or y)`, computes the maximum of two integers `x` +* `B609` — `MAX (x y – x or y)`, computes the maximum of two integers `x` and `y`. -* `B60A` — `MINMAX` or `INTSORT2` `(x y – x y or y x)`, sorts two integers. Quiet +* `B60A` — `MINMAX` or `INTSORT2 (x y – x y or y x)`, sorts two integers. Quiet version of this operation returns two `NaN`s if any of the arguments are `NaN`s. -* `B60B` — `ABS` `(x – |x|)`, computes the absolute value of an integer `x`. +* `B60B` — `ABS (x – |x|)`, computes the absolute value of an integer `x`. + ### A.5.4. Quiet arithmetic primitives. -We opted to make all arithmetic -operations “non-quiet” (signaling) by default, and create their quiet counterparts by means of a prefix. Such an encoding is definitely sub-optimal. It is +We opted to make all arithmetic operations “non-quiet” (signaling) by default, and create their quiet counterparts by means of a prefix. Such an encoding is definitely sub-optimal. It is not yet clear whether it should be done in this way, or in the opposite way by making all arithmetic operations quiet by default, or whether quiet and non-quiet operations should be given opcodes of equal length; this can only @@ -1922,18 +1934,23 @@ be settled by practice. Notice that this does not extend to shift amounts and other parameters that must be within a small range (e.g., `0–1023`). Also notice that this does not disable type-checking exceptions if a value of a type other than `Integer` is supplied. -* `B7A0` — `QADD` `(x y – x + y)`, always works if `x` and `y` are `Integer`s, but + +* `B7A0` — `QADD (x y – x + y)`, always works if `x` and `y` are `Integer`s, but returns a `NaN` if the addition cannot be performed. -* `B7A904` — `QDIV` `(x y – ⌊x/y⌋)`, returns a `NaN` if `y = 0`, or if `y = −1` and - `x = −2^256`, or if either of `x` or `y` is a `NaN`. -* `B7B0` — `QAND` `(x y – x&y)`, bitwise “and” (similar to `AND`), but returns + +* `B7A904` — `QDIV (x y – ⌊x/y⌋)`, returns a `NaN` if `y = 0`, or if `y = −1` and + `x = −2²⁵⁶`, or if either of `x` or `y` is a `NaN`. + +* `B7B0` — `QAND (x y – x&y)`, bitwise “and” (similar to `AND`), but returns a `NaN` if either `x` or `y` is a `NaN` instead of throwing an integer overflow exception. However, if one of the arguments is zero, and the other is a `NaN`, the result is zero. -* `B7B1` — `QOR` `(x y – x∨y)`, bitwise “or”. If `x = −1` or `y = −1`, the result + +* `B7B1` — `QOR (x y – x ∨ y)`, bitwise “or”. If `x = −1` or `y = −1`, the result is always `−1`, even if the other argument is a `NaN`. -* `B7B507` — `QUFITS 8` `(x – x' )`, checks whether `x` is an unsigned byte - (i.e., whether `0 ≤ x < 2^8`), and replaces `x` with a `NaN` if this is not the + +* `B7B507` — `QUFITS 8 (x – x′)`, checks whether `x` is an unsigned byte + (i.e., whether `0 ≤ x < 2⁸`), and replaces `x` with a `NaN` if this is not the case; leaves `x` intact otherwise (i.e., if `x` is an unsigned byte). ## A.6 Comparison primitives @@ -1948,66 +1965,104 @@ with the aid of the `QUIET` prefix (`B7`). If any of the integers being compared are `NaN`s, the result of a quiet comparison will also be a `NaN` (“undefined”), instead of a `−1` (“yes”) or `0` (“no”), thus effectively supporting ternary logic. -* `B8` — `SGN` `(x – sgn(x))`, computes the sign of an integer `x`: `−1` if `x < 0`, +* `B8` — `SGN (x – sgn(x))`, computes the sign of an integer `x`: `−1` if `x < 0`, `0` if `x = 0`, `1` if `x > 0`. -* `B9` — `LESS` `(x y – x < y)`, returns `−1` if `x < y`, `0` otherwise. -* `BA` — `EQUAL` `(x y – x = y)`, returns `−1` if `x = y`, `0` otherwise. -* `BB` — `LEQ` `(x y – x ≤ y)`. -* `BC` — `GREATER` `(x y – x > y)`. -* `BD` — `NEQ` `(x y – x 6= y)`, equivalent to `EQUAL; NOT`. -* `BE` — `GEQ` `(x y – x ≥ y)`, equivalent to `LESS; NOT`. -* `BF` — `CMP` `(x y – sgn(x − y))`, computes the sign of `x − y`: `−1` if `x < y`, + +* `B9` — `LESS (x y – x < y)`, returns `−1` if `x < y`, `0` otherwise. + +* `BA` — `EQUAL (x y – x = y)`, returns `−1` if `x = y`, `0` otherwise. + +* `BB` — `LEQ (x y – x ≤ y)`. + +* `BC` — `GREATER (x y – x > y)`. + +* `BD` — `NEQ (x y – x ≠ y)`, equivalent to `EQUAL; NOT`. + +* `BE` — `GEQ (x y – x ≥ y)`, equivalent to `LESS; NOT`. + +* `BF` — `CMP (x y – sgn(x − y))`, computes the sign of `x − y`: `−1` if `x < y`, `0` if `x = y`, `1` if `x > y`. No integer overflow can occur here unless `x` or `y` is a `NaN`. -* `C0yy` — `EQINT yy` `(x – x = yy)` for `−2^7 ≤ yy < 2^7`. + +* `C0yy` — `EQINT yy (x – x = yy)` for `−2⁷ ≤ yy < 2⁷`. + * `C000` — `ISZERO`, checks whether an integer is zero. Corresponds to Forth’s `0=`. -* `C1yy` — `LESSINT yy` `(x – x < yy)` for `−2^7 ≤ yy < 2^7`. + +* `C1yy` — `LESSINT yy (x – x < yy)` for `−2⁷ ≤ yy < 2⁷`. + * `C100` — `ISNEG`, checks whether an integer is negative. Corresponds to Forth’s `0<`. + * `C101` — `ISNPOS`, checks whether an integer is non-positive. -* `C2yy` — `GTINT yy` `(x – x > yy)` for `−2^7 ≤ yy < 2^7`. + +* `C2yy` — `GTINT yy (x – x > yy)` for `−2⁷ ≤ yy < 2⁷`. + * `C200` — `ISPOS`, checks whether an integer is positive. Corresponds to Forth’s `0>`. + * `C2FF` — `ISNNEG`, checks whether an integer is non-negative. -* `C3yy` — `NEQINT yy` `(x – x 6= yy)` for `−2^7 ≤ yy < 2^7`. -* `C4` — `ISNAN` `(x – x = NaN)`, checks whether `x` is a `NaN`. -* `C5` — `CHKNAN` `(x – x)`, throws an arithmetic overflow exception if `x` is a + +* `C3yy` — `NEQINT yy (x – x ≠ yy)` for `−2⁷ ≤ yy < 2⁷`. + +* `C4` — `ISNAN (x – x = NaN)`, checks whether `x` is a `NaN`. + +* `C5` — `CHKNAN (x – x)`, throws an arithmetic overflow exception if `x` is a `NaN`. + * `C6` — reserved for integer comparison. + ### A.6.2. Other comparison. Most of these “other comparison” primitives actually compare the data portions of `Slice`s as bitstrings. -* `C700` — `SEMPTY` `(s – s = ∅)`, checks whether a `Slice s` is empty (i.e., +* `C700` — `SEMPTY (s – s = ∅)`, checks whether a Slice `s` is empty (i.e., contains no bits of data and no cell references). -* `C701` — `SDEMPTY` `(s – s ≈ ∅)`, checks whether `Slice s` has no bits of + +* `C701` — `SDEMPTY (s – s ≈ ∅)`, checks whether Slice `s` has no bits of data. -* `C702` — `SREMPTY` `(s – r(s) = 0)`, checks whether `Slice s` has no references. -* `C703` — `SDFIRST` `(s – s0 = 1)`, checks whether the first bit of `Slice s` is + +* `C702` — `SREMPTY (s – r(s) = 0)`, checks whether Slice `s` has no + references. + +* `C703` — `SDFIRST (s – s₀ = 1)`, checks whether the first bit of Slice `s` is a one. -* `C704` — `SDLEXCMP` `(s s0 – c)`, compares the data of `s` lexicographically - with the data of `s0`, returning `−1`, `0`, or `1` depending on the result. -* `C705` — `SDEQ` `(s s0 – s ≈ s0)`, checks whether the data parts of `s` and `s0` + +* `C704` — `SDLEXCMP (s s′ – c)`, compares the data of `s` lexicographically + with the data of `s′`, returning `−1`, `0`, or `1` depending on the result. + +* `C705` — `SDEQ (s s′ – s ≈ s′)`, checks whether the data parts of `s` and `s′` coincide, equivalent to `SDLEXCMP; ISZERO`. -* `C708` — `SDPFX` `(s s0 – ? )`, checks whether `s` is a prefix of `s0`. -* `C709` — `SDPFXREV` `(s s0 – ? )`, checks whether `s0` is a prefix of `s`, equivalent - to `SWAP; SDPFX`. -* `C70A` — `SDPPFX` `(s s0 – ? )`, checks whether `s` is a proper prefix of `s0` (i.e., - a prefix distinct from `s0`). -* `C70B` — `SDPPFXREV` `(s s0 – ? )`, checks whether `s0` is a proper prefix of `s`. -* `C70C` — `SDSFX` `(s s0 – ? )`, checks whether `s` is a suffix of `s0`. -* `C70D` — `SDSFXREV` `(s s0 – ? )`, checks whether `s0` is a suffix of `s`. -* `C70E` — `SDPSFX` `(s s0 – ? )`, checks whether `s` is a proper suffix of `s0`. -* `C70F` — `SDPSFXREV` `(s s0 – ? )`, checks whether `s0` is a proper suffix of `s`. -* `C710` — `SDCNTLEAD0` `(s – n)`, returns the number of leading zeroes in - `s`. -* `C711` — `SDCNTLEAD1` `(s – n)`, returns the number of leading ones in `s`. -* `C712` — `SDCNTTRAIL0` `(s – n)`, returns the number of trailing zeroes in + +* `C708` — `SDPFX (s s′ – ? )`, checks whether `s` is a prefix of `s′`. + +* `C709` — `SDPFXREV (s s′ – ? )`, checks whether `s′` is a prefix of `s`, + equivalent to `SWAP; SDPFX`. + +* `C70A` — `SDPPFX (s s′ – ? )`, checks whether `s` is a proper prefix of `s′` + (i.e., a prefix distinct from `s′`). + +* `C70B` — `SDPPFXREV (s s′ – ? )`, checks whether `s′` is a proper prefix of `s`. + +* `C70C` — `SDSFX (s s′ – ? )`, checks whether `s` is a suffix of `s′`. + +* `C70D` — `SDSFXREV (s s′ – ? )`, checks whether `s′` is a suffix of `s`. + +* `C70E` — `SDPSFX (s s′ – ? )`, checks whether `s` is a proper suffix of `s′`. + +* `C70F` — `SDPSFXREV (s s′ – ? )`, checks whether `s′` is a proper suffix of `s`. + +* `C710` — `SDCNTLEAD0 (s – n)`, returns the number of leading zeroes in `s`. -* `C713` — `SDCNTTRAIL1` `(s – n)`, returns the number of trailing ones in `s`. + +* `C711` — `SDCNTLEAD1 (s – n)`, returns the number of leading ones in `s`. + +* `C712` — `SDCNTTRAIL0 (s – n)`, returns the number of trailing zeroes in `s`. + +* `C713` — `SDCNTTRAIL1 (s – n)`, returns the number of trailing ones in `s`. + ## A.7 Cell primitives @@ -2018,738 +2073,1495 @@ with `Builder`s, or cell deserialization primitives, which work with `Slice`s. All these primitives first check whether there is enough space in the Builder, and only then check the range of the value being serialized. -* `C8` — `NEWC` ( – b), creates a new empty Builder. -* `C9` — `ENDC` (b – c), converts a Builder into an ordinary Cell. -* `CAcc` — `STI cc + 1` (x b – b0), stores a signed cc + 1-bit integer x into Builder b for 0 ≤ cc ≤ 255, throws a range check exception if x does not fit into cc + 1 bits. -* `CBcc` — `STU cc + 1` (x b – b0), stores an unsigned cc + 1-bit integer x into Builder b. In all other respects it is similar to STI. -* `CC` — `STREF` (c b – b0), stores a reference to Cell c into Builder b. -* `CD` — `STBREFR` or `ENDCST` (b b00 – b), equivalent to ENDC; SWAP; STREF. -* `CE` — `STSLICE` (s b – b0), stores Slice s into Builder b. -* `CF00` — `STIX` (x b l – b0), stores a signed l-bit integer x into b for 0 ≤ l ≤ 257. -* `CF01` — `STUX` (x b l – b0), stores an unsigned l-bit integer x into b for 0 ≤ l ≤ 256. -* `CF02` — `STIXR` (b x l – b0), similar to STIX, but with arguments in a different order. -* `CF03` — `STUXR` (b x l – b0), similar to STUX, but with arguments in a different order. -* `CF04` — `STIXQ` (x b l – x b f or b0 0), a quiet version of STIX. If there is no space in b, sets b0 = b and f = −1. If x does not fit into l bits, sets b0 = b and f = 1. If the operation succeeds, b0 is the new Builder and f = 0. However, 0 ≤ l ≤ 257, with a range check exception if this is not so. -* `CF05` — `STUXQ` (x b l – b0 f). -* `CF06` — `STIXRQ` (b x l – b x f or b0 0). -* `CF07` — `STUXRQ` (b x l – b x f or b0 0). -* `CF08cc` — a longer version of `STI cc + 1`. -* `CF09cc` — a longer version of `STU cc + 1`. -* `CF0Acc` — `STIR cc + 1` (b x – b0), equivalent to SWAP; STI cc + 1. -* `CF0Bcc` — `STUR cc + 1` (b x – b0), equivalent to SWAP; STU cc + 1. -* `CF0Ccc` — `STIQ cc + 1` (x b – x b f or b0 0). -* `CF0Dcc` — `STUQ cc + 1` (x b – x b f or b0 0). -* `CF0Ecc` — `STIRQ cc + 1` (b x – b x f or b0 0). -* `CF0Fcc` — `STURQ cc + 1` (b x – b x f or b0 0). -* `CF10` — a longer version of `STREF` (c b – b0). -* `CF11` — `STBREF` (b0 b – b00), equivalent to SWAP; STBREFREV. -* `CF12` — a longer version of `STSLICE` (s b – b0). -* `CF13` — `STB` (b0 b – b00), appends all data from Builder b0 to Builder b. -* `CF14` — `STREFR` (b c – b0). -* `CF15` — `STBREFR` (b b0 – b00), a longer encoding of STBREFR. -* `CF16` — `STSLICER` (b s – b0). -* `CF17` — `STBR` (b b0 – b00), concatenates two Builder s, equivalent to SWAP; STB. -* `CF18` — `STREFQ` (c b – c b −1 or b0 0). -* `CF19` — `STBREFQ` (b0 b – b0 b −1 or b00 0). -* `CF1A` — `STSLICEQ` (s b – s b −1 or b0 0). -* `CF1B` — `STBQ` (b0 b – b0 b −1 or b00 0). -* `CF1C` — `STREFRQ` (b c – b c −1 or b0 0). -* `CF1D` — `STBREFRQ` (b b0 – b b0 −1 or b00 0). -* `CF1E` — `STSLICERQ` (b s – b s −1 or b00 0). -* `CF1F` — `STBRQ` (b b0 – b b0 −1 or b00 0). -* `CF20` — `STREFCONST`, equivalent to PUSHREF; STREFR. -* `CF21` — `STREF2CONST`, equivalent to STREFCONST; STREFCONST. -* `CF23` — `ENDXC` (b x – c), if x 6= 0, creates a special or exotic cell (cf. 3.1.2) from Builder b. The type of the exotic cell must be stored in the first 8 bits of b. If x = 0, it is equivalent to ENDC. Otherwise some validity checks on the data and references of b are performed before creating the exotic cell. -* `CF28` — `STILE4` (x b – b0), stores a little-endian signed 32-bit integer. -* `CF29` — `STULE4` (x b – b0), stores a little-endian unsigned 32-bit integer. -* `CF2A` — `STILE8` (x b – b0), stores a little-endian signed 64-bit integer. -* `CF2B` — `STULE8` (x b – b0), stores a little-endian unsigned 64-bit integer. -* `CF30` — `BDEPTH` (b – x), returns the depth of Builder b. If no cell references are stored in b, then x = 0; otherwise x is one plus the maximum of depths of cells referred to from b. -* `CF31` — `BBITS` (b – x), returns the number of data bits already stored in Builder b. -* `CF32` — `BREFS` (b – y), returns the number of cell references already stored in b. -* `CF33` — `BBITREFS` (b – x y), returns the numbers of both data bits and cell references in b. -* `CF35` — `BREMBITS` (b – x0), returns the number of data bits that can still be stored in b. -* `CF36` — `BREMREFS` (b – y0). -* `CF37` — `BREMBITREFS` (b – x0 y0). -* `CF38cc` — `BCHKBITS cc + 1` (b –), checks whether cc + 1 bits can be stored into b, where 0 ≤ cc ≤ 255. -* `CF39` — `BCHKBITS` (b x – ), checks whether x bits can be stored into b, 0 ≤ x ≤ 1023. If there is no space for x more bits in b, or if x is not within the range 0 . . . 1023, throws an exception. -* `CF3A` — `BCHKREFS` (b y – ), checks whether y references can be stored into b, 0 ≤ y ≤ 7. -* `CF3B` — `BCHKBITREFS` (b x y – ), checks whether x bits and y references can be stored into b, 0 ≤ x ≤ 1023, 0 ≤ y ≤ 7. -* `CF3Ccc` — `BCHKBITSQ cc + 1` (b – ?), checks whether cc + 1 bits can be stored into b, where 0 ≤ cc ≤ 255. -* `CF3D` — `BCHKBITSQ` (b x – ?), checks whether x bits can be stored into b, 0 ≤ x ≤ 1023. -* `CF3E` — `BCHKREFSQ` (b y – ?), checks whether y references can be stored into b, 0 ≤ y ≤ 7. -* `CF3F` — `BCHKBITREFSQ` (b x y – ?), checks whether x bits and y references can be stored into b, 0 ≤ x ≤ 1023, 0 ≤ y ≤ 7. -* `CF40` — `STZEROES` (b n – b0), stores n binary zeroes into Builder b. -* `CF41` — `STONES` (b n – b0), stores n binary ones into Builder b. -* `CF42` — `STSAME` (b n x – b0), stores n binary xes (0 ≤ x ≤ 1) into Builder b. -* `CFC0_xysss` — `STSLICECONST sss` (b – b0), stores a constant subslice sss consisting of 0 ≤ x ≤ 3 references and up to 8y + 1 data bits, with 0 ≤ y ≤ 7. Completion bit is assumed. -* `CF81` — `STSLICECONST ‘0’` or `STZERO` (b – b0), stores one binary zero. -* `CF83` — `STSLICECONST ‘1’` or `STONE` (b – b0), stores one binary one. -* `CFA2` — equivalent to `STREFCONST`. -* `CFA3` — almost equivalent to `STSLICECONST ‘1’`; `STREFCONST`. -* `CFC2` — equivalent to `STREF2CONST`. -* `CFE2` — `STREF3CONST`. +* `C8` — `NEWC ( – b)`, creates a new empty Builder. ---- +* `C9` — `ENDC (b – c)`, converts a Builder into an ordinary Cell. -### A.7.2. Cell deserialization primitives +* `CAcc` — `STI cc + 1 (x b – b′)`, stores a signed `cc + 1`-bit integer `x` into + Builder `b` for `0 ≤ cc ≤ 255`, throws a range check exception if `x` does + not fit into `cc + 1` bits. -* `D0` — `CTOS` (c – s), converts a Cell into a Slice. Notice that `c` must be either an ordinary cell, or an exotic cell (cf. 3.1.2) which is automatically loaded to yield an ordinary cell `c0`, converted into a Slice afterwards. -* `D1` — `ENDS` (s – ), removes a Slice `s` from the stack, and throws an exception if it is not empty. -* `D2cc` — `LDI cc + 1` (s – x s0), loads (i.e., parses) a signed cc + 1-bit integer `x` from Slice `s`, and returns the remainder of `s` as `s0`. -* `D3cc` — `LDU cc + 1` (s – x s0), loads an unsigned cc + 1-bit integer `x` from Slice `s`. -* `D4` — `LDREF` (s – c s0), loads a cell reference `c` from `s`. -* `D5` — `LDREFRTOS` (s – s0 s00), equivalent to `LDREF`; `SWAP`; `CTOS`. -* `D6cc` — `LDSLICE cc + 1` (s – s00 s0), cuts the next cc + 1 bits of `s` into a separate Slice `s00`. -* `D700` — `LDIX` (s l – x s0), loads a signed `l`-bit (0 ≤ l ≤ 257) integer `x` from Slice `s`, and returns the remainder of `s` as `s0`. -* `D701` — `LDUX` (s l – x s0), loads an unsigned `l`-bit integer `x` from Slice `s`, 0 ≤ l ≤ 256. -* `D702` — `PLDIX` (s l – x), preloads a signed `l`-bit integer from Slice `s`, 0 ≤ l ≤ 257. -* `D703` — `PLDUX` (s l – x), preloads an unsigned `l`-bit integer from `s`, 0 ≤ l ≤ 256. -* `D704` — `LDIXQ` (s l – x s0 −1 or s0), quiet version of `LDIX`. If `s` has fewer than `l` bits, returns a flag instead of exception. -* `D705` — `LDUXQ` (s l – x s0 −1 or s0), quiet version of `LDUX`. -* `D706` — `PLDIXQ` (s l – x −1 or 0), quiet version of `PLDIX`. -* `D707` — `PLDUXQ` (s l – x −1 or 0), quiet version of `PLDUX`. -* `D708cc` — longer encoding of `LDI cc + 1`. -* `D709cc` — longer encoding of `LDU cc + 1`. -* `D70Acc` — `PLDI cc + 1` (s – x), preloads a signed cc + 1-bit integer from Slice `s`. -* `D70Bcc` — `PLDU cc + 1` (s – x), preloads an unsigned cc + 1-bit integer from `s`. -* `D70Ccc` — `LDIQ cc + 1` (s – x s0 −1 or s0), quiet version of `LDI`. -* `D70Dcc` — `LDUQ cc + 1` (s – x s0 −1 or s0), quiet version of `LDU`. -* `D70Ecc` — `PLDIQ cc + 1` (s – x −1 or 0), quiet version of `PLDI`. -* `D70Fcc` — `PLDUQ cc + 1` (s – x −1 or 0), quiet version of `PLDU`. -* `D714_c` — `PLDUZ 32(c + 1)` (s – s x), preloads first 32(c + 1) bits of Slice `s` into an unsigned integer `x`, 0 ≤ c ≤ 7. Missing bits are assumed zero. Used with `IFBITJMP` etc. -* `D718` — `LDSLICEX` (s l – s00 s0), loads first 0 ≤ l ≤ 1023 bits of `s` into a new Slice `s00`, returns the remainder as `s0`. -* `D719` — `PLDSLICEX` (s l – s00), returns first 0 ≤ l ≤ 1023 bits of `s` as `s00`. -* `D71A` — `LDSLICEXQ` (s l – s00 s0 −1 or s0), quiet version of `LDSLICEX`. -* `D71B` — `PLDSLICEXQ` (s l – s0 −1 or 0), quiet version of `PLDSLICEX`. -* `D71Ccc` — longer encoding of `LDSLICE cc + 1`. -* `D71Dcc` — `PLDSLICE cc + 1` (s – s00), returns first 0 < cc + 1 ≤ 256 bits of `s` as `s00`. -* `D71Ecc` — `LDSLICEQ cc + 1` (s – s00 s0 −1 or s0), quiet version of `LDSLICE`. -* `D71Fcc` — `PLDSLICEQ cc + 1` (s – s00 −1 or 0), quiet version of `PLDSLICE`. -* `D720` — `SDCUTFIRST` (s l – s0), returns first 0 ≤ l ≤ 1023 bits of `s`. Equivalent to `PLDSLICEX`. -* `D721` — `SDSKIPFIRST` (s l – s0), returns all but first 0 ≤ l ≤ 1023 bits of `s`. Equivalent to `LDSLICEX`; `NIP`. -* `D722` — `SDCUTLAST` (s l – s0), returns last 0 ≤ l ≤ 1023 bits of `s`. -* `D723` — `SDSKIPLAST` (s l – s0), returns all but last 0 ≤ l ≤ 1023 bits of `s`. -* `D724` — `SDSUBSTR` (s l l0 – s0), returns substring of length 0 ≤ l0 ≤ 1023 starting at offset 0 ≤ l ≤ 1023. -* `D726` — `SDBEGINSX` (s s0 – s00), checks whether `s` begins with data bits of `s0`. Removes `s0` on success. Throws exception on failure. -* `D727` — `SDBEGINSXQ` (s s0 – s00 −1 or s0), quiet version of `SDBEGINSX`. -* `D72A_xsss` — `SDBEGINS` (s – s00), checks whether `s` begins with constant bitstring `sss` of length 8x + 3 (completion bit assumed). Removes on success. -* `D72802` — `SDBEGINS ‘0’` (s – s00), checks whether `s` begins with binary zero. -* `D72806` — `SDBEGINS ‘1’` (s – s00), checks whether `s` begins with binary one. -* `D72E_xsss` — `SDBEGINSQ` (s – s00 −1 or s0), quiet version of `SDBEGINS`. -* `D730` — `SCUTFIRST` (s l r – s0), returns first 0 ≤ l ≤ 1023 bits and 0 ≤ r ≤ 4 references of `s`. -* `D731` — `SSKIPFIRST` (s l r – s0). -* `D732` — `SCUTLAST` (s l r – s0), returns last 0 ≤ l ≤ 1023 bits and last 0 ≤ r ≤ 4 references. -* `D733` — `SSKIPLAST` (s l r – s0). -* `D734` — `SUBSLICE` (s l r l0 r0 – s0), returns 0 ≤ l0 ≤ 1023 bits and 0 ≤ r0 ≤ 4 refs after skipping first l bits and r refs. -* `D736` — `SPLIT` (s l r – s0 s00), splits off first l bits and r refs of `s` into `s0`, returns remainder as `s00`. -* `D737` — `SPLITQ` (s l r – s0 s00 −1 or s0), quiet version of `SPLIT`. -* `D739` — `XCTOS` (c – s ?), converts a Cell (ordinary or exotic) into a Slice. Returns flag if exotic. -* `D73A` — `XLOAD` (c – c0), loads exotic cell `c` to ordinary `c0`. -* `D73B` — `XLOADQ` (c – c0 −1 or c0), quiet version of `XLOAD`. -* `D741` — `SCHKBITS` (s l – ), checks there are ≥ l data bits. Throws exception if not. -* `D742` — `SCHKREFS` (s r – ), checks ≥ r references. -* `D743` — `SCHKBITREFS` (s l r – ), checks ≥ l bits and ≥ r references. -* `D745` — `SCHKBITSQ` (s l – ?), quiet version of `SCHKBITS`. -* `D746` — `SCHKREFSQ` (s r – ?). -* `D747` — `SCHKBITREFSQ` (s l r – ?). -* `D748` — `PLDREFVAR` (s n – c), returns n-th cell reference of Slice `s`, 0 ≤ n ≤ 3. -* `D749` — `SBITS` (s – l), returns number of data bits. -* `D74A` — `SREFS` (s – r), returns number of references. -* `D74B` — `SBITREFS` (s – l r), returns both bit and ref counts. -* `D74E_n` — `PLDREFIDX n` (s – c), returns n-th reference, 0 ≤ n ≤ 3. -* `D74C` — `PLDREF` (s – c), preloads first reference of `s`. -* `D750` — `LDILE4` (s – x s0), loads little-endian signed 32-bit integer. -* `D751` — `LDULE4` (s – x s0), loads little-endian unsigned 32-bit integer. -* `D752` — `LDILE8` (s – x s0), loads little-endian signed 64-bit integer. -* `D753` — `LDULE8` (s – x s0), loads little-endian unsigned 64-bit integer. -* `D754` — `PLDILE4` (s – x), preloads little-endian signed 32-bit integer. -* `D755` — `PLDULE4` (s – x), preloads little-endian unsigned 32-bit integer. -* `D756` — `PLDILE8` (s – x), preloads little-endian signed 64-bit integer. -* `D757` — `PLDULE8` (s – x), preloads little-endian unsigned 64-bit integer. -* `D758` — `LDILE4Q` (s – x s0 −1 or s0), quiet 32-bit signed LE load. -* `D759` — `LDULE4Q` (s – x s0 −1 or s0), quiet 32-bit unsigned LE load. -* `D75A` — `LDILE8Q` (s – x s0 −1 or s0), quiet 64-bit signed LE load. -* `D75B` — `LDULE8Q` (s – x s0 −1 or s0), quiet 64-bit unsigned LE load. -* `D75C` — `PLDILE4Q` (s – x −1 or 0), quiet preload 32-bit signed. -* `D75D` — `PLDULE4Q` (s – x −1 or 0), quiet preload 32-bit unsigned. -* `D75E` — `PLDILE8Q` (s – x −1 or 0), quiet preload 64-bit signed. -* `D75F` — `PLDULE8Q` (s – x −1 or 0), quiet preload 64-bit unsigned. -* `D760` — `LDZEROES` (s – n s0), returns count n of leading zero bits in `s` and removes them. -* `D761` — `LDONES` (s – n s0), returns count n of leading one bits in `s` and removes them. -* `D762` — `LDSAME` (s x – n s0), returns count n of leading bits equal to `x` (0 ≤ x ≤ 1) in `s`, removes them. -* `D764` — `SDEPTH` (s – x), returns depth of Slice `s`. If no references, x = 0; else x = 1 + max depth of cells referred. -* `D765` — `CDEPTH` (c – x), returns depth of Cell `c`. If no refs, x = 0; else 1 + max depth. If `c` = Null, returns 0. +* `CBcc` — `STU cc + 1 (x b – b′)`, stores an unsigned `cc + 1`-bit integer `x` + into Builder `b`. In all other respects it is similar to `STI`. ---- +* `CC` — `STREF (c b – b′)`, stores a reference to Cell `c` into Builder `b`. -## A.8 Continuation and control flow primitives +* `CD` — `STBREFR` or `ENDCST (b b′′ – b)`, equivalent to `ENDC; SWAP; STREF`. -### A.8.1. Unconditional control flow primitives. +* `CE` — `STSLICE (s b – b′)`, stores Slice `s` into Builder `b`. -* `D8` — **EXECUTE** or **CALLX** `(c – )`, calls or executes continuation `c` (i.e., `cc ← c ◦0 cc`). -* `D9` — **JMPX** `(c – )`, jumps, or transfers control, to continuation `c` (i.e., `cc ← c ◦0 c0, or rather cc ← (c ◦0 c0) ◦1 c1`). The remainder of the previous current continuation `cc` is discarded. -* `DApr` — **CALLXARGS p,r** `(c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. -* `DB0p` — **CALLXARGS p,−1** `(c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. -* `DB1p` — **JMPXARGS p** `(c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). -* `DB2r` — **RETARGS r**, returns to `c0`, with `0 ≤ r ≤ 15` return values taken from the current stack. -* `DB30` — **RET** or **RETTRUE**, returns to the continuation at `c0` (i.e., performs `cc ← c0`). The remainder of the current continuation `cc` is discarded. Approximately equivalent to `PUSH c0; JMPX`. -* `DB31` — **RETALT** or **RETFALSE**, returns to the continuation at `c1` (i.e., `cc ← c1`). Approximately equivalent to `PUSH c1; JMPX`. -* `DB32` — **BRANCH** or **RETBOOL** `(f – )`, performs **RETTRUE** if integer `f ≠ 0`, or **RETFALSE** if `f = 0`. -* `DB34` — **CALLCC** `(c – )`, call with current continuation, transfers control to `c`, pushing the old value of `cc` into `c`’s stack (instead of discarding it or writing it into new `c0`). -* `DB35` — **JMPXDATA** `(c – )`, similar to **CALLCC**, but the remainder of the current continuation (the old value of `cc`) is converted into a Slice before pushing it into the stack of `c`. -* `DB36pr` — **CALLCCARGS p,r** `(c – )`, similar to **CALLXARGS**, but pushes the old value of `cc` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `cc.nargs` to `−1 ≤ r ≤ 14`. -* `DB38` — **CALLXVARARGS** `(c p r – )`, similar to **CALLXARGS**, but takes `−1 ≤ p, r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1 . . . 254`. -* `DB39` — **RETVARARGS** `(p r – )`, similar to **RETARGS**. -* `DB3A` — **JMPXVARARGS** `(c p r – )`, similar to **JMPXARGS**. -* `DB3B` — **CALLCCVARARGS** `(c p r – )`, similar to **CALLCCARGS**. -* `DB3C` — **CALLREF**, equivalent to `PUSHREFCONT; CALLX`. -* `DB3D` — **JMPREF**, equivalent to `PUSHREFCONT; JMPX`. -* `DB3E` — **JMPREFDATA**, equivalent to `PUSHREFCONT; JMPXDATA`. -* `DB3F` — **RETDATA**, equivalent to `PUSH c0; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. +* `CF00` — `STIX (x b l – b′)`, stores a signed `l`-bit integer `x` into `b` for `0 ≤ l ≤ 257`. ---- +* `CF01` — `STUX (x b l – b′)`, stores an unsigned `l`-bit integer `x` into `b` for `0 ≤ l ≤ 256`. -## A.8 Continuation and control flow primitives +* `CF02` — `STIXR (b x l – b′)`, similar to `STIX`, but with arguments in a + different order. -### A.8.1. Unconditional control flow primitives. +* `CF03` — `STUXR (b x l – b′)`, similar to `STUX`, but with arguments in a + different order. -* `D8` — `EXECUTE` or `CALLX` `(c – )`, calls or executes continuation `c` (i.e., `cc ← c ◦0 cc`). -* `D9` — `JMPX` `(c – )`, jumps, or transfers control, to continuation `c` (i.e., `cc ← c ◦0 c0, or rather cc ← (c ◦0 c0) ◦1 c1`). The remainder of the previous current continuation `cc` is discarded. -* `DApr` — `CALLXARGS p,r` `(c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. -* `DB0p` — `CALLXARGS p,−1` `(c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. -* `DB1p` — `JMPXARGS p` `(c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). -* `DB2r` — `RETARGS r`, returns to `c0`, with `0 ≤ r ≤ 15` return values taken from the current stack. -* `DB30` — `RET` or `RETTRUE`, returns to the continuation at `c0` (i.e., performs `cc ← c0`). The remainder of the current continuation `cc` is discarded. Approximately equivalent to `PUSH c0; JMPX`. -* `DB31` — `RETALT` or `RETFALSE`, returns to the continuation at `c1` (i.e., `cc ← c1`). Approximately equivalent to `PUSH c1; JMPX`. -* `DB32` — `BRANCH` or `RETBOOL` `(f – )`, performs `RETTRUE` if integer `f ≠ 0`, or `RETFALSE` if `f = 0`. -* `DB34` — `CALLCC` `(c – )`, call with current continuation, transfers control to `c`, pushing the old value of `cc` into `c`’s stack (instead of discarding it or writing it into new `c0`). -* `DB35` — `JMPXDATA` `(c – )`, similar to `CALLCC`, but the remainder of the current continuation (the old value of `cc`) is converted into a Slice before pushing it into the stack of `c`. -* `DB36pr` — `CALLCCARGS p,r` `(c – )`, similar to `CALLXARGS`, but pushes the old value of `cc` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `cc.nargs` to `−1 ≤ r ≤ 14`. -* `DB38` — `CALLXVARARGS` `(c p r – )`, similar to `CALLXARGS`, but takes `−1 ≤ p, r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1 . . . 254`. -* `DB39` — `RETVARARGS` `(p r – )`, similar to `RETARGS`. -* `DB3A` — `JMPXVARARGS` `(c p r – )`, similar to `JMPXARGS`. -* `DB3B` — `CALLCCVARARGS` `(c p r – )`, similar to `CALLCCARGS`. -* `DB3C` — `CALLREF`, equivalent to `PUSHREFCONT; CALLX`. -* `DB3D` — `JMPREF`, equivalent to `PUSHREFCONT; JMPX`. -* `DB3E` — `JMPREFDATA`, equivalent to `PUSHREFCONT; JMPXDATA`. -* `DB3F` — `RETDATA`, equivalent to `PUSH c0; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. +* `CF04` — `STIXQ (x b l – x b f or b′ 0)`, a quiet version of `STIX`. + - If there is no space in `b`, sets `b′ = b` and `f = −1`. + - If `x` does not fit into `l` bits, sets `b′ = b` and `f = 1`. + - If the operation succeeds, `b′` is the new Builder and `f = 0`. + However, `0 ≤ l ≤ 257`, with a range check exception if this is not so. +* `CF05` — `STUXQ (x b l – b′ f)`. -### A.8.2. Conditional control flow primitives +* `CF06` — `STIXRQ (b x l – b x f or b′ 0)`. -* `DC` — `IFRET` `(f – )`, performs a `RET`, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. -* `DD` — `IFNOTRET` `(f – )`, performs a `RET`, but only if integer `f` is zero. -* `DE` — `IF` `(f c – )`, performs `EXECUTE` for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. -* `DF` — `IFNOT` `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. -* `E0` — `IFJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is non-zero. -* `E1` — `IFNOTJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is zero. -* `E2` — `IFELSE` `(f c c0 – )`, if integer `f` is non-zero, executes `c`, otherwise executes `c0`. Equivalent to `CONDSELCHK; EXECUTE`. -* `E300` — `IFREF` `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. -* `E301` — `IFNOTREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. -* `E302` — `IFJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. -* `E303` — `IFNOTJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. -* `E304` — `CONDSEL` `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. -* `E305` — `CONDSELCHK` `(f x y – x or y)`, same as `CONDSEL`, but first checks whether `x` and `y` have the same type. -* `E308` — `IFRETALT` `(f – )`, performs `RETALT` if integer `f ≠ 0`. -* `E309` — `IFNOTRETALT` `(f – )`, performs `RETALT` if integer `f = 0`. -* `E30D` — `IFREFELSE` `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. -* `E30E` — `IFELSEREF` `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. -* `E30F` — `IFREFELSEREF` `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. -* `E310–E31F` — reserved for loops with break operators (cf. A.8.3). -* `E39_n` — `IFBITJMP n` `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs `JMPX` to continuation `c`. Value `x` is left in the stack. -* `E3B_n` — `IFNBITJMP n` `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. -* `E3D_n` — `IFBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is set in integer `x`. -* `E3F_n` — `IFNBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `CF07` — `STUXRQ (b x l – b x f or b′ 0)`. +* `CF08cc` — a longer version of `STI cc + 1`. -### A.8.3. Control flow primitives: loops +* `CF09cc` — a longer version of `STU cc + 1`. -Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. 4.1.5), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have `*BRK` versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for `*ENDBRK` versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for `*ENDBRK` versions). - -* `E4` — `REPEAT` `(n c – )`, executes continuation `c` `n` times, if integer `n` is non-negative. If `n ≥ 2^31` or `n < −2^31`, generates a range check exception. Notice that a `RET` inside the code of `c` works as a continue, not as a break. One should use either alternative (experimental) loops or alternative `RETALT` (along with a `SETEXITALT` before the loop) to break out of a loop. -* `E5` — `REPEATEND` `(n – )`, similar to `REPEAT`, but it is applied to the current continuation `cc`. -* `E6` — `UNTIL` `(c – )`, executes continuation `c`, then pops an integer `x` from the resulting stack. If `x` is zero, performs another iteration of this loop. Implemented with extraordinary continuation `ec_until`. -* `E7` — `UNTILEND` `( – )`, similar to `UNTIL`, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs a `RET`. -* `E8` — `WHILE` `(c0 c – )`, executes `c0` and pops an integer `x` from the resulting stack. If `x = 0`, exits the loop and transfers control to the original `cc`. If `x ≠ 0`, executes `c`, and then begins a new iteration. -* `E9` — `WHILEEND` `(c0 – )`, similar to `WHILE`, but uses the current continuation `cc` as the loop body. -* `EA` — `AGAIN` `(c – )`, similar to `REPEAT`, but executes `c` infinitely many times. A `RET` only begins a new iteration of the infinite loop, which can be exited only by an exception, or a `RETALT` (or an explicit `JMPX`). -* `EB` — `AGAINEND` `( – )`, similar to `AGAIN`, but performed with respect to the current continuation `cc`. -* `E314` — `REPEATBRK` `(n c – )`, similar to `REPEAT`, but also sets `c1` to the original `cc` after saving the old value of `c1` into the savelist of the original `cc`. In this way `RETALT` could be used to break out of the loop body. -* `E315` — `REPEATENDBRK` `(n – )`, similar to `REPEATEND`, but also sets `c1` to the original `c0` after saving the old value of `c1` into the savelist of the original `c0`. Equivalent to `SAMEALTSAVE; REPEATEND`. -* `E316` — `UNTILBRK` `(c – )`, similar to `UNTIL`, but also modifies `c1` in the same way as `REPEATBRK`. -* `E317` — `UNTILENDBRK` `( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. -* `E318` — `WHILEBRK` `(c0 c – )`, similar to `WHILE`, but also modifies `c1` in the same way as `REPEATBRK`. -* `E319` — `WHILEENDBRK` `(c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. -* `E31A` — `AGAINBRK` `(c – )`, similar to `AGAIN`, but also modifies `c1` in the same way as `REPEATBRK`. -* `E31B` — `AGAINENDBRK` `( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. +* `CF0Acc` — `STIR cc + 1 (b x – b′)`, equivalent to `SWAP; STI cc + 1`. +* `CF0Bcc` — `STUR cc + 1 (b x – b′)`, equivalent to `SWAP; STU cc + 1`. ---- -## A.9 Exception generating and handling primitives +* `CF0Ccc` — `STIQ cc + 1 (x b – x b f or b′ 0)`. -### A.9.1. Throwing exceptions +* `CF0Dcc` — `STUQ cc + 1 (x b – x b f or b′ 0)`. -* `F22_nn` — `THROW nn` `( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. -* `F26_nn` — `THROWIF nn` `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. -* `F2A_nn` — `THROWIFNOT nn` `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. -* `F2C4_nn` — `THROW nn` for `0 ≤ nn < 2^11`, an encoding of `THROW nn` for larger values. -* `F2CC_nn` — `THROWARG nn` `(x – x nn)`, throws exception `0 ≤ nn < 2^11` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. -* `F2D4_nn` — `THROWIF nn` `(f – )` for `0 ≤ nn < 2^11`. -* `F2DC_nn` — `THROWARGIF nn` `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f ≠ 0`. -* `F2E4_nn` — `THROWIFNOT nn` `(f – )` for `0 ≤ nn < 2^11`. -* `F2EC_nn` — `THROWARGIFNOT nn` `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f = 0`. -* `F2F0` — `THROWANY` `(n – 0 n)`, throws exception `0 ≤ n < 2^16` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. -* `F2F1` — `THROWARGANY` `(x n – x n)`, throws exception `0 ≤ n < 2^16` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. -* `F2F2` — `THROWANYIF` `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f ≠ 0`. -* `F2F3` — `THROWARGANYIF` `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f ≠ 0`. -* `F2F4` — `THROWANYIFNOT` `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f = 0`. -* `F2F5` — `THROWARGANYIFNOT` `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f = 0`. +* `CF0Ecc` — `STIRQ cc + 1 (b x – b x f or b′ 0)`. -### A.9.2. Catching and handling exceptions +* `CF0Fcc` — `STURQ cc + 1 (b x – b x f or b′ 0)`. -* `F2FF` — `TRY` `(c c0 – )`, sets `c2` to `c0`, saving the old value of `c2` both into the savelist of `c0` and into the savelist of the current continuation. Then runs `c`. If `c` does not throw any exceptions, the original value of `c2` is restored. If an exception occurs, execution is transferred to `c0`. -* `F3pr` — `TRYARGS p,r` `(c c0 – )`, similar to `TRY`, but with `CALLARGS p,r` internally used instead of `EXECUTE`. +* `CF10` — a longer version of `STREF (c b – b′)`. ---- +* `CF11` — `STBREF (b′ b – b′′)`, equivalent to `SWAP; STBREFREV`. -# A.10 Dictionary manipulation primitives +* `CF12` — a longer version of `STSLICE (s b – b′)`. -TVM’s dictionary support is discussed at length in 3.3. The basic operations with dictionaries are listed in 3.3.10, while the taxonomy of dictionary -115 -A.10. Dictionary manipulation primitives -manipulation primitives is provided in 3.3.11. Here we use the concepts and notation introduced in those sections. +* `CF13` — `STB (b′ b – b′′)`, appends all data from Builder `b′` to Builder `b`. -Dictionaries admit two different representations as TVM stack values: +* `CF14` — `STREFR (b c – b′)`. -* A `Slice` `s` with a serialization of a TL-B value of type `HashmapE(n, X)`. In other words, `s` consists either of one bit equal to zero (if the dictionary is empty), or of one bit equal to one and a reference to a `Cell` containing the root of the binary tree, i.e., a serialized value of type `Hashmap(n, X)`. -* A “maybe `Cell`” `c ?`, i.e., a value that is either a `Cell` (containing a serialized value of type `Hashmap(n, X)` as before) or a `Null` (corresponding to an empty dictionary). When a “maybe `Cell`” `c ?` is used to represent a dictionary, we usually denote it by `D` in the stack notation. +* `CF15` — `STBREFR (b b′ – b′′)`, a longer encoding of `STBREFR`. -Most of the dictionary primitives listed below accept and return dictionaries in the second form, which is more convenient for stack manipulation. However, serialized dictionaries inside larger TL-B objects use the first representation. +* `CF16` — `STSLICER (b s – b′)`. -Opcodes starting with `F4` and `F5` are reserved for dictionary operations. +* `CF17` — `STBR (b b′ – b′′)`, concatenates two Builders, equivalent to `SWAP; STB`. -### A.10.1. Dictionary creation. +* `CF18` — `STREFQ (c b – c b−1 or b′ 0)`. -* `6D` — `NEWDICT` `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for `PUSHNULL`, cf. A.3.1. -* `6E` — `DICTEMPTY` `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for `ISNULL`, cf. A.3.1. +* `CF19` — `STBREFQ (b′ b – b′ b−1 or b′′ 0)`. ---- +* `CF1A` — `STSLICEQ (s b – s b−1 or b′ 0)`. -### A.10.2. Dictionary serialization and deserialization. +* `CF1B` — `STBQ (b′ b – b′ b−1 or b′′ 0)`. -* `CE` — `STDICTS` `(s b – b 0)`, stores a `Slice`-represented dictionary `s` into `Builder` `b`. It is actually a synonym for `STSLICE`. -* `F400` — `STDICT` or `STOPTREF` `(D b – b 0)`, stores dictionary `D` into `Builder` `b`, returing the resulting `Builder` `b 0`. In other words, if `D` is a cell, performs `STONE` and `STREF`; if `D` is `Null`, performs `NIP` and `STZERO`; otherwise throws a type checking exception. -* `F401` — `SKIPDICT` or `SKIPOPTREF` `(s – s 0)`, equivalent to `LDDICT`; `NIP` -* `F402` — `LDDICTS` `(s – s 0 s 00)`, loads (parses) a (`Slice`-represented) dictionary `s 0` from `Slice` `s`, and returns the remainder of `s` as `s 00`. This is a “split function” for all `HashmapE(n, X)` dictionary types. -* `F403` — `PLDDICTS` `(s – s 0)`, preloads a (`Slice`-represented) dictionary `s 0` from `Slice` `s`. Approximately equivalent to `LDDICTS`; `DROP`. -* `F404` — `LDDICT` or `LDOPTREF` `(s – D s0)`, loads (parses) a dictionary `D` from `Slice` `s`, and returns the remainder of `s` as `s 0`. May be applied to dictionaries or to values of arbitrary `(ˆY ) ?` types. -* `F405` — `PLDDICT` or `PLDOPTREF` `(s – D)`, preloads a dictionary `D` from `Slice` `s`. Approximately equivalent to `LDDICT`; `DROP`. -* `F406` — `LDDICTQ` `(s – D s0 −1 or s 0)`, a quiet version of `LDDICT`. -* `F407` — `PLDDICTQ` `(s – D −1 or 0)`, a quiet version of `PLDDICT`. +* `CF1C` — `STREFRQ (b c – b c−1 or b′ 0)`. +* `CF1D` — `STBREFRQ (b b′ – b b′−1 or b′′ 0)`. -### A.10.3. Get dictionary operations. +* `CF1E` — `STSLICERQ (b s – b s−1 or b′′ 0)`. -* `F40A` — `DICTGET` `(k D n – x −1 or 0)`, looks up key `k` (represented by a `Slice`, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the value found as a `Slice` `x`. -* `F40B` — `DICTGETREF` `(k D n – c −1 or 0)`, similar to `DICTGET`, but with a `LDREF`; `ENDS` applied to `x` on success. This operation is useful for dictionaries of type `HashmapE(n, ˆY )`. -* `F40C` — `DICTIGET` `(i D n – x −1 or 0)`, similar to `DICTGET`, but with a signed (big-endian) n-bit `Integer` `i` as a key. If `i` does not fit into n bits, returns `0`. If `i` is a `NaN`, throws an integer overflow exception. -* `F40D` — `DICTIGETREF` `(i D n – c −1 or 0)`, combines `DICTIGET` with `DICTGETREF`: it uses signed n-bit `Integer` `i` as a key and returns a `Cell` instead of a `Slice` on success. -* `F40E` — `DICTUGET` `(i D n – x −1 or 0)`, similar to `DICTIGET`, but with unsigned (big-endian) n-bit `Integer` `i` used as a key. -* `F40F` — `DICTUGETREF` `(i D n – c −1 or 0)`, similar to `DICTIGETREF`, but with an unsigned n-bit `Integer` key `i`. +* `CF1F` — `STBRQ (b b′ – b b′−1 or b′′ 0)`. +* `CF20` — `STREFCONST`, equivalent to `PUSHREF; STREFR`. -## A.10.4. Set/Replace/Add dictionary operations. +* `CF21` — `STREF2CONST`, equivalent to `STREFCONST; STREFCONST`. -The mnemonics of the following dictionary primitives are constructed in a systematic fashion according to the regular expression `DICT[, I, U](SET, REPLACE, ADD)[GET][REF]` depending on the type of the key used (a `Slice` or a signed or unsigned `Integer`), the dictionary operation to be performed, and the way the values are accepted and returned (as `Cells` or as `Slices`). Therefore, we provide a detailed description only for some primitives, assuming that this information is sufficient for the reader to understand the precise action of the remaining primitives. +* `CF23` — `ENDXC (b x – c)`, if `x ≠ 0`, creates a special or exotic cell + (cf. [3.1.2](#3-1-2-ordinary-and-exotic-cells)) from Builder `b`. + - The type of the exotic cell must be stored in the first 8 bits of `b`. + - If `x = 0`, it is equivalent to `ENDC`. + - Otherwise some validity checks on the data and references of `b` are + performed before creating the exotic cell. -* `F412` — `DICTSET` `(x k D n – D0)`, sets the value associated with n-bit key `k` (represented by a `Slice` as in `DICTGET`) in dictionary `D` (also represented by a `Slice`) to value `x` (again a `Slice`), and returns the resulting dictionary as `D0`. -* `F413` — `DICTSETREF` `(c k D n – D0)`, similar to `DICTSET`, but with the value set to a reference to `Cell` `c`. -* `F414` — `DICTISET` `(x i D n – D0)`, similar to `DICTSET`, but with the key represented by a (big-endian) signed n-bit integer `i`. If `i` does not fit into n bits, a range check exception is generated. -* `F415` — `DICTISETREF` `(c i D n – D0)`, similar to `DICTSETREF`, but with the key a signed n-bit integer as in `DICTISET`. -* `F416` — `DICTUSET` `(x i D n – D0)`, similar to `DICTISET`, but with `i` an unsigned n-bit integer. -* `F417` — `DICTUSETREF` `(c i D n – D0)`, similar to `DICTISETREF`, but with `i` unsigned. -* `F41A` — `DICTSETGET` `(x k D n – D0 y −1 or D0 0)`, combines `DICTSET` with `DICTGET`: it sets the value corresponding to key `k` to `x`, but also returns the old value `y` associated with the key in question, if present. -* `F41B` — `DICTSETGETREF` `(c k D n – D0 c 0 −1 or D0 0)`, combines `DICTSETREF` with `DICTGETREF` similarly to `DICTSETGET`. -* `F41C` — `DICTISETGET` `(x i D n – D0 y −1 or D0 0)`, similar to `DICTSETGET`, but with the key represented by a big-endian signed n-bit `Integer` `i` -* `F41D` — `DICTISETGETREF` `(c i D n – D0 c 0 −1 or D0 0)`, a version of `DICTSETGETREF` with signed `Integer` `i` as a key. -* `F41E` — `DICTUSETGET` `(x i D n – D0 y −1 or D0 0)`, similar to `DICTISETGET`, but with `i` an unsigned n-bit integer. -* `F41F` — `DICTUSETGETREF` `(c i D n – D0 c 0 −1 or D0 0)`. -* `F422` — `DICTREPLACE` `(x k D n – D0 −1 or D 0)`, a Replace operation, which is similar to `DICTSET`, but sets the value of key `k` in dictionary `D` to `x` only if the key `k` was already present in `D`. -* `F423` — `DICTREPLACEREF` `(c k D n – D0 −1 or D 0)`, a Replace counterpart of `DICTSETREF`. -* `F424` — `DICTIREPLACE` `(x i D n – D0 −1 or D 0)`, a version of `DICTREPLACE` with signed n-bit `Integer` `i` used as a key. -* `F425` — `DICTIREPLACEREF` `(c i D n – D0 −1 or D 0)`. -* `F426` — `DICTUREPLACE` `(x i D n – D0 −1 or D 0)`. -* `F427` — `DICTUREPLACEREF` `(c i D n – D0 −1 or D 0)`. -* `F42A` — `DICTREPLACEGET` `(x k D n – D0 y −1 or D 0)`, a Replace counterpart of `DICTSETGET`: on success, also returns the old value associated with the key in question. -* `F42B` — `DICTREPLACEGETREF` `(c k D n – D0 c 0 −1 or D 0)`. -* `F42C` — `DICTIREPLACEGET` `(x i D n – D0 y −1 or D 0)`. -* `F42D` — `DICTIREPLACEGETREF` `(c i D n – D0 c 0 −1 or D 0)`. -* `F42E` — `DICTUREPLACEGET` `(x i D n – D0 y −1 or D 0)`. -* `F42F` — `DICTUREPLACEGETREF` `(c i D n – D0 c 0 −1 or D 0)`. -* `F432` — `DICTADD` `(x k D n – D0 −1 or D 0)`, an Add counterpart of `DICTSET`: sets the value associated with key `k` in dictionary `D` to `x`, but only if it is not already present in `D`. -* `F433` — `DICTADDREF` `(c k D n – D0 −1 or D 0)`. -* `F434` — `DICTIADD` `(x i D n – D0 −1 or D 0)`. -* `F435` — `DICTIADDREF` `(c i D n – D0 −1 or D 0)`. -* `F436` — `DICTUADD` `(x i D n – D0 −1 or D 0)`. -* `F437` — `DICTUADDREF` `(c i D n – D0 −1 or D 0)`. -* `F43A` — `DICTADDGET` `(x k D n – D0 −1 or D y 0)`, an Add counterpart of `DICTSETGET`: sets the value associated with key `k` in dictionary `D` to `x`, but only if key `k` is not already present in `D`. Otherwise, just returns the old value `y` without changing the dictionary. -* `F43B` — `DICTADDGETREF` `(c k D n – D0 −1 or D c0 0)`, an Add counterpart of `DICTSETGETREF`. -* `F43C` — `DICTIADDGET` `(x i D n – D0 −1 or D y 0)`. -* `F43D` — `DICTIADDGETREF` `(c i D n – D0 −1 or D c0 0)`. -* `F43E` — `DICTUADDGET` `(x i D n – D0 −1 or D y 0)`. -* `F43F` — `DICTUADDGETREF` `(c i D n – D0 −1 or D c0 0)`. +* `CF28` — `STILE4 (x b – b′)`, stores a little-endian signed 32-bit integer. +* `CF29` — `STULE4 (x b – b′)`, stores a little-endian unsigned 32-bit integer. -### A.10.5. Builder-accepting variants of Set dictionary operations. +* `CF2A` — `STILE8 (x b – b′)`, stores a little-endian signed 64-bit integer. -The following primitives accept the new value as a `Builder` `b` instead of a `Slice` `x`, which often is more convenient if the value needs to be serialized from several components computed in the stack. (This is reflected by appending a `B` to the mnemonics of the corresponding Set primitives that work with `Slices`.) The net effect is roughly equivalent to converting `b` into a `Slice` by `ENDC`; `CTOS` and executing the corresponding primitive listed in A.10.4. - -* `F441` — `DICTSETB` `(b k D n – D0)`. -* `F442` — `DICTISETB` `(b i D n – D0)`. -* `F443` — `DICTUSETB` `(b i D n – D0)`. -* `F445` — `DICTSETGETB` `(b k D n – D0 y −1 or D0 0)`. -* `F446` — `DICTISETGETB` `(b i D n – D0 y −1 or D0 0)`. -* `F447` — `DICTUSETGETB` `(b i D n – D0 y −1 or D0 0)`. -* `F449` — `DICTREPLACEB` `(b k D n – D0 −1 or D 0)`. -* `F44A` — `DICTIREPLACEB` `(b i D n – D0 −1 or D 0)`. -* `F44B` — `DICTUREPLACEB` `(b i D n – D0 −1 or D 0)`. -* `F44D` — `DICTREPLACEGETB` `(b k D n – D0 y −1 or D 0)`. -* `F44E` — `DICTIREPLACEGETB` `(b i D n – D0 y −1 or D 0)`. -* `F44F` — `DICTUREPLACEGETB` `(b i D n – D0 y −1 or D 0)`. -* `F451` — `DICTADDB` `(b k D n – D0 −1 or D 0)`. -* `F452` — `DICTIADDB` `(b i D n – D0 −1 or D 0)`. -* `F453` — `DICTUADDB` `(b i D n – D0 −1 or D 0)`. -* `F455` — `DICTADDGETB` `(b k D n – D0 −1 or D y 0)`. -* `F456` — `DICTIADDGETB` `(b i D n – D0 −1 or D y 0)`. -* `F457` — `DICTUADDGETB` `(b i D n – D0 −1 or D y 0)`. +* `CF2B` — `STULE8 (x b – b′)`, stores a little-endian unsigned 64-bit integer. ---- +* `CF30` — `BDEPTH (b – x)`, returns the depth of Builder `b`. If no cell + references are stored in `b`, then `x = 0`; otherwise `x` is one plus the + maximum of depths of cells referred to from `b`. -### A.10.6. Delete dictionary operations. +* `CF31` — `BBITS (b – x)`, returns the number of data bits already stored + in Builder `b`. -* `F459` — `DICTDEL` `(k D n – D0 −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0` and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. -* `F45A` — `DICTIDEL` `(i D n – D0 ?)`, a version of `DICTDEL` with the key represented by a signed n-bit `Integer` `i`. If `i` does not fit into n bits, simply returns `D 0` (“key not found, dictionary unmodified”). -* `F45B` — `DICTUDEL` `(i D n – D0 ?)`, similar to `DICTIDEL`, but with `i` an unsigned n-bit integer. -* `F462` — `DICTDELGET` `(k D n – D0 x −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0`, the original value `x` associated with the key `k` (represented by a `Slice`), and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. -* `F463` — `DICTDELGETREF` `(k D n – D0 c −1 or D 0)`, similar to `DICTDELGET`, but with `LDREF`; `ENDS` applied to `x` on success, so that the value returned `c` is a `Cell`. -* `F464` — `DICTIDELGET` `(i D n – D0 x −1 or D 0)`, a variant of primitive `DICTDELGET` with signed n-bit integer `i` as a key. -* `F465` — `DICTIDELGETREF` `(i D n – D0 c −1 or D 0)`, a variant of primitive `DICTIDELGET` returning a `Cell` instead of a `Slice`. -* `F466` — `DICTUDELGET` `(i D n – D0 x −1 or D 0)`, a variant of primitive `DICTDELGET` with unsigned n-bit integer `i` as a key. -* `F467` — `DICTUDELGETREF` `(i D n – D0 c −1 or D 0)`, a variant of primitive `DICTUDELGET` returning a `Cell` instead of a `Slice`. +* `CF32` — `BREFS (b – y)`, returns the number of cell references already + stored in `b`. +* `CF33` — `BBITREFS (b – x y)`, returns the numbers of both data bits and + cell references in `b`. -### A.10.7. “Maybe reference” dictionary operations. +* `CF35` — `BREMBITS (b – x′)`, returns the number of data bits that can + still be stored in `b`. -The following operations assume that a dictionary is used to store values `c ?` of type `Cell ?` (“Maybe `Cell`”), which can be used in particular to store dictionaries as values in other dictionaries. The representation is as follows: if `c ?` is a `Cell`, it is stored as a value with no data bits and exactly one reference to this `Cell`. If `c ?` is `Null`, then the corresponding key must be absent from the dictionary altogether. +* `CF36` — `BREMREFS (b – y′)`. -* `F469` — `DICTGETOPTREF` `(k D n – c ? )`, a variant of `DICTGETREF` that returns `Null` instead of the value `c ?` if the key `k` is absent from dictionary `D`. -* `F46A` — `DICTIGETOPTREF` `(i D n – c ? )`, similar to `DICTGETOPTREF`, but with the key given by signed n-bit `Integer` `i`. If the key `i` is out of range, also returns `Null`. -* `F46B` — `DICTUGETOPTREF` `(i D n – c ? )`, similar to `DICTGETOPTREF`, but with the key given by unsigned n-bit `Integer` `i`. -* `F46D` — `DICTSETGETOPTREF` `(c ? k D n – D0 c˜ ? )`, a variant of both `DICTGETOPTREF` and `DICTSETGETREF` that sets the value corresponding to key `k` in dictionary `D` to `c ?` (if `c ?` is `Null`, then the key is deleted instead), and returns the old value `c˜ ?` (if the key `k` was absent before, returns `Null` instead). -* `F46E` — `DICTISETGETOPTREF` `(c ? i D n – D0 c˜ ? )`, similar to primitive `DICTSETGETOPTREF`, but using signed n-bit `Integer` `i` as a key. If `i` does not fit into n bits, throws a range checking exception. -* `F46F` — `DICTUSETGETOPTREF` `(c ? i D n – D0 c˜ ? )`, similar to primitive `DICTSETGETOPTREF`, but using unsigned n-bit `Integer` `i` as a key. +* `CF37` — `BREMBITREFS (b – x′ y′)`. +* `CF38cc` — `BCHKBITS cc + 1 (b – )`, checks whether `cc + 1` bits can be + stored into `b`, where `0 ≤ cc ≤ 255`. -### A.10.8. Prefix code dictionary operations. +* `CF39` — `BCHKBITS (b x – )`, checks whether `x` bits can be stored into `b`, + `0 ≤ x ≤ 1023`. If there is no space for `x` more bits in `b`, or if `x` is not + within the range, throws an exception. -These are some basic operations for constructing prefix code dictionaries (cf. 3.4.2). The primary application for prefix code dictionaries is deserializing TL-B serialized data structures, or, more generally, parsing prefix codes. Therefore, most prefix code dictionaries will be constant and created at compile time, not by the following primitives. -Some Get operations for prefix code dictionaries may be found in A.10.11. -Other prefix code dictionary operations include: +* `CF3A` — `BCHKREFS (b y – )`, checks whether `y` references can be stored + into `b`, `0 ≤ y ≤ 7`. -* `F470` — `PFXDICTSET` `(x k D n – D0 −1 or D 0)`. -* `F471` — `PFXDICTREPLACE` `(x k D n – D0 −1 or D 0)`. -* `F472` — `PFXDICTADD` `(x k D n – D0 −1 or D 0)`. -* `F473` — `PFXDICTDEL` `(k D n – D0 −1 or D 0)`. +* `CF3B` — `BCHKBITREFS (b x y – )`, checks whether `x` bits and `y` + references can be stored into `b`, `0 ≤ x ≤ 1023`, `0 ≤ y ≤ 7`. -These primitives are completely similar to their non-prefix code counterparts `DICTSET` etc (cf. A.10.4), with the obvious difference that even a Set may fail in a prefix code dictionary, so a success flag must be returned by `PFXDICTSET` as well. +* `CF3Ccc` — `BCHKBITSQ cc + 1 (b – ? )`, checks whether `cc + 1` bits can + be stored into `b`, where `0 ≤ cc ≤ 255`. -### A.10.9. Variants of GetNext and GetPrev operations. +* `CF3D` — `BCHKBITSQ (b x – ? )`, checks whether `x` bits can be stored into + `b`, `0 ≤ x ≤ 1023`. -* `F474` — `DICTGETNEXT` `(k D n – x 0 k 0 −1 or 0)`, computes the minimal key `k 0` in dictionary `D` that is lexicographically greater than `k`, and returns `k 0` (represented by a `Slice`) along with associated value `x 0` (also represented by a `Slice`). -* `F475` — `DICTGETNEXTEQ` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETNEXT`, but computes the minimal key `k 0` that is lexicographically greater than or equal to `k`. -* `F476` — `DICTGETPREV` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETNEXT`, but computes the maximal key `k 0` lexicographically smaller than `k`. -* `F477` — `DICTGETPREVEQ` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETPREV`, but computes the maximal key `k 0` lexicographically smaller than or equal to `k`. -* `F478` — `DICTIGETNEXT` `(i D n – x 0 i 0 −1 or 0)`, similar to `DICTGETNEXT`, but interprets all keys in dictionary `D` as big-endian signed n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits). -* `F479` — `DICTIGETNEXTEQ` `(i D n – x 0 i 0 −1 or 0)`. -* `F47A` — `DICTIGETPREV` `(i D n – x 0 i 0 −1 or 0)`. -* `F47B` — `DICTIGETPREVEQ` `(i D n – x 0 i 0 −1 or 0)`. -* `F47C` — `DICTUGETNEXT` `(i D n – x 0 i 0 −1 or 0)`, similar to `DICTGETNEXT`, but interprets all keys in dictionary `D` as big-endian unsigned n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits, and is not necessarily nonnegative). -* `F47D` — `DICTUGETNEXTEQ` `(i D n – x 0 i 0 −1 or 0)`. -* `F47E` — `DICTUGETPREV` `(i D n – x 0 i 0 −1 or 0)`. -* `F47F` — `DICTUGETPREVEQ` `(i D n – x 0 i 0 −1 or 0)`. +* `CF3E` — `BCHKREFSQ (b y – ? )`, checks whether `y` references can be stored + into `b`, `0 ≤ y ≤ 7`. -### A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. +* `CF3F` — `BCHKBITREFSQ (b x y – ? )`, checks whether `x` bits and `y` + references can be stored into `b`, `0 ≤ x ≤ 1023`, `0 ≤ y ≤ 7`. -* `F482` — `DICTMIN` `(D n – x k −1 or 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. -* `F483` — `DICTMINREF` `(D n – c k −1 or 0)`, similar to `DICTMIN`, but returns the only reference in the value as a `Cell` `c`. -* `F484` — `DICTIMIN` `(D n – x i −1 or 0)`, somewhat similar to `DICTMIN`, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by `DICTMIN` and `DICTUMIN` -* `F485` — `DICTIMINREF` `(D n – c i −1 or 0)`. -* `F486` — `DICTUMIN` `(D n – x i −1 or 0)`, similar to `DICTMIN`, but returns the key as an unsigned n-bit `Integer` `i`. -* `F487` — `DICTUMINREF` `(D n – c i −1 or 0)`. -* `F48A` — `DICTMAX` `(D n – x k −1 or 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. -* `F48B` — `DICTMAXREF` `(D n – c k −1 or 0)`. -* `F48C` — `DICTIMAX` `(D n – x i −1 or 0)`. -* `F48D` — `DICTIMAXREF` `(D n – c i −1 or 0)`. -* `F48E` — `DICTUMAX` `(D n – x i −1 or 0)`. -* `F48F` — `DICTUMAXREF` `(D n – c i −1 or 0)`. -* `F492` — `DICTREMMIN` `(D n – D0 x k −1 or D 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. -* `F493` — `DICTREMMINREF` `(D n – D0 c k −1 or D 0)`, similar to `DICTREMMIN`, but returns the only reference in the value as a `Cell` `c`. -* `F494` — `DICTIREMMIN` `(D n – D0 x i −1 or D 0)`, somewhat similar to `DICTREMMIN`, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by `DICTREMMIN` and `DICTUREMMIN`. -* `F495` — `DICTIREMMINREF` `(D n – D0 c i −1 or D 0)`. -* `F496` — `DICTUREMMIN` `(D n – D0 x i −1 or D 0)`, similar to `DICTREMMIN`, but returns the key as an unsigned n-bit `Integer` `i`. -* `F497` — `DICTUREMMINREF` `(D n – D0 c i −1 or D 0)`. -* `F49A` — `DICTREMMAX` `(D n – D0 x k −1 or D 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. -* `F49B` — `DICTREMMAXREF` `(D n – D0 c k −1 or D 0)`. -* `F49C` — `DICTIREMMAX` `(D n – D0 x i −1 or D 0)`. -* `F49D` — `DICTIREMMAXREF` `(D n – D0 c i −1 or D 0)`. -* `F49E` — `DICTUREMMAX` `(D n – D0 x i −1 or D 0)`. -* `F49F` — `DICTUREMMAXREF` `(D n – D0 c i −1 or D 0)`. +* `CF40` — `STZEROES (b n – b′)`, stores `n` binary zeroes into Builder `b`. -### A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. +* `CF41` — `STONES (b n – b′)`, stores `n` binary ones into Builder `b`. -* `F4A0` — `DICTIGETJMP` `(i D n – )`, similar to `DICTIGET` (cf. A.10.12), but with `x` `BLESS`ed into a continuation with a subsequent `JMPX` to it on success. On failure, does nothing. This is useful for implementing switch/case constructions. -* `F4A1` — `DICTUGETJMP` `(i D n – )`, similar to `DICTIGETJMP`, but performs `DICTUGET` instead of `DICTIGET`. -* `F4A2` — `DICTIGETEXEC` `(i D n – )`, similar to `DICTIGETJMP`, but with `EXECUTE` instead of `JMPX`. -* `F4A3` — `DICTUGETEXEC` `(i D n – )`, similar to `DICTUGETJMP`, but with `EXECUTE` instead of `JMPX`. -* `F4A6_n` — `DICTPUSHCONST n` `( – D n)`, pushes a non-empty constant dictionary `D` (as a `Cell ?`) along with its key length `0 ≤ n ≤ 1023`, stored as a part of the instruction. The dictionary itself is created from the first of remaining references of the current continuation. In this way, the complete `DICTPUSHCONST` instruction can be obtained by first serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and a cell reference), and then the unsigned 10-bit integer `n` (as if by a `STU 10` instruction). An empty dictionary can be pushed by a `NEWDICT` primitive (cf. A.10.1) instead. -* `F4A8` — `PFXDICTGETQ` `(s D n – s 0 x s00 −1 or s 0)`, looks up the unique prefix of `Slice` `s` present in the prefix code dictionary (cf. 3.4.2) represented by `Cell ?` `D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is returned as `s 0`, and the corresponding value (also a `Slice`) as `x`. The remainder of `s` is returned as a `Slice` `s 00`. If no prefix of `s` is a key in prefix code dictionary `D`, returns the unchanged `s` and a zero flag to indicate failure. -* `F4A9` — `PFXDICTGET` `(s D n – s 0 x s00)`, similar to `PFXDICTGET`, but throws a cell deserialization failure exception on failure. -* `F4AA` — `PFXDICTGETJMP` `(s D n – s 0 s 00 or s)`, similar to `PFXDICTGETQ`, but on success `BLESS`es the value `x` into a `Continuation` and transfers control to it as if by a `JMPX`. On failure, returns `s` unchanged and continues execution. -* `F4AB` — `PFXDICTGETEXEC` `(s D n – s 0 s 00)`, similar to `PFXDICTGETJMP`, but `EXEC`utes the continuation found instead of jumping to it. On failure, throws a cell deserialization exception. -* `F4AE_n` — `PFXDICTCONSTGETJMP n` or `PFXDICTSWITCH n` `(s – s 0 s 00 or s)`, combines `DICTPUSHCONST n` for `0 ≤ n ≤ 1023` with `PFXDICTGETJMP`. -* `F4BC` — `DICTIGETJMPZ` `(i D n – i or nothing)`, a variant of `DICTIGETJMP` that returns index `i` on failure. -* `F4BD` — `DICTUGETJMPZ` `(i D n – i or nothing)`, a variant of `DICTUGETJMP` that returns index `i` on failure. -* `F4BE` — `DICTIGETEXECZ` `(i D n – i or nothing)`, a variant of `DICTIGETEXEC` that returns index `i` on failure. -* `F4BF` — `DICTUGETEXECZ` `(i D n – i or nothing)`, a variant of `DICTUGETEXEC` that returns index `i` on failure. - -### A.10.12. SubDict dictionary operations. - -* `F4B1` — `SUBDICTGET` `(k l D n – D0)`, constructs a subdictionary consisting of all keys beginning with prefix `k` (represented by a `Slice`, the first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the new subdictionary of the same type `HashmapE(n, X)` as a `Slice` `D0`. -* `F4B2` — `SUBDICTIGET` `(x l D n – D0)`, variant of `SUBDICTGET` with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. -* `F4B3` — `SUBDICTUGET` `(x l D n – D0)`, variant of `SUBDICTGET` with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. -* `F4B5` — `SUBDICTRPGET` `(k l D n – D0)`, similar to `SUBDICTGET`, but removes the common prefix `k` from all keys of the new dictionary `D0`, which becomes of type `HashmapE(n − l, X)`. -* `F4B6` — `SUBDICTIRPGET` `(x l D n – D0)`, variant of `SUBDICTRPGET` with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. -* `F4B7` — `SUBDICTURPGET` `(x l D n – D0)`, variant of `SUBDICTRPGET` with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. -* `F4BC–F4BF` — used by `DICT...Z` primitives in A.10.11. +* `CF42` — `STSAME (b n x – b′)`, stores `n` binary `x`s (`0 ≤ x ≤ 1`) into + Builder `b`. ---- +* `CF81` — `STSLICECONST '0'` or `STZERO (b – b′)`, stores one binary zero. -# A.11 Application-specific primitives +* `CF83` — `STSLICECONST '1'` or `STONE (b – b′)`, stores one binary one. -Opcode range `F8...FB` is reserved for the application-specific primitives. When TVM is used to execute TON Blockchain smart contracts, these application-specific primitives are in fact TON Blockchain-specific. +* `CFA2` — equivalent to `STREFCONST`. -### A.11.1. External actions and access to blockchain configuration data. +* `CFA3` — almost equivalent to `STSLICECONST '1'; STREFCONST`. -Some of the primitives listed below pretend to produce some externally visible actions, such as sending a message to another smart contract. In fact, the execution of a smart contract in TVM never has any effect apart from a modification of the TVM state. All external actions are collected into a linked list stored in special register `c5` (“output actions”). Additionally, some primitives use the data kept in the first component of the Tuple stored in `c7` (“root of temporary data”, cf. 1.3.2). Smart contracts are free to modify any other data kept in the cell `c7`, provided the first reference remains intact (otherwise some application-specific primitives would be likely to throw exceptions when invoked). +* `CFC0_xysss` — `STSLICECONST sss (b – b′)`, stores a constant subslice + `sss` consisting of `0 ≤ x ≤ 3` references and up to `8y + 1` data bits, with + `0 ≤ y ≤ 7`. Completion bit is assumed. -Most of the primitives listed below use 16-bit opcodes. +* `CFC2` — equivalent to `STREF2CONST`. -### A.11.2. Gas-related primitives. +* `CFE2` — `STREF3CONST`. -Of the following primitives, only the first two are “pure” in the sense that they do not use `c5` or `c7`. +### A.7.2. Cell deserialization primitives -* `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. 1.4), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence no gas) with themselves. -* `F801` — `SETGASLIMIT` `(g – )`, sets current gas limit `gl` to the minimum of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed so far (including the present instruction) exceeds the resulting value of `gl`, an (unhandled) out of gas exception is thrown before setting new gas limits. Notice that `SETGASLIMIT` with an argument `g ≥ 2^63 − 1` is equivalent to `ACCEPT`. -* `F802` — `BUYGAS` `(x – )`, computes the amount of gas that can be bought for `x` nanograms, and sets `gl` accordingly in the same way as `SETGASLIMIT`. -* `F804` — `GRAMTOGAS` `(x – g)`, computes the amount of gas that can be bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `2^63−1`, it is replaced with this value. -* `F805` — `GASTOGRAM` `(g – x)`, computes the price of `g` gas in nanograms. -* `F806–F80E` — Reserved for gas-related primitives. -* `F80F` — `COMMIT` `( – )`, commits the current state of registers `c4` (“persistent data”) and `c5` (“actions”) so that the current execution is considered “successful” with the saved values even if an exception is thrown later. +* `D0` — `CTOS (c– s)`, converts a Cell into a Slice. Notice that c must + be either an ordinary cell, or an exotic cell (cf. [3.1.2](#3-1-2-ordinary-and-exotic-cells)) which is au- + tomatically loaded to yield an ordinary cell c′, converted into a Slice + afterwards. ---- +* `D1` — `ENDS (s – )`, removes a Slice s from the stack, and throws an + exception if it is not empty. -### A.11.3. Pseudo-random number generator primitives. +* `D2cc` — `LDI cc+ 1 (s– x s′)`, loads (i.e., parses) a signed cc+ 1-bit + integer x from Slice s, and returns the remainder of s as s′. -The pseudo-random number generator uses the random seed (parameter `#6`, cf. A.11.4), an unsigned 256-bit `Integer`, and (sometimes) other data kept in `c7`. -The initial value of the random seed before a smart contract is executed in TON Blockchain is a hash of the smart contract address and the global block random seed. If there are several runs of the same smart contract inside a block, then all of these runs will have the same random seed. This can be fixed, for example, by running `LTIME`; `ADDRAND` before using the pseudo-random number generator for the first time. +* `D3cc` — `LDU cc+ 1 (s– x s′)`, loads an unsigned cc+ 1-bit integer x + from Slice s. -* `F810` — `RANDU256` `( – x)`, generates a new pseudo-random unsigned 256-bit `Integer` `x`. The algorithm is as follows: if `r` is the old value of the random seed, considered as a 32-byte array (by constructing the big-endian representation of an unsigned 256-bit integer), then its `sha512(r)` is computed; the first 32 bytes of this hash are stored as the new value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`. -* `F811` — `RAND` `(y – z)`, generates a new pseudo-random integer `z` in the range `0 ... y − 1` (or `y ... − 1`, if `y < 0`). More precisely, an unsigned random value `x` is generated as in `RAND256U`; then `z := ⌊x·y/2^256⌋` is computed. Equivalent to `RANDU256`; `MULRSHIFT` `256`. -* `F814` — `SETRAND` `(x – )`, sets the random seed to unsigned 256-bit `Integer` `x`. -* `F815` — `ADDRAND` `(x – )`, mixes unsigned 256-bit `Integer` `x` into the random seed `r` by setting the random seed to `sha256` of the concatenation of two 32-byte strings: the first with the big-endian representation of the old seed `r`, and the second with the big-endian representation of `x`. -* `F810–F81F` — Reserved for pseudo-random number generator primitives. +* `D4` — `LDREF (s– c s′)`, loads a cell reference c from s. ---- +* `D5` — `LDREFRTOS (s– s′ s′′)`, equivalent to LDREF; SWAP; CTOS. -### A.11.4. Configuration primitives. +* `D6cc` — `LDSLICE cc+ 1 (s– s′′s′)`, cuts the next cc+ 1 bits of s into a + separate Slice s′′. -The following primitives read configuration data provided in the Tuple stored in the first component of the Tuple at `c7`. Whenever TVM is invoked for executing TON Blockchain smart contracts, this Tuple is initialized by a `SmartContractInfo` structure; configuration primitives assume that it has remained intact. - -* `F82i` — `GETPARAM` `i` `( – x)`, returns the `i`-th parameter from the Tuple provided at `c7` for `0 ≤ i < 16`. Equivalent to `PUSH` `c7`; `FIRST`; `INDEX` `i`. If one of these internal operations fails, throws an appropriate type checking or range checking exception -* `F823` — `NOW` `( – x)`, returns the current Unix time as an `Integer`. If it is impossible to recover the requested value starting from `c7`, throws a type checking or range checking exception as appropriate. Equivalent to `GETPARAM` `3`. -* `F824` — `BLOCKLT` `( – x)`, returns the starting logical time of the current block. Equivalent to `GETPARAM` `4`. -* `F825` — `LTIME` `( – x)`, returns the logical time of the current transaction. Equivalent to `GETPARAM` `5`. -* `F826` — `RANDSEED` `( – x)`, returns the current random seed as an unsigned 256-bit `Integer`. Equivalent to `GETPARAM` `6`. -* `F827` — `BALANCE` `( – t)`, returns the remaining balance of the smart contract as a `Tuple` consisting of an `Integer` (the remaining Gram balance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys representing the balance of “extra currencies”). Equivalent to `GETPARAM` `7`. Note that RAW primitives such as `SENDRAWMSG` do not update this field. -* `F828` — `MYADDR` `( – s)`, returns the internal address of the current smart contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed further using primitives such as `PARSESTDADDR` or `REWRITESTDADDR`. Equivalent to `GETPARAM` `8`. -* `F829` — `CONFIGROOT` `( – D)`, returns the `Maybe Cell` `D` with the current global configuration dictionary. Equivalent to `GETPARAM` `9`. -* `F830` — `CONFIGDICT` `( – D 32)`, returns the global configuration dictionary along with its key length (`32`). Equivalent to `CONFIGROOT`; `PUSHINT` `32`. -* `F832` — `CONFIGPARAM` `(i – c −1 or 0)`, returns the value of the global configuration parameter with integer index `i` as a `Cell` `c`, and a flag to indicate success. Equivalent to `CONFIGDICT`; `DICTIGETREF`. -* `F833` — `CONFIGOPTPARAM` `(i – c ? )`, returns the value of the global configuration parameter with integer index `i` as a `Maybe Cell` `c ?`. Equivalent to `CONFIGDICT`; `DICTIGETOPTREF`. -* `F820–F83F` — Reserved for configuration primitives. +* `D700` — `LDIX (s l– x s′)`, loads a signed l-bit (0 ≤l ≤257) integer x + from Slice s, and returns the remainder of s as s′. ---- +* `D701` — `LDUX (s l– x s′)`, loads an unsigned l-bit integer x from (the + first l bits of) s, with 0 ≤l≤256. -### A.11.6. Hashing and cryptography primitives. +* `D702` — `PLDIX (s l– x)`, preloads a signed l-bit integer from Slice s, + for 0 ≤l≤257. -* `F900` — `HASHCU` `(c – x)`, computes the representation hash (cf. 3.1.5) of a `Cell` `c` and returns it as a 256-bit unsigned integer `x`. Useful for signing and checking signatures of arbitrary entities represented by a tree of cells. -* `F901` — `HASHSU` `(s – x)`, computes the hash of a `Slice` `s` and returns it as a 256-bit unsigned integer `x`. The result is the same as if an ordinary cell containing only data and references from `s` had been created and its hash computed by `HASHCU`. -* `F902` — `SHA256U` `(s – x)`, computes `sha256` of the data bits of `Slice` `s`. If the bit length of `s` is not divisible by eight, throws a cell underflow exception. The hash value is returned as a 256-bit unsigned integer `x`. -* `F910` — `CHKSIGNU` `(h s k – ? )`, checks the Ed25519-signature `s` of a hash `h` (a 256-bit unsigned integer, usually computed as the hash of some data) using public key `k` (also represented by a 256-bit unsigned integer). The signature `s` must be a `Slice` containing at least 512 databits; only the first 512 bits are used. The result is `−1` if the signature is valid, `0` otherwise. Notice that `CHKSIGNU` is equivalent to `ROT`; `NEWB`; `STU` `256`; `ENDB`; `NEWC`; `ROTREV`; `CHKSIGNS`, i.e., to `CHKSIGNS` with the first argument `d` set to 256-bit `Slice` containing `h`. Therefore, if `h` is computed as the hash of some data, these data are hashed twice, the second hashing occurring inside `CHKSIGNS`. -* `F911` — `CHKSIGNS` `(d s k – ? )`, checks whether `s` is a valid Ed25519-signature of the data portion of `Slice` `d` using public key `k`, similarly to `CHKSIGNU`. If the bit length of `Slice` `d` is not divisible by eight, throws a cell underflow exception. The verification of Ed25519 signatures is the standard one, with `sha256` used to reduce `d` to the 256-bit number that is actually signed. -* `F912–F93F` — Reserved for hashing and cryptography primitives. +* `D703` — `PLDUX (s l– x)`, preloads an unsigned l-bit integer from s, for + 0 ≤l≤256. ---- +* `D704` — `LDIXQ (s l– x s′ −1 or s 0)`, quiet version of LDIX: loads a + signed l-bit integer from ssimilarly to LDIX, but returns a success flag, + equal to−1 on success or to 0 on failure (if s does not have l bits), + instead of throwing a cell underflow exception. -### A.11.7. Miscellaneous primitives. +* `D705` — `LDUXQ (s l– x s′ −1 or s 0)`, quiet version of LDUX. -* `F940` — `CDATASIZEQ` `(c n – x y z −1 or 0)`, recursively computes the count of distinct cells `x`, data bits `y`, and cell references `z` in the dag rooted at `Cell` `c`, effectively returning the total storage used by this dag taking into account the identification of equal cells. The values of `x`, `y`, and `z` are computed by a depth-first traversal of this dag, with a hash table of visited cell hashes used to prevent visits of already-visited cells. The total count of visited cells `x` cannot exceed non-negative `Integer` `n`; otherwise the computation is aborted before visiting the `(n + 1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, returns `x = y = z = 0`. -* `F941` — `CDATASIZE` `(c n – x y z)`, a non-quiet version of `CDATASIZEQ` that throws a cell overflow exception (8) on failure. -* `F942` — `SDATASIZEQ` `(s n – x y z −1 or 0)`, similar to `CDATASIZEQ`, but accepting a `Slice` `s` instead of a `Cell`. The returned value of `x` does not take into account the cell that contains the slice `s` itself; however, the data bits and the cell references of `s` are accounted for in `y` and `z`. -* `F943` — `SDATASIZE` `(s n – x y z)`, a non-quiet version of `SDATASIZEQ` that throws a cell overflow exception (8) on failure. -* `F944–F97F` — Reserved for miscellaneous TON-specific primitives that do not fall into any other specific category. +* `D706` — `PLDIXQ (s l– x−1 or 0)`, quiet version of PLDIX. ---- +* `D707` — `PLDUXQ (s l– x−1 or 0)`, quiet version of PLDUX. -### A.11.8. Currency manipulation primitives. +* `D708cc` — `LDI cc+ 1 (s– x s′)`, a longer encoding for LDI. -* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU` `4`; `SWAP`; `LSHIFT` `3`; `LDUX`. -* `FA01` — `LDVARINT16` `(s – x s0)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU` `4`; `SWAP`; `LSHIFT` `3`; `LDIX`. -* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2^120−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2^(8l)`, followed by an `8l`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. -* `FA03` — `STVARINT16` `(b x – b 0)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2^119 ... 2^119 − 1`. -* `FA04` — `LDVARUINT32` `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2^248`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU` `5`; `SWAP`; `SHIFT` `3`; `LDUX`. -* `FA05` — `LDVARINT32` `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2^247 ≤ x < 2^247`. -* `FA06` — `STVARUINT32` `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2^248` as a `VarUInteger 32`. -* `FA07` — `STVARINT32` `(b x – b 0)`, serializes an `Integer` `−2^247 ≤ x < 2^247` as a `VarInteger 32`. -* `FA08–FA1F` — Reserved for currency manipulation primitives. +* `D709cc` — `LDU cc+ 1 (s– x s′)`, a longer encoding for LDU. +* `D70Acc` — `PLDI cc+ 1 (s– x)`, preloads a signed cc+ 1-bit integer from + Slice s. -### A.11.9. Message and address manipulation primitives. +* `D70Bcc` — `PLDU cc+ 1 (s– x)`, preloads an unsigned cc+ 1-bit integer + from s. -The message and address manipulation primitives listed below serialize and deserialize values according to the following TL-B scheme (cf. 3.3.4): +* `D70Ccc` — `LDIQ cc+ 1 (s– x s′ −1 or s 0)`, a quiet version of LDI. -``` -addr_none$00 = MsgAddressExt; -addr_extern$01 len:(## 8) external_address:(bits len) = MsgAddressExt; -anycast_info$_ depth:(<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; -addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt; -addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) workchain_id:int32 address:(bits addr_len) = MsgAddressInt; -_ _:MsgAddressInt = MsgAddress; -_ _:MsgAddressExt = MsgAddress; +* `D70Dcc` — `LDUQ cc+ 1 (s– x s′ −1 or s 0)`, a quiet version of LDU. -int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool - src:MsgAddress dest:MsgAddressInt - value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams - created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; +* `D70Ecc` — `PLDIQ cc+ 1 (s– x−1 or 0)`, a quiet version of PLDI. -ext_out_msg_info$11 src:MsgAddress dest:MsgAddressExt - created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; -``` +* `D70Fcc` — `PLDUQ cc+ 1 (s– x−1 or 0)`, a quiet version of PLDU. -A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: +* `D714_c` — `PLDUZ 32(c+ 1) (s– s x)`, preloads the first 32(c+ 1) bits + of Slice s into an unsigned integer x, for 0 ≤c ≤7. If s is shorter + than necessary, missing bits are assumed to be zero. This operation is + intended to be used along with IFBITJMP and similar instructions. -* `addr_none` is represented by `t = (0)`, i.e., a `Tuple` containing exactly one `Integer` equal to zero. -* `addr_extern` is represented by `t = (1, s)`, where `Slice` `s` contains the field `external_address`. In other words, `t` is a pair (a `Tuple` consisting of two entries), containing an `Integer` equal to one and `Slice` `s`. -* `addr_std` is represented by `t = (2, u, x, s)`, where `u` is either a `Null` (if `anycast` is absent) or a `Slice` `s0` containing `rewrite_pfx` (if `anycast` is present). Next, `Integer` `x` is the `workchain_id`, and `Slice` `s` contains the address. - `135` - A.11. Application-specific primitives -* `addr_var` is represented by `t = (3, u, x, s)`, where `u`, `x`, and `s` have the same meaning as for `addr_std`. +* `D718` — `LDSLICEX (s l– s′′ s′)`, loads the first 0 ≤l ≤1023 bits from + Slice s into a separate Slice s′′, returning the remainder of s as s′. -The following primitives, which use the above conventions, are defined: +* `D719` — `PLDSLICEX (s l– s′′)`, returns the first 0 ≤l ≤1023 bits of s + as s′′. -### A.11.9. Message and address manipulation primitives. +* `D71A` — `LDSLICEXQ (sl– s′′s′ −1 or s0)`, a quiet version of LDSLICEX. -* `FA40` — `LDMSGADDR` `(s – s 0 s 00)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s 0` and the remainder `s 00` of `s` as `CellSlices`. -* `FA41` — `LDMSGADDRQ` `(s – s 0 s 00 −1 or s 0)`, a quiet version of `LDMSGADDR`: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. -* `FA42` — `PARSEMSGADDR` `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. -* `FA43` — `PARSEMSGADDRQ` `(s – t −1 or 0)`, a quiet version of `PARSEMSGADDR`: returns a zero on error instead of throwing an exception. -* `FA44` — `REWRITESTDADDR` `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. -* `FA45` — `REWRITESTDADDRQ` `(s – x y −1 or 0)`, a quiet version of primitive `REWRITESTDADDR`. -* `FA46` — `REWRITEVARADDR` `(s – x s0)`, a variant of `REWRITESTDADDR` that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). -* `FA47` — `REWRITEVARADDRQ` `(s – x s0 −1 or 0)`, a quiet version of primitive `REWRITEVARADDR`. -* `FA48–FA5F` — Reserved for message and address manipulation primitives. +* `D71B` — `PLDSLICEXQ (s l– s′ −1 or 0)`, a quiet version of LDSLICEXQ. -### A.11.10. Outbound message and output action primitives. +* `D71Ccc` — `LDSLICE cc+ 1 (s– s′′ s′)`, a longer encoding for LDSLICE. -* `FB00` — `SENDRAWMSG` `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. -* `FB02` — `RAWRESERVE` `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. -* `FB03` — `RAWRESERVEX` `(x D y – )`, similar to `RAWRESERVE`, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. -* `FB04` — `SETCODE` `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. -* `FB06` — `SETLIBCODE` `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. -* `FB07` — `CHANGELIB` `(h x – )`, creates an output action similarly to `SETLIBCODE`, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. -* `FB08–FB3F` — Reserved for output action primitives. +* `D71Dcc` — `PLDSLICE cc+ 1 (s– s′′)`, returns the first 0 `cc+ 1 ≤256` + bits of s as s′′. ---- +* `D71Ecc` — `LDSLICEQ cc+ 1 (s– s′′ s′ −1 or s 0)`, a quiet version of + LDSLICE. -## A.12 Debug primitives +* `D71Fcc` — `PLDSLICEQ cc + 1 (s– s′′ −1 or 0)`, a quiet version of + PLDSLICE. -Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) `NOP` operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. +* `D720` — `SDCUTFIRST (s l– s′)`, returns the first 0 ≤l≤1023 bits of s. + It is equivalent to PLDSLICEX. -### A.12.1. Debug primitives as multibyte NOPs. +* `D721` — `SDSKIPFIRST (s l– s′)`, returns all but the first 0 ≤l ≤1023 + bits of s. It is equivalent to LDSLICEX; NIP. -* `FEnn` — `DEBUG nn`, for `0 ≤ nn < 240`, is a two-byte `NOP`. -* `FEFnssss` — `DEBUGSTR ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte `NOP`, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. +* `D722` — `SDCUTLAST (s l– s′)`, returns the last 0 ≤l≤1023 bits of s. -### A.12.2. Debug primitives as operations without side-effect. +* `D723` — `SDSKIPLAST (s l– s′)`, returns all but the last 0 ≤l ≤1023 + bits of s. -Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte `NOP`s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as `NOP`s, but they cannot throw exceptions. +* `D724` — `SDSUBSTR (s l l′ – s′)`, returns 0 ≤l′≤1023 bits of s starting + from offset 0 ≤l ≤1023, thus extracting a bit substring out of the + data of s. -* `FE00` — `DUMPSTK`, dumps the stack (at most the top 255 values) and shows the total stack depth. -* `FE0n` — `DUMPSTKTOP n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. -* `FE10` — `HEXDUMP`, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. -* `FE11` — `HEXPRINT`, similar to `HEXDUMP`, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. -* `FE12` — `BINDUMP`, dumps `s0` in binary form, similarly to `HEXDUMP`. -* `FE13` — `BINPRINT`, outputs the binary representation of `s0` to a text buffer. -* `FE14` — `STRDUMP`, dumps the `Slice` at `s0` as an UTF-8 string. -* `FE15` — `STRPRINT`, similar to `STRDUMP`, but outputs the string into a text buffer (without carriage return). -* `FE1E` — `DEBUGOFF`, disables all debug output until it is re-enabled by a `DEBUGON`. More precisely, this primitive increases an internal counter, which disables all debug operations (except `DEBUGOFF` and `DEBUGON`) when strictly positive. -* `FE1F` — `DEBUGON`, enables debug output (in a debug version of TVM). -* `FE2n` — `DUMP s(n)`, `0 ≤ n < 15`, dumps `s(n)`. -* `FE3n` — `PRINT s(n)`, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. -* `FEC0–FEEF` — Use these opcodes for custom/experimental debug operations. -* `FEFnssss` — `DUMPTOSFMT ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). -* `FEFn00ssss` — `LOGSTR ssss`, string `ssss` is `n` bytes long. -* `FEF000` — `LOGFLUSH`, flushes all pending debug output from the buffer into the debug log. -* `FEFn01ssss` — `PRINTSTR ssss`, string `ssss` is `n` bytes long. +* `D726` — `SDBEGINSX (ss′ – s′′)`, checks whether sbegins with (the data + bits of) s′, and removes s′ from s on success. On failure throws a + cell deserialization exception. Primitive SDPFXREV can be considered a + quiet version of SDBEGINSX. ---- +* `D727` — `SDBEGINSXQ (ss′ – s′′ −1 or s0)`, a quiet version of SDBEGINSX. -## A.13 Codepage primitives +* `D72A_xsss` — `SDBEGINS(s– s′′)`, checks whether sbegins with constant + bitstring sss of length 8x+ 3 (with continuation bit assumed), where + 0 ≤x≤127, and removes sss from s on success. -The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. 5.1.8). +* `D72802` — `SDBEGINS ‘0’ (s– s′′)`, checks whether s begins with a + binary zero. -* `FFnn` — `SETCP nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. -* `FF00` — `SETCP0`, selects TVM (test) codepage zero as described in this document. -* `FFFz` — `SETCP z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 ... −1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in B.2.6. Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. -* `FFF0` — `SETCPX` `(c – )`, selects codepage `c` with `−2^15 ≤ c < 2^15` passed in the top of the stack. ---- +* `D72806` — `SDBEGINS ‘1’ (s– s′′)`, checks whether s begins with a + binary one. -# B Formal properties and specifications of TVM +* `D72E_xsss` — `SDBEGINSQ(s–s′′ −1 ors0)`, a quiet version of SDBEGINS. -This appendix discusses certain formal properties of TVM that are necessary for executing smart contracts in the TON Blockchain and validating such executions afterwards. +* `D730` — `SCUTFIRST (s l r– s′)`, returns the first 0 ≤l≤1023 bits and + first 0 ≤r≤4 references of s. -## B.1 Serialization of the TVM state +* `D731` — `SSKIPFIRST (s l r– s′)`. -Recall that a virtual machine used for executing smart contracts in a blockchain must be deterministic, otherwise the validation of each execution would require the inclusion of all intermediate steps of the execution into a block, or at least of the choices made when indeterministic operations have been performed. +* `D732` — `SCUTLAST (s l r– s′)`, returns the last 0 ≤l ≤1023 data bits + and last 0 ≤r≤4 references of s. -Furthermore, the state of such a virtual machine must be (uniquely) serializable, so that even if the state itself is not usually included in a block, its hash is still well-defined and can be included into a block for verification purposes. +* `D733` — `SSKIPLAST (s l r– s′)`. -### B.1.1. TVM stack values. +* `D734` — `SUBSLICE (s l r l′ r′ – s′)`, returns 0 ≤l′ ≤1023 bits and + 0 ≤r′≤4 references from Slice s, after skipping the first 0 ≤l≤1023 + bits and first 0 ≤r≤4 references. -TVM stack values can be serialized as follows: +* `D736` — `SPLIT (slr– s′s′′)`, splits the first 0 ≤l≤1023 data bits and + first 0 ≤r ≤4 references from s into s′, returning the remainder of s + as s′′. -``` -vm_stk_tinyint#01 value:int64 = VmStackValue; -vm_stk_int#0201_ value:int257 = VmStackValue; -vm_stk_nan#02FF = VmStackValue; -vm_stk_cell#03 cell:^Cell = VmStackValue; -_ cell:^Cell st_bits:(## 10) end_bits:(## 10) - { st_bits <= end_bits } - st_ref:(#<= 4) end_ref:(#<= 4) - { st_ref <= end_ref } = VmCellSlice; -vm_stk_slice#04 _:VmCellSlice = VmStackValue; -vm_stk_builder#05 cell:^Cell = VmStackValue; +* `D737` — `SPLITQ (s l r– s′ s′′ −1 or s 0)`, a quiet version of SPLIT. + +* `D739` — `XCTOS (c– s ?),` transforms an ordinary or exotic cell into a + Slice, asifitwereanordinarycell. Aflagisreturnedindicatingwhether + c is exotic. If that be the case, its type can later be deserialized from + the first eight bits of s. + +* `D73A` — `XLOAD (c– c′)`, loads an exotic cell c and returns an ordinary + cell c′. If c is already ordinary, does nothing. If c cannot be loaded, + throws an exception. + +* `D73B` — `XLOADQ (c– c′ −1 or c 0)`, loads an exotic cell c as XLOAD, but + returns 0 on failure. + +* `D741` — `SCHKBITS (sl– )`, checks whether there are at least ldata bits + in Slice s. If this is not the case, throws a cell deserialisation (i.e., cell + underflow) exception. + +* `D742` — `SCHKREFS (sr–)`, checkswhetherthereareatleastrreferences + in Slice s. + +* `D743` — `SCHKBITREFS (s l r – )`, checks whether there are at least l + data bits and r references in Slice s. + +* `D745` — `SCHKBITSQ (s l– ?),` checks whether there are at least l data + bits in Slice s. + +* `D746` — `SCHKREFSQ (sr– ?),` checks whether there are at least r refer- + ences in Slice s. + +* `D747` — `SCHKBITREFSQ (s l r– ?),` checks whether there are at least l + data bits and r references in Slice s. + +* `D748` — `PLDREFVAR (s n– c)`, returns the n-th cell reference of Slice s + for 0 ≤n≤3. + +* `D749` — `SBITS (s– l)`, returns the number of data bits in Slice s. + +* `D74A` — `SREFS (s– r)`, returns the number of references in Slice s. + +* `D74B` — `SBITREFS (s– l r)`, returns both the number of data bits and + the number of references in s. + +* `D74E_n` — `PLDREFIDX n (s– c)`, returns the n-th cell reference of + Slice s, where 0 ≤n≤3. + +* `D74C` — `PLDREF (s– c)`, preloads the first cell reference of a Slice. + +* `D750` — `LDILE4 (s– x s′)`, loads a little-endian signed 32-bit integer. + +* `D751` — `LDULE4 (s– xs′)`, loads a little-endian unsigned 32-bit integer. + +* `D752` — `LDILE8 (s– x s′)`, loads a little-endian signed 64-bit integer. + +* `D753` — `LDULE8 (s– xs′)`, loads a little-endian unsigned 64-bit integer. + +* `D754` — `PLDILE4 (s– x)`, preloads a little-endian signed 32-bit integer. + +* `D755` — `PLDULE4 (s– x)`, preloads a little-endian unsigned 32-bit inte- + ger. + +* `D756` — `PLDILE8 (s– x)`, preloads a little-endian signed 64-bit integer. + +* `D757` — `PLDULE8 (s– x)`, preloads a little-endian unsigned 64-bit inte- + ger. + +* `D758` — `LDILE4Q (s– x s′ −1 or s 0)`, quietly loads a little-endian + signed 32-bit integer. + +* `D759` — `LDULE4Q (s– x s′ −1 or s 0)`, quietly loads a little-endian + unsigned 32-bit integer. + +* `D75A` — `LDILE8Q (s– x s′ −1 or s 0)`, quietly loads a little-endian + signed 64-bit integer. + +* `D75B` — `LDULE8Q (s– x s′ −1 or s 0)`, quietly loads a little-endian + unsigned 64-bit integer. + +* `D75C` — `PLDILE4Q (s– x−1 or 0)`, quietly preloads a little-endian + signed 32-bit integer. + +* `D75D` — `PLDULE4Q (s– x−1 or 0)`, quietly preloads a little-endian + unsigned 32-bit integer. + +* `D75E` — `PLDILE8Q (s– x−1 or 0)`, quietly preloads a little-endian + signed 64-bit integer. + +* `D75F` — `PLDULE8Q (s– x−1 or 0)`, quietly preloads a little-endian + unsigned 64-bit integer. + +* `D760` — `LDZEROES (s– n s′)`, returns the count n of leading zero bits + in s, and removes these bits from s. + +* `D761` — `LDONES (s– ns′)`, returns the count nof leading one bits in s, + and removes these bits from s. + +* `D762` — `LDSAME (s x– n s′)`, returns the count n of leading bits equal + to 0 ≤x≤1 in s, and removes these bits from s. + +* `D764` — `SDEPTH (s– x)`, returns the depth of Slice s. If s has no + references, then x= 0; otherwise xis one plus the maximum of depths + of cells referred to from s. + +* `D765` — `CDEPTH (c– x)`, returns the depth of Cell c. If c has no + references, then x= 0; otherwise xis one plus the maximum of depths + of cells referred to from c. If cis a Null instead of a Cell, returns zero. + +--- + +## A.8 Continuation and control flow primitives + +### A.8.1. Unconditional control flow primitives. + +• `D8` — `EXECUTE` or `CALLX (c – )`, calls or executes continuation `c` (i.e., `c꜀ ← c◦₀c꜀`). + +• `D9` — `JMPX (c – )`, jumps, or transfers control, to continuation `c` (i.e., `c꜀ ← c◦₀c₀`, or rather `c꜀ ← (c◦₀c₀)◦₁c₁`). The remainder of the previous current continuation `c꜀` is discarded. + +• `DApr` — `CALLXARGS p,r (c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. + +• `DB0p` — `CALLXARGS p,−1 (c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. + +• `DB1p` — `JMPXARGS p (c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). + +• `DB2r` — `RETARGS r`, returns to `c₀`, with `0 ≤ r ≤ 15` return values taken from the current stack. + +• `DB30` — `RET` or `RETTRUE`, returns to the continuation at `c₀` (i.e., performs `c꜀ ← c₀`). The remainder of the current continuation `c꜀` is discarded. Approximately equivalent to `PUSH c₀; JMPX`. + +• `DB31` — `RETALT` or `RETFALSE`, returns to the continuation at `c₁` (i.e., `c꜀ ← c₁`). Approximately equivalent to `PUSH c₁; JMPX`. + +• `DB32` — `BRANCH` or `RETBOOL (f – )`, performs `RETTRUE` if integer `f ≠ 0`, or `RETFALSE` if `f = 0`. + +• `DB34` — `CALLCC (c – )`, call with current continuation, transfers control to `c`, pushing the old value of `c꜀` into `c`’s stack (instead of discarding it or writing it into new `c₀`). + +• `DB35` — `JMPXDATA (c – )`, similar to `CALLCC`, but the remainder of the current continuation (the old value of `c꜀`) is converted into a Slice before pushing it into the stack of `c`. + +• `DB36pr` — `CALLCCARGS p,r (c – )`, similar to `CALLXARGS`, but pushes the old value of `c꜀` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `c꜀.nargs` to `−1 ≤ r ≤ 14`. + +• `DB38` — `CALLXVARARGS (c p r – )`, similar to `CALLXARGS`, but takes `−1 ≤ p,r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1...254`. + +• `DB39` — `RETVARARGS (p r – )`, similar to `RETARGS`. + +• `DB3A` — `JMPXVARARGS (c p r – )`, similar to `JMPXARGS`. + +• `DB3B` — `CALLCCVARARGS (c p r – )`, similar to `CALLCCARGS`. + +• `DB3C` — `CALLREF`, equivalent to `PUSHREFCONT; CALLX`. + +• `DB3D` — `JMPREF`, equivalent to `PUSHREFCONT; JMPX`. + +• `DB3E` — `JMPREFDATA`, equivalent to `PUSHREFCONT; JMPXDATA`. + +• `DB3F` — `RETDATA`, equivalent to `PUSH c₀; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. + +### A.8.2. Conditional control flow primitives + +* `DC` — `IFRET` `(f – )`, performs a `RET`, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. +* `DD` — `IFNOTRET` `(f – )`, performs a `RET`, but only if integer `f` is zero. +* `DE` — `IF` `(f c – )`, performs `EXECUTE` for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. +* `DF` — `IFNOT` `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. +* `E0` — `IFJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is non-zero. +* `E1` — `IFNOTJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is zero. +* `E2` — `IFELSE` `(f c c′ – )`, if integer `f` is non-zero, executes `c`, otherwise executes ` c′`. Equivalent to `CONDSELCHK; EXECUTE`. +* `E300` — `IFREF` `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. +* `E301` — `IFNOTREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. +* `E302` — `IFJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. +* `E303` — `IFNOTJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. +* `E304` — `CONDSEL` `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. +* `E305` — `CONDSELCHK` `(f x y – x or y)`, same as `CONDSEL`, but first checks whether `x` and `y` have the same type. +* `E308` — `IFRETALT` `(f – )`, performs `RETALT` if integer `f ≠ 0`. +* `E309` — `IFNOTRETALT` `(f – )`, performs `RETALT` if integer `f = 0`. +* `E30D` — `IFREFELSE` `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. +* `E30E` — `IFELSEREF` `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. +* `E30F` — `IFREFELSEREF` `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. +* `E310–E31F` — reserved for loops with break operators (cf. [A.8.3](#a-8-3-control-flow-primitives%3A-loops)). +* `E39_n` — `IFBITJMP n` `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs `JMPX` to continuation `c`. Value `x` is left in the stack. +* `E3B_n` — `IFNBITJMP n` `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `E3D_n` — `IFBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is set in integer `x`. +* `E3F_n` — `IFNBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is not set in integer `x`. + + +### A.8.3. Control flow primitives: loops + +Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. [4.1.5](#4-1-5-extraordinary-continuations)), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have `*BRK` versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for `*ENDBRK` versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for `*ENDBRK` versions). + +* `E4` — `REPEAT (n c – )`, executes continuation `c` `n` times, if integer `n` + is non-negative. If `n ≥ 2³¹` or `n < −2³¹`, generates a range check + exception. Notice that a `RET` inside the code of `c` works as a continue, + not as a break. One should use either alternative (experimental) loops + or alternative `RETALT` (along with a `SETEXITALT` before the loop) to + break out of a loop. + +* `E5` — `REPEATEND (n – )`, similar to `REPEAT`, but it is applied to the + current continuation `cc`. + +* `E6` — `UNTIL (c – )`, executes continuation `c`, then pops an integer `x` + from the resulting stack. If `x` is zero, performs another iteration of + this loop. The actual implementation of this primitive involves an + extraordinary continuation `ec_until` (cf. 4.1.5) with its arguments + set to the body of the loop (continuation `c`) and the original current + continuation `cc`. This extraordinary continuation is then saved into + the savelist of `c` as `c.c₀` and the modified `c` is then executed. The + other loop primitives are implemented similarly with the aid of suitable + extraordinary continuations. + +* `E7` — `UNTILEND ( – )`, similar to `UNTIL`, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs + a `RET`. + +* `E8` — `WHILE (c′ c – )`, executes `c′` and pops an integer `x` from the + resulting stack. If `x` is zero, exists the loop and transfers control to + the original `cc`. If `x` is non-zero, executes `c`, and then begins a new + iteration. + +* `E9` — `WHILEEND (c′ – )`, similar to `WHILE`, but uses the current continuation `cc` as the loop body. + +* `EA` — `AGAIN (c – )`, similar to `REPEAT`, but executes `c` infinitely many + times. A `RET` only begins a new iteration of the infinite loop, which can + be exited only by an exception, or a `RETALT` (or an explicit `JMPX`). + +* `EB` — `AGAINEND ( – )`, similar to `AGAIN`, but performed with respect to + the current continuation `cc`. + +* `E314` — `REPEATBRK (n c – )`, similar to `REPEAT`, but also sets `c₁` to + the original `cc` after saving the old value of `c₁` into the savelist of the + original `cc`. In this way `RETALT` could be used to break out of the loop + body. + +* `E315` — `REPEATENDBRK (n – )`, similar to `REPEATEND`, but also sets `c₁` + to the original `c₀` after saving the old value of `c₁` into the savelist of + the original `c₀`. Equivalent to `SAMEALTSAVE; REPEATEND`. + +* `E316` — `UNTILBRK (c – )`, similar to `UNTIL`, but also modifies `c₁` in the + same way as `REPEATBRK`. + +* `E317` — `UNTILENDBRK ( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. + +* `E318` — `WHILEBRK (c′ c – )`, similar to `WHILE`, but also modifies `c₁` in + the same way as `REPEATBRK`. + +* `E319` — `WHILEENDBRK (c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. + +* `E31A` — `AGAINBRK (c – )`, similar to `AGAIN`, but also modifies `c₁` in the + same way as `REPEATBRK`. + +* `E31B` — `AGAINENDBRK ( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. + + +### A.8.4. Manipulating the stack of continuations + +* **`ECr n`** — `SETCONTARGS r,n(x₁ … xᵣ c – c′)`, similar to `SETCONTARGS r`, but sets `c.nargs` to the final size of the stack of `c′` plus `n`. In other words, transforms `c` into a closure or a partially applied function, with `0 ≤ n ≤ 14` arguments missing. + +* **`EC0n`** — `SETNUMARGS n` or `SETCONTARGS 0,n (c – c′)`, sets `c.nargs` to `n` plus the current depth of `c`’s stack, where `0 ≤ n ≤ 14`. If `c.nargs` is already set to a non-negative value, does nothing. + +* **`ECrF`** — `SETCONTARGS r` or `SETCONTARGS r,−1 (x₁ … xᵣ c – c′)`, pushes `0 ≤ r ≤ 15` values `x₁ … xᵣ` into the stack of (a copy of) the continuation `c`, starting with `x₁`. If the final depth of `c`’s stack turns out to be greater than `c.nargs`, a stack overflow exception is generated. + +* **`ED0p`** — `RETURNARGS p ( – )`, leaves only the top `0 ≤ p ≤ 15` values in the current stack (similarly to `ONLYTOPX`), with all the unused bottom values not discarded, but saved into continuation `c₀` in the same way as `SETCONTARGS` does. + +* **`ED10`** — `RETURNVARARGS(p – )`, similar to `RETURNARGS`, but with integer `0 ≤ p ≤ 255` taken from the stack. + +* **`ED11`** — `SETCONTVARARGS(x₁ … xᵣ c r n – c′)`, similar to `SETCONTARGS`, but with `0 ≤ r ≤ 255` and `−1 ≤ n ≤ 255` taken from the stack. + +* **`ED12`** — `SETNUMVARARGS (c n – c′)`, where `−1 ≤ n ≤ 255`. If `n = −1`, this operation does nothing (`c′ = c`). Otherwise, its action is similar to `SETNUMARGS n`, but with `n` taken from the stack. + +### A.8.5. Creating simple continuations and closures + +* **`ED1E`** — `BLESS (s – c)`, transforms a slice `s` into a simple ordinary continuation `c`, with `c.code = s` and an empty stack and savelist. + +* **`ED1F`** — `BLESSVARARGS (x₁ … xᵣ s r n – c)`, equivalent to `ROT; BLESS; ROTREV; SETCONTVARARGS`. + +* **`EEr n`** — `BLESSARGS r,n (x₁ … xᵣ s – c)`, where `0 ≤ r ≤ 15`, `−1 ≤ n ≤ 14`, equivalent to `BLESS; SETCONTARGS r,n`. The value of `n` is represented inside the instruction by the 4-bit integer `n mod 16`. + +* **`EE0n`** — `BLESSNUMARGS n` or `BLESSARGS 0,n (s – c)`, transforms a slice `s` into a continuation `c`, but sets `c.nargs` to `0 ≤ n ≤ 14`. + +### A.8.6. Operations with continuation savelists and control registers + +* **`ED4i`** — `PUSH cᵢ` or `PUSHCTR cᵢ ( – x)`, pushes the current value of control register `cᵢ`. If the control register is not supported in the current codepage, or if it does not have a value, an exception is triggered. + +* **`ED44`** — `PUSH c₄` or `PUSHROOT`, pushes the “global data root” cell reference, enabling access to persistent smart-contract data. + +* **`ED5i`** — `POP cᵢ` or `POPCTR cᵢ (x – )`, pops a value `x` from the stack and stores it into control register `cᵢ`, if supported in the current codepage. Type-checking exceptions may occur if the control register accepts only values of a specific type. + +* **`ED54`** — `POP c₄` or `POPROOT`, sets the “global data root” cell reference, allowing modification of persistent smart-contract data. + +* **`ED6i`** — `SETCONT cᵢ` or `SETCONTCTR cᵢ (x c – c′)`, stores `x` into the savelist of continuation `c` as `cᵢ`, and returns the resulting continuation `c′`. + +* **`ED7i`** — `SETRETCTR cᵢ (x – )`, equivalent to `PUSH c₀; SETCONTCTR cᵢ; POP c₀`. + +* **`ED8i`** — `SETALTCTR cᵢ (x – )`, equivalent to `PUSH c₁; SETCONTCTR cᵢ; POP c₀`. + +* **`ED9i`** — `POPSAVE cᵢ` or `POPCTRSAVE cᵢ (x – )`, similar to `POP cᵢ`, but also saves the old value of `cᵢ` into continuation `c₀`. Equivalent (up to exceptions) to `SAVECTR cᵢ; POP cᵢ`. + +* **`EDAi`** — `SAVE cᵢ` or `SAVECTR cᵢ ( – )`, saves the current value of `cᵢ` into the savelist of continuation `c₀`. Equivalent to `PUSH cᵢ; SETRETCTR cᵢ`. + +* **`EDBi`** — `SAVEALT cᵢ` or `SAVEALTCTR cᵢ ( – )`, similar to `SAVE cᵢ`, but saves into the savelist of `c₁`. + +* **`EDCi`** — `SAVEBOTH cᵢ` or `SAVEBOTHCTR cᵢ ( – )`, equivalent to `DUP; SAVE cᵢ; SAVEALT cᵢ`. + +* **`EDE0`** — `PUSHCTRX (i – x)`, similar to `PUSHCTR cᵢ`, but with `i`, `0 ≤ i ≤ 255`, taken from the stack. + +* **`EDE1`** — `POPCTRX (xᵢ – )`, similar to `POPCTR cᵢ`, but with `0 ≤ i ≤ 255` from the stack. + +* **`EDE2`** — `SETCONTCTRX (x cᵢ – c′)`, similar to `SETCONTCTR cᵢ`, but with `0 ≤ i ≤ 255` from the stack. + + +### A.8.7. Dictionary subroutine calls and jumps + +* **`F0n`** — `CALL n` or `CALLDICT n ( – n)`, calls the continuation in `c₃`, pushing integer `0 ≤ n ≤ 255` into its stack as an argument. Equivalent to `PUSHINT n; PUSH c₃; EXECUTE`. + +* **`F12_n`** — `CALL n` for `0 ≤ n < 2¹⁴ ( – n)`, an encoding of `CALL n` for larger values. + +* **`F16_n`** — `JMP n` or `JMPDICT n ( – n)`, jumps to the continuation in `c₃`, pushing integer `0 ≤ n < 2¹⁴` as its argument. Equivalent to `PUSHINT n; PUSH c₃; JMPX`. + +* **`F1A_n`** — `PREPARE n` or `PREPAREDICT n ( – n c)`, equivalent to `PUSHINT n; PUSH c₃`, for `0 ≤ n < 2¹⁴`. In this way, `CALL n ≈ PREPARE n; EXECUTE` and `JMP n ≈ PREPARE n; JMPX`. + + +--- + +## A.9 Exception generating and handling primitives + +### A.9.1. Throwing exceptions + +* `F22_nn` — `THROW nn ( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. + +* `F26_nn` — `THROWIF nn (f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. + +* `F2A_nn` — `THROWIFNOT nn (f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. + +* `F2C4_nn` — `THROW nn` for `0 ≤ nn < 2¹¹`, an encoding of `THROW nn` for larger values. + +* `F2CC_nn` — `THROWARG nn (x – x nn)`, throws exception `0 ≤ nn < 2¹¹` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. + +* `F2D4_nn` — `THROWIF nn (f – )` for `0 ≤ nn < 2¹¹`. + +* `F2DC_nn` — `THROWARGIF nn (x f – )`, throws exception `0 ≤ nn < 2¹¹` with parameter `x` only if integer `f ≠ 0`. + +* `F2E4_nn` — `THROWIFNOT nn (f – )` for `0 ≤ nn < 2¹¹`. + +* `F2EC_nn` — `THROWARGIFNOT nn (x f – )`, throws exception `0 ≤ nn < 2¹¹` with parameter `x` only if integer `f = 0`. + +* `F2F0` — `THROWANY (n – 0 n)`, throws exception `0 ≤ n < 2¹⁶` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. + +* `F2F1` — `THROWARGANY (x n – x n)`, throws exception `0 ≤ n < 2¹⁶` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. + +* `F2F2` — `THROWANYIF (n f – )`, throws exception `0 ≤ n < 2¹⁶` with parameter zero only if `f ≠ 0`. + +* `F2F3` — `THROWARGANYIF (x n f – )`, throws exception `0 ≤ n < 2¹⁶` with parameter `x` only if `f ≠ 0`. + +* `F2F4` — `THROWANYIFNOT (n f – )`, throws exception `0 ≤ n < 2¹⁶` with parameter zero only if `f = 0`. + +* `F2F5` — `THROWARGANYIFNOT (x n f – )`, throws exception `0 ≤ n < 2¹⁶` with parameter `x` only if `f = 0`. + + +### A.9.2. Catching and handling exceptions + +* `F2FF` — `TRY (c c′ – )`, sets `c2` to `c′`, first saving the old value of `c2` both + into the savelist of `c′` and into the savelist of the current continuation, + which is stored into `c.c0` and `c′.c0`. Then runs `c` similarly to `EXECUTE`. + If `c` does not throw any exceptions, the original value of `c2` is automati- + cally restored on return from `c`. If an exception occurs, the execution is + transferred to `c′`, but the original value of `c2` is restored in the process, + so that `c′` can re-throw the exception by `THROWANY` if it cannot handle + it by itself. + +* `F3pr` — `TRYARGS p,r (c c′ – )`, similar to `TRY`, but with `CALLARGS + p,r` internally used instead of `EXECUTE`. In this way, all but the top + `0 ≤ p ≤ 15` stack elements will be saved into current continuation’s + stack, and then restored upon return from either `c` or `c′`, with the top + `0 ≤ r ≤ 15` values of the resulting stack of `c` or `c′` copied as return + values. + +--- + +# A.10 Dictionary manipulation primitives + +TVM’s dictionary support is discussed at length in [3.3](#3-3-hashmaps%2C-or-dictionaries). The basic operations with dictionaries are listed in [3.3.10](#3-3-10-basic-dictionary-operations), while the taxonomy of dictionary manipulation primitives is provided in [3.3.11](#3-3-11-taxonomy-of-dictionary-primitives). Here we use the concepts and notation introduced in those sections. + +Dictionaries admit two different representations as TVM stack values: + +* A Slice `s` with a serialization of a TL-B value of type `HashmapE(n, X)`. +In other words, `s` consists either of one bit equal to zero (if the dic- +tionary is empty), or of one bit equal to one and a reference to a Cell +containing the root of the binary tree, i.e., a serialized value of type +`Hashmap(n, X)`. + +* A “maybe Cell” `cˀ`, i.e., a value that is either a Cell (containing a seri- + alized value of type `Hashmap(n, X)` as before) or a Null (corresponding + to an empty dictionary). When a “maybe Cell” `cˀ` is used to represent + a dictionary, we usually denote it by `D` in the stack notation. + +Most of the dictionary primitives listed below accept and return dictionaries in the second form, which is more convenient for stack manipulation. However, serialized dictionaries inside larger TL-B objects use the first representation. + +Opcodes starting with `F4` and `F5` are reserved for dictionary operations. + + +### A.10.1. Dictionary creation. + +* `6D` — `NEWDICT` `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for `PUSHNULL`, (cf. [A.3.1](#a-3-1-null-primitives)). +* `6E` — `DICTEMPTY` `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for `ISNULL`, (cf. [A.3.1](#a-3-1-null-primitives)). + + +### A.10.2. Dictionary serialization and deserialization + +* `CE` — `STDICTS (s b– b′)`, stores a Slice-represented dictionary `s` into + Builder `b`. It is actually a synonym for `STSLICE`. + +* `F400` — `STDICT or STOPTREF (D b– b′)`, stores dictionary `D` into Builder + `b`, returing the resulting Builder `b′`. In other words, if `D` is a cell, + performs `STONE` and `STREF`; if `D` is `Null`, performs `NIP` and `STZERO`; + otherwise throws a type checking exception. + +* `F401` — `SKIPDICT or SKIPOPTREF (s– s′)`, equivalent to `LDDICT; NIP`. + +* `F402` — `LDDICTS (s– s′ s′′)`, loads (parses) a Slice-represented dictionary + `s′` from Slice `s`, and returns the remainder of `s` as `s′′`. This is a + “split function” for all `HashmapE(n, X)` dictionary types. + +* `F403` — `PLDDICTS (s– s′)`, preloads a Slice-represented dictionary `s′` + from Slice `s`. Approximately equivalent to `LDDICTS; DROP`. + +* `F404` — `LDDICT or LDOPTREF (s– D s′)`, loads (parses) a dictionary `D` + from Slice `s`, and returns the remainder of `s` as `s′`. May be applied to + dictionaries or to values of arbitrary `(Ŷˀ)` types. + +* `F405` — `PLDDICT or PLDOPTREF (s– D)`, preloads a dictionary `D` from + Slice `s`. Approximately equivalent to `LDDICT; DROP`. + +* `F406` — `LDDICTQ (s– D s′ −1 or s 0)`, a quiet version of `LDDICT`. + +* `F407` — `PLDDICTQ (s– D −1 or 0)`, a quiet version of `PLDDICT`. + + +### A.10.3. Get dictionary operations + +* `F40A` — `DICTGET (k D n– x −1 or 0)`, looks up key `k` (represented by + a Slice, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) + in dictionary `D` of type `HashmapE(n, X)` with `n`-bit keys. On success, + returns the value found as a Slice `x`. + +* `F40B` — `DICTGETREF (k D n– c −1 or 0)`, similar to `DICTGET`, but with + a `LDREF; ENDS` applied to `x` on success. This operation is useful for + dictionaries of type `HashmapE(n, Ŷ)`. + +* `F40C` — `DICTIGET (i D n– x −1 or 0)`, similar to `DICTGET`, but with + a signed (big-endian) `n`-bit Integer `i` as a key. If `i` does not fit into `n` + bits, returns 0. If `i` is a `NaN`, throws an integer overflow exception. + +* `F40D` — `DICTIGETREF (i D n– c −1 or 0)`, combines `DICTIGET` with + `DICTGETREF`: it uses signed `n`-bit Integer `i` as a key and returns a Cell + instead of a Slice on success. + +* `F40E` — `DICTUGET (i D n– x −1 or 0)`, similar to `DICTIGET`, but with + unsigned (big-endian) `n`-bit Integer `i` used as a key. + +* `F40F` — `DICTUGETREF (i D n– c −1 or 0)`, similar to `DICTIGETREF`, but + with an unsigned `n`-bit Integer key `i`. + + +### A.10.4. Set/Replace/Add dictionary operations. + +The mnemonics of the following dictionary primitives are constructed in a systematic fashion according to the regular expression `DICT[, I, U](SET, REPLACE, ADD)[GET][REF]` depending on the type of the key used (a `Slice` or a signed or unsigned `Integer`), the dictionary operation to be performed, and the way the values are accepted and returned (as `Cells` or as `Slices`). Therefore, we provide a detailed description only for some primitives, assuming that this information is sufficient for the reader to understand the precise action of the remaining primitives. + +* `F412`— `DICTSET (x k D n– D′)`, sets the value associated with n-bit + key k (represented by a Slice as in `DICTGET`) in dictionary D (also rep- + resented by a Slice) to value x(again a Slice), and returns the resulting + dictionary as D′. + +* `F413`— `DICTSETREF (c k D n– D′)`, similar to `DICTSET`, but with the + value set to a reference to Cell c. + +* `F414`— `DICTISET (x i D n– D′)`, similar to `DICTSET`, but with the + key represented by a (big-endian) signed n-bit integer i. If i does not + fit into n bits, a range check exception is generated. + +* `F415`— `DICTISETREF (ciD n– D′)`, similar to `DICTSETREF`, but with + the key a signed n-bit integer as in `DICTISET`. + +* `F416`— `DICTUSET (x i D n– D′)`, similar to `DICTISET`, but with i an + unsigned n-bit integer. + +* `F417`— `DICTUSETREF (ciDn– D′)`, similar to `DICTISETREF`, but with + i unsigned. + +* `F41A`— `DICTSETGET (x k D n– D′ y−1 or D′ 0)`, combines `DICTSET` + with DICTGET: it sets the value corresponding to key k to x, but also + returns the old value y associated with the key in question, if present. + +* `F41B`— `DICTSETGETREF (c k D n– D′ c′ −1 or D′ 0)`, combines + DICTSETREF with DICTGETREF similarly to DICTSETGET. + +* `F41C`—`DICTISETGET(xiDn–D′y−1 orD′0)`,similar to `DICTSETGET,` + but with the key represented by a big-endian signed n-bit Integer i. + +* `F41D`— `DICTISETGETREF (c i D n– D′ c′ −1 or D′ 0)`, a version of + DICTSETGETREF with signed Integer i as a key. + +* `F41E`—`DICTUSETGET(xiDn–D′y−1 orD′0)`,similar to`DICTISETGET`, + but with i an unsigned n-bit integer. + +* `F41F`— `DICTUSETGETREF (c i D n– D′ c′ −1 or D′ 0)`. + +* `F422`— `DICTREPLACE(xkDn– D′ −1 or D0)`, a Replace operation, + which is similar to `DICTSET`, but sets the value of key k in dictionary + D to x only if the key k was already present in D. + +* `F423`— `DICTREPLACEREF (c k D n– D′ −1 or D 0)`, a Replace + counterpart of DICTSETREF. + +* `F424`—`DICTIREPLACE(xiDn–D′ −1 orD0)`,a version of `DICTREPLACE` + with signed n-bit Integer `i` used as a key. + +* `F425`— `DICTIREPLACEREF (c i D n– D′ −1 or D 0)`. + +* `F426`— `DICTUREPLACE (x i D n– D′ −1 or D 0)`. + +* `F427`— `DICTUREPLACEREF (c i D n– D′ −1 or D 0)`. + +* `F42A`— `DICTREPLACEGET (x k D n– D′ y−1 or D 0)`, a Replace + counterpart of `DICTSETGET`: on success, also returns the old value asso- + ciated with the key in question. + +* `F42B`— `DICTREPLACEGETREF (c k D n– D′ c′ −1 or D 0)`. + +* `F42C`— `DICTIREPLACEGET (x i D n– D′ y−1 or D 0)`. + +* `F42D`— `DICTIREPLACEGETREF (c i D n– D′ c′ −1 or D 0)`. + +* `F42E`— `DICTUREPLACEGET (x i D n– D′ y−1 or D 0)`. + +* `F42F`— `DICTUREPLACEGETREF (c i D n– D′ c′ −1 or D 0)`. + +### A.10.5. Builder-accepting variants of Set dictionary operations. + +The following primitives accept the new value as a Builder b instead of a +Slice x, which often is more convenient if the value needs to be serialized from +several components computed in the stack. (This is reflected by appending +a B to the mnemonics of the corresponding Set primitives that work with +Slices.) The net effect is roughly equivalent to converting b into a Slice by +`ENDC`; `CTOS` and executing the corresponding primitive listed in [A.10.4](#a-10-4-set%2Freplace%2Fadd-dictionary-operations). + +* `F441`— `DICTSETB (b k D n– D′)`. +* `F442`— `DICTISETB (b i D n– D′)`. +* `F443`— `DICTUSETB (b i D n– D′)`. +* `F445`— `DICTSETGETB (b k D n– D′ y−1 or D′ 0)`. +* `F446`— `DICTISETGETB (b i D n– D′ y−1 or D′ 0)`. +* `F447`— `DICTUSETGETB (b i D n– D′ y−1 or D′ 0)`. +* `F449`— `DICTREPLACEB (b k D n– D′ −1 or D 0)`. +* `F44A`— `DICTIREPLACEB (b i D n– D′ −1 or D 0)`. +* `F44B`— `DICTUREPLACEB (b i D n– D′ −1 or D 0)`. +* `F44D`— `DICTREPLACEGETB (b k D n– D′ y−1 or D 0)`. +* `F44E`— `DICTIREPLACEGETB (b i D n– D′ y−1 or D 0)`. +* `F44F`— `DICTUREPLACEGETB (b i D n– D′ y−1 or D 0)`. +* `F451`— `DICTADDB (b k D n– D′ −1 or D 0)`. +* `F452`— `DICTIADDB (b i D n– D′ −1 or D 0)`. +* `F453`— `DICTUADDB (b i D n– D′ −1 or D 0)`. +* `F455`— `DICTADDGETB (b k D n– D′ −1 or D y 0)`. +* `F456`— `DICTIADDGETB (b i D n– D′ −1 or D y 0)`. +* `F457`— `DICTUADDGETB (b i D n– D′ −1 or D y 0)`. + +### A.10.6. Delete dictionary operations. + +* `F459`— `DICTDEL(kDn– D′ −1 or D0)`, deletes n-bit key, represented + by a Slice k, from dictionary `D`. If the key is present, returns the + modified dictionary `D′`and the success flag−1. Otherwise, returns the + original dictionary `D` and `0`. + +* `F45A`— `DICTIDEL (i D n– D′ ? )`, a version of `DICTDEL` with the key + represented by a signed n-bit Integer i. If i does not fit into n bits, + simply returns D 0 (“key not found, dictionary unmodified”). + +* `F45B`— `DICTUDEL (i D n– D′ ? )`, similar to `DICTIDEL`, but with i an + unsigned n-bit integer. + +* `F462`— `DICTDELGET (k D n– D′ x−1 or D 0)`, deletes n-bit key, + represented by a Slice k, from dictionary D. If the key is present, + returns the modified dictionary D′, the original value xassociated with + the key k (represented by a Slice), and the success flag−1. Otherwise, + returns the original dictionary D and 0. + +* `F463`—`DICTDELGETREF(kDn–D′c−1 orD0)`,similar `to `DICTDELGET`, + but with LDREF; ENDS applied to x on success, so that the value re- + turned c is a Cell. + +* `F464`— `DICTIDELGET (iD n– D′x−1 or D 0)`, a variant of primitive + DICTDELGET with signed n-bit integer i as a key. + +* `F465`— `DICTIDELGETREF (i D n– D′ c−1 or D 0)`, a variant of + primitive DICTIDELGET returning a Cell instead of a Slice. + +* `F466`— `DICTUDELGET (iD n– D′x−1 or D 0)`, a variant of primitive + DICTDELGET with unsigned n-bit integer i as a key. + +* `F467`— `DICTUDELGETREF (i D n– D′ c−1 or D 0)`, a variant of + primitive DICTUDELGET returning a Cell instead of a Slice. + +### A.10.7. “Maybe reference” dictionary operations. + +The following operations assume that a dictionary is used to store values `cˀ` of type Cellˀ +(“Maybe Cell”), which can be used in particular to store dictionaries as val- +ues in other dictionaries. The representation is as follows: if `cˀ` is a Cell, it +is stored as a value with no data bits and exactly one reference to this Cell. +If cˀ is Null, then the corresponding key must be absent from the dictionary +altogether. + +* `F469`— `DICTGETOPTREF (k D n– cˀ)`, a variant of `DICTGETREF` that + returns Null instead of the value cˀ if the key k is absent from dictio- + nary D. + +* `F46A`— `DICTIGETOPTREF (i D n– cˀ)`, similar to `DICTGETOPTREF`, but + with the key given by signed n-bit Integer i. If the key iis out of range, + also returns Null. + +* `F46B`— `DICTUGETOPTREF (i D n– cˀ)`, similar to `DICTGETOPTREF`, but + with the key given by unsigned n-bit Integer i. + +* `F46D`— `DICTSETGETOPTREF (cˀ k D n– D′ ˜cˀ)`, a variant of both + `DICTGETOPTREF` and `DICTSETGETREF` that sets the value corresponding + to key k in dictionary D to cˀ (if cˀ is Null, then the key is deleted + instead), and returns the old value ˜cˀ (if the key k was absent before, + returns Null instead). + +* `F46E`— `DICTISETGETOPTREF (cˀ i D n– D′ ˜cˀ)`, similar to primitive + `DICTSETGETOPTREF`, but using signed n-bit Integer ias a key. If idoes + not fit into n bits, throws a range checking exception. + +* `F46F`— `DICTUSETGETOPTREF (cˀ i D n– D′ ˜cˀ)`, similar to primitive + DICTSETGETOPTREF, but using unsigned n-bit Integer i as a key. + +### A.10.8. Prefix code dictionary operations. + +SomeGet operationsforprefixcodedictionariesmaybefoundinA.10.11. +Other prefix code dictionary operations include: + +* `F470`— `PFXDICTSET (x k D n– D′ −1 or D 0)`. +* `F471`— `PFXDICTREPLACE (x k D n– D′ −1 or D 0)`. +* `F472`— `PFXDICTADD (x k D n– D′ −1 or D 0)`. +* `F473`— `PFXDICTDEL (k D n– D′ −1 or D 0)`. + +These primitives are completely similar to their non-prefix code counterparts +`DICTSET` etc (cf.A.10.4),with the obvious difference that even a Set may fail +in a prefix code dictionary, so a success flag must be returned by `PFXDICTSET` +as well. + +### A.10.9. Variants of GetNext and GetPrev operations. + +* `F474`— `DICTGETNEXT (k D n– x′ k′ −1 or 0)`, computes the minimal + key `k′` in dictionary D that is lexicographically greater than `k`, and + returns `k′` (represented by a Slice) along with associated value `x′` (also + represented by a Slice). + +* `F475`—`DICTGETNEXTEQ(kDn–x′k′ −1 or0)`,similar to `DICTGETNEXT`, + but computes the minimal key k′that is lexicographically greater than + or equal to k. + +* `F476`— `DICTGETPREV (kDn– x′k′ −1 or 0)`, similar to `DICTGETNEXT`, + but computes the maximal key k′ lexicographically smaller than k. + +* `F477`—`DICTGETPREVEQ(kDn–x′k′ −1 or0)`,similar to `DICTGETPREV`, + but computes the maximal key k′ lexicographically smaller than or + equal to k. + +* `F478`— `DICTIGETNEXT (iDn– x′i′ −1 or 0)`, similar to `DICTGETNEXT`, + but interprets all keys in dictionary D as big-endian signed n-bit in- + tegers, and computes the minimal key i′ that is larger than Integer i + (which does not necessarily fit into n bits). + +* `F479`— `DICTIGETNEXTEQ (i D n– x′ i′ −1 or 0)`. + +* `F47A`— `DICTIGETPREV (i D n– x′ i′ −1 or 0)`. + +* `F47B`— `DICTIGETPREVEQ (i D n– x′ i′ −1 or 0)`. + +* `F47C`— `DICTUGETNEXT (iDn– x′i′ −1 or 0)`, similar to `DICTGETNEXT`, + but interprets all keys in dictionary D as big-endian unsigned n-bit + integers, and computes the minimal key i′ that is larger than Integer i + (which does not necessarily fit into n bits, and is not necessarily non- + negative). + +* `F47D`— `DICTUGETNEXTEQ (i D n– x′ i′ −1 or 0)`. + +* `F47E`— `DICTUGETPREV (i D n– x′ i′ −1 or 0)`. + +* `F47F`— `DICTUGETPREVEQ (i D n– x′ i′ −1 or 0)`. + +### A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. + +* `F482`— `DICTMIN (D n– x k−1 or 0)`, computes the minimal key k + (represented by a Slice with n data bits) in dictionary D, and returns + k along with the associated value x. + +* `F483`— `DICTMINREF (D n– c k−1 or 0)`, similar to DICTMIN, but + returns the only reference in the value as a Cell c. + +* `F484`— `DICTIMIN (D n– x i−1 or 0)`, somewhat similar to DICTMIN, + but computes the minimal key i under the assumption that all keys + are big-endian signed n-bit integers. Notice that the key and value + returned may differ from those computed by `DICTMIN` and `DICTUMIN`. + +* `F485`— `DICTIMINREF (D n– c i−1 or 0)`. + +* `F486`— `DICTUMIN (Dn– xi−1 or 0)`, similar to `DICTMIN`, but returns + the key as an unsigned n-bit Integer i. + +* `F487`— `DICTUMINREF (D n– c i−1 or 0)`. + +* `F48A`— `DICTMAX (D n– x k−1 or 0)`, computes the maximal key k + (represented by a Slice with n data bits) in dictionary D, and returns + k along with the associated value x. + +* `F48B`— `DICTMAXREF (D n– c k−1 or 0)`. + +* `F48C`— `DICTIMAX (D n– x i−1 or 0)`. + +* `F48D`— `DICTIMAXREF (D n– c i−1 or 0)`. + +* `F48E`— `DICTUMAX (D n– x i−1 or 0)`. + +* `F48F`— `DICTUMAXREF (D n– c i−1 or 0)`. + +* `F492`— `DICTREMMIN (D n– D′xk−1 or D 0)`, computes the minimal + key k(represented by a Slice with ndata bits) in dictionary D, removes + k from the dictionary, and returns k along with the associated value x + and the modified dictionary D′. + +* `F493`—`DICTREMMINREF(Dn–D′ck−1 orD0)`,similar to`DICTREMMIN`, + but returns the only reference in the value as a Cell c. + +* `F494`— `DICTIREMMIN (D n– D′ x i−1 or D 0)`, somewhat similar + to DICTREMMIN, but computes the minimal key iunder the assumption + that all keys are big-endian signed n-bit integers. Notice that the key + and value returned may differ from those computed by `DICTREMMIN` and + `DICTUREMMIN`. + +* `F495`— `DICTIREMMINREF (D n– D′ c i−1 or D 0)`. + +* `F496`— `DICTUREMMIN(Dn– D′xi−1 or D0)`, similar to `DICTREMMIN`, + but returns the key as an unsigned n-bit Integer i. + +* `F497`— `DICTUREMMINREF (D n– D′ c i−1 or D 0)`. + +### A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. + +* `F4A0` — `DICTIGETJMP (i D n – )`, similar to `DICTIGET` (cf. [A.10.12](#a-10-12-subdict-dictionary-operations)), + but with `x` `BLESS`ed into a continuation with a subsequent `JMPX` to it + on success. On failure, does nothing. This is useful for implementing + switch/case constructions. + +* `F4A1` — `DICTUGETJMP (i D n – )`, similar to `DICTIGETJMP`, but performs + `DICTUGET` instead of `DICTIGET`. + +* `F4A2` — `DICTIGETEXEC (i D n – )`, similar to `DICTIGETJMP`, but with + `EXECUTE` instead of `JMPX`. + +* `F4A3` — `DICTUGETEXEC (i D n – )`, similar to `DICTUGETJMP`, but with + `EXECUTE` instead of `JMPX`. + +* `F4A6_n` — `DICTPUSHCONST n ( – D n)`, pushes a non-empty constant + dictionary `D` (as a `Cellˀ`) along with its key length `0 ≤ n ≤ 1023`, + stored as a part of the instruction. The dictionary itself is created from + the first of remaining references of the current continuation. In this + way, the complete `DICTPUSHCONST` instruction can be obtained by first + serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and + a cell reference), and then the unsigned 10-bit integer `n` (as if by a `STU 10` + instruction). An empty dictionary can be pushed by a `NEWDICT` + primitive (cf. [A.10.1](#a-10-1-dictionary-creation)) instead. + +* `F4A8` — `PFXDICTGETQ (s D n – s′ x s′′ −1 or s 0)`, looks up the unique + prefix of `Slice s` present in the prefix code dictionary (cf. `3.4.2`) rep- + resented by `Cellˀ D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is + returned as `s′`, and the corresponding value (also a `Slice`) as `x`. The + remainder of `s` is returned as a `Slice s′′`. If no prefix of `s` is a key in + prefix code dictionary `D`, returns the unchanged `s` and a zero flag to + indicate failure. + +* `F4A9` — `PFXDICTGET (s D n – s′ x s′′)`, similar to `PFXDICTGET`, but + throws a cell deserialization failure exception on failure. + +* `F4AA` — `PFXDICTGETJMP (s D n – s′ s′′ or s)`, similar to `PFXDICTGETQ`, + but on success `BLESS`es the value `x` into a `Continuation` and transfers + control to it as if by a `JMPX`. On failure, returns `s` unchanged and + continues execution. + +* `F4AB` — `PFXDICTGETEXEC (s D n – s′ s′′)`, similar to `PFXDICTGETJMP`, + but `EXECUTE`s the continuation found instead of jumping to it. On + failure, throws a cell deserialization exception. + +* `F4AE_n` — `PFXDICTCONSTGETJMP n` or `PFXDICTSWITCH n (s – s′ s′′ or s)`, + combines `DICTPUSHCONST n` for `0 ≤ n ≤ 1023` with `PFXDICTGETJMP`. + +* `F4BC` — `DICTIGETJMPZ (i D n – i or nothing)`, a variant of `DICTIGETJMP` + that returns index `i` on failure. + +* `F4BD` — `DICTUGETJMPZ (i D n – i or nothing)`, a variant of `DICTUGETJMP` + that returns index `i` on failure. + +* `F4BE` — `DICTIGETEXECZ (i D n – i or nothing)`, a variant of `DICTIGETEXEC` + that returns index `i` on failure. + +* `F4BF` — `DICTUGETEXECZ (i D n – i or nothing)`, a variant of `DICTUGETEXEC` + that returns index `i` on failure. + + +### A.10.12. SubDict dictionary operations + +* `F4B1` — `SUBDICTGET (k l D n – D′)`, constructs a subdictionary con- + sisting of all keys beginning with prefix `k` (represented by a `Slice`, the + first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` + in dictionary `D` of type `HashmapE(n, X)` with `n`-bit keys. On success, + returns the new subdictionary of the same type `HashmapE(n, X)` as a + `Slice D′`. + +* `F4B2` — `SUBDICTIGET (x l D n – D′)`, variant of `SUBDICTGET` with + the prefix represented by a signed big-endian `l`-bit `Integer x`, where + necessarily `l ≤ 257`. + +* `F4B3` — `SUBDICTUGET (x l D n – D′)`, variant of `SUBDICTGET` with the + prefix represented by an unsigned big-endian `l`-bit `Integer x`, where + necessarily `l ≤ 256`. + +* `F4B5` — `SUBDICTRPGET (k l D n – D′)`, similar to `SUBDICTGET`, but + removes the common prefix `k` from all keys of the new dictionary `D′`, + which becomes of type `HashmapE(n − l, X)`. + +* `F4B6` — `SUBDICTIRPGET (x l D n – D′)`, variant of `SUBDICTRPGET` with + the prefix represented by a signed big-endian `l`-bit `Integer x`, where + necessarily `l ≤ 257`. + +* `F4B7` — `SUBDICTURPGET (x l D n – D′)`, variant of `SUBDICTRPGET` with + the prefix represented by an unsigned big-endian `l`-bit `Integer x`, where + necessarily `l ≤ 256`. + +* `F4BC–F4BF` — used by `DICT...Z` primitives in [A.10.11](#a-10-11-special-get-dictionary-and-prefix-code-dictionary-operations%2C-and-constant-dictionaries). + + +## A.11 Application-specific primitives + +OpcoderangeF8...FB is reserved for the application-specific primitives. When +TVM is used to execute TON Blockchain smart contracts, these application- +specific primitives are in fact TON Blockchain-specific. + +### A.11.1. External actions and access to blockchain configuration data. + +Most of the primitives listed below use 16-bit opcodes. + +* * `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value + `gm`, and resets the gas credit `gc` to zero (cf. `1.4`), decreasing the value + of `gr` by `gc` in the process. In other words, the current smart contract + agrees to buy some gas to finish the current transaction. This action + is required to process external messages, which bring no value (hence + no gas) with themselves. + +* `F801` — `SETGASLIMIT (g – )`, sets current gas limit `gl` to the minimum + of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed + so far (including the present instruction) exceeds the resulting value of + `gl`, an (unhandled) out of gas exception is thrown before setting new + gas limits. Notice that `SETGASLIMIT` with an argument `g ≥263 −1` is + equivalent to `ACCEPT`. + +* `F802` — `BUYGAS (x – )`, computes the amount of gas that can be + bought for `x` nanograms, and sets `gl` accordingly in the same way as + `SETGASLIMIT`. + +* `F804` — `GRAMTOGAS (x– g)`, computes the amount of gas that can be + bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `263 −1`, + it is replaced with this value. + +* `F805` — `GASTOGRAM (g– x)`, computes the price of `g` gas in nanograms. + +* `F806–F80E` — Reserved for gas-related primitives. + +* `F80F` — `COMMIT ( – )`, commits the current state of registers `c4` (“persis- + tentdata”) and `c5` (“actions”) so that the current execution is considered + “successful” with the saved values even if an exception is thrown later. + + +### A.11.3. Pseudo-random number generator primitives. + +* `F810` — `RANDU256 ( – x)`, generates a new pseudo-random unsigned + 256-bit `Integer x`. The algorithm is as follows: if `r` is the old value + of the random seed, considered as a 32-byte array (by constructing + the big-endian representation of an unsigned 256-bit integer), then its + `sha512(r)` is computed; the first 32 bytes of this hash are stored as + the new value `r′` of the random seed, and the remaining 32 bytes are + returned as the next random value `x`. + +* `F811` — `RAND (y – z)`, generates a new pseudo-random integer `z` in the + range `0 ... y − 1` (or `y ... −1`, if `y < 0`). More precisely, an unsigned + random value `x` is generated as in `RANDU256`; then + `z := ⌊x·y / 2^256⌋` is computed. + Equivalent to `RANDU256; MULRSHIFT 256`. + +* `F814` — `SETRAND (x – )`, sets the random seed to unsigned 256-bit + `Integer x`. + +* `F815` — `ADDRAND (x – )`, mixes unsigned 256-bit `Integer x` into the ran- + dom seed `r` by setting the random seed to `sha256` of the concatenation + of two 32-byte strings: the first with the big-endian representation of + the old seed `r`, and the second with the big-endian representation of `x`. + +* `F810–F81F` — Reserved for pseudo-random number generator primi- + tives. + + +### A.11.4. Configuration primitives. + +* `F82i` — `GETPARAM i ( – x)`, returns the `i`-th parameter from the `Tuple` + provided at `c7` for `0 ≤ i < 16`. Equivalent to `PUSH c7; FIRST; INDEX i`. + If one of these internal operations fails, throws an appropriate type + checking or range checking exception. + +* `F823` — `NOW ( – x)`, returns the current Unix time as an `Integer`. + If it is impossible to recover the requested value starting from `c7`, + throws a type checking or range checking exception as appropriate. + Equivalent to `GETPARAM 3`. + +* `F824` — `BLOCKLT ( – x)`, returns the starting logical time of the current + block. Equivalent to `GETPARAM 4`. + +* `F825` — `LTIME ( – x)`, returns the logical time of the current transaction. + Equivalent to `GETPARAM 5`. + +* `F826` — `RANDSEED ( – x)`, returns the current random seed as an unsigned + 256-bit `Integer`. Equivalent to `GETPARAM 6`. + +* `F827` — `BALANCE ( – t)`, returns the remaining balance of the smart + contract as a `Tuple` consisting of an `Integer` (the remaining Gram bal- + ance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys + representing the balance of “extra currencies”). Equivalent to `GETPARAM 7`. + Note that RAW primitives such as `SENDRAWMSG` do not update this field. + +* `F828` — `MYADDR ( – s)`, returns the internal address of the current smart + contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed + further using primitives such as `PARSESTDADDR` or `REWRITESTDADDR`. + Equivalent to `GETPARAM 8`. + +* `F829` — `CONFIGROOT ( – D)`, returns the `Maybe Cell D` with the current + global configuration dictionary. Equivalent to `GETPARAM 9`. + +* `F830` — `CONFIGDICT ( – D 32)`, returns the global configuration dic- + tionary along with its key length `(32)`. Equivalent to `CONFIGROOT; PUSHINT 32`. + +* `F832` — `CONFIGPARAM (i – c −1 or 0)`, returns the value of the global + configuration parameter with integer index `i` as a `Cell c`, and a flag to + indicate success. Equivalent to `CONFIGDICT; DICTIGETREF`. + +* `F833` — `CONFIGOPTPARAM (i – cˀ)`, returns the value of the global config- + uration parameter with integer index `i` as a `Maybe Cell cˀ`. Equivalent + to `CONFIGDICT; DICTIGETOPTREF`. + +* `F820–F83F` — Reserved for configuration primitives. + +### A.11.5. Global variable primitives. + +* `F840`— `GETGLOBVAR (k– x)`, returns the k-th global variable for `0 ≤ + k < 255`. Equivalent to PUSH c7; SWAP; INDEXVARQ (cf. A.3.2). + +* `F85_k`— `GETGLOB k ( – x)`, returns the k-th global variable for 1 ≤ + k≤31. Equivalent to PUSH c7; INDEXQ k. + +* `F860`— `SETGLOBVAR (x k – )`, assigns x to the k-th global variable for + `0 ≤ k< 255`. Equivalent to `PUSH c7`; `ROTREV`; `SETINDEXVARQ`; `POP c7`. + +* `F87_k`— `SETGLOB k (x – )`, assigns x to the k-th global variable for + `1 ≤k≤31`. Equivalent to `PUSH c7`; `SWAP`; `SETINDEXQ k`; `POP c7`. + +### A.11.6. Hashing and cryptography primitives. + +* `F900`— `HASHCU (c– x)`, computes the representation hash (cf. 3.1.5) + of a Cell c and returns it as a 256-bit unsigned integer x. Useful for + signing and checking signatures of arbitrary entities represented by a + tree of cells. + +* `F901`— `HASHSU (s– x)`, computes the hash of a Slice s and returns it + as a 256-bit unsigned integer x. The result is the same as if an ordinary + cell containing only data and references from s had been created and + its hash computed by HASHCU. + +* `F902`— `SHA256U (s– x)`, computes sha256 of the data bits of Slice s. + If the bit length of s is not divisible by eight, throws a cell underflow + exception. The hash value is returned as a 256-bit unsigned integer x. + +* `F910`— `CHKSIGNU (h s k– ? )`, checks the Ed25519-signature s of a + hash h (a 256-bit unsigned integer, usually computed as the hash of + some data) using public key k (also represented by a 256-bit unsigned + integer). The signature s must be a Slice containing at least 512 data + bits; only the first 512 bits are used. The result is−1 if the signature + is valid, 0 otherwise. Notice that CHKSIGNU is equivalent to ROT; NEWB; + STU 256; ENDB; NEWC; ROTREV; CHKSIGNS, i.e., to CHKSIGNS with the + first argument d set to 256-bit Slice containing h. Therefore, if h is + computed as the hash of some data, these data are hashed twice, the + second hashing occurring inside CHKSIGNS. + +* `F911`— `CHKSIGNS (d s k– ? )`, checks whether s is a valid Ed25519- + signature of the data portion of Slice dusing public key k, similarly to + CHKSIGNU. If the bit length of Slice d is not divisible by eight, throws + a cell underflow exception. The verification of Ed25519 signatures is + the standard one, with sha256 used to reduce dto the 256-bit number + that is actually signed. + +* `F912–F93F` — Reserved for hashing and cryptography primitives. + +### A.11.7. Miscellaneous primitives. + +* `F940` — `CDATASIZEQ (c n – x y z −1 or 0)`, recursively computes the + count of distinct cells `x`, data bits `y`, and cell references `z` in the DAG + rooted at `Cell c`, effectively returning the total storage used by this + DAG taking into account the identification of equal cells. The values of + `x`, `y`, and `z` are computed by a depth-first traversal of this DAG, with a + hash table of visited cell hashes used to prevent visits of already-visited + cells. The total count of visited cells `x` cannot exceed non-negative + `Integer n`; otherwise the computation is aborted before visiting the + `(n+1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, + returns `x = y = z = 0`. + +* `F941` — `CDATASIZE (c n – x y z)`, a non-quiet version of `CDATASIZEQ` + that throws a cell overflow exception (8) on failure. + +* `F942` — `SDATASIZEQ (s n – x y z −1 or 0)`, similar to `CDATASIZEQ`, but + accepting a `Slice s` instead of a `Cell`. The returned value of `x` does not + take into account the cell that contains the slice `s` itself; however, the + data bits and the cell references of `s` are accounted for in `y` and `z`. + +* `F943` — `SDATASIZE (s n – x y z)`, a non-quiet version of `SDATASIZEQ` + that throws a cell overflow exception (8) on failure. + +* `F944–F97F` — Reserved for miscellaneous TON-specific primitives that + do not fall into any other specific category. + + + +### A.11.8. Currency manipulation primitives. + +* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDUX`. + +* `FA01` — `LDVARINT16` `(s – x s0)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDIX`. + +* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2¹²⁰−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2⁸ˡ`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. + +* `FA03` — `STVARINT16` `(b x – b 0)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2¹¹⁹ ... 2¹¹⁹ − 1`. + +* `FA04` — `LDVARUINT32` `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2²⁴⁸`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 5`; `SWAP`; `SHIFT 3`; `LDUX`. + +* `FA05` — `LDVARINT32` `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷`. + +* `FA06` — `STVARUINT32` `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2²⁴⁸` as a `VarUInteger 32`. + +* `FA07` — `STVARINT32` `(b x – b 0)`, serializes an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷` as a `VarInteger 32`. + +* `FA08–FA1F` — Reserved for currency manipulation primitives. + + +### A.11.9. Message and address manipulation primitives. + +The message and address manipulation primitives listed below serialize and deserialize values according to the following TL-B scheme (cf. [3.3.4](#3-3-4-serialization-of-standard-types)): + +```asm +addr_none$00 = MsgAddressExt; +addr_extern$01 len:(## 8) external_address:(bits len) = MsgAddressExt; +anycast_info$_ depth:(<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; +addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt; +addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) workchain_id:int32 address:(bits addr_len) = MsgAddressInt; +_ _:MsgAddressInt = MsgAddress; +_ _:MsgAddressExt = MsgAddress; + +int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + src:MsgAddress dest:MsgAddressInt + value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams + created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; + +ext_out_msg_info$11 src:MsgAddress dest:MsgAddressExt + created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; +``` + +A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: + +* `addr_none` is represented by `t = (0)`, i.e., a `Tuple` containing exactly one `Integer` equal to zero. +* `addr_extern` is represented by `t = (1, s)`, where `Slice` `s` contains the field `external_address`. In other words, `t` is a pair (a `Tuple` consisting of two entries), containing an `Integer` equal to one and `Slice` `s`. +* `addr_std` is represented by `t = (2, u, x, s)`, where `u` is either a `Null` (if `anycast` is absent) or a `Slice` `s′` containing `rewrite_pfx` (if `anycast` is present). Next, `Integer` `x` is the `workchain_id`, and `Slice` `s` contains the address. + `135` + A.11. Application-specific primitives +* `addr_var` is represented by `t = (3, u, x, s)`, where `u`, `x`, and `s` have the same meaning as for `addr_std`. + + +### A.11.9. Message and address manipulation primitives. + +* `FA40` — `LDMSGADDR` `(s – s′ s′′)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s′` and the remainder `s′′` of `s` as `CellSlices`. +* `FA41` — `LDMSGADDRQ` `(s – s′ s′′ −1 or s 0)`, a quiet version of `LDMSGADDR`: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. +* `FA42` — `PARSEMSGADDR` `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. +* `FA43` — `PARSEMSGADDRQ` `(s – t −1 or 0)`, a quiet version of `PARSEMSGADDR`: returns a zero on error instead of throwing an exception. +* `FA44` — `REWRITESTDADDR` `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. +* `FA45` — `REWRITESTDADDRQ` `(s – x y −1 or 0)`, a quiet version of primitive `REWRITESTDADDR`. +* `FA46` — `REWRITEVARADDR` `(s – x s′)`, a variant of `REWRITESTDADDR` that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). +* `FA47` — `REWRITEVARADDRQ` `(s – x s′ −1 or 0)`, a quiet version of primitive `REWRITEVARADDR`. +* `FA48–FA5F` — Reserved for message and address manipulation primitives. + +### A.11.10. Outbound message and output action primitives. + +* `FB00` — `SENDRAWMSG` `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. +* `FB02` — `RAWRESERVE` `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. +* `FB03` — `RAWRESERVEX` `(x D y – )`, similar to `RAWRESERVE`, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. +* `FB04` — `SETCODE` `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. +* `FB06` — `SETLIBCODE` `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. +* `FB07` — `CHANGELIB` `(h x – )`, creates an output action similarly to `SETLIBCODE`, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. +* `FB08–FB3F` — Reserved for output action primitives. + +--- + +## A.12 Debug primitives + +Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) `NOP` operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. + +### A.12.1. Debug primitives as multibyte NOPs. + +* `FEnn` — `DEBUG nn`, for `0 ≤ nn < 240`, is a two-byte `NOP`. +* `FEFnssss` — `DEBUGSTR ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte `NOP`, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. + +### A.12.2. Debug primitives as operations without side-effect. + +Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte `NOP`s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as `NOP`s, but they cannot throw exceptions. + +* `FE00` — `DUMPSTK`, dumps the stack (at most the top 255 values) and shows the total stack depth. +* `FE0n` — `DUMPSTKTOP n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. +* `FE10` — `HEXDUMP`, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. +* `FE11` — `HEXPRINT`, similar to `HEXDUMP`, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. +* `FE12` — `BINDUMP`, dumps `s0` in binary form, similarly to `HEXDUMP`. +* `FE13` — `BINPRINT`, outputs the binary representation of `s0` to a text buffer. +* `FE14` — `STRDUMP`, dumps the `Slice` at `s0` as an UTF-8 string. +* `FE15` — `STRPRINT`, similar to `STRDUMP`, but outputs the string into a text buffer (without carriage return). +* `FE1E` — `DEBUGOFF`, disables all debug output until it is re-enabled by a `DEBUGON`. More precisely, this primitive increases an internal counter, which disables all debug operations (except `DEBUGOFF` and `DEBUGON`) when strictly positive. +* `FE1F` — `DEBUGON`, enables debug output (in a debug version of TVM). +* `FE2n` — `DUMP s(n)`, `0 ≤ n < 15`, dumps `s(n)`. +* `FE3n` — `PRINT s(n)`, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. +* `FEC0–FEEF` — Use these opcodes for custom/experimental debug operations. +* `FEFnssss` — `DUMPTOSFMT ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). +* `FEFn00ssss` — `LOGSTR ssss`, string `ssss` is `n` bytes long. +* `FEF000` — `LOGFLUSH`, flushes all pending debug output from the buffer into the debug log. +* `FEFn01ssss` — `PRINTSTR ssss`, string `ssss` is `n` bytes long. + +--- + +## A.13 Codepage primitives + +The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. [5.1.8](#5-1-8-setting-the-codepage-in-the-code-itself)). + +* `FFnn` — `SETCP nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. +* `FF00` — `SETCP0`, selects TVM (test) codepage zero as described in this document. +* `FFFz` — `SETCP z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 ... −1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in [B.2.6](#b-2-6-codepage-−1). Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. +* `FFF0` — `SETCPX` `(c – )`, selects codepage `c` with `−−2¹⁵ ≤ c < 2¹⁵` passed in the top of the stack. +--- + +# B Formal properties and specifications of TVM + +This appendix discusses certain formal properties of TVM that are necessary for executing smart contracts in the TON Blockchain and validating such executions afterwards. + +## B.1 Serialization of the TVM state + +Recall that a virtual machine used for executing smart contracts in a blockchain must be deterministic, otherwise the validation of each execution would require the inclusion of all intermediate steps of the execution into a block, or at least of the choices made when indeterministic operations have been performed. + +Furthermore, the state of such a virtual machine must be (uniquely) serializable, so that even if the state itself is not usually included in a block, its hash is still well-defined and can be included into a block for verification purposes. + +### B.1.1. TVM stack values. + +TVM stack values can be serialized as follows: + +```asm +vm_stk_tinyint#01 value:int64 = VmStackValue; +vm_stk_int#0201_ value:int257 = VmStackValue; +vm_stk_nan#02FF = VmStackValue; +vm_stk_cell#03 cell:^Cell = VmStackValue; +_ cell:^Cell st_bits:(## 10) end_bits:(## 10) + { st_bits <= end_bits } + st_ref:(#<= 4) end_ref:(#<= 4) + { st_ref <= end_ref } = VmCellSlice; +vm_stk_slice#04 _:VmCellSlice = VmStackValue; +vm_stk_builder#05 cell:^Cell = VmStackValue; vm_stk_cont#06 cont:VmCont = VmStackValue; ``` @@ -2759,7 +3571,7 @@ Of these, `vm_stk_tinyint` is never used by TVM in codepage zero; it is used onl The TVM stack can be serialized as follows: -``` +```asm vm_stack#_ depth:(## 24) stack:(VmStackList depth) = VmStack; vm_stk_cons#_ {n:#} head:VmStackValue tail:^(VmStackList n) = VmStackList (n + 1); @@ -2770,7 +3582,7 @@ vm_stk_nil#_ = VmStackList 0; Control registers in TVM can be serialized as follows: -``` +```asm _ cregs:(HashmapE 4 VmStackValue) = VmSaveList; ``` @@ -2778,7 +3590,7 @@ _ cregs:(HashmapE 4 VmStackValue) = VmSaveList; Gas limits in TVM can be serialized as follows: -``` +```asm gas_limits#_ remaining:int64 _:^[ max_limit:int64 cur_limit:int64 credit:int64 ] = VmGasLimits; @@ -2788,7 +3600,7 @@ gas_limits#_ remaining:int64 _:^[ The TVM library environment can be serialized as follows: -``` +```asm _ libraries:(HashmapE 256 ^Cell) = VmLibraries; ``` @@ -2796,7 +3608,7 @@ _ libraries:(HashmapE 256 ^Cell) = VmLibraries; Continuations in TVM can be serialized as follows: -``` +```asm vmc_std$00 nargs:(## 22) stack:(Maybe VmStack) save:VmSaveList cp:int16 code:VmCellSlice = VmCont; vmc_envelope$01 nargs:(## 22) stack:(Maybe VmStack) @@ -2816,7 +3628,7 @@ vmc_pushint$1111 value:int32 next:^VmCont = VmCont; The total state of TVM can be serialized as follows: -``` +```asm vms_init$00 cp:int16 step:int32 gas:GasLimits stack:(Maybe VmStack) save:VmSaveList code:VmCellSlice lib:VmLibraries = VmState; @@ -2864,54 +3676,63 @@ The TON Blockchain adopts this approach to validate the runs of TVM (e.g., those ### B.2.6. Codepage −1. -Codepage `−1` of TVM is reserved for the stripped-down version of TVM. Its main purpose is to execute the reference implementation of the step function of the full TVM. This codepage contains only special versions of arithmetic primitives working with “tiny integers” (64-bit signed integers); therefore, TVM’s 257-bit `Integer` arithmetic must be defined in terms of 64-bit arithmetic. Elliptic curve cryptography primitives are also implemented directly in codepage `−1`, without using any third-party libraries. Finally, a reference implementation of the `sha256` hash function is also provided in codepage `−1`. +Codepage `−1` of TVM is reserved for the stripped-down version of TVM. Its main purpose is to execute the reference implementation of the step function of the full TVM. This codepage contains only special versions of arithmetic primitives working with “tiny integers” (64-bit signed integers); therefore, TVM’s 257-bit `Integer` arithmetic must be defined in terms of 64-bit arithmetic. + +Elliptic curve cryptography primitives are also implemented directly in codepage `−1`, without using any third-party libraries. Finally, a reference implementation of the `sha256` hash function is also provided in codepage `−1`. ### B.2.7. Codepage −2. -This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage −2”. All 64-bit arithmetic used in codepage −1 would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage −1. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer.[30](#footnote-30) +This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage −2”. + +All 64-bit arithmetic used in codepage −1 would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage −1. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer.[30](#footnote-30) --- # C Code density of stack and register machines -This appendix extends the general consideration of stack manipulation primitives provided in 2.2, explaining the choice of such primitives for TVM, with a comparison of stack machines and register machines in terms of the quantity of primitives used and the code density. We do this by comparing the machine code that might be generated by an optimizing compiler for the same source files, for different (abstract) stack and register machines. +This appendix extends the general consideration of stack manipulation primitives provided in [2.2](#2-2-stack-manipulation-primitives), explaining the choice of such primitives for TVM, with a comparison of stack machines and register machines in terms of the quantity of primitives used and the code density. We do this by comparing the machine code that might be generated by an optimizing compiler for the same source files, for different (abstract) stack and register machines. -It turns out that the stack machines (at least those equipped with the basic stack manipulation primitives described in 2.2.1) have far superior code density. Furthermore, the stack machines have excellent extendability with respect to additional arithmetic and arbitrary data processing operations, especially if one considers machine code automatically generated by optimizing compilers. +It turns out that the stack machines (at least those equipped with the basic stack manipulation primitives described in [2.2.1](#2-2-1-basic-stack-manipulation-primitives)) have far superior code density. Furthermore, the stack machines have excellent extendability with respect to additional arithmetic and arbitrary data processing operations, especially if one considers machine code automatically generated by optimizing compilers. ## C.1 Sample leaf function -We start with a comparison of machine code generated by an (imaginary) optimizing compiler for several abstract register and stack machines, corresponding to the same high-level language source code that contains the definition of a leaf function (i.e., a function that does not call any other functions). For both the register machines and stack machines, we observe the notation and conventions introduced in 2.1. +We start with a comparison of machine code generated by an (imaginary) optimizing compiler for several abstract register and stack machines, corresponding to the same high-level language source code that contains the definition of a leaf function (i.e., a function that does not call any other functions). For both the register machines and stack machines, we observe the notation and conventions introduced in [2.1](#2-1-stack-calling-conventions). ### C.1.1. Sample source file for a leaf function. - -The source file we consider contains one function f that takes six (integer) arguments, a, b, c, d, e, f, and returns two (integer) values, x and y, which are the solutions of the system of two linear equations +The source file we consider contains one function `f` that takes six (integer) arguments `a, b, c, d, e, f`, and returns two (integer) values `x` and `y`, which are the solutions of the system of two linear equations: ```math -( ax + by = e cx + dy = f (6) -``` +```` The source code of the function, in a programming language similar to C, might look as follows: - -```math -(int, int) f(int a, int b, int c, int d, int e, int f) \\ -{ \\ - int D = a*d - b*c; \\ - int Dx = e*d - b*f; \\ - int Dy = a*f - e*c; \\ - return (Dx / D, Dy / D); \\ +```c +(int, int) f(int a, int b, int c, int d, int e, int f) +{ + int D = a*d - b*c; + int Dx = e*d - b*f; + int Dy = a*f - e*c; + return (Dx / D, Dy / D); } ``` -We assume (cf. 2.1) that the register machines we consider accept the six parameters a. . . f in registers r0. . . r5, and return the two values x and y in r0 and r1. We also assume that the register machines have 16 registers, and that the stack machine can directly access s0 to s15 by its stack manipulation primitives; the stack machine will accept the parameters in s5 to s0, and return the two values in s0 and s1, somewhat similarly to the register machine. Finally, we assume at first that the register machine is allowed to destroy values in all registers (which is slightly unfair towards the stack machine); this assumption will be revisited later. + +We assume (cf. [2.1](#2-1-stack-calling-conventions)) that the register machines we consider accept the six parameters `a…f` in registers `r0…r5`, and return the two values `x` and `y` in `r0` and `r1`. + +We also assume that the register machines have 16 registers, and that the stack machine can directly access `s0` to `s15` by its stack manipulation primitives. The stack machine will accept the parameters in `s5…s0`, and return the two values in `s0` and `s1`, somewhat similarly to the register machine. + +Finally, we assume at first that the register machine is allowed to destroy values in all registers (which is slightly unfair towards the stack machine); this assumption will be revisited later. + + + ### C.1.2. Three-address register machine. -The machine code (or rather the corresponding assembly code) for a three-address register machine (cf. 2.1.7) might look as follows: +The machine code (or rather the corresponding assembly code) for a three-address register machine (cf. [2.1.7](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines)) might look as follows: -``` +```asm IMUL r6,r0,r3 // r6 := r0 * r3 = ad IMUL r7,r1,r2 // r7 := bc SUB r6,r6,r7 // r6 := ad-bc = D @@ -2925,14 +3746,15 @@ IDIV r0,r3,r6 // x := Dx/D IDIV r1,r1,r6 // y := Dy/D RET ``` +We have used `12` operations and at least `23` bytes (each operation uses `3×4 = 12` bits to indicate the three registers involved, and at least `4` bits to indicate the operation performed; thus we need two or three bytes to encode each operation). -We have used 12 operations and at least 23 bytes (each operation uses 3×4 = 12 bits to indicate the three registers involved, and at least 4 bits to indicate the operation performed; thus we need two or three bytes to encode each operation). A more realistic estimate would be 34 (three bytes for each arithmetic operation) or 31 bytes (two bytes for addition and subtraction, three bytes for multiplication and division). +A more realistic estimate would be `34` (three bytes for each arithmetic operation) or `31` bytes (two bytes for addition and subtraction, three bytes for multiplication and division). ### C.1.3. Two-address register machine. The machine code for a two-address register machine might look as follows: -``` +```c MOV r6,r0 // r6 := r0 = a MOV r7,r1 // r7 := b IMUL r6,r3 // r6 := r6*r3 = ad @@ -2951,13 +3773,13 @@ IDIV r1,r6 // r1 := Dy/D RET ``` -We have used 16 operations; optimistically assuming each of them (with the exception of RET) can be encoded by two bytes, this code would require 31 bytes.[31](#footnote-31) +We have used `16` operations; optimistically assuming each of them (with the exception of `RET`) can be encoded by `2` bytes, this code would require `31` bytes.[31](#footnote-31) ### C.1.4. One-address register machine. The machine code for a one-address register machine might look as follows: -``` +```asm MOV r8,r0 // r8 := r0 = a XCHG r1 // r0 <-> r1; r0 := b, r1 := a MOV r6,r0 // r6 := b @@ -2965,16 +3787,6 @@ IMUL r2 // r0 := r0*r2; r0 := bc MOV r7,r0 // r7 := bc MOV r0,r8 // r0 := a IMUL r3 // r0 := ad -31It is interesting to compare this code with that generated by optimizing C compilers -for the x86-64 architecture. -First of all, the integer division operation for x86-64 uses the one-address form, with -the (double-length) dividend to be supplied in accumulator pair r2:r0. The quotient is -also returned in r0. As a consequence, two single-to-double extension operations (CDQ or -CQO) and at least one move operation need to be added. -Secondly, the encoding used for arithmetic and move operations is less optimistic than -in our example above, requiring about three bytes per operation on average. As a result, -we obtain a total of 43 bytes for 32-bit integers, and 68 bytes for 64-bit integers. -C.1. Sample leaf function SUB r7 // r0 := ad-bc = D XCHG r1 // r1 := D, r0 := b IMUL r5 // r0 := bf @@ -2993,13 +3805,16 @@ MOV r0,r2 // r0 := x RET ``` -We have used 23 operations; if we assume one-byte encoding for all arithmetic operations and XCHG, and two-byte encodings for MOV, the total size of the code will be 29 bytes. Notice, however, that to obtain the compact code shown above we had to choose a specific order of computation, and made heavy use of the commutativity of multiplication. (For example, we compute bc before af, and af − bc immediately after af.) It is not clear whether a compiler would be able to make all such optimizations by itself. +We have used `23` operations; if we assume one-byte encoding for all arithmetic operations and `XCHG`, and two-byte encodings for `MOV`, the total size of the code will be `29` bytes. + +Notice, however, that to obtain the compact code shown above we had to choose a specific order of computation, and made heavy use of the commutativity of multiplication. (For example, we compute `bc` before `af`, and `af − bc` immediately after `af`.) It is not clear whether a compiler would be able to make all such optimizations by itself. + ### C.1.5. Stack machine with basic stack primitives. -The machine code for a stack machine equipped with basic stack manipulation primitives described in 2.2.1 might look as follows: +The machine code for a stack machine equipped with basic stack manipulation primitives described in [2.2.1](#2-2-1-basic-stack-manipulation-primitives) might look as follows: -``` +```asm PUSH s5 // a b c d e f a PUSH s3 // a b c d e f a d IMUL // a b c d e f ad @@ -3031,20 +3846,25 @@ IDIV // x y RET ``` -We have used 29 operations; assuming one-byte encodings for all stack operations involved (including XCHG s1,s(i)), we have used 29 code bytes as well. Notice that with one-byte encoding, the “unsystematic” operation ROT (equivalent to XCHG s1; XCHG s2) would reduce the operation and byte count to 28. This shows that such “unsystematic” operations, borrowed from Forth, may indeed reduce the code size on some occasions. +We have used `29` operations; assuming one-byte encodings for all stack operations involved (including `XCHG s1,s(i)`), we have used `29` code bytes as well. + +Notice that with one-byte encoding, the “unsystematic” operation `ROT` (equivalent to `XCHG s1; XCHG s2`) would reduce the operation and byte count to `28`. This shows that such “unsystematic” operations, borrowed from Forth, may indeed reduce the code size on some occasions. + +Notice as well that we have implicitly used the commutativity of multiplication in this code, computing `de − bf` instead of `ed − bf` as specified in high-level language source code. If we were not allowed to do so, an extra `XCHG s1` would need to be inserted before the third `IMUL`, increasing the total size of the code by one operation and one byte. -Notice as well that we have implicitly used the commutativity of multiplication in this code, computing de − bf instead of ed − bf as specified in high-level language source code. If we were not allowed to do so, an extra XCHG s1 would need to be inserted before the third IMUL, increasing the total size of the code by one operation and one byte. +The code presented above might have been produced by a rather unsophisticated compiler that simply computed all expressions and subexpressions in the order they appear, then rearranged the arguments near the top of the stack before each operation as outlined in [2.2.2](#2-2-2-basic-stack-manipulation-primitives-suffice). -The code presented above might have been produced by a rather unsophisticated compiler that simply computed all expressions and subexpressions in the order they appear, then rearranged the arguments near the top of the stack before each operation as outlined in 2.2.2. The only “manual” optimization done here involves computing ec before af; one can check that the other order would lead to slightly shorter code of 28 operations and bytes (or 29, if we are not allowed to use the commutativity of multiplication), but -151 -C.1. Sample leaf function -the ROT optimization would not be applicable. +The only “manual” optimization done here involves computing `ec` before `af`; one can check that the other order would lead to slightly shorter code of `28` operations and bytes (or `29`, if we are not allowed to use the commutativity of multiplication), but the `ROT` optimization would not be applicable. ### C.1.6. Stack machine with compound stack primitives. -A stack machine with compound stack primitives (cf. 2.2.3) would not significantly improve code density of the code presented above, at least in terms of bytes used. The only difference is that, if we were not allowed to use commutativity of multiplication, the extra XCHG s1 inserted before the third IMUL might be combined with two previous operations XCHG s3, PUSH s2 into one compound operation PUXC s2,s3; we provide the resulting code below. To make this less redundant, we show a version of the code that computes subexpression af before ec as specified in the original source file. We see that this replaces six operations (starting from line 15) with five other operations, and disables the ROT optimization: +A stack machine with compound stack primitives (cf. [2.2.3](#2-2-3-compound-stack-manipulation-primitives)) would not significantly improve code density of the code presented above, at least in terms of bytes used. -``` +The only difference is that, if we were not allowed to use commutativity of multiplication, the extra `XCHG s1` inserted before the third `IMUL` might be combined with two previous operations `XCHG s3`, `PUSH s2` into one compound operation `PUXC s2,s3`; we provide the resulting code below. + +To make this less redundant, we show a version of the code that computes subexpression `af` before `ec` as specified in the original source file. We see that this replaces six operations (starting from line `15`) with five other operations, and disables the `ROT` optimization: + +```asm PUSH s5 // a b c d e f a PUSH s3 // a b c d e f a d IMUL // a b c d e f ad @@ -3074,17 +3894,21 @@ IDIV // x y RET ``` -We have used a total of 27 operations and 28 bytes, the same as the previous version (with the ROT optimization). However, we did not use the commutativity of multiplication here, so we can say that compound stack manipulation primitives enable us to reduce the code size from 29 to 28 bytes. +We have used a total of `27` operations and `28` bytes, the same as the previous version (with the `ROT` optimization). However, we did not use the commutativity of multiplication here, so we can say that compound stack manipulation primitives enable us to reduce the code size from `29` to `28` bytes. -Yet again, notice that the above code might have been generated by an unsophisticated compiler. Manual optimizations might lead to more compact code; for instance, we could use compound operations such as XCHG3 to prepare in advance not only the correct values of s0 and s1 for the next arithmetic operation, but also the value of s2 for the arithmetic operation after that. The next section provides an example of such an optimization. +Yet again, notice that the above code might have been generated by an unsophisticated compiler. Manual optimizations might lead to more compact code; for instance, we could use compound operations such as `XCHG3` to prepare in advance not only the correct values of `s0` and `s1` for the next arithmetic operation, but also the value of `s2` for the arithmetic operation after that. -### C.1.7. Stack machine with compound stack primitives and manually optimized code. +The next section provides an example of such an optimization. -The previous version of code for a stack machine with compound stack primitives can be manually optimized as follows. +### C.1.7. Stack machine with compound stack primitives and manually optimized code -By interchanging XCHG operations with preceding XCHG, PUSH, and arithmetic operations whenever possible, we obtain code fragment XCHG s2,s6; XCHG s1,s0; XCHG s0,s5, which can then be replaced by compound operation XCHG3 s6,s0,s5. This compound operation would admit a two-byte encoding, thus leading to 27-byte code using only 21 operations: +The previous version of code for a stack machine with compound stack primitives can be manually optimized as follows. -``` +By interchanging `XCHG` operations with preceding `XCHG`, `PUSH`, and arithmetic operations whenever possible, we obtain code fragment `XCHG s2,s6; XCHG s1,s0; XCHG s0,s5`, which can then be replaced by compound operation `XCHG3 s6,s0,s5`. + +This compound operation would admit a two-byte encoding, thus leading to `27`-byte code using only `21` operations: + +```asm PUSH2 s5,s2 // a b c d e f a d IMUL // a b c d e f ad PUSH2 s5,s4 // a b c d e f ad b c @@ -3101,8 +3925,6 @@ XCHG s4 // e Dx c D a f IMUL // e Dx c D af XCHG2 s4,s2 // D Dx af e c IMUL // D Dx af ec -153 -C.2. Comparison of machine code for sample leaf function SUB // D Dx Dy XCPU s1,s2 // D Dy Dx D IDIV // D Dy x @@ -3117,30 +3939,33 @@ It is interesting to note that this version of stack machine code contains only # C.2 Comparison of machine code for sample leaf function -Table 1 summarizes the properties of machine code corresponding to the same source file described in C.1.1, generated for a hypothetical three-address register machine (cf. C.1.2), with both “optimistic” and “realistic” instruction encodings; a two-address machine (cf. C.1.3); a one-address machine (cf. C.1.4); and a stack machine, similar to TVM, using either only the basic stack manipulation primitives (cf. C.1.5) or both the basic and the composite stack primitives (cf. C.1.7). +Table 1 summarizes the properties of machine code corresponding to the same source file described in [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function), generated for a hypothetical three-address register machine (cf. [C.1.2](#c-1-2-three-address-register-machine)), with both “optimistic” and “realistic” instruction encodings; a two-address machine (cf. [C.1.3](#c-1-3-two-address-register-machine)); a one-address machine (cf. [C.1.4](#c-1-4-one-address-register-machine)); and a stack machine, similar to TVM, using either only the basic stack manipulation primitives (cf. [C.1.5](#c-1-5-stack-machine-with-basic-primitives)) or both the basic and the composite stack primitives (cf. [C.1.7](#c-1-7-stack-machine-with-compound-primitives)). -The meaning of the columns in Table 1 is as follows: +The meaning of the columns in [Table 1](#table-1) is as follows: -* “Operations” — The quantity of instructions used, split into “data” (i.e., register move and exchange instructions for register machines, and stack manipulation instructions for stack machines) and “arithmetic” (instructions for adding, subtracting, multiplying and dividing integer numbers). The “total” is one more than the sum of these two, because there is also a one-byte RET instruction at the end of machine code. -* “Code bytes” — The total amount of code bytes used. -* “Opcode space” — The portion of “opcode space” (i.e., of possible choices for the first byte of the encoding of an instruction) used by data and arithmetic instructions in the assumed instruction encoding. For example, the “optimistic” encoding for the three-address machine assumes two-byte encodings for all arithmetic instructions `op r(i), r(j), r(k)`. Each arithmetic instruction would then consume portion `16/256 = 1/16` of the opcode space. Notice that for the stack machine we have assumed one-byte encodings for `XCHG s(i)`, `PUSH s(i)` and `POP s(i)` in all cases, augmented by `XCHG s1,s(i)` for the basic stack instructions case only. As for the compound stack operations, we have assumed two-byte encodings for `PUSH3`, `XCHG3`, `XCHG2`, `XCPU`, `PUXC`, `PUSH2`, but not for `XCHG s1,s(i)`. +- **Operations** — The quantity of instructions used, split into “data” (i.e., register move and exchange instructions for register machines, and stack manipulation instructions for stack machines) and “arithmetic” (instructions for adding, subtracting, multiplying and dividing integer numbers). The “total” is one more than the sum of these two, because there is also a one-byte `RET` instruction at the end of machine code. +- **Code bytes** — The total amount of code bytes used. +- **Opcode space** — The portion of opcode space (i.e., of possible choices for the first byte of the encoding of an instruction) used by data and arithmetic instructions in the assumed instruction encoding. For example, the “optimistic” encoding for the three-address machine assumes two-byte encodings for all arithmetic instructions `op r(i), r(j), r(k)`. Each arithmetic instruction would then consume portion `16/256 = 1/16` of the opcode space. -The “code bytes” column reflects the density of the code for the specific sample source. However, “opcode space” is also important, because it reflects the extendability of the achieved density to other classes of operations (e.g., if one were to complement arithmetic operations with string manipulation operations and so on). Here the “arithmetic” subcolumn is more important than the “data” subcolumn, because no further data manipulation operations would be required for such extensions. + Notice that for the stack machine we have assumed one-byte encodings for `XCHG s(i)`, `PUSH s(i)` and `POP s(i)` in all cases, augmented by `XCHG s1,s(i)` for the basic stack instructions case only. As for the compound stack operations, we have assumed two-byte encodings for `PUSH3`, `XCHG3`, `XCHG2`, `XCPU`, `PUXC`, `PUSH2`, but not for `XCHG s1,s(i)`. -We see that the three-address register machine with the “optimistic” encoding, assuming two-byte encodings for all three-register arithmetic operations, achieves the best code density, requiring only 23 bytes. However, this comes at a price: each arithmetic operation consumes 1/16 of the opcode space, so the four operations already use a quarter of the opcode space. At most 11 other operations, arithmetic or not, might be added to this architecture while preserving such high code density. On the other hand, when we consider the “realistic” encoding for the three-address machine, using two-byte encodings only for the most frequently used addition/subtraction operations (and longer encodings for less frequently used multiplication/division operations, reflecting the fact that the possible extension operations would likely fall in this class), then the three-address machine ceases to offer such attractive code density. +The **code bytes** column reflects the density of the code for the specific sample source. However, **opcode space** is also important, because it reflects the extendability of the achieved density to other classes of operations (e.g., if one were to complement arithmetic operations with string manipulation operations, and so on). Here the “arithmetic” subcolumn is more important than the “data” subcolumn, because no further data manipulation operations would be required for such extensions. -In fact, the two-address machine becomes equally attractive at this point: it is capable of achieving the same code size of 31 bytes as the three-address machine with the “realistic” encoding, using only 6/256 of the opcode space for this! However, 31 bytes is the worst result in this table. +We see that the three-address register machine with the “optimistic” encoding, assuming two-byte encodings for all three-register arithmetic operations, achieves the best code density, requiring only `23` bytes. However, this comes at a price: each arithmetic operation consumes `1/16` of the opcode space, so the four operations already use a quarter of the opcode space. At most 11 other operations, arithmetic or not, might be added to this architecture while preserving such high code density. On the other hand, when we consider the “realistic” encoding for the three-address machine, using two-byte encodings only for the most frequently used addition/subtraction operations (and longer encodings for less frequently used multiplication/division operations, reflecting the fact that the possible extension operations would likely fall in this class), then the three-address machine ceases to offer such attractive code density. -The one-address machine uses 29 bytes, slightly less than the two-address machine. However, it utilizes a quarter of the opcode space for its arithmetic operations, hampering its extendability. In this respect it is similar to the three-address machine with the “optimistic” encoding, but requires 29 bytes instead of 23! So there is no reason to use the one-address machine at all, in terms of extendability (reflected by opcode space used for arithmetic operations) compared to code density. +In fact, the two-address machine becomes equally attractive at this point: it is capable of achieving the same code size of `31` bytes as the three-address machine with the “realistic” encoding, using only `6/256` of the opcode space for this! However, `31` bytes is the worst result in this table. -Finally, the stack machine wins the competition in terms of code density (27 or 28 bytes), losing only to the three-address machine with the “optimistic” encoding (which, however, is terrible in terms of extendability). +The one-address machine uses `29` bytes, slightly less than the two-address machine. However, it utilizes a quarter of the opcode space for its arithmetic operations, hampering its extendability. In this respect it is similar to the three-address machine with the “optimistic” encoding, but requires `29` bytes instead of `23`. So there is no reason to use the one-address machine at all, in terms of extendability (reflected by opcode space used for arithmetic operations) compared to code density. -To summarize: the two-address machine and stack machine achieve the best extendability with respect to additional arithmetic or data processing instructions (using only 1/256 of code space for each such instruction), while the stack machine additionally achieves the best code density by a small margin. The stack machine utilizes a significant part of its code space (more than a quarter) for data (i.e., stack) manipulation instructions; however, this does not seriously hamper extendability, because the stack manipulation instructions occupy a constant part of the opcode stace, regardless of all other instructions and extensions. +Finally, the stack machine wins the competition in terms of code density (`27` or `28` bytes), losing only to the three-address machine with the “optimistic” encoding (which, however, is terrible in terms of extendability). -While one might still be tempted to use a two-address register machine, we will explain shortly (cf. C.3) why the two-address register machine offers worse code density and extendability in practice than it appears based on this table. +To summarize: the two-address machine and stack machine achieve the best extendability with respect to additional arithmetic or data processing instructions (using only `1/256` of code space for each such instruction), while the stack machine additionally achieves the best code density by a small margin. The stack machine utilizes a significant part of its code space (more than a quarter) for data (i.e., stack) manipulation instructions; however, this does not seriously hamper extendability, because the stack manipulation instructions occupy a constant part of the opcode space, regardless of all other instructions and extensions. + +While one might still be tempted to use a two-address register machine, we will explain shortly (cf. [C.3](#c-3-sample-non-leaf-function)) why the two-address register machine offers worse code density and extendability in practice than it appears based on this table. As for the choice between a stack machine with only basic stack manipulation primitives or one supporting compound stack primitives as well, the case for the more sophisticated stack machine appears to be weaker: it offers only one or two fewer bytes of code at the expense of using considerably more opcode space for stack manipulation, and the optimized code using these additional instructions is hard for programmers to write and for compilers to automatically generate. + ### Table 1 | Machine | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | @@ -3152,32 +3977,60 @@ As for the choice between a stack machine with only basic stack manipulation pri | stack (basic) | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | | stack (comp.) | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | -Table 1: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. C.1.1). The two most important columns, reflecting code density and extendability to other operations, are marked by bold font. Smaller values are better in both of these columns. +**Table 1:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)). + +The two most important columns, reflecting **code density** and **extendability to other operations**, are marked by bold font. Smaller values are better in both of these columns. --- ### C.2.1. Register calling conventions: some registers must be preserved by functions. -Up to this point, we have considered the machinecode of only one function, without taking into account the interplay between this function and other functions in the same program. +Up to this point, we have considered the machine code of only one function, without taking into account the interplay between this function and other functions in the same program. + +Usually a program consists of more than one function, and when a function is not a “simple” or “leaf” function, it must call other functions. Therefore, it becomes important whether a called function preserves all or at least some registers. + +- If it preserves all registers except those used to return results, the caller can safely keep its local and temporary variables in certain registers; however, the callee needs to save all the registers it will use for its temporary values somewhere (usually into the stack, which also exists on register machines), and then restore the original values. +- On the other hand, if the called function is allowed to destroy all registers, it can be written in the manner described in [C.1.2](#c-1-2-three-address-register-machine), [C.1.3](#c-1-3-two-address-register-machine), and [C.1.4](#c-1-4-one-address-register-machine), but the caller will now be responsible for saving all its temporary values into the stack before the call, and restoring these values afterwards. + +In most cases, calling conventions for register machines require preservation of some but not all registers. We will assume that `m ≤ n` registers will be preserved by functions (unless they are used for return values), and that these registers are `r(n−m)…r(n−1)`. -Usually a program consists of more than one function, and when a function is not a “simple” or “leaf” function, it must call other functions. Therefore, it becomes important whether a called function preserves all or at least some registers. If it preserves all registers except those used to return results, the caller can safely keep its local and temporary variables in certain registers; however, the callee needs to save all the registers it will use for its temporary values somewhere (usually into the stack, which also exists on register machines), and then restore the original values. On the other hand, if the called function is allowed to destroy all registers, it can be written in the manner described in C.1.2, C.1.3, and C.1.4, but the caller will now be responsible for saving all its temporary values into the stack before the call, and restoring these values afterwards. +- Case `m = 0` corresponds to the case “the callee is free to destroy all registers” considered so far; it is quite painful for the caller. +- Case `m = n` corresponds to the case “the callee must preserve all registers”; it is quite painful for the callee, as we will see in a moment. +- Usually a value of `m` around `n/2` is used in practice. -In most cases, calling conventions for register machines require preservation of some but not all registers. We will assume that m ≤ n registers will be preserved by functions (unless they are used for return values), and that these registers are r(n − m). . . r(n − 1). Case m = 0 corresponds to the case “the callee is free to destroy all registers” considered so far; it is quite painful for the caller. Case m = n corresponds to the case “the callee must preserve all registers”; it is quite painful for the callee, as we will see in a moment. Usually a value of m around n/2 is used in practice. +The following sections consider cases `m = 0`, `m = 8`, and `m = 16` for our register machines with `n = 16` registers. -The following sections consider cases m = 0, m = 8, and m = 16 for our register machines with n = 16 registers. ### C.2.2. Case m = 0: no registers to preserve. -This case has been considered and summarized in C.2 and Table 1 above. +This case has been considered and summarized in [C.2](#c-2-comparison-of-machine-code-for-sample-leaf-function) and [Table 1](#table-1) above. -### C.2.3. Case m = n = 16: all registers must be preserved. +### C.2.3. Case `m = n = 16`: all registers must be preserved + +This case is the most painful one for the called function. It is especially difficult for leaf functions like the one we have been considering, which do not benefit at all from the fact that other functions preserve some registers when called — they do not call any functions, but instead must preserve all registers themselves. + +In order to estimate the consequences of assuming `m = n = 16`, we will assume that all our register machines are equipped with a stack, and with one-byte instructions `PUSH r(i)` and `POP r(i)`, which push or pop a register into/from the stack. + +For example, the three-address machine code provided in [C.1.2](#c-1-2-three-address-register-machine) destroys the values in registers `r2`, `r3`, `r6`, and `r7`; this means that the code of this function must be augmented by four instructions: + +```asm +PUSH r2; PUSH r3; PUSH r6; PUSH r7 +```` + +at the beginning, and by four instructions: + +```asm +POP r7; POP r6; POP r3; POP r2 +``` -This case is the most painful one for the called function. It is especially difficult for leaf functions like the one we have been considering, which do not benefit at all from the fact that other functions preserve some registers when called—they do not call any functions, but instead must preserve all registers themselves. +right before the `RET` instruction, in order to restore the original values of these registers from the stack. -In order to estimate the consequences of assuming m = n = 16, we will assume that all our register machines are equipped with a stack, and with one-byte instructions `PUSH r(i)` and `POP r(i)`, which push or pop a register into/from the stack. For example, the three-address machine code provided in C.1.2 destroys the values in registers r2, r3, r6, and r7; this means that the code of this function must be augmented by four instructions `PUSH r2; PUSH r3; PUSH r6; PUSH r7` at the beginning, and by four instructions `POP r7; POP r6; POP r3; POP r2` right before the `RET` instruction, in order to restore the original values of these registers from the stack. These four additional `PUSH/POP` pairs would increase the operation count and code size in bytes by `4 × 2 = 8`. A similar analysis can be done for other register machines as well, leading to Table 2. +These four additional `PUSH/POP` pairs would increase the operation count and code size in bytes by `4 × 2 = 8`. A similar analysis can be done for other register machines as well, leading to [Table 2](#table-2). We see that under these assumptions the stack machines are the obvious winners in terms of code density, and are in the winning group with respect to extendability. + + ### Table 2 | Machine | r | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | @@ -3189,13 +4042,21 @@ We see that under these assumptions the stack machines are the obvious winners i | stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | | stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | -Table 2: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. C.1.1), assuming all of the 16 registers must be preserved by called functions (m = n = 16). The new column labeled r denotes the number of registers to be saved and restored, leading to 2r more operations and code bytes compared to Table 1. Newly-added PUSH and POP instructions for register machines also utilize 32/256 of the opcode space. The two rows corresponding to stack machines remain unchanged. -### C.2.4. Case m = 8, n = 16: registers r8. . . r15 must be preserved. +**Table 2:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)), assuming all of the `16` registers must be preserved by called functions (`m = n = 16`). + +The new column labeled `r` denotes the number of registers to be saved and restored, leading to `2r` more operations and code bytes compared to [Table 1](#table-1). Newly added `PUSH` and `POP` instructions for register machines also utilize `32/256` of the opcode space. + +The two rows corresponding to stack machines remain unchanged. -The analysis of this case is similar to the previous one. The results are summarized in Table 3. -Notice that the resulting table is very similar to Table 1, apart from the “Opcode space” columns and the row for the one-address machine. Therefore, the conclusions of C.2 still apply in this case, with some minor modifications. We must emphasize, however, that these conclusions are valid only for leaf functions, i.e., functions that do not call other functions. Any program aside from the very simplest will have many non-leaf functions, especially if we are minimizing resulting machine code size (which prevents inlining of functions in most cases). +### C.2.4. Case `m = 8`, `n = 16`: registers `r8…r15` must be preserved + +The analysis of this case is similar to the previous one. The results are summarized in [Table 3](#table-3). + +Notice that the resulting table is very similar to [Table 1](#table-1), apart from the **Opcode space** columns and the row for the one-address machine. Therefore, the conclusions of [C.2](#c-2-comparison-of-machine-code-for-sample-leaf-function) still apply in this case, with some minor modifications. + +We must emphasize, however, that these conclusions are valid only for *leaf functions*, i.e., functions that do not call other functions. Any program aside from the very simplest will have many non-leaf functions, especially if we are minimizing resulting machine code size (which prevents inlining of functions in most cases). ### Table 3 @@ -3208,17 +4069,25 @@ Notice that the resulting table is very similar to Table 1, apart from the “Op | stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | | stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | -Table 3: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address and stack machines, generated for a sample leaf function (cf. C.1.1), assuming that only the last 8 of the 16 registers must be preserved by called functions (m = 8, n = 16). This table is similar to Table 2, but has smaller values of r. -### C.2.5. A fairer comparison using a binary code instead of a byte code. +**Table 3:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)), assuming that only the last `8` of the `16` registers must be preserved by called functions (`m = 8`, `n = 16`). + +This table is similar to [Table 2](#table-2), but has smaller values of `r`. -The reader may have noticed that our preceding discussion of kaddress register machines and stack machines depended very much on our insistence that complete instructions be encoded by an integer number of bytes. If we had been allowed to use a “bit” or “binary code” instead of a byte code for encoding instructions, we could more evenly balance the opcode space used by different machines. For instance, the opcode of SUB for a threeaddress machine had to be either 4-bit (good for code density, bad for opcode space) or 12-bit (very bad for code density), because the complete instruction has to occupy a multiple of eight bits (e.g., 16 or 24 bits), and 3 · 4 = 12 of those bits have to be used for the three register names. +### C.2.5. A fairer comparison using a binary code instead of a byte code -Therefore, let us get rid of this restriction. +The reader may have noticed that our preceding discussion of k-address register machines and stack machines depended very much on our insistence that complete instructions be encoded by an integer number of bytes. If we had been allowed to use a “bit” or “binary code” instead of a byte code for encoding instructions, we could more evenly balance the opcode space used by different machines. -Now that we can use any number of bits to encode an instruction, we can choose all opcodes of the same length for all the machines considered. For instance, all arithmetic instructions can have 8-bit opcodes, as the stack machine does, using 1/256 of the opcode space each; then the three-address register machine will use 20 bits to encode each complete arithmetic instruction. All MOVs, XCHGs, PUSHes, and POPs on register machines can be assumed to have 4-bit opcodes, because this is what we do for the most common stack manipulation primitives on a stack machine. The results of these changes are shown in Table 4. +For instance, the opcode of `SUB` for a three-address machine had to be either `4`-bit (good for code density, bad for opcode space) or `12`-bit (very bad for code density), because the complete instruction has to occupy a multiple of eight bits (e.g., `16` or `24` bits), and `3 · 4 = 12` of those bits have to be used for the three register names. + +Therefore, let us get rid of this restriction. + +Now that we can use any number of bits to encode an instruction, we can choose all opcodes of the same length for all the machines considered. For instance, all arithmetic instructions can have `8`-bit opcodes, as the stack machine does, using `1/256` of the opcode space each; then the three-address register machine will use `20` bits to encode each complete arithmetic instruction. + +All `MOV`s, `XCHG`s, `PUSH`es, and `POP`s on register machines can be assumed to have `4`-bit opcodes, because this is what we do for the most common stack manipulation primitives on a stack machine. The results of these changes are shown in [Table 4](#table-4). + +We can see that the performance of the various machines is much more balanced, with the stack machine still the winner in terms of the code density, but with the three-address machine enjoying the second place it really merits. If we were to consider the decoding speed and the possibility of parallel execution of instructions, we would have to choose the three-address machine, because it uses only `12` instructions instead of `21`. -We can see that the performance of the various machines is much more balanced, with the stack machine still the winner in terms of the code density, but with the three-address machine enjoying the second place it really merits. If we were to consider the decoding speed and the possibility of parallel execution of instructions, we would have to choose the three-address machine, because it uses only 12 instructions instead of 21. ### Table 4 @@ -3230,15 +4099,20 @@ We can see that the performance of the various machines is much more balanced, w | stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | | stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | -Table 4: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address and stack machines, generated for a sample leaf function (cf. C.1.1), assuming that only 8 of the 16 registers must be preserved by functions (m = 8, n = 16). This time we can use fractions of bytes to encode instructions, so as to match opcode space used by different machines. All arithmetic instructions have 8-bit opcodes, all data/stack manipulation instructions have 4-bit opcodes. In other respects this table is similar to Table 3. + +**Table 4:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)), assuming that only `8` of the `16` registers must be preserved by functions (`m = 8`, `n = 16`). + +This time we can use fractions of bytes to encode instructions, so as to match opcode space used by different machines. All arithmetic instructions have `8`-bit opcodes, all data/stack manipulation instructions have `4`-bit opcodes. In other respects this table is similar to [Table 3](#table-3). + +--- # C.3 Sample non-leaf function -This section compares the machine code for different register machines for a sample non-leaf function. Again, we assume that either m = 0, m = 8, or m = 16 registers are preserved by called functions, with m = 8 representing the compromise made by most modern compilers and operating systems. +This section compares the machine code for different register machines for a sample non-leaf function. Again, we assume that either `m = 0`, `m = 8`, or `m = 16` registers are preserved by called functions, with `m = 8` representing the compromise made by most modern compilers and operating systems. -### C.3.1. Sample source code for a non-leaf function. +### C.3.1. Sample source code for a non-leaf function -A sample source file may be obtained by replacing the built-in integer type with a custom Rational type, represented by a pointer to an object in memory, in our function for solving systems of two linear equations (cf. C.1.1): +A sample source file may be obtained by replacing the built-in integer type with a custom `Rational` type, represented by a pointer to an object in memory, in our function for solving systems of two linear equations (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)): ```c struct Rational; @@ -3255,19 +4129,29 @@ return (r_div(Dx, D), r_div(Dy, D)); // Dx/D, Dy/D } ``` -We will ignore all questions related to allocating new objects of type Rational in memory (e.g., in heap), and to preventing memory leaks. We may assume that the called subroutines r\_sub, r\_mul, and so on allocate new objects simply by advancing some pointer in a pre-allocated buffer, and that unused objects are later freed by a garbage collector, external to the code being analysed. +We will ignore all questions related to allocating new objects of type `Rational` in memory (e.g., in heap), and to preventing memory leaks. We may assume that the called subroutines `r_sub`, `r_mul`, and so on allocate new objects simply by advancing some pointer in a pre-allocated buffer, and that unused objects are later freed by a garbage collector, external to the code being analysed. -Rational numbers will now be represented by pointers, addresses, or references, which will fit into registers of our hypothetical register machines or into the stack of our stack machines. If we want to use TVM as an instance of these stack machines, we should use values of type Cell to represent such references to objects of type Rational in memory. +`Rational` numbers will now be represented by pointers, addresses, or references, which will fit into registers of our hypothetical register machines or into the stack of our stack machines. If we want to use TVM as an instance of these stack machines, we should use values of type `Cell` to represent such references to objects of type `Rational` in memory. -We assume that subroutines (or functions) are called by a special CALL instruction, which is encoded by three bytes, including the specification of the function to be called (e.g., the index in a “global function table”). +We assume that subroutines (or functions) are called by a special `CALL` instruction, which is encoded by `3` bytes, including the specification of the function to be called (e.g., the index in a “global function table”). -### C.3.2. Three-address and two-address register machines, m = 0 preserved registers. +### C.3.2. Three-address and two-address register machines, `m = 0` preserved registers -Because our sample function does not use built-in arithmetic instructions at all, compilers for our hypothetical three-address and two-address register machines will produce the same machine code. Apart from the previously introduced PUSH r(i) and POP r(i) one-byte instructions, we assume that our two- and three-address machines support the following two-byte instructions: MOV r(i),s(j), MOV s(j),r(i), and XCHG r(i),s(j), for 0 ≤ i, j ≤ 15. Such instructions occupy only 3/256 of the opcode space, so their addition seems quite natural. +Because our sample function does not use built-in arithmetic instructions at all, compilers for our hypothetical three-address and two-address register machines will produce the same machine code. -We first assume that m = 0 (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for `r_f` does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. A size-optimizing compiler might produce the following code: +Apart from the previously introduced `PUSH r(i)` and `POP r(i)` one-byte instructions, we assume that our two- and three-address machines support the following two-byte instructions: -``` +- `MOV r(i),s(j)` +- `MOV s(j),r(i)` +- `XCHG r(i),s(j)` + +for `0 ≤ i, j ≤ 15`. Such instructions occupy only `3/256` of the opcode space, so their addition seems quite natural. + +We first assume that `m = 0` (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for `r_f` does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. + +A size-optimizing compiler might produce the following code: + +```asm PUSH r4 // STACK: e PUSH r1 // STACK: e b PUSH r0 // .. e b a @@ -3277,8 +4161,6 @@ PUSH r3 // .. e b a f c d MOV r0,r1 // b MOV r1,r2 // c CALL r_mul // bc -161 -C.3. Sample non-leaf function PUSH r0 // .. e b a f c d bc MOV r0,s4 // a MOV r1,s1 // d @@ -3313,17 +4195,24 @@ POP r0 // x ; .. RET ``` -We have used 41 instructions: 17 one-byte (eight PUSH/POP pairs and one RET), 13 two-byte (MOV and XCHG; out of them 11 “new” ones, involving the stack),and 11 three-byte (CALL), for a total of 17 · 1 + 13 · 2 + 11 · 3 = 76 bytes.[32](#footnote-32) +We have used `41` instructions: `17` one-byte (eight `PUSH/POP` pairs and one `RET`), `13` two-byte (`MOV` and `XCHG`; out of them `11` “new” ones, involving the stack), and `11` three-byte (`CALL`), for a total of `17 · 1 + 13 · 2 + 11 · 3 = 76` bytes.[32](#footnote-32) -### C.3.3. Three-address and two-address register machines, m = 8 preserved registers. +### C.3.3. Three-address and two-address register machines, `m = 8` preserved registers -Now we have eight registers, r8 to r15, that are preserved by subroutine calls. We might keep some intermediate values there instead of pushing them into the stack. However, the penalty for doing so consists in a PUSH/POP pair for every such register that we choose to use, because our function is also required to preserve its original value. It seems that using these registers under such a penalty does not improve the density of the code, so the optimal code for three- and two-address machines for m = 8 preserved registers is the same as that provided in C.3.2, with a total of 42 instructions and 74 code bytes. +Now we have eight registers, `r8` to `r15`, that are preserved by subroutine calls. We might keep some intermediate values there instead of pushing them into the stack. However, the penalty for doing so consists in a `PUSH/POP` pair for every such register that we choose to use, because our function is also required to preserve its original value. -## C.3.4. Three-address and two-address register machines, m = 16 preserved registers. +It seems that using these registers under such a penalty does not improve the density of the code, so the optimal code for three- and two-address machines for `m = 8` preserved registers is the same as that provided in [C.3.2](#c-3-2-three-and-two-address-m-0), with a total of `42` instructions and `74` code bytes. -This time all registers must be preserved by the subroutines, excluding those used for returning the results. This means that our code must preserve the original values of r2 to r5, as well as any other registers it uses for temporary values. A straightforward way of writing the code of our subroutine would be to push registers r2 up to, say, r8 into the stack, then perform all the operations required, using r6–r8 for intermediate values, and finally restore registers from the stack. However, this would not optimize code size. We choose another approach: -``` +### C.3.4. Three-address and two-address register machines, `m = 16` preserved registers + +This time all registers must be preserved by the subroutines, excluding those used for returning the results. This means that our code must preserve the original values of `r2` to `r5`, as well as any other registers it uses for temporary values. + +A straightforward way of writing the code of our subroutine would be to push registers `r2` up to, say, `r8` into the stack, then perform all the operations required, using `r6–r8` for intermediate values, and finally restore registers from the stack. + +However, this would not optimize code size. We choose another approach: + +```asm PUSH r0 // STACK: a PUSH r1 // STACK: a b MOV r0,r1 // b @@ -3339,10 +4228,6 @@ XCHG r0,s0 // b; .. a D MOV r1,r5 // f CALL r_mul // bf PUSH r0 // .. a D bf -with size-optimization enabled actually occupied 150 bytes, due mostly to the fact that -actual instruction encodings are about twice as long as we had optimistically assumed. -163 -C.3. Sample non-leaf function MOV r0,r4 // e MOV r1,r3 // d CALL r_mul // ed @@ -3369,15 +4254,27 @@ POP r0 // x RET ``` -We have used 39 instructions: 11 one-byte, 17 two-byte (among them 5 “new” instructions), and 11 three-byte, for a total of 11 · 1 + 17 · 2 + 11 · 3 = 78 bytes. Somewhat paradoxically, the code size in bytes is slightly longer than in the previous case (cf. C.3.2), contrary to what one might have expected. This is partially due to the fact that we have assumed two-byte encodings for “new” MOV and XCHG instructions involving the stack, similarly to the “old” instructions. Most existing architectures (such as x86-64) use longer encodings (maybe even twice as long) for their counterparts of our “new” move and exchange instructions compared to the “usual” register-register ones. Taking this into account, we see that we would have obtained here 83 bytes (versus 87 for the code in C.3.2) assuming three-byte encodings of new operations, and 88 bytes (versus 98) assuming four-byte encodings. This shows that, for two-address architectures without optimized encodings for register-stackmove and exchange operations, m = 16 preserved registers might result in slightly shorter code for some non-leaf functions, at the expense of leaf functions (cf. C.2.3 and C.2.4), which would become considerably longer. +We have used `39` instructions: `11` one-byte, `17` two-byte (among them `5` “new” instructions), and `11` three-byte, for a total of `11 · 1 + 17 · 2 + 11 · 3 = 78` bytes. -### C.3.5. One-address register machine, m = 0 preserved registers. +Somewhat paradoxically, the code size in bytes is slightly longer than in the previous case (cf. [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers)), contrary to what one might have expected. This is partially due to the fact that we have assumed two-byte encodings for “new” `MOV` and `XCHG` instructions involving the stack, similarly to the “old” instructions. -For our one-address register machine, we assume that new register-stack instructions work through the accumulator only. Therefore, we have three new instructions, LD s(j) (equivalent to MOV r0,s(j) of two-address machines), ST s(j) (equivalent to MOV s(j),r0), and XCHG s(j) (equivalent to XCHG r0,s(j)). To make the comparison with two-address machines more interesting, we assume one-byte encodings for these new instructions, even though this would consume 48/256 = 3/16 of the opcode space. +Most existing architectures (such as x86-64) use longer encodings (maybe even twice as long) for their counterparts of our “new” move and exchange instructions compared to the “usual” register–register ones. Taking this into account, we see that we would have obtained here `83` bytes (versus `87` for the code in [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers)) assuming three-byte encodings of new operations, and `88` bytes (versus `98`) assuming four-byte encodings. -By adapting the code provided in C.3.2 to the one-address machine, we obtain the following: +This shows that, for two-address architectures without optimized encodings for register–stack move and exchange operations, `m = 16` preserved registers might result in slightly shorter code for some non-leaf functions, at the expense of leaf functions (cf. [C.2.3](#c-2-3-case-m-%3D-n-%3D-16%3A-all-registers-must-be-preserved) and [C.2.4](#c-2-4-case-m-%3D-8%2C-n-%3D-16%3A-registers-r8…-r15-must-be-preserved)), which would become considerably longer. -``` +### C.3.5. One-address register machine, `m = 0` preserved registers + +For our one-address register machine, we assume that new register–stack instructions work through the accumulator only. Therefore, we have three new instructions: + +- `LD s(j)` (equivalent to `MOV r0,s(j)` of two-address machines) +- `ST s(j)` (equivalent to `MOV s(j),r0`) +- `XCHG s(j)` (equivalent to `XCHG r0,s(j)`) + +To make the comparison with two-address machines more interesting, we assume one-byte encodings for these new instructions, even though this would consume `48/256 = 3/16` of the opcode space. + +By adapting the code provided in [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers) to the one-address machine, we obtain the following: + +```asm PUSH r4 // STACK: e PUSH r1 // STACK: e b PUSH r0 // .. e b a @@ -3402,8 +4299,6 @@ CALL r_mul // bf POP r1 // d ; .. e D a f c PUSH r0 // .. e D a f c bf LD s5 // e -165 -C.3. Sample non-leaf function CALL r_mul // ed POP r1 // bf; .. e D a f c CALL r_sub // Dx:=ed-bf @@ -3427,17 +4322,20 @@ POP r0 // r0:=x ; .. RET ``` -We have used 45 instructions: 34 one-byte and 11 three-byte, for a total of 67 bytes. Compared to the 76 bytes used by two- and three-address machines in C.3.2, we see that, again, the one-address register machine code may be denser than that of two-register machines, at the expense of utilizing more opcode space (just as shown in C.2). However, this time the extra 3/16 of the opcode space was used for data manipulation instructions, which do not depend on specific arithmetic operations or user functions invoked. +We have used `45` instructions: `34` one-byte and `11` three-byte, for a total of `67` bytes. Compared to the `76` bytes used by two- and three-address machines in [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers), we see that, again, the one-address register machine code may be denser than that of two-register machines, at the expense of utilizing more opcode space (just as shown in [C.2](#c-2-comparison-of-machine-code-for-sample-leaf-function)). -### C.3.6. One-address register machine, m = 8 preserved registers. +However, this time the extra `3/16` of the opcode space was used for data manipulation instructions, which do not depend on specific arithmetic operations or user functions invoked. -As explained in C.3.3, the preservation of r8–r15 between subroutine calls does not improve the size of our previously written code, so the one-address machine will use for m = 8 the same code provided in C.3.5. -### C.3.7. One-address register machine, m = 16 preserved registers. +### C.3.6. One-address register machine, `m = 8` preserved registers -We simply adapt the code provided in C.3.4 to the one-address register machine: +As explained in [C.3.3](#c-3-3-three-address-and-two-address-register-machines%2C-m-%3D-8-preserved-registers), the preservation of `r8–r15` between subroutine calls does not improve the size of our previously written code, so the one-address machine will use for `m = 8` the same code provided in [C.3.5](#c-3-5-one-address-m-0). -``` +### C.3.7. One-address register machine, `m = 16` preserved registers + +We simply adapt the code provided in [C.3.4](#c-3-4-three-address-and-two-address-register-machines%2C-m-%3D-16-preserved-registers) to the one-address register machine: + +```asm PUSH r0 // STACK: aPUSH r1 // STACK: a b MOV r0,r1 // b MOV r1,r2 // c @@ -3476,18 +4374,20 @@ POP r1 // D ; .. x CALL r_div // y:=Dy/D MOV r1,r0 // y POP r0 // x -167 -C.3. Sample non-leaf function RET ``` -We have used 40 instructions: 18 one-byte, 11 two-byte, and 11 three-byte, for a total of 18 · 1 + 11 · 2 + 11 · 3 = 73 bytes. +We have used `40` instructions: `18` one-byte, `11` two-byte, and `11` three-byte, for a total of `18 · 1 + 11 · 2 + 11 · 3 = 73` bytes. ### C.3.8. Stack machine with basic stack primitives. -We reuse the code provided in C.1.5, simply replacing arithmetic primitives (VM instructions) with subroutine calls. The only substantive modification is the insertion of the previously optional XCHG s1 before the third multiplication, because even an optimizing compiler cannot now know whether CALL r\_mul is a commutative operation. We have also used the “tail recursion optimization” by replacing the final CALL r\_div followed by RET with JMP r\_div. +We reuse the code provided in [C.1.5](#c-1-5-stack-machine-with-basic-stack-primitives), simply replacing arithmetic primitives (VM instructions) with subroutine calls. -``` +The only substantive modification is the insertion of the previously optional `XCHG s1` before the third multiplication, because even an optimizing compiler cannot now know whether `CALL r_mul` is a commutative operation. + +We have also used the “tail recursion optimization” by replacing the final `CALL r_div` followed by `RET` with `JMP r_div`. + +```asm PUSH s5 // a b c d e f a PUSH s3 // a b c d e f a d CALL r_mul // a b c d e f ad @@ -3519,13 +4419,13 @@ XCHG s2 // x Dy D JMP r_div // x y ``` -We have used 29 instructions; assuming one-byte encodings for all stack operations, and three-byte encodings for CALL and JMP instructions, we end up with 51 bytes. +We have used `29` instructions; assuming one-byte encodings for all stack operations, and three-byte encodings for `CALL` and `JMP` instructions, we end up with `51` bytes. -### C.3.9. Stack machine with compound stack primitives. +### C.3.9. Stack machine with compound stack primitives -We again reuse the code provided in C.1.7, replacing arithmetic primitives with subroutine calls and making the tail recursion optimization: +We again reuse the code provided in [C.1.7](#c-1-7-stack-machine-with-compound-stack-primitives-and-manually-optimized-code), replacing arithmetic primitives with subroutine calls and making the tail recursion optimization: -``` +```asm PUSH2 s5,s2 // a b c d e f a d CALL r_mul // a b c d e f ad PUSH2 s5,s4 // a b c d e f ad b c @@ -3549,7 +4449,7 @@ XCHG s2 // x Dy D JMP r_div // x y ``` -This code uses only 20 instructions, 9 stack-related and 11 control flowrelated (CALL and JMP), for a total of 48 bytes. +This code uses only `20` instructions, `9` stack-related and `11` control flow–related (`CALL` and `JMP`), for a total of `48` bytes. --- @@ -3566,22 +4466,25 @@ This code uses only 20 instructions, 9 stack-related and 11 control flowrelated | stack (basic) | − | 18 | 11 | 29 | 18 | 33 | 51 | 64/256 | 4/256 | 71/256 | | stack (comp.) | − | 9 | 11 | 20 | 15 | 33 | 48 | 84/256 | 4/256 | 91/256 | -Table 5: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. C.3.1), assuming m of the 16 registers must be preserved by called subroutines. + +**Table 5:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. [C.3.1](#c-3-1-sample-source-code-for-a-non-leaf-function)), assuming `m` of the `16` registers must be preserved by called subroutines. + --- -# C.4 Comparison of machine code for sample non-leaf +## C.4 Comparison of machine code for sample non-leaf function + +[Table 5](#table-5) summarizes the properties of machine code corresponding to the same source file provided in [C.3.1](#c-3-1-sample-source-code-for-a-non-leaf-function). We consider only the “realistically” encoded three-address machines. -function +Three-address and two-address machines have the same code density properties, but differ in the utilization of opcode space. The one-address machine, somewhat surprisingly, managed to produce shorter code than the two-address and three-address machines, at the expense of using up more than half of all opcode space. -Table 5 summarizes the properties of machine code corresponding to the same source file provided in C.3.1. We consider only the “realistically” encoded three-address machines. Three-address and two-address machines have the same code density properties, but differ in the utilization of opcode space. The one-address machine, somewhat surprisingly, managed to produced shorter code than the two-address and three-address machines, at the expense of using up more than half of all opcode space. The stack machine is the obvious winner in this code density contest, without compromizing its excellent extendability (measured in opcode space used for arithmetic and other data transformation instructions). +The stack machine is the obvious winner in this code density contest, without compromising its excellent extendability (measured in opcode space used for arithmetic and other data transformation instructions). -## C.4.1. Combining with results for leaf functions. +### C.4.1. Combining with results for leaf functions -It is instructive to compare this table with the results in C.2 for a sample leaf function, summarized in Table 1 (for m = 0 preserved registers) and the very similar Table 3 (for m = 8 preserved registers), and, if one is still interested in case m = 16 (which turned out to be worse than m = 8 in almost all situations), also to Table 2. -We see that the stack machine beats all register machines on non-leaf functions. As for the leaf functions, only the three-address machine with the “optimistic” encoding of arithmetic instructions was able to beat the stack machine, winning by 15%, by compromising its extendability. However, the same three-address machine produces 25% longer code for non-leaf functions. +It is instructive to compare this table with the results in [C.2](#c-2-comparison-of-machine-code-for-sample-leaf-function) for a sample leaf function, summarized in [Table 1](#table-1) (for `m = 0` preserved registers) and the very similar [Table 3](#table-3) (for `m = 8` preserved registers), and, if one is still interested in case `m = 16` (which turned out to be worse than `m = 8` in almost all situations), also to [Table 2](#table-2). -### C.4. Comparison of machine code for sample non-leaf function +We see that the stack machine beats all register machines on non-leaf functions. As for the leaf functions, only the three-address machine with the “optimistic” encoding of arithmetic instructions was able to beat the stack machine, winning by `15%`, by compromising its extendability. However, the same three-address machine produces `25%` longer code for non-leaf functions. **Operations** | **Code bytes** | **Opcode space** @@ -3596,23 +4499,32 @@ We see that the stack machine beats all register machines on non-leaf functions. | stack (basic) | − | 18 | 11 | 29 | 18 | 33 | 51 | 64/256 | 4/256 | 71/256 | | stack (comp.) | − | 9 | 11 | 20 | 15 | 33 | 48 | 84/256 | 4/256 | 91/256 | -Table 6: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. C.3.1), assuming m of the 16 registers must be preserved by called subroutines. This time we use fractions of bytes to encode instructions, enabling a fairer comparison. Otherwise, this table is similar to Table 5. +**Table 6:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. [C.3.1](#c-3-1-sample-source-code-for-a-non-leaf-function)), assuming `m` of the `16` registers must be preserved by called subroutines. + +This time we use fractions of bytes to encode instructions, enabling a fairer comparison. Otherwise, this table is similar to [Table 5](#table-5). + +If a typical program consists of a mixture of leaf and non-leaf functions in approximately equal proportion, then the stack machine will still win. + +### C.4.2. A fairer comparison using a binary code instead of a byte code + +Similarly to [C.2.5](#c-2-5-a-fairer-comparison-using-a-binary-code-instead-of-a-byte-code), we may offer a fairer comparison of different register machines and the stack machine by using arbitrary binary codes instead of byte codes to encode instructions, and matching the opcode space used for data manipulation and arithmetic instructions by different machines. + +The results of this modified comparison are summarized in [Table 6](#table-6). We see that the stack machines still win by a large margin, while using less opcode space for stack/data manipulation. + +### C.4.3. Comparison with real machines -If a typical program consists of a mixture of leaf and non-leaf functions in approximately equal proportion, then the stack machine will still win. +Note that our hypothetical register machines have been considerably optimized to produce shorter code than actually existing register machines; the latter are subject to other design considerations apart from code density and extendability, such as backward compatibility, faster instruction decoding, parallel execution of neighboring instructions, ease of automatically producing optimized code by compilers, and so on. -## C.4.2. A fairer comparison using a binary code instead of a byte code. +For example, the very popular two-address register architecture x86-64 produces code that is approximately twice as long as our “ideal” results for the two-address machines. On the other hand, our results for the stack machines are directly applicable to TVM, which has been explicitly designed with the considerations presented in this appendix in mind. -Similarly to C.2.5, we may offer a fairer comparison of different register machines and the stack machine by using arbitrary binary codes instead of byte codes to encode instructions, and matching the opcode space used for data manipulation and arithmetic instructions by different machines. The results of this modified comparison are summarized in Table 6. We see that the stack machines still win by a large margin, while using less opcode space for stack/data manipulation. +Furthermore, the actual TVM code is even shorter (in bytes) than shown in [Table 5](#table-5) because of the presence of the two-byte `CALL` instruction, allowing TVM to call up to `256` user-defined functions from the dictionary at `c3`. This means that one should subtract `10` bytes from the results for stack machines in [Table 5](#table-5) if one wants to specifically consider TVM, rather than an abstract stack machine; this produces a code size of approximately `40` bytes (or shorter), almost half that of an abstract two-address or three-address machine. -## C.4.3. Comparison with real machines. +### C.4.4. Automatic generation of optimized code -Note that our hypothetical register machines have been considerably optimized to produce shorter code than actually existing register machines; the latter are subject to other design considerations apart from code density and extendability, such as backward compatibility, faster instruction decoding, parallel execution of neighboring instructions, ease of automatically producing optimized code by compilers, and so on. -For example, the very popular two-address register architecture x86-64 produces code that is approximately twice as long as our “ideal” results for the two-address machines. On the other hand, our results for the stack machines are directly applicable to TVM, which has been explicitly designed with the considerations presented in this appendix in mind. Furthermore, the actual TVM code is even shorter (in bytes) than shown in Table 5 because of the presence of the two-byte CALL instruction, allowing TVM to call up to 256 user-defined functions from the dictionary at c3. This means that one should subtract 10 bytes from the results for stack machines in Table 5 if one wants to specifically consider TVM, rather than an abstract stack machine; this produces a code size of approximately 40 bytes (or shorter), almost half that of an abstract two-address or three-address machine. +An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in [2.2.2](#2-2-2-basic-stack-manipulation-primitives-suffice) and [2.2.5](#2-2-5-semantics-of-compound-stack-operations). The only exception is the unimportant “manual” `XCHG3` optimization described in [C.1.7](#c-1-7-stack-machine-with-compound-stack-primitives-and-manually-optimized-code), which enabled us to shorten the code by one more byte. -## C.4.4. Automatic generation of optimized code. +By contrast, the heavily optimized (with respect to size) code for register machines shown in [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers) and [C.3.3](#c-3-3-three-address-and-two-address-register-machines%2C-m-%3D-8-preserved-registers) is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. -An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in 2.2.2 and 2.2.5. The only exception is the unimportant “manual” XCHG3 optimization described in C.1.7, which enabled us to shorten the code by one more byte. -By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. ## References @@ -3658,11 +4570,11 @@ By contrast, the heavily optimized (with respect to size) code for register mach **19.** Versions of this operation may be introduced where `f` and `g` receive an additional bitstring argument, equal to the key (for leaves) or to the common prefix of all keys (for forks) in the corresponding subtree. [Back ↑](#3-3-10-basic-dictionary-operations) - **20.** If there are no bits of data left in `code`, but there is still exactly one reference, an implicit `JMP` to the cell at that reference is performed instead of an implicit `RET`. [Back ↑](#414-normal-work-of-tvm-or-the-main-loop) + **20.** If there are no bits of data left in `code`, but there is still exactly one reference, an implicit `JMP` to the cell at that reference is performed instead of an implicit `RET`. [Back ↑](#4-1-4-normal-work-of-tvm%2C-or-the-main-loop) - **21.** Technically, TVM may simply invoke a virtual method `run()` of the continuation currently in `cc`. [Back ↑](#415-extraordinary-continuations) + **21.** Technically, TVM may simply invoke a virtual method `run()` of the continuation currently in `cc`. [Back ↑](#4-1-5-extraordinary-continuations) - **22.** The already used savelist `cc.save` of the new `cc` is emptied before the execution starts. [Back ↑](#418-restoring-control-registers-from-the-new-continuation-c) + **22.** The already used savelist `cc.save` of the new `cc` is emptied before the execution starts. [Back ↑](#4-1-8-restoring-control-registers-from-the-new-continuation-c) **23.** The implementation of REPEAT involves an extraordinary continuation that remembers the remaining number of iterations, the body of the loop c, and the return continuation c'. (The latter term represents the remainder of the body of the function that invoked REPEAT, which would be normally stored in c0 of the new cc.) [Back ↑](#422-iterated-execution-and-loops) @@ -3678,8 +4590,8 @@ By contrast, the heavily optimized (with respect to size) code for register mach **29.** Notice that any modifications after launch cannot be done unilaterally; rather they would require the support of at least two-thirds of validators. [Back ↑](#5-3-1-upgradability) - **30.** The preliminary version of TVM does not use codepage −2 for this purpose. This may change in the future. [Back ↑](#b27-codepage-2) + **30.** The preliminary version of TVM does not use codepage −2 for this purpose. This may change in the future. [Back ↑](#b-2-7-codepage-−2) **31.** It is interesting to compare this code with that generated by optimizing C compilers for the x86-64 architecture. First of all, the integer division operation for x86-64 uses the one-address form, with the (double-length) dividend to be supplied in accumulator pair `r2:r0`. The quotient is also returned in `r0`. As a consequence, two single-to-double extension operations (**CDQ** or **CQO**) and at least one move operation need to be added. Secondly, the encoding used for arithmetic and move operations is less optimistic than in our example above, requiring about three bytes per operation on average. As a result, we obtain a total of 43 bytes for 32-bit integers, and 68 bytes for 64-bit integers. [Back ↑](#c13-two-address-register-machine) - **32.** Code produced for this function by an optimizing compiler for x86-64 architecture. [Back ↑](#c32-three-address-and-two-address-register-machines-m--0-preserved-registers) \ No newline at end of file + **32.** Code produced for this function by an optimizing compiler for x86-64 architecture. [Back ↑](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers) \ No newline at end of file From bd7f7ace38dafa0cb8114be2d0f38c498125d397 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Tue, 9 Sep 2025 03:20:59 +0100 Subject: [PATCH 05/18] fix markdown header --- ton/tvm.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index aa704237..44cc6cb6 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -1323,7 +1323,7 @@ TVM makes special provisions for simple and concise implementation of selector f Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. [A.7.2](#a-7-2-cell-deserialization-primitives)). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. -## 4.6.12 Alternative: using a hashmap to select the correct function +### 4.6.12 Alternative: using a hashmap to select the correct function Yet another alternative is to use a Hashmap (cf. [3.3](#3-3-hashmaps%2C-or-dictionaries)) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. [A.10](#a-10-dictionary-manipulation-primitives)) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. [A.8.5](#a-8-5-creating-simple-continuations-and-closures)) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. [A.10.11](#a-10-10-getmin%2C-getmax%2C-removemin%2C-removemax-operations)). This approach may be more efficient for larger programs and switch statements. From f0e712c7db569be2b335b43d475093ed96a00324 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Tue, 9 Sep 2025 23:35:44 +0100 Subject: [PATCH 06/18] fix unordered list --- ton/tvm.mdx | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 44cc6cb6..b2fc49fa 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -3231,7 +3231,7 @@ specific primitives are in fact TON Blockchain-specific. Most of the primitives listed below use 16-bit opcodes. -* * `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value +* `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. `1.4`), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action @@ -3416,24 +3416,23 @@ Most of the primitives listed below use 16-bit opcodes. do not fall into any other specific category. +### A.11.8. Currency manipulation primitives -### A.11.8. Currency manipulation primitives. +* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s′)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s′` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDUX`. -* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDUX`. +* `FA01` — `LDVARINT16` `(s – x s′)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDIX`. -* `FA01` — `LDVARINT16` `(s – x s0)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDIX`. +* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b′)`, stores (serializes) an `Integer` `x` in the range `0 ... 2¹²⁰ − 1` into `Builder` `b`, and returns the resulting `Builder` `b′`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2⁸ˡ`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. -* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2¹²⁰−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2⁸ˡ`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. +* `FA03` — `STVARINT16` `(b x – b′)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2¹¹⁹ ... 2¹¹⁹ − 1`. -* `FA03` — `STVARINT16` `(b x – b 0)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2¹¹⁹ ... 2¹¹⁹ − 1`. +* `FA04` — `LDVARUINT32` `(s – x s′)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2²⁴⁸`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 5`; `SWAP`; `SHIFT 3`; `LDUX`. -* `FA04` — `LDVARUINT32` `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2²⁴⁸`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 5`; `SWAP`; `SHIFT 3`; `LDUX`. +* `FA05` — `LDVARINT32` `(s – x s′)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷`. -* `FA05` — `LDVARINT32` `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷`. +* `FA06` — `STVARUINT32` `(b x – b′)`, serializes an `Integer` `0 ≤ x < 2²⁴⁸` as a `VarUInteger 32`. -* `FA06` — `STVARUINT32` `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2²⁴⁸` as a `VarUInteger 32`. - -* `FA07` — `STVARINT32` `(b x – b 0)`, serializes an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷` as a `VarInteger 32`. +* `FA07` — `STVARINT32` `(b x – b′)`, serializes an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷` as a `VarInteger 32`. * `FA08–FA1F` — Reserved for currency manipulation primitives. @@ -3465,12 +3464,9 @@ A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: * `addr_none` is represented by `t = (0)`, i.e., a `Tuple` containing exactly one `Integer` equal to zero. * `addr_extern` is represented by `t = (1, s)`, where `Slice` `s` contains the field `external_address`. In other words, `t` is a pair (a `Tuple` consisting of two entries), containing an `Integer` equal to one and `Slice` `s`. * `addr_std` is represented by `t = (2, u, x, s)`, where `u` is either a `Null` (if `anycast` is absent) or a `Slice` `s′` containing `rewrite_pfx` (if `anycast` is present). Next, `Integer` `x` is the `workchain_id`, and `Slice` `s` contains the address. - `135` - A.11. Application-specific primitives * `addr_var` is represented by `t = (3, u, x, s)`, where `u`, `x`, and `s` have the same meaning as for `addr_std`. - -### A.11.9. Message and address manipulation primitives. +The following primitives, which use the above conventions, are defined: * `FA40` — `LDMSGADDR` `(s – s′ s′′)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s′` and the remainder `s′′` of `s` as `CellSlices`. * `FA41` — `LDMSGADDRQ` `(s – s′ s′′ −1 or s 0)`, a quiet version of `LDMSGADDR`: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. From b4887b61b451c304c724cb744deb0f1c7efe512d Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Sun, 14 Sep 2025 01:24:30 +0100 Subject: [PATCH 07/18] fix broken links --- ton/tvm.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index b2fc49fa..a229a477 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -152,7 +152,7 @@ The original version of TVM defines and uses the following control registers: - **c0** — Contains the next continuation or return continuation (similar to the subroutine return address in conventional designs). This value must be a `Continuation`. - **c1** — Contains the alternative (return) continuation; this value must be a `Continuation`. It is used in some (experimental) control flow primitives, allowing TVM to define and call “subroutines with two exit points”. - **c2** — Contains the exception handler. This value is a `Continuation`, invoked whenever an exception is triggered. -- **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in [4.6](#4-6-...-reference), this value is also a `Continuation`, not a `Cell` as one might expect. +- **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in [4.6](#4-6-functions%2C-recursion%2C-and-dictionaries), this value is also a `Continuation`, not a `Cell` as one might expect. - **c4** — Contains the root of persistent data, or simply the data. This value is a `Cell`. When the code of a smart contract is invoked, `c4` points to the root cell of its persistent data kept in the blockchain state. If the smart contract needs to modify this data, it changes `c4` before returning. - **c5** — Contains the output actions. It is also a `Cell` initialized by a reference to an empty cell, but its final value is considered one of the smart contract outputs. For instance, the `SENDMSG` primitive, specific for the TON Blockchain, simply inserts the message into a list stored in the output actions. - **c7** — Contains the root of temporary data. It is a `Tuple`, initialized by a reference to an empty `Tuple` before invoking the smart contract and discarded after its termination.[4](#footnote-4) From 509b5de5afe6765cf70e957d420eb0ef413cabca Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Fri, 5 Sep 2025 13:58:49 +0000 Subject: [PATCH 08/18] Convert the TVM latex to markdown --- ton/tvm.mdx | 4763 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4763 insertions(+) create mode 100644 ton/tvm.mdx diff --git a/ton/tvm.mdx b/ton/tvm.mdx new file mode 100644 index 00000000..8aaf890a --- /dev/null +++ b/ton/tvm.mdx @@ -0,0 +1,4763 @@ +--- +title: "TVM" +--- + +## Introduction +The primary purpose of the Telegram Open Network Virtual Machine (TON VM or TVM) is to execute smart-contract code in the TON Blockchain. TVM must support all operations required to parse incoming messages and persistent data, and to create new messages and modify persistent data. + +Additionally, TVM must meet the following requirements: +* It must provide for possible future extensions and improvements while retaining backward compatibility and interoperability, because the code of a smart contract, once committed into the blockchain, must continue working in a predictable manner regardless of any future modifications to the VM. +* It must strive to attain high "(virtual) machine code" density, so that the code of a typical smart contract occupies as little persistent blockchain storage as possible. +* It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used.[^1] + +The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM,[^2] the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. + +TVM is not intended to be implemented in hardware (e.g., in a specialized microprocessor chip); rather, it should be implemented in software running on conventional hardware. This consideration lets us incorporate some high-level concepts and operations in TVM that would require convoluted microcode in a hardware implementation but pose no significant problems for a software implementation. Such operations are useful for achieving high code density and minimizing the byte (or storage cell) profile of smart-contract code when deployed in the TON Blockchain. + +--- + +## 1.0 Notation for bitstrings + +The following notation is used for bit strings (or bitstrings)—i.e., finite strings consisting of binary digits (bits), 0 and 1—throughout this document. + +### 1.0.1 Hexadecimal notation for bitstrings + +When the length of a bitstring is a multiple of four, we subdivide it into groups of four bits and represent each group by one of sixteen hexadecimal digits 0–9, A–F in the usual manner: + +* 0₁₆ ↔ 0000 +* 1₁₆ ↔ 0001 +* … +* F₁₆ ↔ 1111 + +The resulting hexadecimal string is our equivalent representation for the original binary string. + +### 1.0.2 Bitstrings of lengths not divisible by four + +If the length of a binary string is not divisible by four, we augment it by one `1` and several (maybe zero) `0`s at the end, so that its length becomes divisible by four, and then transform it into a string of hexadecimal digits as described above. To indicate that such a transformation has taken place, a special **completion tag** `_` is added to the end of the hexadecimal string. + +The reverse transformation (applied if the completion tag is present) consists in first replacing each hexadecimal digit by four corresponding bits, and then removing all trailing zeroes (if any) and the last `1` immediately preceding them (if the resulting bitstring is non-empty at this point). + +Notice that there are several admissible hexadecimal representations for the same bitstring. Among them, the shortest one is **canonical**. It can be deterministically obtained by the above procedure. + +For example: + +* `8A` corresponds to binary string `10001010`. +* `8A_` and `8A0_` both correspond to `100010`. +* An empty bitstring may be represented by either `''`, `8_`, `0_`, `_`, or `00_`. + +### 1.0.3 Emphasizing that a string is a hexadecimal representation of a bitstring + +Sometimes we need to emphasize that a string of hexadecimal digits (with or without a `_` at the end) is the hexadecimal representation of a bitstring. In such cases, we either prepend `x` to the resulting string (e.g., `x8A`), or prepend `x{` and append `}` (e.g., `x{2D9_}`, which is `00101101100`). + +This should not be confused with hexadecimal numbers, usually prepended by `0x` (e.g., `0x2D9` or `0x2d9`, which is the integer 729). + +### 1.0.4 Serializing a bitstring into a sequence of octets + +When a bitstring needs to be represented as a sequence of 8-bit bytes (octets), which take values in integers 0…255, this is achieved essentially in the same fashion as above: we split the bitstring into groups of eight bits and interpret each group as the binary representation of an integer 0…255. + +If the length of the bitstring is not a multiple of eight, the bitstring is augmented by a binary `1` and up to seven binary `0`s before being split into groups. The fact that such a completion has been applied is usually reflected by a **completion tag** bit. + +For instance, `00101101100` corresponds to the sequence of two octets: + +* `(0x2d, 0x90)` in hexadecimal +* `(45, 144)` in decimal + +…along with a completion tag bit equal to `1` (meaning that the completion has been applied), which must be stored separately. + +In some cases, it is more convenient to assume the completion is enabled by default rather than store an additional completion tag bit separately. Under such conventions, `8n`-bit strings are represented by `n + 1` octets, with the last octet always equal to `0x80 = 128`. + +Perfect — I’ll keep the **exact wording** from your excerpt, only formatting it in Markdown for readability (headings, lists, code style for inline values). Numbering stays **exactly as in the source**. + +--- + +# 1.1 TVM is a stack machine + +First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective.³ + +Most operations and user-defined functions take their arguments from the top of the stack, and replace them with their result. For example, the integer addition primitive (built-in operation) `ADD` does not take any arguments describing which registers or immediate values should be added together and where the result should be stored. Instead, the two top values are taken from the stack, they are added together, and their sum is pushed into the stack in their place. + +³ A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. + +--- + +## 1.1.1 TVM values + +The entities that can be stored in the TVM stack will be called **TVM values**, or simply **values** for brevity. They belong to one of several predefined value types. Each value belongs to exactly one value type. The values are always kept on the stack along with tags uniquely determining their types, and all built-in TVM operations (or primitives) only accept values of predefined types. + +For example, the integer addition primitive `ADD` accepts only two integer values, and returns one integer value as a result. One cannot supply `ADD` with two strings instead of two integers expecting it to concatenate these strings or to implicitly transform the strings into their decimal integer values; any attempt to do so will result in a run-time type-checking exception. + +--- + +## 1.1.2 Static typing, dynamic typing, and run-time type checking + +In some respects TVM performs a kind of dynamic typing using run-time type checking. However, this does not make the TVM code a “dynamically typed language” like PHP or Javascript, because all primitives accept values and return results of predefined (value) types, each value belongs to strictly one type, and values are never implicitly converted from one type to another. + +If, on the other hand, one compares the TVM code to the conventional microprocessor machine code, one sees that the TVM mechanism of value tagging prevents, for example, using the address of a string as a number—or, potentially even more disastrously, using a number as the address of a string—thus eliminating the possibility of all sorts of bugs and security vulnerabilities related to invalid memory accesses, usually leading to memory corruption and segmentation faults. + +This property is highly desirable for a VM used to execute smart contracts in a blockchain. In this respect, TVM’s insistence on tagging all values with their appropriate types, instead of reinterpreting the bit sequence in a register depending on the needs of the operation it is used in, is just an additional run-time type-safety mechanism. + +An alternative would be to somehow analyze the smart-contract code for type correctness and type safety before allowing its execution in the VM, or even before allowing it to be uploaded into the blockchain as the code of a smart contract. Such a static analysis of code for a Turing-complete machine appears to be a time-consuming and non-trivial problem (likely to be equivalent to the stopping problem for Turing machines), something we would rather avoid in a blockchain smart-contract context. + +One should bear in mind that one always can implement compilers from statically typed high-level smart-contract languages into the TVM code (and we do expect that most smart contracts for TON will be written in such languages), just as one can compile statically typed languages into conventional machine code (e.g., x86 architecture). If the compiler works correctly, the resulting machine code will never generate any run-time type-checking exceptions. + +All type tags attached to values processed by TVM will always have expected values and may be safely ignored during the analysis of the resulting TVM code, apart from the fact that the run-time generation and verification of these type tags by TVM will slightly slow down the execution of the TVM code. + +--- + +## 1.1.3 Preliminary list of value types + +A preliminary list of value types supported by TVM is as follows: + +* **Integer** — Signed 257-bit integers, representing integer numbers in the range −2²⁵⁶ … 2²⁵⁶−1, as well as a special “not-a-number” value `NaN`. +* **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. \[1, 2.5.14]). +* **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. +* **Null** — A type with exactly one value ⊥, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. +* **Slice** — A TVM cell slice, or slice for short, is a contiguous “sub-cell” of an existing cell, containing some of its bits of data and some of its references. Essentially, a slice is a read-only view for a subcell of a cell. Slices are used for unpacking data previously stored (or serialized) in a cell or a tree of cells. +* **Builder** — A TVM cell builder, or builder for short, is an “incomplete” cell that supports fast operations of appending bitstrings and cell references at its end. Builders are used for packing (or serializing) data from the top of the stack into new cells (e.g., before transferring them to persistent storage). +* **Continuation** — A special value containing TVM code and execution context that can be invoked (executed) later. As such, it generalizes function addresses (i.e., function pointers and references), subroutine return addresses, instruction pointer addresses, exception handler addresses, closures, partial applications, anonymous functions, and so on. + +This list of value types is incomplete and may be extended in future revisions of TVM without breaking the old TVM code, due mostly to the fact that all originally defined primitives accept only values of types known to them and will fail (generate a type-checking exception) if invoked on values of new types. + +Furthermore, existing value types themselves can also be extended in the future: for example, 257-bit `Integer` might become 513-bit `LongInteger`, with originally defined arithmetic primitives failing if either of the arguments or the result does not fit into the original subtype `Integer`. + +Backward compatibility with respect to the introduction of new value types and extension of existing value types will be discussed in more detail later (cf. 5.1.4). + +--- + +## 1.2 Categories of TVM instructions + +TVM instructions, also called **primitives** and sometimes **(built-in) operations**, are the smallest operations atomically performed by TVM that can be present in the TVM code. They fall into several categories, depending on the types of values (cf. 1.1.3) they work on. The most important of these categories are: + +* **Stack (manipulation) primitives** — Rearrange data in the TVM stack, so that the other primitives and user-defined functions can later be called with correct arguments. Unlike most other primitives, they are polymorphic, i.e., work with values of arbitrary types. +* **Tuple (manipulation) primitives** — Construct, modify, and decompose Tuples. Similarly to the stack primitives, they are polymorphic. +* **Constant or literal primitives** — Push into the stack some “constant” or “literal” values embedded into the TVM code itself, thus providing arguments to the other primitives. They are somewhat similar to stack primitives, but are less generic because they work with values of specific types. +* **Arithmetic primitives** — Perform the usual integer arithmetic operations on values of type Integer. +* **Cell (manipulation) primitives** — Create new cells and store data in them (cell creation primitives) or read data from previously created cells (cell parsing primitives). Because all memory and persistent storage of TVM consists of cells, these cell manipulation primitives actually correspond to “memory access instructions” of other architectures. Cell creation primitives usually work with values of type Builder, while cell parsing primitives work with Slices. +* **Continuation and control flow primitives** — Create and modify Continuations, as well as execute existing Continuations in different ways, including conditional and repeated execution. +* **Custom or application-specific primitives** — Efficiently perform specific high-level actions required by the application (in our case, the TON Blockchain), such as computing hash functions, performing elliptic curve cryptography, sending new blockchain messages, creating new smart contracts, and so on. These primitives correspond to standard library functions rather than microprocessor instructions. + +--- + +## 1.3 Control registers + +While TVM is a stack machine, some rarely changed values needed in almost all functions are better passed in certain special registers, and not near the top of the stack. Otherwise, a prohibitive number of stack reordering operations would be required to manage all these values. + +To this end, the TVM model includes, apart from the stack, up to **16 special control registers**, denoted by `c0` to `c15`, or `c(0)` to `c(15)`. The original version of TVM makes use of only some of these registers; the rest may be supported later. + +--- + +### 1.3.1 Values kept in control registers + +The values kept in control registers are of the same types as those kept on the stack. However, some control registers accept only values of specific types, and any attempt to load a value of a different type will lead to an exception. + +--- + +### 1.3.2 List of control registers + +The original version of TVM defines and uses the following control registers: + +* **c0** — Contains the return continuation (similar to the subroutine return address in conventional designs). This value must be a Continuation. +* **c1** — Contains the alternative (return) continuation; this value must be a Continuation. It is used in some (experimental) control flow primitives, allowing TVM to define and call “subroutines with two exit points”. +* **c2** — Contains the exception handler. This value is a Continuation, invoked whenever an exception is triggered. +* **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in 4.6, this value is also a Continuation, not a Cell as one might expect. +* **c4** — Contains the root of persistent data, or simply the data. This value is a Cell. When the code of a smart contract is invoked, `c4` points to the root cell of its persistent data kept in the blockchain state. If the smart contract needs to modify this data, it changes `c4` before returning. +* **c5** — Contains the output actions. It is also a Cell initialized by a reference to an empty cell, but its final value is considered one of the smart contract outputs. For instance, the `SENDMSG` primitive, specific for the TON Blockchain, simply inserts the message into a list stored in the output actions. +* **c7** — Contains the root of temporary data. It is a Tuple, initialized by a reference to an empty Tuple before invoking the smart contract and discarded after its termination.⁴ + +⁴ In the TON Blockchain context, `c7` is initialized with a singleton Tuple, the only component of which is a Tuple containing blockchain-specific data. The smart contract is free to modify `c7` to store its temporary data provided the first component of this Tuple remains intact. + +More control registers may be defined in the future for specific TON Blockchain or high-level programming language purposes, if necessary. + +--- + +## 1.4 Total state of TVM (SCCCG) + +The total state of TVM consists of the following components: + +* **Stack** (cf. 1.1) — Contains zero or more values (cf. 1.1.1), each belonging to one of value types listed in 1.1.3. +* **Control registers `c0–c15`** — Contain some specific values as described in 1.3.2. (Only seven control registers are used in the current version.) +* **Current continuation `cc`** — Contains the current continuation (i.e., the code that would be normally executed after the current primitive is completed). This component is similar to the instruction pointer register (`ip`) in other architectures. +* **Current codepage `cp`** — A special signed 16-bit integer value that selects the way the next TVM opcode will be decoded. For example, future versions of TVM might use different codepages to add new opcodes while preserving backward compatibility. +* **Gas limits `gas`** — Contains four signed 64-bit integers: the current gas limit `gl`, the maximal gas limit `gm`, the remaining gas `gr`, and the gas credit `gc`. Always `0 ≤ gl ≤ gm`, `gc ≥ 0`, and `gr ≤ gl + gc`; `gc` is usually initialized by zero, `gr` is initialized by `gl + gc` and gradually decreases as the TVM runs. When `gr` becomes negative or if the final value of `gr` is less than `gc`, an out of gas exception is triggered. + +Notice that there is no “return stack” containing the return addresses of all previously called but unfinished functions. Instead, only control register `c0` is used. The reason for this will be explained later in 4.1.9. + +Also notice that there are no general-purpose registers, because TVM is a stack machine (cf. 1.1). So the above list, which can be summarized as “stack, control, continuation, codepage, and gas” (**SCCCG**), similarly to the classical SECD machine state (“stack, environment, control, dump”), is indeed the total state of TVM. + +Perfect — here’s the next part, keeping the **exact wording** but properly formatted into Markdown. + +--- + +## 1.5 Integer arithmetic + +All arithmetic primitives of TVM operate on several arguments of type **Integer**, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that Integer represents all integer values in the range `−2²⁵⁶ ≤ x < 2²⁵⁶`, and additionally contains a special value **NaN** (“not-a-number”). + +If one of the results does not fit into the supported range of integers—or if one of the arguments is a NaN—then this result or all of the results are replaced by a NaN, and (by default) an integer overflow exception is generated. However, special “quiet” versions of arithmetic operations will simply produce NaNs and keep going. If these NaNs end up being used in a “non-quiet” arithmetic operation, or in a non-arithmetic operation, an integer overflow exception will occur. + +--- + +### 1.5.1 Absence of automatic conversion of integers + +Notice that TVM Integers are “mathematical” integers, and not 257-bit strings interpreted differently depending on the primitive used, as is common for other machine code designs. For example, TVM has only one multiplication primitive `MUL`, rather than two (`MUL` for unsigned multiplication and `IMUL` for signed multiplication) as occurs, for example, in the popular x86 architecture. + +--- + +### 1.5.2 Automatic overflow checks + +Notice that all TVM arithmetic primitives perform overflow checks of the results. If a result does not fit into the Integer type, it is replaced by a NaN, and (usually) an exception occurs. In particular, the result is not automatically reduced modulo `2²⁵⁶` or `2²⁵⁷`, as is common for most hardware machine code architectures. + +--- + +### 1.5.3 Custom overflow checks + +In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. + +* `FITS n` checks whether the value on the top of the stack is an integer `x` in the range `−2ⁿ⁻¹ ≤ x < 2ⁿ⁻¹`. +* `UFITS n` checks whether the value is in the range `0 ≤ x < 2ⁿ`. + +If the value does not fit, it is replaced with a NaN and (optionally) an integer overflow exception is generated. + +This greatly simplifies the implementation of arbitrary `n`-bit integer types, signed or unsigned: the programmer or the compiler must insert appropriate `FITS` or `UFITS` primitives either after each arithmetic operation (which is more reasonable, but requires more checks) or before storing computed values and returning them from functions. This is important for smart contracts, where unexpected integer overflows happen to be among the most common source of bugs. + +--- + +### 1.5.4 Reduction modulo 2ⁿ + +TVM also has a primitive `MODPOW2 n`, which reduces the integer at the top of the stack modulo `2ⁿ`, with the result ranging from `0` to `2ⁿ − 1`. + +--- + +### 1.5.5 Integer is 257-bit, not 256-bit + +One can understand now why TVM’s Integer is (signed) 257-bit, not 256-bit. The reason is that it is the smallest integer type containing both signed 256-bit integers and unsigned 256-bit integers, which does not require automatic reinterpreting of the same 256-bit string depending on the operation used (cf. 1.5.1). + +--- + +### 1.5.6 Division and rounding + +The most important division primitives are `DIV`, `MOD`, and `DIVMOD`. All of them take two numbers from the stack, `x` and `y` (`y` is taken from the top of the stack, and `x` is originally under it), compute the quotient `q` and remainder `r` of the division of `x` by `y` (i.e., two integers such that `x = yq + r` and `|r| < |y|`), and return either `q`, `r`, or both of them. + +* If `y` is zero, then all of the expected results are replaced by NaNs, and (usually) an integer overflow exception is generated. +* By default, these primitives round to `−∞`, meaning that `q = ⌊x / y⌋`, and `r` has the same sign as `y`. (Most conventional implementations of division use “rounding to zero” instead, meaning that `r` has the same sign as `x`.) + +Apart from this **floor rounding**, two other rounding modes are available: + +* **Ceiling rounding**: `q = ⌈x / y⌉`, and `r` and `y` have opposite signs. +* **Nearest rounding**: `q = ⌊x / y + 1/2⌋` and `|r| ≤ |y| / 2`. + +These rounding modes are selected by using other division primitives, with letters `C` and `R` appended to their mnemonics. For example, `DIVMODR` computes both the quotient and the remainder using rounding to the nearest integer. + +--- + +### 1.5.7 Combined multiply-divide, multiply-shift, and shift-divide operations + +To simplify implementation of fixed-point arithmetic, TVM supports combined multiply-divide, multiply-shift, and shift-divide operations with double-length (i.e., 514-bit) intermediate product. + +For example, `MULDIVMODR` takes three integer arguments from the stack, `a`, `b`, and `c`, first computes `ab` using a 514-bit intermediate result, and then divides `ab` by `c` using rounding to the nearest integer. + +* If `c` is zero or if the quotient does not fit into Integer, either two NaNs are returned, or an integer overflow exception is generated, depending on whether a quiet version of the operation has been used. +* Otherwise, both the quotient and the remainder are pushed into the stack. + +--- + +# 2 The stack + +This chapter contains a general discussion and comparison of register and +stack machines, expanded further in Appendix C, and describes the two +main classes of stack manipulation primitives employed by TVM: the basic +and the compound stack manipulation primitives. An informal explanation of +their sufficiency for all stack reordering required for correctly invoking other +primitives and user-defined functions is also provided. Finally, the problem +of efficiently implementing TVM stack manipulation primitives is discussed +in 2.3. + +## 2.1 Stack calling conventions + +A stack machine, such as TVM, uses the stack—and especially the values +near the top of the stack—to pass arguments to called functions and primitives (such as built-in arithmetic operations) and receive their results. This +section discusses the TVM stack calling conventions, introduces some notation, and compares TVM stack calling conventions with those of certain +register machines. + +### 2.1.1. Notation for “stack registers”. + +Recall that a stack machine, as +opposed to a more conventional register machine, lacks general-purpose registers. However, one can treat the values near the top of the stack as a kind +of “stack registers”. +We denote by s0 or s(0) the value at the top of the stack, by s1 or s(1) +the value immediately under it, and so on. The total number of values in the +stack is called its depth. If the depth of the stack is n, then s(0), s(1), . . . , +s(n − 1) are well-defined, while s(n) and all subsequent s(i) with i > n are +not. Any attempt to use s(i) with i ≥ n should produce a stack underflow +exception. +A compiler, or a human programmer in “TVM code”, would use these +“stack registers” to hold all declared variables and intermediate values, similarly to the way general-purpose registers are used on a register machine. + +### 2.1.2. Pushing and popping values. + +When a value x is pushed into a +stack of depth n, it becomes the new s0; at the same time, the old s0 becomes +the new s1, the old s1—the new s2, and so on. The depth of the resulting +stack is n + 1. +Similarly, when a value x is popped from a stack of depth n ≥ 1, it is the +old value of s0 (i.e., the old value at the top of the stack). After this, it is +removed from the stack, and the old s1 becomes the new s0 (the new value +at the top of the stack), the old s2 becomes the new s1, and so on. The +depth of the resulting stack is n − 1. +If originally n = 0, then the stack is empty, and a value cannot be popped +from it. If a primitive attempts to pop a value from an empty stack, a stack +underflow exception occurs. + +### 2.1.3. Notation for hypothetical general-purpose registers. + +In order +to compare stack machines with sufficiently general register machines, we will +denote the general-purpose registers of a register machine by r0, r1, and so +on, or by r(0), r(1), . . . , r(n − 1), where n is the total number of registers. +When we need a specific value of n, we will use n = 16, corresponding to the +very popular x86-64 architecture. + +### 2.1.4. The top-of-stack register s0 vs. the accumulator register r0. + +Some register machine architectures require one of the arguments for most +arithmetic and logical operations to reside in a special register called the +accumulator. In our comparison, we will assume that the accumulator is +the general-purpose register r0; otherwise we could simply renumber the +registers. In this respect, the accumulator is somewhat similar to the top-ofstack “register” s0 of a stack machine, because virtually all operations of a +stack machine both use s0 as one of their arguments and return their result +as s0. + +### 2.1.5. Register calling conventions. + +When compiled for a register machine, high-level language functions usually receive their arguments in certain +registers in a predefined order. If there are too many arguments, these functions take the remainder from the stack (yes, a register machine usually has +a stack, too!). Some register calling conventions pass no arguments in registers at all, however, and only use the stack (for example, the original calling +conventions used in implementations of Pascal and C, although modern implementations of C use some registers as well). +For simplicity, we will assume that up to m ≤ n function arguments are +passed in registers, and that these registers are r0, r1, . . . , r(m − 1), in that +order (if some other registers are used, we can simply renumber them).6 +6Our inclusion of r0 here creates a minor conflict with our assumption that the ac + +### 2.1.6. Order of function arguments. + +If a function or primitive requires +m arguments x1, . . . , xm, they are pushed by the caller into the stack in the +same order, starting from x1. Therefore, when the function or primitive is +invoked, its first argument x1 is in s(m − 1), its second argument x2 is in +s(m − 2), and so on. The last argument xm is in s0 (i.e., at the top of the +stack). It is the called function or primitive’s responsibility to remove its +arguments from the stack. +In this respect the TVM stack calling conventions—obeyed, at least, by +TMV primitives—match those of Pascal and Forth, and are the opposite of +those of C (in which the arguments are pushed into the stack in the reverse +order, and are removed by the caller after it regains control, not the callee). +Of course, an implementation of a high-level language for TVM might +choose some other calling conventions for its functions, different from the +default ones. This might be useful for certain functions—for instance, if the +total number of arguments depends on the value of the first argument, as +happens for “variadic functions” such as scanf and printf. In such cases, +the first one or several arguments are better passed near the top of the stack, +not somewhere at some unknown location deep in the stack. + +### 2.1.7. Arguments to arithmetic primitives on register machines. + +On a stack machine, built-in arithmetic primitives (such as ADD or DIVMOD) +follow the same calling conventions as user-defined functions. In this respect, +user-defined functions (for example, a function computing the square root of +a number) might be considered as “extensions” or “custom upgrades” of the +stack machine. This is one of the clearest advantages of stack machines +(and of stack programming languages such as Forth) compared to register +machines. + +In contrast, arithmetic instructions (built-in operations) on register machines usually get their parameters from general-purpose registers encoded +in the full opcode. A binary operation, such as SUB, thus requires two arguments, r(i) and r(j), with i and j specified by the instruction. A register +r(k) for storing the result also must be specified. Arithmetic operations can +take several possible forms, depending on whether i, j, and k are allowed to +take arbitrary values: + +* Three-address form — Allows the programmer to arbitrarily choose + not only the two source registers r(i) and r(j), but also a separate + destination register r(k). This form is common for most RISC processors, and for the XMM and AVX SIMD instruction sets in the x86-64 + architecture. +* Two-address form — Uses one of the two operand registers (usually + r(i)) to store the result of an operation, so that k = i is never indicated + explicitly. Only i and j are encoded inside the instruction. This is the + most common form of arithmetic operations on register machines, and + is quite popular on microprocessors (including the x86 family). +* One-address form — Always takes one of the arguments from the accumulator r0, and stores the result in r0 as well; then i = k = 0, and + only j needs to be specified by the instruction. This form is used by + some simpler microprocessors (such as Intel 8080). + +Note that this flexibility is available only for built-in operations, but not for user-defined functions. In this respect, register machines are not as easily “upgradable” as stack machines.7 + +Got it ✅ — you want all the inline code-like things (mnemonics, variables, stack notation, etc.) properly wrapped in backticks (`` ` ``) for Markdown. I’ll take the exact text from Chapter 2 (as we’ve been doing), but ensure things like `s0`, `s(i)`, `XCHG`, `PUSH`, `DIV`, etc. are in backticks so they render as code. + +Here’s the **cleaned version with backticks applied** (continuing from §2.1.8 to the end of Chapter 2): + +--- + +### 2.1.8. Return values of functions. + +In stack machines such as TVM, +when a function or primitive needs to return a result value, it simply pushes +it into the stack (from which all arguments to the function have already been +removed). Therefore, the caller will be able to access the result value through +the top-of-stack “register” `s0`. +This is in complete accordance with Forth calling conventions, but differs slightly from Pascal and C calling conventions, where the accumulator +register `r0` is normally used for the return value. + +### 2.1.9. Returning several values. + +Some functions might want to return +several values `y1, . . . , yk`, with `k` not necessarily equal to one. In these cases, +the `k` return values are pushed into the stack in their natural order, starting +from `y1`. +For example, the “divide with remainder” primitive `DIVMOD` needs to return two values, the quotient `q` and the remainder `r`. Therefore, `DIVMOD` +pushes `q` and `r` into the stack, in that order, so that the quotient is available +thereafter at `s1` and the remainder at `s0`. The net effect of `DIVMOD` is to +divide the original value of `s1` by the original value of `s0`, and return the +quotient in `s1` and the remainder in `s0`. In this particular case the depth +of the stack and the values of all other “stack registers” remain unchanged, +because `DIVMOD` takes two arguments and returns two results. In general, the +values of other “stack registers” that lie in the stack below the arguments +passed and the values returned are shifted according to the change of the +depth of the stack. +In principle, some primitives and user-defined functions might return a +variable number of result values. In this respect, the remarks above about +variadic functions (cf. 2.1.6) apply: the total number of result values and +their types should be determined by the values near the top of the stack. +(For example, one might push the return values `y1, . . . , yk`, and then push +their total number `k` as an integer. The caller would then determine the total +number of returned values by inspecting `s0`.) +In this respect TVM, again, faithfully observes Forth calling conventions. + +### 2.1.10. Stack notation. + +When a stack of depth `n` contains values `z1, . . . , +zn`, in that order, with `z1` the deepest element and `zn` the top of the stack, +the contents of the stack are often represented by a list `z1 z2 . . . zn`, in that +order. When a primitive transforms the original stack state `S0` +into a new +state `S00`, this is often written as `S0 – S00`; this is the so-called stack notation. +For example, the action of the division primitive `DIV` can be described by +`S x y – S ⌊x/y⌋`, where `S` is any list of values. This is usually abbreviated as +`x y – ⌊x/y⌋`, tacitly assuming that all other values deeper in the stack remain +intact. +Alternatively, one can describe `DIV` as a primitive that runs on a stack `S0` +of depth `n ≥ 2`, divides `s1` by `s0`, and returns the floor-rounded quotient as +`s0` of the new stack `S00` of depth `n − 1`. The new value of `s(i)` equals the old +value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but +saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `. . . x y` into `. . . ⌊x/y⌋`, is more +concise. +The stack notation is extensively used throughout Appendix A, where all +currently defined TVM primitives are listed. + +### 2.1.11. Explicitly defining the number of arguments to a function. + +Stack machines usually pass the current stack in its entirety to the invoked +primitive or function. That primitive or function accesses only the several +values near the top of the stack that represent its arguments, and pushes the +return values in their place, by convention leaving all deeper values intact. +Then the resulting stack, again in its entirety, is returned to the caller. +Most TVM primitives behave in this way, and we expect most user-defined +functions to be implemented under such conventions. However, TVM provides mechanisms to specify how many arguments must be passed to a called +function (cf. 4.1.10). When these mechanisms are employed, the specified +number of values are moved from the caller’s stack into the (usually initially +empty) stack of the called function, while deeper values remain in the caller’s +stack and are inaccessible to the callee. The caller can also specify how many +return values it expects from the called function. +Such argument-checking mechanisms might be useful, for example, for a +library function that calls user-provided functions passed as arguments to it. + +--- + +## 2.2 Stack manipulation primitives + +A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, +so that they become located near the top of the stack in correct order. This +section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some +examples of code using these primitives can be found in Appendix C. + +### 2.2.1. Basic stack manipulation primitives. + +The most important stack +manipulation primitives used by TVM are the following: + +* Top-of-stack exchange operation: `XCHG s0,s(i)` or `XCHG s(i)` — Exchanges values of `s0` and `s(i)`. When `i = 1`, operation `XCHG s1` is + traditionally denoted by `SWAP`. When `i = 0`, this is a `NOP` (an operation + that does nothing, at least if the stack is non-empty). + +* Arbitrary exchange operation: `XCHG s(i),s(j)` — Exchanges values of + `s(i)` and `s(j)`. Notice that this operation is not strictly necessary, because it can be simulated by three top-of-stack exchanges: + `XCHG s(i); XCHG s(j); XCHG s(i)`. However, it is useful to have arbitrary exchanges + as primitives, because they are required quite often. + +* Push operation: `PUSH s(i)` — Pushes a copy of the (old) value of `s(i)` + into the stack. Traditionally, `PUSH s0` is also denoted by `DUP` (it duplicates the value at the top of the stack), and `PUSH s1` by `OVER`. + +* Pop operation: `POP s(i)` — Removes the top-of-stack value and puts it + into the (new) `s(i − 1)`, or the old `s(i)`. Traditionally, `POP s0` is also + denoted by `DROP` (it simply drops the top-of-stack value), and `POP s1` + by `NIP`. + +Some other “unsystematic” stack manipulation operations might be also +defined (e.g., `ROT`, with stack notation `a b c – b c a`). While such operations are defined in stack languages like Forth (where `DUP`, `DROP`, `OVER`, `NIP` +and `SWAP` are also present), they are not strictly necessary because the basic +stack manipulation primitives listed above suffice to rearrange stack registers +to allow any arithmetic primitives and user-defined functions to be invoked +correctly. + +Perfect 👍 — let’s continue from **§2.2.2** through the end of Chapter 2, with all mnemonics, variables, and stack notation in backticks for Markdown. + +--- + +### 2.2.2. Basic stack manipulation primitives suffice. + +A compiler or a +human TVM-code programmer might use the basic stack primitives as follows. +Suppose that the function or primitive to be invoked is to be passed, say, +three arguments `x`, `y`, and `z`, currently located in stack registers `s(i)`, `s(j)`, +and `s(k)`. In this circumstance, the compiler (or programmer) might issue +operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) +or `XCHG s(i)` (if it will not be needed afterwards) to put the first argument +`x` into the top of the stack. Then, the compiler (or programmer) could use +either `PUSH s(j0)` or `XCHG s(j0)`, where `j0 = j` or `j + 1`, to put `y` into the new +top of the stack. + +Proceeding in this manner, we see that we can put the original values of +`x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using +a sequence of push and exchange operations (cf. 2.2.4 and 2.2.5 for a more +detailed explanation). In order to generate this sequence, the compiler will +need to know only the three values `i`, `j` and `k`, describing the old locations of +variables or temporary values in question, and some flags describing whether +each value will be needed thereafter or is needed only for this primitive or +function call. The locations of other variables and temporary values will be +affected in the process, but a compiler (or a human programmer) can easily +track their new locations. + +Similarly, if the results returned from a function need to be discarded +or moved to other stack registers, a suitable sequence of exchange and pop +operations will do the job. In the typical case of one return value in `s0`, +this is achieved either by an `XCHG s(i)` or a `POP s(i)` (in most cases, a `DROP`) +operation. + +Rearranging the result value or values before returning from a function is +essentially the same problem as arranging arguments for a function call, and +is achieved similarly. + +### 2.2.3. Compound stack manipulation primitives. + +In order to improve +the density of the TVM code and simplify development of compilers, compound stack manipulation primitives may be defined, each combining up to +four exchange and push or exchange and pop basic primitives. Such compound stack operations might include, for example: + +* `XCHG2 s(i),s(j)` — Equivalent to `XCHG s1,s(i); XCHG s(j)`. +* `PUSH2 s(i),s(j)` — Equivalent to `PUSH s(i); PUSH s(j + 1)`. +* `XCPU s(i),s(j)` — Equivalent to `XCHG s(i); PUSH s(j)`. +* `PUXC s(i),s(j)` — Equivalent to `PUSH s(i); SWAP; XCHG s(j+1)`. When + `j ≠ i` and `j ≠ 0`, it is also equivalent to `XCHG s(j); PUSH s(i); SWAP`. +* `XCHG3 s(i),s(j),s(k)` — Equivalent to `XCHG s2,s(i); XCHG s1,s(j); + XCHG s(k)`. +* `PUSH3 s(i),s(j),s(k)` — Equivalent to `PUSH s(i); PUSH s(j + 1); PUSH + s(k + 2)`. + +Of course, such operations make sense only if they admit a more compact +encoding than the equivalent sequence of basic operations. For example, +if all top-of-stack exchanges, `XCHG s1,s(i)` exchanges, and push and pop +operations admit one-byte encodings, the only compound stack operations +suggested above that might merit inclusion in the set of stack manipulation +primitives are `PUXC`, `XCHG3`, and `PUSH3`. + +Notice that the most common `XCHG s(i)` operation is not really required here if we +do not insist on keeping the same temporary value or variable always in the same stack +location, but rather keep track of its subsequent locations. We will move it to some other +location while preparing the arguments to the next primitive or function call. + +### 2.2.4. Mnemonics of compound stack operations. + +The mnemonics +of compound stack operations, some examples of which have been provided +in 2.2.3, are created as follows. +The `γ ≥ 2` formal arguments `s(i1), . . . , s(iγ)` to such an operation `O` +represent the values in the original stack that will end up in `s(γ − 1), . . . , +s0` after the execution of this compound operation, at least if all `iν, 1 ≤ +ν ≤ γ`, are distinct and at least γ. The mnemonic itself of the operation +`O` is a sequence of γ two-letter strings `PU` and `XC`, with `PU` meaning that +the corresponding argument is to be PUshed (i.e., a copy is to be created), +and `XC` meaning that the value is to be eXChanged (i.e., no other copy of +the original value is created). Sequences of several `PU` or `XC` strings may be +abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, +we write `PUXC2PU` instead of `PUXCXCPU`.) +As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, +so that the compound operation is equivalent to a sequence of `m` `PUSH`es or +`XCHG`s, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. + +### 2.2.5. Semantics of compound stack operations. + +Each compound `γ`- +ary operation `O s(i1),. . . ,s(iγ)` is translated into an equivalent sequence of +basic stack operations by induction in `γ` as follows: + +* As a base of induction, if `γ = 0`, the only nullary compound stack + operation corresponds to an empty sequence of basic stack operations. +* Equivalently, we might begin the induction from `γ = 1`. Then `PU s(i)` + corresponds to the sequence consisting of one basic operation `PUSH + s(i)`, and `XC s(i)` corresponds to the one-element sequence consisting + of `XCHG s(i)`. +* For `γ ≥ 1` (or for `γ ≥ 2`, if we use `γ = 1` as induction base), there are + two subcases: + + 1. `O s(i1), . . . , s(iγ)`, with `O = XCO0`, where `O0` + is a compound operation of arity `γ−1` (i.e., the mnemonic of `O0` + consists of `γ−1` strings + `XC` and `PU`). Let `α` be the total quantity of PUshes in `O`, and `β` be + that of eXChanges, so that `α+β = γ`. Then the original operation + is translated into `XCHG s(β −1),s(i1)`, followed by the translation + of `O0 s(i2), . . . , s(iγ)`, defined by the induction hypothesis. + + 2. `O s(i1), . . . , s(iγ)`, with `O = PUO0`, + where `O0` + is a compound operation of arity `γ − 1`. Then the original operation is translated into + `PUSH s(i1); XCHG s(β)`, followed by the translation of + `O0 s(i2 + 1), . . . , s(iγ + 1)`, defined by the induction hypothesis. + +An alternative, arguably better, translation of +`PUO0 s(i1), . . . , s(iγ)` consists of the +translation of `O0 s(i2), . . . , s(iγ)`, followed by +`PUSH s(i1 + α − 1); XCHG s(γ − 1)`. + +### 2.2.6. Stack manipulation instructions are polymorphic. + +Notice that +the stack manipulation instructions are almost the only “polymorphic” primitives in TVM—i.e., they work with values of arbitrary types (including the +value types that will appear only in future revisions of TVM). For example, `SWAP` always interchanges the two top values of the stack, even if one of +them is an integer and the other is a cell. Almost all other instructions, especially the data processing instructions (including arithmetic instructions), +require each of their arguments to be of some fixed type (possibly different +for different arguments). + +--- + +## 2.3 Efficiency of stack manipulation primitives + +Stack manipulation primitives employed by a stack machine, such as TVM, +have to be implemented very efficiently, because they constitute more than +half of all the instructions used in a typical program. In fact, TVM performs +all these instructions in a (small) constant time, regardless of the values +involved (even if they represent very large integers or very large trees of +cells). + +### 2.3.1. Implementation of stack manipulation primitives: using references for operations instead of objects. + +The efficiency of TVM’s +implementation of stack manipulation primitives results from the fact that a +typical TVM implementation keeps in the stack not the value objects themselves, but only the references (pointers) to such objects. Therefore, a `SWAP` +instruction only needs to interchange the references at `s0` and `s1`, not the +actual objects they refer to. + +### 2.3.2. Efficient implementation of DUP and PUSH instructions using copy-on-write. + +Furthermore, a `DUP` (or, more generally, `PUSH s(i)`) instruction, which appears to make a copy of a potentially large object, also works +in small constant time, because it uses a copy-on-write technique of delayed +copying: it copies only the reference instead of the object itself, but increases +the “reference counter” inside the object, thus sharing the object between the +two references. If an attempt to modify an object with a reference counter +greater than one is detected, a separate copy of the object in question is made +first (incurring a certain “non-uniqueness penalty” or “copying penalty” for +the data manipulation instruction that triggered the creation of a new copy). + +### 2.3.3. Garbage collecting and reference counting. + +When the reference counter of a TVM object becomes zero (for example, because the last +reference to such an object has been consumed by a `DROP` operation or an +arithmetic instruction), it is immediately freed. Because cyclic references +are impossible in TVM data structures, this method of reference counting +provides a fast and convenient way of freeing unused objects, replacing slow +and unpredictable garbage collectors. + +### 2.3.4. Transparency of the implementation: Stack values are “values”, not “references”. + +Regardless of the implementation details just discussed, all stack values are really “values”, not “references”, from the perspective of the TVM programmer, similarly to the values of all types in functional +programming languages. Any attempt to modify an existing object referred +to from any other objects or stack locations will result in a transparent replacement of this object by its perfect copy before the modification is actually +performed. +In other words, the programmer should always act as if the objects themselves were directly manipulated by stack, arithmetic, and other data transformation primitives, and treat the previous discussion only as an explanation +of the high efficiency of the stack manipulation primitives. + +### 2.3.5. Absence of circular references. + +One might attempt to create a +circular reference between two cells, `A` and `B`, as follows: first create `A` and +write some data into it; then create `B` and write some data into it, along +with a reference to previously constructed cell `A`; finally, add a reference to +`B` into `A`. While it may seem that after this sequence of operations we obtain +a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. +In fact, we obtain a new cell `A0`, which contains a copy of the data originally +stored into cell `A` along with a reference to cell `B`, which contains a reference +to (the original) cell `A`. +In this way the transparent copy-on-write mechanism and the “everything +is a value” paradigm enable us to create new cells using only previously +constructed cells, thus forbidding the appearance of circular references. This +property also applies to all other data structures: for instance, the absence +of circular references enables TVM to use reference counting to immediately +free unused memory instead of relying on garbage collectors. Similarly, this +property is crucial for storing data in the TON Blockchain. + +Great — here’s **Chapter 3 (Cells, memory, and persistent storage)** reformatted to Markdown with all mnemonics, variables, and notation in backticks. + +--- + +# 3 Cells, memory, and persistent storage + +This chapter briefly describes TVM cells, used to represent all data structures +inside the TVM memory and its persistent storage, and the basic operations +used to create cells, write (or serialize) data into them, and read (or deserialize) data from them. + +## 3.1 Generalities on cells + +### 3.1.1. TVM memory and persistent storage consist of cells. + +Recall +that the TVM memory and persistent storage consist of (TVM) cells. Each +cell contains up to `1023` bits of data and up to four references to other cells. +Circular references are forbidden and cannot be created by means of TVM +(cf. 2.3.5). In this way, all cells kept in TVM memory and persistent storage +constitute a directed acyclic graph (DAG). + +### 3.1.2. Ordinary and exotic cells. + +Apart from the data and references, +a cell has a cell type, encoded by an integer `−1 ... 255`. A cell of type `−1` +is called ordinary; such cells do not require any special processing. Cells of +other types are called exotic, and may be loaded—automatically replaced by +other cells when an attempt to deserialize them (i.e., to convert them into +a `Slice` by a `CTOS` instruction) is made. They may also exhibit a non-trivial +behavior when their hashes are computed. + +The most common use for exotic cells is to represent some other cells—for +instance, cells present in an external library, or pruned from the original tree +of cells when a Merkle proof has been created. + +The type of an exotic cell is stored as the first eight bits of its data. If an +exotic cell has less than eight data bits, it is invalid. + +### 3.1.3. The level of a cell. + +Every cell `c` has another attribute `Lvl(c)` called +its (de Brujn) level, which currently takes integer values in the range `0...3`. +The level of an ordinary cell is always equal to the maximum of the levels of +all its children `ci`: + +``` +Lvl(c) = max ( Lvl(ci) ) for 1 ≤ i ≤ r +``` + +for an ordinary cell `c` containing `r` references to cells `c1, ..., cr`. +If `r = 0`, then `Lvl(c) = 0`. Exotic cells may have different rules for setting their level. + +A cell’s level affects the number of higher hashes it has. More precisely, +a level `l` cell has `l` higher hashes `Hash1(c), ..., Hashl(c)` in addition to its +representation hash `Hash(c) = Hash∞(c)`. Cells of non-zero level appear +inside Merkle proofs and Merkle updates, after some branches of the tree of +cells representing a value of an abstract data type are pruned. + +### 3.1.4. Standard cell representation. + +When a cell needs to be transferred +by a network protocol or stored in a disk file, it must be serialized. +The standard representation `CellRepr(c) = CellRepr∞(c)` of a cell `c` as an +octet (byte) sequence is constructed as follows: + +1. Two descriptor bytes `d1` and `d2` are serialized first. + + * `d1 = r + 8s + 32l`, where `0 ≤ r ≤ 4` is the number of cell references contained + in the cell, `0 ≤ l ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is `1` for + exotic cells and `0` for ordinary cells. + * `d2 = ⌊b/8⌋ + ⌈b/8⌉`, where `0 ≤ b ≤ 1023` is the number of data bits in `c`. + +2. Then the data bits are serialized as `⌈b/8⌉` 8-bit octets (bytes). + If `b` is not a multiple of eight, a binary `1` and up to six binary `0`s are appended to + the data bits. After that, the data is split into `⌈b/8⌉` eight-bit groups, + and each group is interpreted as an unsigned big-endian integer `0...255` + and stored into an octet. + +3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(ci)` of the cell `ci` referred to. + +In this way, `2 + ⌈b/8⌉ + 32r` bytes of `CellRepr(c)` are obtained. + +### 3.1.5. The representation hash of a cell. + +The 256-bit representation +hash or simply hash `Hash(c)` of a cell `c` is recursively defined as the `sha256` +of the standard representation of the cell `c`: + +``` +Hash(c) := sha256(CellRepr(c)) +``` + +Notice that cyclic cell references are not allowed and cannot be created by +means of the TVM (cf. 2.3.5), so this recursion always ends, and the representation hash of any cell is well-defined. + +### 3.1.6. The higher hashes of a cell. + +Recall that a cell `c` of level `l` has `l` +higher hashes `Hashi(c)`, `1 ≤ i ≤ l`. Exotic cells have their own rules +for computing their higher hashes. Higher hashes `Hashi(c)` of an ordinary +cell `c` are computed similarly to its representation hash, but using the higher +hashes `Hashi(cj)` of its children `cj` instead of their representation hashes +`Hash(cj)`. By convention, we set `Hash∞(c) := Hash(c)`, and `Hashi(c) := Hash(c)` +for all `i > l`. + +Perfect — here’s the continuation of **Chapter 3**, keeping **all text exactly the same** but fully in Markdown, with mnemonics, variables, and formulas wrapped in backticks: + +--- + +### 3.1.7. Types of exotic cells. + +TVM currently supports the following cell +types: + +* **Type −1: Ordinary cell** — Contains up to `1023` bits of data and up to + four cell references. +* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ l ≤ 3`. It + contains exactly `8 + 256l` data bits: first an 8-bit integer equal to `1` + (representing the cell’s type), then its `l` higher hashes `Hash1(c), ..., + Hashl(c)`. The level `l` of a pruned branch cell may be called its *de + Brujn index*, because it determines the outer Merkle proof or Merkle + update during the construction of which the branch has been pruned. + An attempt to load a pruned branch cell usually leads to an exception. +* **Type 2: Library reference cell** — Always has level `0`, and contains `8+256` + data bits, including its 8-bit type integer `2` and the representation hash + `Hash(c0)` of the library cell being referred to. When loaded, a library + reference cell may be transparently replaced by the cell it refers to, if + found in the current library context. +* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c1` and level + `0 ≤ l ≤ 3`, which must be one less than the level of its only child `c1`: + + ``` + Lvl(c) = max(Lvl(c1) − 1, 0) + ``` + + The `8 + 256` data bits of a Merkle proof cell contain its 8-bit type + integer `3`, followed by `Hash1(c1)` (assumed to be equal to `Hash(c1)` if + `Lvl(c1) = 0`). The higher hashes `Hashi(c)` of `c` are computed similarly + to the higher hashes of an ordinary cell, but with `Hashi+1(c1)` used + instead of `Hashi(c1)`. When loaded, a Merkle proof cell is replaced by + `c1`. +* **Type 4: Merkle update cell `c`** — Has two children `c1` and `c2`. Its level + `0 ≤ l ≤ 3` is given by: + + ``` + Lvl(c) = max(Lvl(c1) − 1, Lvl(c2) − 1, 0) + ``` + + A Merkle update behaves like a Merkle proof for both `c1` and `c2`, and + contains `8 + 256 + 256` data bits with `Hash1(c1)` and `Hash1(c2)`. + However, an extra requirement is that all pruned branch cells `c0` that are + descendants of `c2` and are bound by `c` must also be descendants of `c1`. + When a Merkle update cell is loaded, it is replaced by `c2`. + +--- + +### 3.1.8. All values of algebraic data types are trees of cells. + +Arbitrary +values of arbitrary algebraic data types (e.g., all types used in functional +programming languages) can be serialized into trees of cells (of level `0`), and +such representations are used for representing such values within TVM. + +The copy-on-write mechanism (cf. 2.3.2) allows TVM to identify cells containing +the same data and references, and to keep only one copy of such cells. This +actually transforms a tree of cells into a directed acyclic graph (with the +additional property that all its vertices be accessible from a marked vertex +called the “root”). However, this is a storage optimization rather than an +essential property of TVM. From the perspective of a TVM code programmer, +one should think of TVM data structures as trees of cells. + +--- + +### 3.1.9. TVM code is a tree of cells. + +The TVM code itself is also represented by a tree of cells. Indeed, TVM code is simply a value of some +complex algebraic data type, and as such, it can be serialized into a tree of +cells. + +The exact way in which the TVM code (e.g., TVM assembly code) is +transformed into a tree of cells is explained later (cf. 4.1.4 and 5.2), in sections discussing control flow instructions, continuations, and TVM instruction encoding. + +--- + +### 3.1.10. “Everything is a bag of cells” paradigm. + +As described in `[1, +2.5.14]`, all the data used by the TON Blockchain, including the blocks +themselves and the blockchain state, can be represented—and are represented—as +collections, or “bags”, of cells. + +We see that TVM’s structure of data (cf. 3.1.8) +and code (cf. 3.1.9) nicely fits into this “everything is a bag of cells” paradigm. +In this way, TVM can naturally be used to execute smart contracts in the +TON Blockchain, and the TON Blockchain can be used to store the code +and persistent data of these smart contracts between invocations of TVM. + +(Of course, both TVM and the TON Blockchain have been designed so that +this would become possible.) +Got it — here’s the continuation with **3.2 Data manipulation instructions and cells** in proper Markdown, keeping **all text exactly the same** but formatted (mnemonics, values, variables in backticks): + +--- + +## 3.2 Data manipulation instructions and cells + +The next large group of TVM instructions consists of data manipulation +instructions, also known as cell manipulation instructions or simply cell +instructions. They correspond to memory access instructions of other architectures. + +--- + +### 3.2.1. Classes of cell manipulation instructions. + +The TVM cell instructions are naturally subdivided into two principal classes: + +* **Cell creation instructions** or **serialization instructions**, used to construct new cells from values previously kept in the stack and previously + constructed cells. +* **Cell parsing instructions** or **deserialization instructions**, used to extract + data previously stored into cells by cell creation instructions. + +Additionally, there are exotic cell instructions used to create and inspect +exotic cells (cf. 3.1.2), which in particular are used to represent pruned +branches of Merkle proofs and Merkle proofs themselves. + +--- + +### 3.2.2. Builder and Slice values. + +Cell creation instructions usually work +with `Builder` values, which can be kept only in the stack (cf. 1.1.3). Such +values represent partially constructed cells, for which fast operations for appending bitstrings, integers, other cells, and references to other cells can be +defined. Similarly, cell parsing instructions make heavy use of `Slice` values, +which represent either the remainder of a partially parsed cell, or a value +(subcell) residing inside such a cell and extracted from it by a parsing instruction. + +--- + +### 3.2.3. Builder and Slice values exist only as stack values. + +Notice that +`Builder` and `Slice` objects appear only as values in a TVM stack. They cannot +be stored in “memory” (i.e., trees of cells) or “persistent storage” (which is +also a bag of cells). In this sense, there are far more `Cell` objects than `Builder` +or `Slice` objects in a TVM environment, but, somewhat paradoxically, a TVM +program sees `Builder` and `Slice` objects in its stack more often than `Cell`s. + +In fact, a TVM program does not have much use for `Cell` values, because they +are immutable and opaque; all cell manipulation primitives require that a +`Cell` value be transformed into either a `Builder` or a `Slice` first, before it can +be modified or inspected. + +--- + +### 3.2.4. TVM has no separate Bitstring value type. + +Notice that TVM +offers no separate bitstring value type. Instead, bitstrings are represented by +`Slice`s that happen to have no references at all, but can still contain up to +`1023` data bits. + +--- + +### 3.2.5. Cells and cell primitives are bit-oriented, not byte-oriented. + +An important point is that TVM regards data kept in cells as sequences +(strings, streams) of (up to `1023`) bits, not of bytes. In other words, TVM +is a bit-oriented machine, not a byte-oriented machine. If necessary, an +application is free to use, say, `21`-bit integer fields inside records serialized into +TVM cells, thus using fewer persistent storage bytes to represent the same +data. + +--- + +### 3.2.6. Taxonomy of cell creation (serialization) primitives. + +Cell creation primitives usually accept a `Builder` argument and an argument representing the value to be serialized. Additional arguments controlling some +aspects of the serialization process (e.g., how many bits should be used for +serialization) can be also provided, either in the stack or as an immediate +value inside the instruction. + +The result of a cell creation primitive is usually +another `Builder`, representing the concatenation of the original builder and +the serialization of the value provided. + +Therefore, one can suggest a classification of cell serialization primitives +according to the answers to the following questions: + +* Which is the type of values being serialized? +* How many bits are used for serialization? If this is a variable number, + does it come from the stack, or from the instruction itself? +* What happens if the value does not fit into the prescribed number of + bits? Is an exception generated, or is a success flag equal to zero silently + returned in the top of stack? +* What happens if there is insufficient space left in the `Builder`? Is an + exception generated, or is a zero success flag returned along with the + unmodified original `Builder`? + +The mnemonics of cell serialization primitives usually begin with `ST`. Subsequent letters describe the following attributes: + +* The type of values being serialized and the serialization format (e.g., `I` + for signed integers, `U` for unsigned integers). +* The source of the field width in bits to be used (e.g., `X` for integer + serialization instructions means that the bit width `n` is supplied in + the stack; otherwise it has to be embedded into the instruction as an + immediate value). +* The action to be performed if the operation cannot be completed (by + default, an exception is generated; “quiet” versions of serialization instructions are marked by a `Q` letter in their mnemonics). + +This classification scheme is used to create a more complete taxonomy of cell +serialization primitives, which can be found in **A.7.1**. + +--- + +### 3.2.7. Integer serialization primitives. + +Integer serialization primitives +can be classified according to the above taxonomy as well. For example: + +* There are signed and unsigned (big-endian) integer serialization primitives. +* The size `n` of the bit field to be used (`1 ≤ n ≤ 257` for signed integers, + `0 ≤ n ≤ 256` for unsigned integers) can either come from the top of + stack or be embedded into the instruction itself. +* If the integer `x` to be serialized is not in the range `−2^(n−1) ≤ x < 2^(n−1)` + (for signed integer serialization) or `0 ≤ x < 2^n` (for unsigned integer + serialization), a range check exception is usually generated, and if `n` bits + cannot be stored into the provided `Builder`, a cell overflow exception is + generated. +* Quiet versions of serialization instructions do not throw exceptions; + instead, they push `-1` on top of the resulting `Builder` upon success, or + return the original `Builder` with `0` on top of it to indicate failure. + +Integer serialization instructions have mnemonics like `STU 20` (“store an +unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of +variable length provided in the stack”). + +The full list of these instructions— +including their mnemonics, descriptions, and opcodes—is provided in **A.7.1**. + +--- + +### 3.2.8. Integers in cells are big-endian by default. + +Notice that the +default order of bits in `Integer`s serialized into `Cell`s is big-endian, not little- +endian. + +In this respect TVM is a big-endian machine. However, this affects +only the serialization of integers inside cells. The internal representation of +the `Integer` value type is implementation-dependent and irrelevant for the +operation of TVM. + +Besides, there are some special primitives such as `STULE` +for (de)serializing little-endian integers, which must be stored into an integral +number of bytes (otherwise “little-endianness” does not make sense, unless +one is also willing to revert the order of bits inside octets). + +Such primitives are +useful for interfacing with the little-endian world—for instance, for parsing +custom-format messages arriving to a TON Blockchain smart contract from +the outside world. + +--- + +### 3.2.9. Other serialization primitives. + +Other cell creation primitives serialize bitstrings (i.e., cell slices without references), either taken from the stack +or supplied as literal arguments; cell slices (which are concatenated to the +cell builder in an obvious way); other `Builder`s (which are also concatenated); +and cell references (`STREF`). + +--- + +### 3.2.10. Other cell creation primitives. + +In addition to the cell serialization primitives for certain built-in value types described above, there are +simple primitives that create a new empty `Builder` and push it into the stack +(`NEWC`), or transform a `Builder` into a `Cell` (`ENDC`), thus finishing the cell +creation process. + +An `ENDC` can be combined with a `STREF` into a single instruction `ENDCST`, which finishes the creation of a cell and immediately stores +a reference to it in an “outer” `Builder`. + +There are also primitives that obtain +the quantity of data bits or references already stored in a `Builder`, and check how many data bits or references can be stored. + +--- + +### 3.2.11. Taxonomy of cell deserialisation primitives. + +Cell parsing, or +deserialization, primitives can be classified as described in 3.2.6, with the +following modifications: + +* They work with `Slice`s (representing the remainder of the cell being + parsed) instead of `Builder`s. +* They return deserialized values instead of accepting them as arguments. +* They may come in two flavors, depending on whether they remove the + deserialized portion from the `Slice` supplied (“fetch operations”) or leave + it unmodified (“prefetch operations”). +* Their mnemonics usually begin with `LD` (or `PLD` for prefetch operations) + instead of `ST`. + +For example, an unsigned big-endian 20-bit integer previously serialized into +a cell by a `STU 20` instruction is likely to be deserialized later by a matching +`LDU 20` instruction. + +Again, more detailed information about these instructions is provided in **A.7.2**. + +--- + +### 3.2.12. Other cell slice primitives. + +In addition to the cell deserialisation +primitives outlined above, TVM provides some obvious primitives for initializing and completing the cell deserialization process. + +For instance, one can +convert a `Cell` into a `Slice` (`CTOS`), so that its deserialisation might begin; +or check whether a `Slice` is empty, and generate an exception if it is not +(`ENDS`); or deserialize a cell reference and immediately convert it into a `Slice` +(`LDREFTOS`, equivalent to two instructions `LDREF` and `CTOS`). + +--- + +### 3.2.13. Modifying a serialized value in a cell. + +The reader might wonder +how the values serialized inside a cell may be modified. + +Suppose a cell contains three serialized 29-bit integers, `(x, y, z)`, representing the coordinates of +a point in space, and we want to replace `y` with `y' = y + 1`, leaving the other +coordinates intact. How would we achieve this? + +TVM does not offer any ways to modify existing values (cf. 2.3.4 and +2.3.5), so our example can only be accomplished with a series of operations +as follows: + +1. Deserialize the original cell into three `Integer`s `x`, `y`, `z` in the stack (e.g., + by `CTOS; LDI 29; LDI 29; LDI 29; ENDS`). +2. Increase `y` by one (e.g., by `SWAP; INC; SWAP`). +3. Finally, serialize the resulting `Integer`s into a new cell (e.g., by `XCHG s2; NEWC; STI 29; STI 29; STI 29; ENDC`). + +--- + +### 3.2.14. Modifying the persistent storage of a smart contract. + +If the +TVM code wants to modify its persistent storage, represented by the tree of +cells rooted at `c4`, it simply needs to rewrite control register `c4` by the root +of the tree of cells containing the new value of its persistent storage. (If only +part of the persistent storage needs to be modified, cf. 3.2.13.) + +--- + +## 3.3 Hashmaps, or dictionaries + +Hashmaps, or dictionaries, are a specific data structure represented by a tree +of cells. Essentially, a hashmap represents a map from keys, which are bitstrings of either fixed or variable length, into values of an arbitrary type `X`, +in such a way that fast lookups and modifications be possible. While any +such structure might be inspected or modified with the aid of generic cell serialization and deserialization primitives, TVM introduces special primitives +to facilitate working with these hashmaps. + +--- + +### 3.3.1. Basic hashmap types. + +The two most basic hashmap types predefined in TVM are `HashmapE n X` or `HashmapE(n, X)`, which represents +a partially defined map from n-bit strings (called keys) for some fixed `0 ≤ n ≤ 1023` into values of some type `X`, and `Hashmap(n, X)`, which is similar +to `HashmapE(n, X)` but is not allowed to be empty (i.e., it must contain at +least one key-value pair). + +Other hashmap types are also available—for example, one with keys of +arbitrary length up to some predefined bound (up to 1023 bits). + +--- + +### 3.3.2. Hashmaps as Patricia trees. + +The abstract representation of a +hashmap in TVM is a Patricia tree, or a compact binary trie. It is a binary +tree with edges labelled by bitstrings, such that the concatenation of all edge +labels on a path from the root to a leaf equals a key of the hashmap. The +corresponding value is kept in this leaf (for hashmaps with keys of fixed +length), or optionally in the intermediate vertices as well (for hashmaps with +keys of variable length). + +Furthermore, any intermediate vertex must have +two children, and the label of the left child must begin with a binary zero, +while the label of the right child must begin with a binary one. This enables +us not to store the first bit of the edge labels explicitly. + +It is easy to see that any collection of key-value pairs (with distinct keys) +is represented by a unique Patricia tree. + +--- + +### 3.3.3. Serialization of hashmaps. + +The serialization of a hashmap into a +tree of cells (or, more generally, into a `Slice`) is defined by the following TL-B +scheme: + +``` +bit#_ _:(## 1) = Bit; +hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) +{n = (~m) + l} node:(HashmapNode m X) = Hashmap n X; +hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X; +hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X) +right:^(Hashmap n X) = HashmapNode (n + 1) X; +hml_short$0 {m:#} {n:#} len:(Unary ~n) +s:(n * Bit) = HmLabel ~n m; +hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m; +hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m; +unary_zero$0 = Unary ~0; +unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1); +hme_empty$0 {n:#} {X:Type} = HashmapE n X; +hme_root$1 {n:#} {X:Type} root:^(Hashmap n X) = HashmapE n X; +true#_ = True; +_ {n:#} _:(Hashmap n True) = BitstringSet n; +``` + +--- + +### 3.3.4. Brief explanation of TL-B schemes. + +A TL-B scheme, like the +one above, includes the following components. + +The right-hand side of each “equation” is a type, either simple (such as +`Bit` or `True`) or parametrized (such as `Hashmap n X`). The parameters of a +type must be either natural numbers (i.e., non-negative integers, which are +required to fit into 32 bits in practice), such as `n` in `Hashmap n X`, or other +types, such as `X` in `Hashmap n X`. + +The left-hand side of each equation describes a way to define, or even to +serialize, a value of the type indicated in the right-hand side. Such a description begins with the name of a constructor, such as `hm_edge` or `hml_long`, +immediately followed by an optional constructor tag, such as `#_` or `$10`, which +describes the bitstring used to encode (serialize) the constructor in question. + +Such tags may be given in either binary (after a dollar sign) or hexadecimal +notation (after a hash sign), using the conventions described in 1.0. + +If a tag is not explicitly provided, TL-B computes a default 32-bit constructor tag +by hashing the text of the “equation” defining this constructor in a certain +fashion. Therefore, empty tags must be explicitly provided by `#_` or `$_`. All +constructor names must be distinct, and constructor tags for the same type +must constitute a prefix code (otherwise the deserialization would not be +unique). + +The constructor and its optional tag are followed by field definitions. Each +field definition is of the form `ident : type-expr`, where `ident` is an identifier +with the name of the field (replaced by an underscore for anonymous fields), +and `type-expr` is the field’s type. + +The type provided here is a type expression, +which may include simple types or parametrized types with suitable parameters. + +Variables—i.e., the identifiers of the previously defined fields of types +`#` (natural numbers) or `Type` (type of types)—may be used as parameters +for the parametrized types. The serialization process recursively serializes +each field according to its type, and the serialization of a value ultimately +consists of the concatenation of bitstrings representing the constructor (i.e., +the constructor tag) and the field values. + +Some fields may be implicit. Their definitions are surrounded by curly +braces, which indicate that the field is not actually present in the serialization, +but that its value must be deduced from other data (usually the parameters +of the type being serialized). + +Some occurrences of “variables” (i.e., already-defined fields) are prefixed +by a tilde. This indicates that the variable’s occurrence is used in the opposite way of the default behavior: in the left-hand side of the equation, it +means that the variable will be deduced (computed) based on this occurrence, +instead of substituting its previously computed value; in the right-hand side, +conversely, it means that the variable will not be deduced from the type being +serialized, but rather that it will be computed during the deserialization process. + +In other words, a tilde transforms an “input argument” into an “output +argument”, and vice versa.17 + +Finally, some equalities may be included in curly brackets as well. These +are certain “equations”, which must be satisfied by the “variables” included in +them. If one of the variables is prefixed by a tilde, its value will be uniquely +determined by the values of all other variables participating in the equation +(which must be known at this point) when the definition is processed from +the left to the right. + +A caret (`^`) preceding a type `X` means that instead of serializing a value +of type `X` as a bitstring inside the current cell, we place this value into a +separate cell, and add a reference to it into the current cell. Therefore `^X` +means “the type of references to cells containing values of type X”. + +Parametrized type `#<= p` with `p : #` (this notation means “p of type #”, +i.e., a natural number) denotes the subtype of the natural numbers type +`#`, consisting of integers `0 . . . p`; it is serialized into `⌈log2(p + 1)⌉` bits as an +unsigned big-endian integer. + +Type `#` by itself is serialized as an unsigned +32-bit integer. Parametrized type `## b` with `b : #<=31` is equivalent to `#<= 2^b − 1` (i.e., it is an unsigned b-bit integer). + +--- + +### 3.3.5. Application to the serialization of hashmaps. + +Let us explain +the net result of applying the general rules described in 3.3.4 to the TL-B +scheme presented in 3.3.3. + +Suppose we wish to serialize a value of type `HashmapE n X` for some +integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with n-bit keys +and values of type `X`, admitting an abstract representation as a Patricia tree +(cf. 3.3.2)). + +First of all, if our dictionary is empty, it is serialized into a single binary `0`, +which is the tag of nullary constructor `hme_empty`. Otherwise, its serialization +consists of a binary `1` (the tag of `hme_root`), along with a reference to a cell +containing the serialization of a value of type `Hashmap n X` (i.e., a necessarily +non-empty dictionary). + +The only way to serialize a value of type `Hashmap n X` is given by the +`hm_edge` constructor, which instructs us to serialize first the label `label` of +the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel l ⊥ n`, which means that it is a bitstring of length at most n, serialized in such +a way that the true length l of the label, `0 ≤ l ≤ n`, becomes known from +the serialization of the label. (This special serialization method is described +separately in 3.3.6.) + +The label must be followed by the serialization of a node of type +`HashmapNode m X`, where `m = n − l`. It corresponds to a vertex of the Patricia tree, +representing a non-empty subdictionary of the original dictionary with m-bit +keys, obtained by removing from all the keys of the original subdictionary +their common prefix of length l. + +If `m = 0`, a value of type `HashmapNode 0 X` is given by the `hmn_leaf` +constructor, which describes a leaf of the Patricia tree—or, equivalently, a +subdictionary with 0-bit keys. A leaf simply consists of the corresponding +value of type `X` and is serialized accordingly. + +On the other hand, if `m > 0`, a value of type `HashmapNode m X` corresponds to a fork (i.e., an intermediate node) in the Patricia tree, and is +given by the `hmn_fork` constructor. Its serialization consists of `left` and +`right`, two references to cells containing values of type `Hashmap m − 1 X`, +which correspond to the left and the right child of the intermediate node in +question—or, equivalently, to the two subdictionaries of the original dictionary consisting of key-value pairs with keys beginning with a binary `0` or +a binary `1`, respectively. Because the first bit of all keys in each of these +subdictionaries is known and fixed, it is removed, and the resulting (necessarily non-empty) subdictionaries are recursively serialized as values of type +`Hashmap m − 1 X`. + +--- + +### 3.3.6. Serialization of labels. + +There are several ways to serialize a label +of length at most n, if its exact length is `l ≤ n` (recall that the exact length +must be deducible from the serialization of the label itself, while the upper +bound n is known before the label is serialized or deserialized). These ways +are described by the three constructors `hml_short`, `hml_long`, and `hml_same` +of type `HmLabel l ⊥ n`: + +* `hml_short` — Describes a way to serialize “short” labels, of small length + `l ≤ n`. Such a serialization consists of a binary `0` (the constructor tag + of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary + representation of the length l), followed by l bits comprising the label + itself. + +* `hml_long` — Describes a way to serialize “long” labels, of arbitrary + length `l ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation + of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by l bits comprising the label itself. + +* `hml_same` — Describes a way to serialize “long” labels, consisting of l + repetitions of the same bit v. Such a serialization consists of `11` (the + constructor tag of `hml_same`), followed by the bit `v`, followed by the + length l stored in `⌈log2(n + 1)⌉` bits as before. + +Each label can always be serialized in at least two different fashions, using +`hml_short` or `hml_long` constructors. Usually the shortest serialization (and +in the case of a tie—the lexicographically smallest among the shortest) is +preferred and is generated by TVM hashmap primitives, while the other +variants are still considered valid. + +This label encoding scheme has been designed to be efficient for dictionaries +with “random” keys (e.g., hashes of some data), as well as for dictionaries with +“regular” keys (e.g., big-endian representations of integers in some range). + +--- + +### 3.3.7. An example of dictionary serialization. + +Consider a dictionary +with three 16-bit keys 13, 17, and 239 (considered as big-endian integers) +and corresponding 16-bit values 169, 289, and 57121. + +In binary form: + +``` +0000000000001101 => 0000000010101001 +0000000000010001 => 0000000100100001 +0000000011101111 => 1101111100100001 +``` + +The corresponding Patricia tree consists of a root `A`, two intermediate +nodes `B` and `C`, and three leaf nodes `D`, `E`, and `F`, corresponding to 13, 17, +and 239, respectively. The root `A` has only one child, `B`; the label on the +edge `AB` is `00000000 = 08`. The node `B` has two children: its left child is +an intermediate node `C` with the edge `BC` labelled by `(0)00`, while its right +child is the leaf `F` with `BF` labelled by `(1)1101111`. Finally, `C` has two leaf +children `D` and `E`, with `CD` labelled by `(0)1101` and `CE`—by `(1)0001`. + +The corresponding value of type `HashmapE 16 (## 16)` may be written +in human-readable form as: + +``` +(hme_root$1 + root:^(hm_edge label:(hml_same$11 v:0 n:8) node:(hm_fork + left:^(hm_edge label:(hml_short$0 len:$110 s:$00) node:(hm_fork + left:^(hm_edge label:(hml_long$10 n:4 s:$1101) + node:(hm_leaf value:169)) + right:^(hm_edge label:(hml_long$10 n:4 s:$0001) + node:(hm_leaf value:289)))) + right:^(hm_edge label:(hml_long$10 n:7 s:$1101111) + node:(hm_leaf value:57121))))) +``` + +The serialization of this data structure into a tree of cells consists of six +cells with the following binary data contained in them: + +``` +A := 1 +A.0 := 11 0 01000 +A.0.0 := 0 110 00 +A.0.0.0 := 10 100 1101 0000000010101001 +A.0.0.1 := 10 100 0001 0000000100100001 +A.0.1 := 10 111 1101111 1101111100100001 +``` + +Here `A` is the root cell, `A.0` is the cell at the first reference of `A`, `A.1` is +the cell at the second reference of `A`, and so on. This tree of cells can be +represented more compactly using the hexadecimal notation described in 1.0, +using indentation to reflect the tree-of-cells structure: + +``` +C_ +C8 +62_ +A68054C_ +A08090C_ +BEFDF21 +``` + +A total of 93 data bits and 5 references in 6 cells have been used to serialize +this dictionary. Notice that a straightforward representation of three 16- +bit keys and their corresponding 16-bit values would already require 96 bits +(albeit without any references), so this particular serialization turns out to +be quite efficient. + +--- + +### 3.3.8. Ways to describe the serialization of type X. + +Notice that the +built-in TVM primitives for dictionary manipulation need to know something +about the serialization of type `X`; otherwise, they would not be able to work +correctly with `Hashmap n X`, because values of type `X` are immediately +contained in the Patricia tree leaf cells. There are several options available +to describe the serialization of type `X`: + +* The simplest case is when `X = ^Y` for some other type `Y`. In this case + the serialization of `X` itself always consists of one reference to a cell, + which in fact must contain a value of type `Y`, something that is not + relevant for dictionary manipulation primitives. + +* Another simple case is when the serialization of any value of type `X` + always consists of `0 ≤ b ≤ 1023` data bits and `0 ≤ r ≤ 4` references. Integers `b` and `r` can then be passed to a dictionary manipulation primitive + as a simple description of `X`. (Notice that the previous case corresponds + to `b = 0, r = 1`.) + +* A more sophisticated case can be described by four integers + `1 ≤ b0, b1 ≤ 1023`, `0 ≤ r0, r1 ≤ 4`, with `bi` and `ri` used when the first bit of the + serialization equals `i`. When `b0 = b1` and `r0 = r1`, this case reduces to + the previous one. + +* Finally, the most general description of the serialization of a type `X` + is given by a splitting function `splitX` for `X`, which accepts one `Slice` + parameter `s`, and returns two `Slice`s, `s'` and `s''`, where `s'` + is the only prefix of `s` that is the serialization of a value of type `X`, and `s''` is + the remainder of `s`. If no such prefix exists, the splitting function is + expected to throw an exception. Notice that a compiler for a high-level + language, which supports some or all algebraic TL-B types, is likely to + automatically generate splitting functions for all types defined in the + program. + +--- + +### 3.3.9. A simplifying assumption on the serialization of `X`. + +One +may notice that values of type `X` always occupy the remaining part of an +`hm_edge`/`hme_leaf` cell inside the serialization of a `HashmapE n X`. Therefore, if we do not insist on strict validation of all dictionaries accessed, we +may assume that everything left unparsed in an `hm_edge`/`hme_leaf` cell after deserializing its label is a value of type `X`. This greatly simplifies the +creation of dictionary manipulation primitives, because in most cases they +turn out not to need any information about `X` at all. + +--- + +### 3.3.10. Basic dictionary operations. + +Let us present a classification of +basic operations with dictionaries (i.e., values `D` of type `HashmapE n X`): + +* `Get(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns + the corresponding value `D[k] : X?` kept in `D`. +* `Set(D, k, x)` — Given `D : HashmapE(n, X)`, a key `k : n · bit`, and a + value `x : X`, sets `D0[k]` to `x` in a copy `D0` of `D`, and returns the resulting + dictionary `D0` (cf. 2.3.4). +* `Add(D, k, x)` — Similar to `Set`, but adds the key-value pair `(k, x)` to + `D` only if key `k` is absent in `D`. +* `Replace(D, k, x)` — Similar to `Set`, but changes `D0[k]` to `x` only if key + `k` is already present in `D`. +* `GetSet`, `GetAdd`, `GetReplace` — Similar to `Set`, `Add`, and `Replace`, + respectively, but returns the old value of `D[k]` as well. +* `Delete(D, k)` — Deletes key `k` from dictionary `D`, and returns the + resulting dictionary `D0`. +* `GetMin(D)`, `GetMax(D)` — Gets the minimal or maximal key `k` + from dictionary `D`, along with the associated value `x : X`. +* `RemoveMin(D)`, `RemoveMax(D)` — Similar to `GetMin` and `GetMax`, but also removes the key in question from dictionary `D`, and + returns the modified dictionary `D0`. May be used to iterate over all + elements of `D`, effectively using (a copy of) `D` itself as an iterator. +* `GetNext(D, k)` — Computes the minimal key `k0 > k` (or `k0 ≥ k` in a + variant) and returns it along with the corresponding value `x0 : X`. May + be used to iterate over all elements of `D`. +* `GetPrev(D, k)` — Computes the maximal key `k0 < k` (or `k0 ≤ k` in a + variant) and returns it along with the corresponding value `x0 : X`. +* `Empty(n)` — Creates an empty dictionary `D : HashmapE(n, X)`. +* `IsEmpty(D)` — Checks whether a dictionary is empty. +* `Create(n, {(ki , xi)})` — Given `n`, creates a dictionary from a list `(ki , xi)` + of key-value pairs passed in stack. +* `GetSubdict(D, l, k0)` — Given `D : HashmapE(n, X)` and some `l`-bit + string `k0 : l · bit` for `0 ≤ l ≤ n`, returns subdictionary `D0 = D/k0` of `D`, + consisting of keys beginning with `k0`. The result `D0` may be of either + type `HashmapE(n, X)` or type `HashmapE(n − l, X)`. +* `ReplaceSubdict(D, l, k0, D0)` — Given `D : HashmapE(n, X)`, `0 ≤ + l ≤ n`, `k0 : l · bit`, and `D0 : HashmapE(n − l, X)`, replaces with `D0` + the subdictionary `D/k0` of `D` consisting of keys beginning with `k0`, and + returns the resulting dictionary `D00 : HashmapE(n, X)`. Some variants + of `ReplaceSubdict` may also return the old value of the subdictionary + `D/k0` in question. +* `DeleteSubdict(D, l, k0)` — Equivalent to `ReplaceSubdict` with `D0` + being an empty dictionary. +* `Split(D)` — Given `D : HashmapE(n, X)`, returns `D0 := D/0` and + `D1 := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with 0 and 1, respectively. +* `Merge(D0, D1)` — Given `D0` and `D1 : HashmapE(n−1, X)`, computes + `D : HashmapE(n, X)`, such that `D/0 = D0` and `D/1 = D1`. +* `Foreach(D, f)` — Executes a function `f` with two arguments `k` and + `x`, with `(k, x)` running over all key-value pairs of a dictionary `D` in + lexicographical order.18 +* `ForeachRev(D, f)` — Similar to `Foreach`, but processes all keyvalue pairs in reverse order. +* `TreeReduce(D, o, f, g)` — Given `D : HashmapE(n, X)`, a value `o : X`, + and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree + reduction” of `D` by first applying `f` to all the leaves, and then using `g` + to compute the value corresponding to a fork starting from the values + assigned to its children.19 + +--- + +### 3.3.11. Taxonomy of dictionary primitives. + +The dictionary primitives, +described in detail in A.10, can be classified according to the following categories: + +* Which dictionary operation (cf. 3.3.10) do they perform? +* Are they specialized for the case `X = ^Y`? If so, do they represent values of type `Y` by `Cells` or by `Slices`? (Generic versions always represent + values of type `X` as `Slices`.) +* Are the dictionaries themselves passed and returned as `Cells` or as + `Slices`? (Most primitives represent dictionaries as `Slices`.) +* Is the key length `n` fixed inside the primitive, or is it passed in the + stack? +* Are the keys represented by `Slices`, or by signed or unsigned `Integer`s? + +In addition, TVM includes special serialization/deserialization primitives, +such as `STDICT`, `LDDICT`, and `PLDDICT`. They can be used to extract a dictionary from a serialization of an encompassing object, or to insert a dictionary +into such a serialization. + +--- + +Great — here’s **3.4 Hashmaps with variable-length keys** in Markdown, text unchanged and with inline code backticked where needed: + +--- + +### 3.4 Hashmaps with variable-length keys + +TVM provides some support for dictionaries, or hashmaps, with variablelength keys, in addition to its support for dictionaries with fixed-length keys +(as described in 3.3 above). + +#### 3.4.1. Serialization of dictionaries with variable-length keys. + +The +serialization of a `VarHashmap` into a tree of cells (or, more generally, into a +`Slice`) is defined by a TL-B scheme, similar to that described in 3.3.3: + +``` +vhm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) +{n = (~m) + l} node:(VarHashmapNode m X) += VarHashmap n X; + +vhmn_leaf$00 {n:#} {X:Type} value:X = VarHashmapNode n X; + +vhmn_fork$01 {n:#} {X:Type} left:^(VarHashmap n X) +right:^(VarHashmap n X) value:(Maybe X) += VarHashmapNode (n + 1) X; + +vhmn_cont$1 {n:#} {X:Type} branch:bit child:^(VarHashmap n X) +value:X = VarHashmapNode (n + 1) X; + +nothing$0 {X:Type} = Maybe X; + +just$1 {X:Type} value:X = Maybe X; + +vhme_empty$0 {n:#} {X:Type} = VarHashmapE n X; + +vhme_root$1 {n:#} {X:Type} root:^(VarHashmap n X) += VarHashmapE n X; +``` + +# 4 Control flow, continuations, and exceptions + +This chapter describes continuations, which may represent execution tokens +and exception handlers in TVM. Continuations are deeply involved with the +control flow of a TVM program; in particular, subroutine calls and conditional and iterated execution are implemented in TVM using special primitives that accept one or more continuations as their arguments. +We conclude this chapter with a discussion of the problem of recursion +and of families of mutually recursive functions, exacerbated by the fact that +cyclic references are not allowed in TVM data structures (including TVM +code). + +## 4.1 Continuations and subroutines + +Recall (cf.1.1.3) that `Continuation` values represent “execution tokens” that +can be executed later—for example, by `EXECUTE=CALLX` (“execute” or “call +indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations +are responsible for the execution of the program, and are heavily used by +control flow primitives, enabling subroutine calls, conditional expressions, +loops, and so on. + +### 4.1.1. Ordinary continuations. + +The most common kind of continuations +are the ordinary continuations, containing the following data: +• A `Slice` code (cf. 1.1.3 and 3.2.2), containing (the remainder of) the +TVM code to be executed. +• A (possibly empty) `Stack` stack, containing the original contents of +the stack for the code to be executed. +• A (possibly empty) list `save` of pairs (`c(i)`, `vi`) (also called “savelist”), +containing the values of control registers to be restored before the execution of the code. +• A 16-bit integer value `cp`, selecting the TVM codepage used to interpret +the TVM code from code. +• An optional non-negative integer `nargs`, indicating the number of arguments expected by the continuation. + +### 4.1.2. Simple ordinary continuations. + +In most cases, the ordinary continuations are the simplest ones, having empty stack and `save`. They consist +essentially of a reference `code` to (the remainder of) the code to be executed, +and of the codepage `cp` to be used while decoding the instructions from this +code. + +### 4.1.3. Current continuation `cc`. + +The “current continuation” `cc` is an important part of the total state of TVM, representing the code being executed +right now (cf. 1.1). In particular, what we call “the current stack” (or simply +“the stack”) when discussing all other primitives is in fact the stack of the +current continuation. All other components of the total state of TVM may +be also thought of as parts of the current continuation `cc`; however, they +may be extracted from the current continuation and kept separately as part +of the total state for performance reasons. This is why we describe the stack, +the control registers, and the codepage as separate parts of the TVM state +in 1.4. + +### 4.1.4. Normal work of TVM, or the main loop. + +TVM usually performs +the following operations: +If the current continuation `cc` is an ordinary one, it decodes the first +instruction from the `Slice` `code`, similarly to the way other cells are deserialized by TVM `LD*` primitives (cf. 3.2 and 3.2.11): it decodes the opcode +first, and then the parameters of the instruction (e.g., 4-bit fields indicating +“stack registers” involved for stack manipulation primitives, or constant values for “push constant” or “literal” primitives). The remainder of the `Slice` +is then put into the `code` of the new `cc`, and the decoded operation is executed on the current stack. This entire process is repeated until there are no +operations left in `cc.code`. +If the code is empty (i.e., contains no bits of data and no references), or if +a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, +the current continuation is discarded, and the “return continuation” from +control register `c0` is loaded into `cc` instead (this process is discussed in +more detail starting in 4.1.6).20 Then the execution continues by parsing +operations from the new current continuation. + +### 4.1.5. Extraordinary continuations. + +In addition to the ordinary continuations considered so far (cf. 4.1.1), TVM includes some extraordinary continuations, representing certain less common states. Examples of extraordinary +continuations include: +• The continuation `ec_quit` with its parameter set to zero, which represents the end of the work of TVM. This continuation is the original +value of `c0` when TVM begins executing the code of a smart contract. +• The continuation `ec_until`, which contains references to two other +continuations (ordinary or not) representing the body of the loop being +executed and the code to be executed after the loop. +Execution of an extraordinary continuation by TVM depends on its specific +class, and differs from the operations for ordinary continuations described in +4.1.4. +21 + +### 4.1.6. Switching to another continuation: `JMP` and `RET`. + +The process of +switching to another continuation `c` may be performed by such instructions +as `JMPX` (which takes `c` from the stack) or `RET` (which uses `c0` as `c`). This +process is slightly more complex than simply setting the value of `cc` to `c`: +before doing this, either all values or the top `n` values in the current stack +are moved to the stack of the continuation `c`, and only then is the remainder +of the current stack discarded. +If all values need to be moved (the most common case), and if the continuation `c` has an empty stack (also the most common case; notice that +extraordinary continuations are assumed to have an empty stack), then the +new stack of `c` equals the stack of the current continuation, so we can simply +transfer the current stack in its entirety to `c`. (If we keep the current stack +as a separate part of the total state of TVM, we have to do nothing at all.) + +### 4.1.7. Determining the number `n` of arguments passed to the next continuation `c`. + +By default, `n` equals the depth of the current stack. However, if `c` has an explicit value of `nargs` (number of arguments to be provided), +then `n` is computed as `n0`, equal to `c.nargs` minus the current depth of `c`’s +stack. +Furthermore, there are special forms of `JMPX` and `RET` that provide an +explicit value `n00`, the number of parameters from the current stack to be +passed to continuation `c`. If `n00` is provided, it must be less than or equal to +the depth of the current stack, or else a stack underflow exception occurs. If +both `n0` and `n00` are provided, we must have `n0 ≤ n00`, in which case `n = n0` is +used. If `n00` is provided and `n0` +is not, then `n = n00` is used. +One could also imagine that the default value of `n00` equals the depth of +the original stack, and that `n00` values are always removed from the top of +the original stack even if only `n0` of them are actually moved to the stack of +the next continuation `c`. Even though the remainder of the current stack is +discarded afterwards, this description will become useful later. + +### 4.1.8. Restoring control registers from the new continuation `c`. + +After +the new stack is computed, the values of control registers present in `c.save` +are restored accordingly, and the current codepage `cp` is also set to `c.cp`. +Only then does TVM set `cc` equal to the new `c` and begin its execution.22 + +### 4.1.9. Subroutine calls: `CALLX` or `EXECUTE` primitives. + +The execution +of continuations as subroutines is slightly more complicated than switching +to continuations. +Consider the `CALLX` or `EXECUTE` primitive, which takes a continuation `c` +from the (current) stack and executes it as a subroutine. +Apart from doing the stack manipulations described in 4.1.6 and 4.1.7 +and setting the new control registers and codepage as described in 4.1.8, +these primitives perform several additional steps: + +1. After the top `n00` values are removed from the current stack (cf. 4.1.7), + the (usually empty) remainder is not discarded, but instead is stored + in the (old) current continuation `cc`. +2. The old value of the special register `c0` is saved into the (previously + empty) savelist `cc.save`. +3. The continuation `cc` thus modified is not discarded, but instead is set + as the new `c0`, which performs the role of “next continuation” or “return + continuation” for the subroutine being called. +4. After that, the switching to `c` continues as before. In particular, some + control registers are restored from `c.save`, potentially overwriting the + value of `c0` set in the previous step. (Therefore, a good optimization + would be to check that `c0` is present in `c.save` from the very beginning, + and skip the three previous steps as useless in this case.) + In this way, the called subroutine can return control to the caller by + switching the current continuation to the return continuation saved in `c0`. + Nested subroutine calls work correctly because the previous value of `c0` ends + up saved into the new `c0`’s control register savelist `c0.save`, from which it is + restored later. + +### 4.1.10. Determining the number of arguments passed to and/or return values accepted from a subroutine. + +Similarly to `JMPX` and `RET`, +`CALLX` also has special (rarely used) forms, which allow us to explicitly specify +the number `n00` of arguments passed from the current stack to the called +subroutine (by default, `n00` equals the depth of the current stack, i.e., it is +passed in its entirety). Furthermore, a second number `n000` can be specified, +used to set `nargs` of the modified `cc` continuation before storing it into the +new `c0`; the new `nargs` equals the depth of the old stack minus `n00` plus `n000`. +This means that the caller is willing to pass exactly `n00` arguments to the +called subroutine, and is willing to accept exactly `n000` results in their stead. +Such forms of `CALLX` and `RET` are mostly intended for library functions +that accept functional arguments and want to invoke them safely. Another +application is related to the “virtualization support” of TVM, which enables +TVM code to run other TVM code inside a “virtual TVM machine”. Such +virtualization techniques might be useful for implementing sophisticated payment channels in the TON Blockchain (cf. \[1, 5]). + +### 4.1.11. `CALLCC`: call with current continuation. + +Notice that TVM supports a form of the “call with current continuation” primitive. Namely, primitive `CALLCC` is similar to `CALLX` or `JMPX` in that it takes a continuation `c` from +the stack and switches to it; however, `CALLCC` does not discard the previous +current continuation `c0` +(as `JMPX` does) and does not write `c0` +to `c0` (as `CALLX` +does), but rather pushes `c0` +into the (new) stack as an extra argument to `c`. +The primitive `JMPXDATA` does a similar thing, but pushes only the (remainder +of the) code of the previous current continuation as a `Slice`. + +## 4.2 Control flow primitives: conditional and iterated + +execution + +### 4.2.1. Conditional execution: `IF`, `IFNOT`, `IFELSE`. + +An important modification of `EXECUTE` (or `CALLX`) consists in its conditional forms. For example, +`IF` accepts an integer `x` and a continuation `c`, and executes `c` (in the same +way as `EXECUTE` would do it) only if `x` is non-zero; otherwise both values +are simply discarded from the stack. Similarly, `IFNOT` accepts `x` and `c`, but +executes `c` only if `x = 0`. Finally, `IFELSE` accepts `x`, `c`, and `c0`, removes these +values from the stack, and executes `c` if `x 6= 0` or `c0` if `x = 0`. + +### 4.2.2. Iterated execution and loops. + +More sophisticated modifications +of `EXECUTE` include: +• `REPEAT` — Takes an integer `n` and a continuation `c`, and executes `c` `n` +times.23 +• `WHILE` — Takes `c0` and `c00`, executes `c0`, and then takes the top value `x` +from the stack. If `x` is non-zero, it executes `c00` and then begins a new +loop by executing `c0` again; if `x` is zero, it stops. +• `UNTIL` — Takes `c`, executes it, and then takes the top integer `x` from +the stack. If `x` is zero, a new iteration begins; if `x` is non-zero, the +previously executed code is resumed. + +### 4.2.3. Constant, or literal, continuations. + +We see that we can create +arbitrarily complex conditional expressions and loops in the TVM code, provided we have a means to push constant continuations into the stack. In fact, +TVM includes special versions of “literal” or “constant” primitives that cut +the next `n` bytes or bits from the remainder of the current code `cc.code` into +a cell slice, and then push it into the stack not as a `Slice` (as a `PUSHSLICE` +does) but as a simple ordinary `Continuation` (which has only `code` and `cp`). +The simplest of these primitives is `PUSHCONT`, which has an immediate +argument `n` describing the number of subsequent bytes (in a byte-oriented +version of TVM) or bits to be converted into a simple continuation. Another +primitive is `PUSHREFCONT`, which removes the first cell reference from the +current continuation `cc.code`, converts the cell referred to into a cell slice, +and finally converts the cell slice into a simple continuation. + +### 4.2.4. Constant continuations combined with conditional or iterated execution primitives. + +Because constant continuations are very often +used as arguments to conditional or iterated execution primitives, combined +versions of these primitives (e.g., `IFCONT` or `UNTILREFCONT`) may be defined +in a future revision of TVM, which combine a `PUSHCONT` or `PUSHREFCONT` +with another primitive. If one inspects the resulting code, `IFCONT` looks very +much like the more customary “conditional-branch-forward” instruction. + +## 4.3 Operations with continuations + +### 4.3.1. Continuations are opaque. + +Notice that all continuations are opaque, +at least in the current version of TVM, meaning that there is no way to +modify a continuation or inspect its internal data. Almost the only use of a +continuation is to supply it to a control flow primitive. +While there are some arguments in favor of including support for nonopaque continuations in TVM (along with opaque continuations, which are +required for virtualization), the current revision offers no such support. + +### 4.3.2. Allowed operations with continuations. + +However, some operations with opaque continuations are still possible, mostly because they are +equivalent to operations of the kind “create a new continuation, which will +do something special, and then invoke the original continuation”. Allowed +operations with continuations include: +• Push one or several values into the stack of a continuation `c` (thus +creating a partial application of a function, or a closure). +• Set the saved value of a control register `c(i)` inside the savelist `c.save` +of a continuation `c`. If there is already a value for the control register +in question, this operation silently does nothing. + +### 4.3.3. Example: operations with control registers. + +TVM has some +primitives to set and inspect the values of control registers. The most important of them are `PUSH c(i)` (pushes the current value of `c(i)` into the stack) +and `POP c(i)` (sets the value of `c(i)` from the stack, if the supplied value is +of the correct type). However, there is also a modified version of the latter +instruction, called `POPSAVE c(i)`, which saves the old value of `c(i)` (for `i > 0`) +into the continuation at `c0` as described in 4.3.2 before setting the new value. + +### 4.3.4. Example: setting the number of arguments to a function in its code. + +The primitive `LEAVEARGS n` demonstrates another application of +continuations in an operation: it leaves only the top `n` values of the current stack, and moves the remainder to the stack of the continuation in `c0`. +This primitive enables a called function to “return” unneeded arguments to +its caller’s stack, which is useful in some situations (e.g., those related to +exception handling). + +### 4.3.5. Boolean circuits. + +A continuation `c` may be thought of as a piece +of code with two optional exit points kept in the savelist of `c`: the principal +exit point given by `c.c0 := c.save(c0)`, and the auxiliary exit point given +by `c.c1 := c.save(c1)`. If executed, a continuation performs whatever action +it was created for, and then (usually) transfers control to the principal exit +point, or, on some occasions, to the auxiliary exit point. We sometimes say +that a continuation `c` with both exit points `c.c0` and `c.c1` defined is a two-exit +continuation, or a boolean circuit, especially if the choice of the exit point +depends on some internally-checked condition. + +### 4.3.6. Composition of continuations. + +One can compose two continuations `c` and `c0` simply by setting `c.c0` or `c.c1` to `c0`. This creates a new +continuation denoted by `c ◦0 c0` or `c ◦1 c0`, which differs from `c` in its savelist. +(Recall that if the savelist of `c` already has an entry corresponding to the control register in question, such an operation silently does nothing as explained +in 4.3.2). +By composing continuations, one can build chains or other graphs, possibly with loops, representing the control flow. In fact, the resulting graph +resembles a flow chart, with the boolean circuits corresponding to the “condition nodes” (containing code that will transfer control either to `c0` or to `c1` +depending on some condition), and the one-exit continuations corresponding +to the “action nodes”. + +### 4.3.7. Basic continuation composition primitives. + +Two basic primitives for composing continuations are `COMPOS` (also known as `SETCONT c0` and +`BOOLAND`) and `COMPOSALT` (also known as `SETCONT c1` and `BOOLOR`), which +take `c` and `c0` from the stack, set `c.c0` or `c.c1` to `c0`, and return the resulting continuation `c00 = c ◦0 c0` or `c ◦1 c0`. All other continuation composition +operations can be expressed in terms of these two primitives. + +--- + +### 4.3.8. Advanced continuation composition primitives. + +However, TVM can compose continuations not only taken from stack, but also taken from `c0` or `c1`, or from the current continuation `cc`; likewise, the result may be pushed into the stack, stored into either `c0` or `c1`, or used as the new current continuation (i.e., the control may be transferred to it). Furthermore, TVM can define conditional composition primitives, performing some of the above actions only if an integer value taken from the stack is non-zero. + +For instance, `EXECUTE` can be described as `cc ← c ◦0 cc`, with continuation `c` taken from the original stack. Similarly, `JMPX` is `cc ← c`, and `RET` (also known as `RETTRUE` in a boolean circuit context) is `cc ← c0`. Other interesting primitives include `THENRET` (`c0 ← c ◦0 c0`) and `ATEXIT` (`c0 ← c ◦0 c0`). + +Finally, some “experimental” primitives also involve `c1` and `◦1`. For example: + +* `RETALT` or `RETFALSE` does `cc ← c1`. +* Conditional versions of `RET` and `RETALT` may also be useful: `RETBOOL` takes an integer `x` from the stack, and performs `RETTRUE` if `x 6= 0`, `RETFALSE` otherwise. +* `INVERT` does `c0 ↔ c1`; if the two continuations in `c0` and `c1` represent the two branches we should select depending on some boolean expression, `INVERT` negates this expression on the outer level. +* `INVERTCONT` does `c.c0 ↔ c.c1` to a continuation `c` taken from the stack. +* Variants of `ATEXIT` include `ATEXITALT` (`c1 ← c ◦1 c1`) and `SETEXITALT` (`c1 ← (c ◦0 c0) ◦1 c1`). +* `BOOLEVAL` takes a continuation `c` from the stack and does: + + ``` + cc ← ((c ◦0 (PUSH − 1)) ◦1 (PUSH0)) ◦0 cc + ``` + + If `c` represents a boolean circuit, the net effect is to evaluate it and push either `−1` or `0` into the stack before continuing. + +--- + +## 4.4 Continuations as objects + +### 4.4.1. Representing objects using continuations. + +Object-oriented programming in Smalltalk (or Objective C) style may be implemented with the +aid of continuations. For this, an object is represented by a special continuation `o`. If it has any data fields, they can be kept in the stack of `o`, making +`o` a partial application (i.e., a continuation with a non-empty stack). +When somebody wants to invoke a method `m` of `o` with arguments `x1, x2, +. . . , xn`, she pushes the arguments into the stack, then pushes a magic number +corresponding to the method `m`, and then executes `o` passing `n+1` arguments +(cf. 4.1.10). Then `o` uses the top-of-stack integer `m` to select the branch with +5 + +### 4.5. Exception handling + +the required method, and executes it. If `o` needs to modify its state, it simply +computes a new continuation `o0` of the same sort (perhaps with the same code +as `o`, but with a different initial stack). The new continuation `o0` +is returned +to the caller along with whatever other return values need to be returned. + +### 4.4.2. Serializable objects. + +Another way of representing Smalltalk-style +objects as continuations, or even as trees of cells, consists in using the +`JMPREFDATA` primitive (a variant of `JMPXDATA`, cf. 4.1.11), which takes the +first cell reference from the code of the current continuation, transforms the +cell referred to into a simple ordinary continuation, and transfers control to +it, first pushing the remainder of the current continuation as a `Slice` into the +stack. In this way, an object might be represented by a cell `o˜` that contains +`JMPREFDATA` at the beginning of its data, and the actual code of the object +in the first reference (one might say that the first reference of cell `o˜` is the +class of object `o˜`). Remaining data and references of this cell will be used for +storing the fields of the object. +Such objects have the advantage of being trees of cells, and not just +continuations, meaning that they can be stored into the persistent storage of +a TON smart contract. + +### 4.4.3. Unique continuations and capabilities. + +It might make sense (in +a future revision of TVM) to mark some continuations as unique, meaning +that they cannot be copied, even in a delayed manner, by increasing their +reference counter to a value greater than one. If an opaque continuation is +unique, it essentially becomes a capability, which can either be used by its +owner exactly once or be transferred to somebody else. +For example, imagine a continuation that represents the output stream to +a printer (this is an example of a continuation used as an object, cf. 4.4.1). +When invoked with one integer argument `n`, this continuation outputs the +character with code `n` to the printer, and returns a new continuation of +the same kind reflecting the new state of the stream. Obviously, copying +such a continuation and using the two copies in parallel would lead to some +unintended side effects; marking it as unique would prohibit such adverse +usage. + +## 4.5 Exception handling + +TVM’s exception handling is quite simple and consists in a transfer of control +to the continuation kept in control register `c2`. + +### 4.5.1. Two arguments of the exception handler: exception parameter and exception number. + +Every exception is characterized by two +arguments: the exception number (an `Integer`) and the exception parameter +(any value, most often a zero `Integer`). Exception numbers 0–31 are reserved +for TVM, while all other exception numbers are available for user-defined +exceptions. + +### 4.5.2. Primitives for throwing an exception. + +There are several special primitives used for throwing an exception. The most general of them, +`THROWANY`, takes two arguments, `v` and `0 ≤ n < 2^16`, from the stack, and +throws the exception with number `n` and value `v`. There are variants of +this primitive that assume `v` to be a zero integer, store `n` as a literal value, +and/or are conditional on an integer value taken from the stack. User-defined +exceptions may use arbitrary values as `v` (e.g., trees of cells) if needed. + +### 4.5.3. Exceptions generated by TVM. + +Of course, some exceptions are +generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit +into a signed 257-bit integer. In such cases, the arguments of the exception, +`v` and `n`, are determined by TVM itself. + +### 4.5.4. Exception handling. + +The exception handling itself consists in a +control transfer to the exception handler—i.e., the continuation specified in +control register `c2`, with `v` and `n` supplied as the two arguments to this +continuation, as if a `JMP` to `c2` had been requested with `n00 = 2` arguments +(cf. 4.1.7 and 4.1.6). As a consequence, `v` and `n` end up in the top of the +stack of the exception handler. The remainder of the old stack is discarded. +Notice that if the continuation in `c2` has a value for `c2` in its savelist, it +will be used to set up the new value of `c2` before executing the exception +handler. In particular, if the exception handler invokes `THROWANY`, it will rethrow the original exception with the restored value of `c2`. This trick enables +the exception handler to handle only some exceptions, and pass the rest to +an outer exception handler. + +### 4.5.5. Default exception handler. + +When an instance of TVM is created, +`c2` contains a reference to the “default exception handler continuation”, which +is an `ec_fatal` extraordinary continuation (cf. 4.1.5). Its execution leads +to the termination of the execution of TVM, with the arguments `v` and `n` +of the exception returned to the outside caller. In the context of the TON +Blockchain, `n` will be stored as a part of the transaction’s result. +59 + +### 4.5.6. `TRY` primitive. + +A `TRY` primitive can be used to implement C++-like +exception handling. This primitive accepts two continuations, `c` and `c0`. It +stores the old value of `c2` into the savelist of `c0`, sets `c2` to `c0`, and executes `c` +just as `EXECUTE` would, but additionally saving the old value of `c2` into the +savelist of the new `c0` as well. Usually a version of the `TRY` primitive with an +explicit number of arguments `n00` passed to the continuation `c` is used. +The net result is roughly equivalent to C++’s `try { c } catch(...) { c0 }` operator. + +### 4.5.7. List of predefined exceptions + +Predefined exceptions of TVM correspond to exception numbers `n` in the range `0–31`. They include: + +* **Normal termination (`n = 0`)** — Should never be generated, but it is useful for some tricks. +* **Alternative termination (`n = 1`)** — Again, should never be generated. +* **Stack underflow (`n = 2`)** — Not enough arguments in the stack for a primitive. +* **Stack overflow (`n = 3`)** — More values have been stored on a stack than allowed by this version of TVM. +* **Integer overflow (`n = 4`)** — Integer does not fit into `−2^256 ≤ x < 2^256`, or a division by zero has occurred. +* **Range check error (`n = 5`)** — Integer out of expected range. +* **Invalid opcode (`n = 6`)** — Instruction or its immediate arguments cannot be decoded. +* **Type check error (`n = 7`)** — An argument to a primitive is of incorrect value type. +* **Cell overflow (`n = 8`)** — Error in one of the serialization primitives. +* **Cell underflow (`n = 9`)** — Deserialization error. +* **Dictionary error (`n = 10`)** — Error while deserializing a dictionary object. +* **Unknown error (`n = 11`)** — Unknown error, may be thrown by user programs. +* **Fatal error (`n = 12`)** — Thrown by TVM in situations deemed impossible. +* **Out of gas (`n = 13`)** — Thrown by TVM when the remaining gas (`gr`) becomes negative. This exception usually cannot be caught and leads to an immediate termination of TVM. + +Most of these exceptions have no parameter (i.e., use a zero integer instead). +The order in which these exceptions are checked is outlined below in **4.5.8**. + +--- + +### 4.5.8. Order of stack underflow, type check, and range check exceptions. + +All TVM primitives first check whether the stack contains the +required number of arguments, generating a stack underflow exception if this +is not the case. Only then are the type tags of the arguments and their ranges +(e.g., if a primitive expects an argument not only to be an `Integer`, but also +to be in the range from 0 to 256) checked, starting from the value in the top +of the stack (the last argument) and proceeding deeper into the stack. If an +argument’s type is incorrect, a type-checking exception is generated; if the +type is correct, but the value does not fall into the expected range, a range +check exception is generated. +Some primitives accept a variable number of arguments, depending on the +values of some small fixed subset of arguments located near the top of the +stack. In this case, the above procedure is first run for all arguments from +this small subset. Then it is repeated for the remaining arguments, once +their number and types have been determined from the arguments already +processed. + + +--- + +# 4.6 Functions, recursion, and dictionaries + +### 4.6.1. The problem of recursion. + +The conditional and iterated execution primitives described in 4.2—along with the unconditional branch, call, and return primitives described in 4.1— enable one to implement more or less arbitrary code with nested loops and conditional expressions, with one notable exception: one can only create new constant continuations from parts of the current continuation. (In particular, one cannot invoke a subroutine from itself in this way.) Therefore, the code being executed—i.e., the current continuation—gradually becomes smaller and smaller. + +### 4.6.2. Y -combinator solution: pass a continuation as an argument to itself. + +One way of dealing with the problem of recursion is by passing a copy of the continuation representing the body of a recursive function as an extra argument to itself. Consider, for example, the following code for a factorial function: + +``` +71 PUSHINT 1 +9C PUSHCONT { +22 PUSH s2 +72 PUSHINT 2 +B9 LESS +DC IFRET +59 ROTREV +21 PUSH s1 +A8 MUL +01 SWAP +A5 DEC +02 XCHG s2 +20 DUP +D9 JMPX +} +20 DUP +D8 EXECUTE +30 DROP +31 NIP +``` + +This roughly corresponds to defining an auxiliary function body with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, n·x, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. + +### 4.6.3. A variant of Y -combinator solution. + +Another way of recursively computing the factorial, more closely following the classical recursive definition + +``` +fact(n) := ( +1 if n < 2, +n · fact(n − 1) otherwise +) +``` + +is as follows: + +``` +9D PUSHCONT { +21 OVER +C102 LESSINT 2 +92 PUSHCONT { +5B 2DROP +71 PUSHINT 1 +} +E0 IFJMP +21 OVER +A5 DEC +01 SWAP +20 DUP +D8 EXECUTE +A8 MUL +} +20 DUP +D9 JMPX +``` + +This definition of the factorial function is two bytes shorter than the previous one, but it uses general recursion instead of tail recursion, so it cannot be easily transformed into a loop. + +### 4.6.4. Comparison: non-recursive definition of the factorial function. + +Incidentally, a non-recursive definition of the factorial with the aid of a `REPEAT` loop is also possible, and it is much shorter than both recursive definitions: + +``` +71 PUSHINT 1 +01 SWAP +20 DUP +94 PUSHCONT { +66 TUCK +A8 MUL +01 SWAP +A5 DEC +} +E4 REPEAT +30 DROP +``` + +### 4.6.5. Several mutually recursive functions. + +If one has a collection `f1, . . . , fn` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fi}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. + +### 4.6.6. Combining several functions into one tuple. + +One might also combine a collection of continuations representing functions `f1, . . . , fn` into a “tuple” `f := (f1, . . . , fn)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fi`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. + +### 4.6.7. Combining several functions into a selector function. + +Another approach is to combine several functions `f1, . . . , fn` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fi` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. + +### 4.6.8. Using a dedicated register to keep the selector function. + +However, even if we use one of the two previous approaches to combine all functions into one extra argument, passing this argument to all mutually recursive functions is still quite cumbersome and requires a lot of additional stack manipulation operations. Because this argument changes very rarely, one might use a dedicated register to keep it and transparently pass it to all functions called. This is the approach used by TVM by default. + +### 4.6.9. Special register c3 for the selector function. + +In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. A.8.7) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. + +In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). + +### 4.6.10. Initialization of c3. + +A TVM program might initialize `c3` by means of a `POP c3` instruction. However, because this usually is the very first action undertaken by a program (e.g., a smart contract), TVM makes some provisions for the automatic initialization of `c3`. Namely, `c3` is initialized by the code (the initial value of `cc`) of the program itself, and an extra zero (or, in some cases, some other predefined number `s`) is pushed into the stack before the program’s execution. This is approximately equivalent to invoking `JMPDICT 0` (or `JMPDICT s`) at the very beginning of a program—i.e., the function with index zero is effectively the `main()` function for the program. + +### 4.6.11. Creating selector functions and switch statements. + +TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. A.8.2). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. + +Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. A.7.2). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. + +### 4.6.12. Alternative: using a hashmap to select the correct function. + +Yet another alternative is to use a `Hashmap` (cf. 3.3) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. A.10) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. A.8.5) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. A.10.11). This approach may be more efficient for larger programs and switch statements. + + +Got it ✅ — here’s **Chapter 5: Codepages and instruction encoding** converted cleanly into Markdown. +I kept the **text exactly as-is** (no paraphrasing), just formatted with proper Markdown: headings, subheadings, inline backticks for mnemonics/opcodes, and bullet lists where appropriate. + +--- + +# 5 Codepages and instruction encoding + +This chapter describes the codepage mechanism, which allows TVM to be +flexible and extendable while preserving backward compatibility with respect +to previously generated code. +We also discuss some general considerations about instruction encodings +(applicable to arbitrary machine code, not just TVM), as well as the implications of these considerations for TVM and the choices made while designing +TVM’s (experimental) codepage zero. The instruction encodings themselves +are presented later in Appendix A. + +## 5.1 Codepages and interoperability of different TVM versions + +The codepages are an essential mechanism of backward compatibility and +of future extensions to TVM. They enable transparent execution of code +written for different revisions of TVM, with transparent interaction between +instances of such code. The mechanism of the codepages, however, is general +and powerful enough to enable some other originally unintended applications. + +### 5.1.1. Codepages in continuations + +Every ordinary continuation contains +a 16-bit codepage field `cp` (cf. 4.1.1), which determines the codepage that +will be used to execute its code. If a continuation is created by a `PUSHCONT` +(cf. 4.2.3) or similar primitive, it usually inherits the current codepage (i.e., +the codepage of `cc`).25 + +### 5.1.2. Current codepage + +The current codepage `cp` (cf. 1.4) is the codepage of the current continuation `cc`. It determines the way the next instruction will be decoded from `cc.code`, the remainder of the current continuation’s code. Once the instruction has been decoded and executed, it +determines the next value of the current codepage. In most cases, the current codepage is left unchanged. + +On the other hand, all primitives that switch the current continuation +load the new value of `cp` from the new current continuation. In this way, all +code in continuations is always interpreted exactly as it was intended to be. + +--- + +### 5.1.3. Different versions of TVM may use different codepages + +Different versions of TVM may use different codepages for their code. For +example, the original version of TVM might use codepage zero. A newer +version might use codepage one, which contains all the previously defined +opcodes, along with some newly defined ones, using some of the previously +unused opcode space. A subsequent version might use yet another codepage, +and so on. + +However, a newer version of TVM will execute old code for codepage zero +exactly as before. If the old code contained an opcode used for some new +operations that were undefined in the original version of TVM, it will still +generate an invalid opcode exception, because the new operations are absent +in codepage zero. + +--- + +### 5.1.4. Changing the behavior of old operations + +New codepages can +also change the effects of some operations present in the old codepages while +preserving their opcodes and mnemonics. + +For example, imagine a future 513-bit upgrade of TVM (replacing the +current 257-bit design). It might use a 513-bit Integer type within the same +arithmetic primitives as before. However, while the opcodes and instructions +in the new codepage would look exactly like the old ones, they would work +differently, accepting 513-bit integer arguments and results. On the other +hand, during the execution of the same code in codepage zero, the new +machine would generate exceptions whenever the integers used in arithmetic +and other primitives do not fit into 257 bits.26 In this way, the upgrade would +not change the behavior of the old code. + +--- + +### 5.1.5. Improving instruction encoding + +Another application for codepages is to change instruction encodings, reflecting improved knowledge of +the actual frequencies of such instructions in the code base. In this case, +the new codepage will have exactly the same instructions as the old one, but +with different encodings, potentially of differing lengths. + +For example, one +might create an experimental version of the first version of TVM, using a +(prefix) bitcode instead of the original bytecode, aiming to achieve higher +code density. + +--- + +### 5.1.6. Making instruction encoding context-dependent + +Another way +of using codepages to improve code density is to use several codepages with +different subsets of the whole instruction set defined in each of them, or with +the whole instruction set defined, but with different length encodings for the +same instructions in different codepages. + +Imagine, for instance, a “stack manipulation” codepage, where stack manipulation primitives have short encodings at the expense of all other operations, and a “data processing” codepage, where all other operations are +shorter at the expense of stack manipulation operations. If stack manipulation operations tend to come one after another, we can automatically +switch to “stack manipulation” codepage after executing any such instruction. When a data processing instruction occurs, we switch back to “data +processing” codepage. + +If conditional probabilities of the class of the next instruction depending on the class of the previous instruction are considerably +different from corresponding unconditional probabilities, this technique— +automatically switching into stack manipulation mode to rearrange the stack +with shorter instructions, then switching back—might considerably improve +the code density. + +--- + +### 5.1.7. Using codepages for status and control flags + +Another potential +application of multiple codepages inside the same revision of TVM consists in +switching between several codepages depending on the result of the execution +of some instructions. + +For example, imagine a version of TVM that uses two new codepages, `2` +and `3`. Most operations do not change the current codepage. However, the +integer comparison operations will switch to codepage `2` if the condition is +false, and to codepage `3` if it is true. Furthermore, a new operation `?EXECUTE`, +similar to `EXECUTE`, will indeed be equivalent to `EXECUTE` in codepage `3`, but +will instead be a `DROP` in codepage `2`. Such a trick effectively uses bit 0 of +the current codepage as a status flag. + +Alternatively, one might create a couple of codepages—say, `4` and `5`— +which differ only in their cell deserialisation primitives. For instance, in +codepage `4` they might work as before, while in codepage `5` they might deserialize data not from the beginning of a Slice, but from its end. Two new +instructions—say, `CLD` and `STD`—might be used for switching to codepage `4` +or codepage `5`. Clearly, we have now described a status flag, affecting the +execution of some instructions in a certain new manner. + +--- + +### 5.1.8. Setting the codepage in the code itself + +For convenience, we +reserve some opcode in all codepages—say, `FF n`—for the instruction `SETCP n`, +with `n` from 0 to 255 (cf. A.13). Then by inserting such an instruction +into the very beginning of (the main function of) a program (e.g., a TON +Blockchain smart contract) or a library function, we can ensure that the code +will always be executed in the intended codepage. + +--- + +## 5.2 Instruction encoding + +This section discusses the general principles of instruction encoding valid for +all codepages and all versions of TVM. Later, 5.3 discusses the choices made +for the experimental “codepage zero”. + +### 5.2.1. Instructions are encoded by a binary prefix code + +All complete instructions (i.e., instructions along with all their parameters, such as +the names of stack registers `s(i)` or other embedded constants) of a TVM +codepage are encoded by a **binary prefix code**. This means that a (finite) +binary string (i.e., a bitstring) corresponds to each complete instruction, in +such a way that binary strings corresponding to different complete instructions do not coincide, and no binary string among the chosen subset is a +prefix of another binary string from this subset. + +--- + +### 5.2.2. Determining the first instruction from a code stream + +As a consequence of this encoding method, any binary string admits at most one +prefix, which is an encoding of some complete instruction. In particular, +the code `cc.code` of the current continuation (which is a Slice, and thus a +bitstring along with some cell references) admits at most one such prefix, +which corresponds to the (uniquely determined) instruction that TVM will +execute first. After execution, this prefix is removed from the code of the +current continuation, and the next instruction can be decoded. + +--- + +### 5.2.3. Invalid opcode + +If no prefix of `cc.code` encodes a valid instruction +in the current codepage, an invalid opcode exception is generated (cf. 4.5.7). + +However, the case of an empty `cc.code` is treated separately as explained +in 4.1.4 (the exact behavior may depend on the current codepage). + +--- + +### 5.2.4. Special case: end-of-code padding + +As an exception to the above +rule, some codepages may accept some values of `cc.code` that are too short +to be valid instruction encodings as additional variants of `NOP`, thus effectively +using the same procedure for them as for an empty `cc.code`. Such bitstrings +may be used for padding the code near its end. + +For example, if binary string `00000000` (i.e., `x00`, cf. 1.0.3) is used in a +codepage to encode `NOP`, its proper prefixes cannot encode any instructions. +So this codepage may accept `0`, `00`, `000`, …, `0000000` as variants of `NOP` if +this is all that is left in `cc.code`, instead of generating an invalid opcode +exception. + +Such a padding may be useful, for example, if the `PUSHCONT` primitive +(cf. 4.2.3) creates only continuations with code consisting of an integral +number of bytes, but not all instructions are encoded by an integral number +of bytes. + +--- + +### 5.2.5. TVM code is a bitcode, not a bytecode + +Recall that TVM is +a bit-oriented machine in the sense that its Cells (and Slices) are naturally +considered as sequences of bits, not just of octets (bytes), cf. 3.2.5. Because +the TVM code is also kept in cells (cf. 3.1.9 and 4.1.4), there is no reason +to use only bitstrings of length divisible by eight as encodings of complete +instructions. In other words, generally speaking, the TVM code is a **bitcode**, +not a **bytecode**. + +That said, some codepages (such as our experimental codepage zero) may +opt to use a bytecode (i.e., to use only encodings consisting of an integral +number of bytes)—either for simplicity, or for the ease of debugging and of +studying memory (i.e., cell) dumps.27 + +--- + +### 5.2.6. Opcode space used by a complete instruction + +Recall from coding theory that the lengths of bitstrings `li` used in a binary prefix code satisfy +Kraft–McMillan inequality: + +``` +Σ 2^(-li) ≤ 1 +``` + +This is applicable in particular to +the (complete) instruction encoding used by a TVM codepage. We say that +a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2^(-l)` of the opcode space, if it is encoded +by an `l`-bit string. One can see that all complete instructions together utilize +at most 1 (i.e., “at most the whole opcode space”). + +--- + +### 5.2.7. Opcode space used by an instruction, or a class of instructions + +The above terminology is extended to instructions (considered with +all admissible values of their parameters), or even classes of instructions (e.g., +all arithmetic instructions). We say that an (incomplete) instruction, or a +class of instructions, occupies portion `α` of the opcode space, if `α` is the sum +of the portions of the opcode space occupied by all complete instructions +belonging to that class. + +--- + +### 5.2.8. Opcode space for bytecodes + +A useful approximation of the above +definitions is as follows: + +Consider all 256 possible values for the first byte of +an instruction encoding. Suppose that `k` of these values correspond to the +specific instruction or class of instructions we are considering. Then this +instruction or class of instructions occupies approximately the portion `k/256` +of the opcode space. + +This approximation shows why all instructions cannot occupy together +more than the portion `256/256 = 1` of the opcode space, at least without +compromising the uniqueness of instruction decoding. + +--- + +### 5.2.9. Almost optimal encodings + +Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete +instruction (`2^(-l)`, if the complete instruction is encoded in `l` bits) should be +approximately equal to the probability or frequency of its occurrence in real +programs.28 The same should hold for (incomplete) instructions, or primitives +(i.e., generic instructions without specified values of parameters), and +for classes of instructions. + +--- + +### 5.2.10. Example: stack manipulation primitives + +For instance, if stack +manipulation instructions constitute approximately half of all instructions in +a typical TVM program, one should allocate approximately half of the opcode +space for encoding stack manipulation instructions. + +One might reserve the +first bytes (“opcodes”) `0x00–0x7f` for such instructions. If a quarter of these +instructions are `XCHG`, it would make sense to reserve `0x00–0x1f` for `XCHG`s. +Similarly, if half of all `XCHG`s involve the top of stack `s0`, it would make sense +to use `0x00–0x0f` to encode `XCHG s0,s(i)`. + +--- + +### 5.2.11. Simple encodings of instructions + +In most cases, simple encodings of complete instructions are used. Simple encodings begin with a fixed +bitstring called the opcode of the instruction, followed by, say, 4-bit fields +containing the indices `i` of stack registers `s(i)` specified in the instruction, followed by all other constant (literal, immediate) parameters included in the +complete instruction. + +While simple encodings may not be exactly optimal, +they admit short descriptions, and their decoding and encoding can be easily +implemented. + +If a (generic) instruction uses a simple encoding with an `l`-bit opcode, then +the instruction will utilize `2^(-l)` portion of the opcode space. This observation +might be useful for considerations described in 5.2.9 and 5.2.10. + +--- + +### 5.2.12. Optimizing code density further: Huffman codes + +One might +construct optimally dense binary code for the set of all complete instructions, +provided their probabilities or frequencies in real code are known. This is the +well-known **Huffman code** (for the given probability distribution). However, +such code would be highly unsystematic and hard to decode. + +--- + +### 5.2.13. Practical instruction encodings + +In practice, instruction encodings used in TVM and other virtual machines offer a compromise between +code density and ease of encoding and decoding. Such a compromise may +be achieved by selecting simple encodings (cf. 5.2.11) for all instructions +(maybe with separate simple encodings for some often used variants, such +as `XCHG s0,s(i)` among all `XCHG s(i),s(j)`), and allocating opcode space for +such simple encodings using the heuristics outlined in 5.2.9 and 5.2.10; this +is the approach currently used in TVM. + +--- + +## 5.3 Instruction encoding in codepage zero + +This section provides details about the experimental instruction encoding +for codepage zero, as described elsewhere in this document (cf. Appendix A) +and used in the preliminary test version of TVM. + +### 5.3.1. Upgradability + +First of all, even if this preliminary version somehow gets into the production version of the TON Blockchain, the codepage +mechanism (cf. 5.1) enables us to introduce better versions later without +compromising backward compatibility.29 So in the meantime, we are free to +experiment. + +--- + +### 5.3.2. Choice of instructions + +We opted to include many “experimental” +and not strictly necessary instructions in codepage zero just to see how they +might be used in real code. For example, we have both the basic (cf. 2.2.1) +and the compound (cf. 2.2.3) stack manipulation primitives, as well as some +“unsystematic” ones such as `ROT` (mostly borrowed from Forth). If such +primitives are rarely used, their inclusion just wastes some part of the opcode +space and makes the encodings of other instructions slightly less effective, +something we can afford at this stage of TVM’s development. + +--- + +### 5.3.3. Using experimental instructions + +Some of these experimental +instructions have been assigned quite long opcodes, just to fit more of them +into the opcode space. One should not be afraid to use them just because +they are long; if these instructions turn out to be useful, they will receive +shorter opcodes in future revisions. Codepage zero is not meant to be fine +tuned in this respect. + +--- + +### 5.3.4. Choice of bytecode. + +We opted to use a bytecode (i.e., to use encodings of complete instructions of lengths divisible by eight). While this may not produce optimal code density, because such a length restriction makes it more difficult to match portions of opcode space used for the encoding of instructions with estimated frequencies of these instructions in TVM code +(cf. 5.2.11 and 5.2.9), such an approach has its advantages: it admits a +simpler instruction decoder and simplifies debugging (cf. 5.2.5). + +After all, we do not have enough data on the relative frequencies of different instructions right now, so our code density optimizations are likely to +be very approximate at this stage. The ease of debugging and experimenting +and the simplicity of implementation are more important at this point. + +### 5.3.5. Simple encodings for all instructions. + +For similar reasons, we +opted to use simple encodings for all instructions (cf. 5.2.11 and 5.2.13), +with separate simple encodings for some very frequently used subcases as +outlined in 5.2.13. That said, we tried to distribute opcode space using the +heuristics described in 5.2.9 and 5.2.10. + +### 5.3.6. Lack of context-dependent encodings. + +This version of TVM also +does not use context-dependent encodings (cf. 5.1.6). They may be added +at a later stage, if deemed useful. + +### 5.3.7. The list of all instructions. + +The list of all instructions available in codepage zero, along with their encodings and (in some cases) short descriptions, may be found in Appendix A. + +--- + +# A Instructions and opcodes + +This appendix lists all instructions available in the (experimental) codepage +zero of TVM, as explained in 5.3. +We list the instructions in lexicographical opcode order. However, the +opcode space is distributed in such way as to make all instructions in each +category (e.g., arithmetic primitives) have neighboring opcodes. So we first +list a number of stack manipulation primitives, then constant primitives, +arithmetic primitives, comparison primitives, cell primitives, continuation +primitives, dictionary primitives, and finally application-specific primitives. +We use hexadecimal notation (cf. 1.0) for bitstrings. Stack registers `s(i)` +usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare +occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, +8-bit, or variable length. +The stack notation described in 2.1.10 is extensively used throughout +this appendix. + +## A.1 Gas prices + +The gas price for most primitives equals the basic gas price, computed as +`Pb := 10 + b + 5r`, where `b` is the instruction length in bits and `r` is the +number of cell references included in the instruction. When the gas price +of an instruction differs from this basic price, it is indicated in parentheses +after its mnemonics, either as `(x)`, meaning that the total gas price equals +`x`, or as `(+x)`, meaning `Pb + x`. Apart from integer constants, the following +expressions may appear: + +* `Cr` — The total price of “reading” cells (i.e., transforming cell references + into cell slices). Currently equal to 100 or 25 gas units per cell + depending on whether it is the first time a cell with this hash is being + “read” during the current run of the VM or not. +* `L` — The total price of loading cells. Depends on the loading action + required. +* `Bw` — The total price of creating new `Builder`s. Currently equal to 0 + gas units per builder. +* `Cw` — The total price of creating new `Cell`s from `Builder`s. Currently + equal to 500 gas units per cell. + +By default, the gas price of an instruction equals `P := Pb + Cr + L + Bw + Cw`. + +## A.2 Stack manipulation primitives + +This section includes both the basic (cf. 2.2.1) and the compound (cf. 2.2.3) +stack manipulation primitives, as well as some “unsystematic” ones. Some +compound stack manipulation primitives, such as `XCPU` or `XCHG2`, turn out +to have the same length as an equivalent sequence of simpler operations. We +have included these primitives regardless, so that they can easily be allocated +shorter opcodes in a future revision of TVM—or removed for good. +Some stack manipulation instructions have two mnemonics: one Forth- +style (e.g., `-ROT`), the other conforming to the usual rules for identifiers (e.g., +`ROTREV`). Whenever a stack manipulation primitive (e.g., `PICK`) accepts an +integer parameter `n` from the stack, it must be within the range `0 . . . 255`; +otherwise a range check exception happens before any further checks. + +### A.2.1. Basic stack manipulation primitives. + +* `00` — **NOP**, does nothing. +* `01` — **XCHG s1**, also known as **SWAP**. +* `0i` — **XCHG s(i)** or **XCHG s0,s(i)**, interchanges the top of the stack with `s(i)`, `1 ≤ i ≤ 15`. +* `10ij` — **XCHG s(i),s(j)**, `1 ≤ i < j ≤ 15`, interchanges `s(i)` with `s(j)`. +* `11ii` — **XCHG s0,s(ii)**, with `0 ≤ ii ≤ 255`. +* `1i` — **XCHG s1,s(i)**, `2 ≤ i ≤ 15`. +* `2i` — **PUSH s(i)**, `0 ≤ i ≤ 15`, pushes a copy of the old `s(i)` into the stack. +* `20` — **PUSH s0**, also known as **DUP**. +* `21` — **PUSH s1**, also known as **OVER**. +* `3i` — **POP s(i)**, `0 ≤ i ≤ 15`, pops the old top-of-stack value into the old `s(i)`. +* `30` — **POP s0**, also known as **DROP**, discards the top-of-stack value. +* `31` — **POP s1**, also known as **NIP**. + + +### A.2.2. Compound stack manipulation primitives. + +Parameters `i`, `j`, +and `k` of the following primitives all are 4-bit integers in the range `0 . . . 15`. +* `4ijk` — **XCHG3 s(i),s(j),s(k)**, equivalent to **XCHG s2,s(i); XCHG s1,s(j); XCHG s0,s(k)**, with `0 ≤ i, j, k ≤ 15`. +* `50ij` — **XCHG2 s(i),s(j)**, equivalent to **XCHG s1,s(i); XCHG s(j)**. +* `51ij` — **XCPU s(i),s(j)**, equivalent to **XCHG s(i); PUSH s(j)**. +* `52ij` — **PUXC s(i),s(j − 1)**, equivalent to **PUSH s(i); SWAP; XCHG s(j)**. +* `53ij` — **PUSH2 s(i),s(j)**, equivalent to **PUSH s(i); PUSH s(j + 1)**. +* `540ijk` — **XCHG3 s(i),s(j),s(k)** (long form). +* `541ijk` — **XC2PU s(i),s(j),s(k)**, equivalent to **XCHG2 s(i),s(j); PUSH s(k)**. +* `542ijk` — **XCPUXC s(i),s(j),s(k−1)**, equivalent to **XCHG s1,s(i); PUXC s(j),s(k − 1)**. +* `543ijk` — **XCPU2 s(i),s(j),s(k)**, equivalent to **XCHG s(i); PUSH2 s(j),s(k)**. +* `544ijk` — **PUXC2 s(i),s(j − 1),s(k − 1)**, equivalent to **PUSH s(i); XCHG s2; XCHG2 s(j),s(k)**. +* `545ijk` — **PUXCPU s(i),s(j−1),s(k−1)**, equivalent to **PUXC s(i),s(j− 1); PUSH s(k)**. +* `546ijk` — **PU2XC s(i),s(j−1),s(k−2)**, equivalent to **PUSH s(i); SWAP; PUXC s(j),s(k − 1)**. +* `547ijk` — **PUSH3 s(i),s(j),s(k)**, equivalent to **PUSH s(i); PUSH2 s(j + 1),s(k + 1)**. +* `54C_` — **unused**. + +### A.2.3. Exotic stack manipulation primitives. + +* `55ij` — **BLKSWAP i+1,j+1**, permutes two blocks `s(j + i + 1)…s(j + 1)` and `s(j)…s0`, for `0 ≤ i, j ≤ 15`. Equivalent to **REVERSE i+1,j+1; REVERSE j+1,0; REVERSE i+j+2,0**. +* `5513` — **ROT2** or **2ROT** (`a b c d e f – c d e f a b`), rotates the three topmost pairs of stack entries. +* `550i` — **ROLL i+1**, rotates the top `i+1` stack entries. Equivalent to **BLKSWAP 1,i+1**. +* `55i0` — **ROLLREV i+1** or **-ROLL i+1**, rotates the top `i+1` stack entries in the other direction. Equivalent to **BLKSWAP i+1,1**. +* `56ii` — **PUSH s(ii)** for `0 ≤ ii ≤ 255`. +* `57ii` — **POP s(ii)** for `0 ≤ ii ≤ 255`. +* `58` — **ROT** (`a b c – b c a`), equivalent to **BLKSWAP 1,2** or to **XCHG2 s2,s1**. +* `59` — **ROTREV** or **-ROT** (`a b c – c a b`), equivalent to **BLKSWAP 2,1** or to **XCHG2 s2,s2**. +* `5A` — **SWAP2** or **2SWAP** (`a b c d – c d a b`), equivalent to **BLKSWAP 2,2** or to **XCHG2 s3,s2**. +* `5B` — **DROP2** or **2DROP** (`a b –`), equivalent to **DROP; DROP**. +* `5C` — **DUP2** or **2DUP** (`a b – a b a b`), equivalent to **PUSH2 s1,s0**. +* `5D` — **OVER2** or **2OVER** (`a b c d – a b c d a b`), equivalent to **PUSH2 s3,s2**. +* `5Eij` — **REVERSE i+2,j**, reverses the order of `s(j+i+1)…s(j)` for `0 ≤ i, j ≤ 15`; equivalent to a sequence of `⌊i/2⌋+1` **XCHG**s. +* `5F0i` — **BLKDROP i**, equivalent to **DROP** performed `i` times. +* `5Fij` — **BLKPUSH i,j**, equivalent to **PUSH s(j)** performed `i` times, `1 ≤ i ≤ 15`, `0 ≤ j ≤ 15`. +* `60` — **PICK** or **PUSHX**, pops integer `i` from the stack, then performs **PUSH s(i)**. +* `61` — **ROLLX**, pops integer `i` from the stack, then performs **BLKSWAP 1,i**. +* `62` — **-ROLLX** or **ROLLREVX**, pops integer `i` from the stack, then performs **BLKSWAP i,1**. +* `63` — **BLKSWX**, pops integers `i,j` from the stack, then performs **BLKSWAP i,j**. +* `64` — **REVX**, pops integers `i,j` from the stack, then performs **REVERSE i,j**. +* `65` — **DROPX**, pops integer `i` from the stack, then performs **BLKDROP i**. +* `66` — **TUCK** (`a b – b a b`), equivalent to **SWAP; OVER** or to **XCPU s1,s1**. +* `67` — **XCHGX**, pops integer `i` from the stack, then performs **XCHG s(i)**. +* `68` — **DEPTH**, pushes the current depth of the stack. +* `69` — **CHKDEPTH**, pops integer `i` from the stack, then checks whether there are at least `i` elements, generating a stack underflow exception otherwise. +* `6A` — **ONLYTOPX**, pops integer `i` from the stack, then removes all but the top `i` elements. +* `6B` — **ONLYX**, pops integer `i` from the stack, then leaves only the bottom `i` elements. Approximately equivalent to **DEPTH; SWAP; SUB; DROPX**. +* `6C00–6C0F` — **reserved** for stack operations. +* `6Cij` — **BLKDROP2 i,j**, drops `i` stack elements under the top `j` elements, where `1 ≤ i ≤ 15` and `0 ≤ j ≤ 15`. Equivalent to **REVERSE i+j,0; BLKDROP i; REVERSE j,0**. + + +## A.3 Tuple, List, and Null primitives + +Tuples are ordered collections consisting of at most 255 TVM stack values of +arbitrary types (not necessarily the same). Tuple primitives create, modify, +and unpack Tuples; they manipulate values of arbitrary types in the process, +similarly to the stack primitives. We do not recommend using Tuples of more +than 15 elements. +When a Tuple `t` contains elements `x1, . . . , xn` (in that order), we write +`t = (x1, . . . , xn)`; number `n ≥ 0` is the length of Tuple `t`. It is also denoted +by `|t|`. Tuples of length two are called pairs, and Tuples of length three are +triples. +Lisp-style lists are represented with the aid of pairs, i.e., tuples consisting +of exactly two elements. An empty list is represented by a `Null` value, and +a non-empty list is represented by pair `(h, t)`, where `h` is the first element of +the list, and `t` is its tail. + +### A.3.1. Null primitives. + +The following primitives work with (the only) +value `⊥` of type `Null`, useful for representing empty lists, empty branches +of binary trees, and absence of values in `Maybe X` types. An empty Tuple +created by `NIL` could have been used for the same purpose; however, `Null` is +more efficient and costs less gas. + +* `6D` — `NULL` or `PUSHNULL` `( – ⊥)`, pushes the only value of type `Null`. +* `6E` — `ISNULL` `(x – ? )`, checks whether `x` is a `Null`, and returns `−1` or `0` + accordingly. + +### A.3.2. Tuple primitives. + +* `6F0n` — `TUPLE n` `(x1 . . . xn – t)`, creates a new Tuple `t = (x1, . . . , xn)` + containing `n` values `x1, . . . , xn`, where `0 ≤ n ≤ 15`. +* `6F00` — `NIL` `( – t)`, pushes the only Tuple `t = ()` of length zero. +* `6F01` — `SINGLE` `(x – t)`, creates a singleton `t := (x)`, i.e., a Tuple of + length one. +* `6F02` — `PAIR` or `CONS` `(x y – t)`, creates pair `t := (x, y)`. +* `6F03` — `TRIPLE` `(x y z – t)`, creates triple `t := (x, y, z)`. +* `6F1k` — `INDEX k` `(t – x)`, returns the `k`-th element of a Tuple `t`, where + `0 ≤ k ≤ 15`. In other words, returns `xk+1` if `t = (x1, . . . , xn)`. If `k ≥ n`, + throws a range check exception. +* `6F10` — `FIRST` or `CAR` `(t – x)`, returns the first element of a Tuple. +* `6F11` — `SECOND` or `CDR` `(t – y)`, returns the second element of a Tuple. +* `6F12` — `THIRD` `(t – z)`, returns the third element of a Tuple +* `6F2n` — `UNTUPLE n` `(t – x1 . . . xn)`, unpacks a Tuple `t = (x1, . . . , xn)` of + length equal to `0 ≤ n ≤ 15`. If `t` is not a Tuple, of if `|t| 6= n`, a type + check exception is thrown. +* `6F21` — `UNSINGLE` `(t – x)`, unpacks a singleton `t = (x)`. +* `6F22` — `UNPAIR` or `UNCONS` `(t – x y)`, unpacks a pair `t = (x, y)`. +* `6F23` — `UNTRIPLE` `(t – x y z)`, unpacks a triple `t = (x, y, z)`. +* `6F3k` — `UNPACKFIRST k` `(t – x1 . . . xk)`, unpacks first `0 ≤ k ≤ 15` + elements of a Tuple `t`. If `|t| < k`, throws a type check exception. +* `6F30` — `CHKTUPLE` `(t – )`, checks whether `t` is a Tuple. +* `6F4n` — `EXPLODE n` `(t – x1 . . . xm m)`, unpacks a Tuple `t = (x1, . . . , xm)` + and returns its length `m`, but only if `m ≤ n ≤ 15`. Otherwise throws a + type check exception. +* `6F5k` — `SETINDEX k` `(t x – t' )`, computes Tuple `t'` that differs from `t` + only at position `t'k+1`, which is set to `x`. In other words, `|t'| = |t|`, `t'i = ti` + for `i 6= k + 1`, and `t'k+1 = x`, for given `0 ≤ k ≤ 15`. If `k ≥ |t|`, throws a + range check exception. +* `6F50` — `SETFIRST` `(t x – t' )`, sets the first component of Tuple `t` to `x` + and returns the resulting Tuple `t'`. +* `6F51` — `SETSECOND` `(t x – t' )`, sets the second component of Tuple `t` to + `x` and returns the resulting Tuple `t'`. +* `6F52` — `SETTHIRD` `(t x – t' )`, sets the third component of Tuple `t` to `x` + and returns the resulting Tuple `t'`. +* `6F6k` — `INDEXQ k` `(t – x)`, returns the `k`-th element of a Tuple `t`, where + `0 ≤ k ≤ 15`. In other words, returns `xk+1` if `t = (x1, . . . , xn)`. If `k ≥ n`, + or if `t` is `Null`, returns a `Null` instead of `x`. +* `6F7k` — `SETINDEXQ k` `(t x – t' )`, sets the `k`-th component of Tuple `t` to + `x`, where `0 ≤ k < 16`, and returns the resulting Tuple `t'`. If `|t| ≤ k`, first + extends the original Tuple to length `k+1` by setting all new components + to `Null`. If the original value of `t` is `Null`, treats it as an empty Tuple. + If `t` is not `Null` or `Tuple`, throws an exception. If `x` is `Null` and either + `|t| ≤ k` or `t` is `Null`, then always returns `t' = t` (and does not consume + tuple creation gas). +* `6F80` — `TUPLEVAR` `(x1 . . . xn n – t)`, creates a new Tuple `t` of length `n` + similarly to `TUPLE`, but with `0 ≤ n ≤ 255` taken from the stack. +* `6F81` — `INDEXVAR` `(t k – x)`, similar to `INDEX k`, but with `0 ≤ k ≤ 254` + taken from the stack. +* `6F82` — `UNTUPLEVAR` `(t n – x1 . . . xn)`, similar to `UNTUPLE n`, but with + `0 ≤ n ≤ 255` taken from the stack. +* `6F83` — `UNPACKFIRSTVAR` `(t n – x1 . . . xn)`, similar to `UNPACKFIRST n`, + but with `0 ≤ n ≤ 255` taken from the stack. +* `6F84` — `EXPLODEVAR` `(t n – x1 . . . xm m)`, similar to `EXPLODE n`, but + with `0 ≤ n ≤ 255` taken from the stack. +* `6F85` — `SETINDEXVAR` `(t x k – t' )`, similar to `SETINDEX k`, but with + `0 ≤ k ≤ 254` taken from the stack. +* `6F86` — `INDEXVARQ` `(t k – x)`, similar to `INDEXQ n`, but with `0 ≤ k ≤ 254` + taken from the stack. +* `6F87` — `SETINDEXVARQ` `(t x k – t' )`, similar to `SETINDEXQ k`, but with + `0 ≤ k ≤ 254` taken from the stack. +* `6F88` — `TLEN` `(t – n)`, returns the length of a Tuple. +* `6F89` — `QTLEN` `(t – n or −1)`, similar to `TLEN`, but returns `−1` if `t` is not + a Tuple. +* `6F8A` — `ISTUPLE` `(t – ? )`, returns `−1` or `0` depending on whether `t` is a + Tuple. +* `6F8B` — `LAST` `(t – x)`, returns the last element `t|t|` of a non-empty Tuple `t`. +* `6F8C` — `TPUSH` or `COMMA` `(t x – t' )`, appends a value `x` to a Tuple `t = + (x1, . . . , xn)`, but only if the resulting Tuple `t' = (x1, . . . , xn, x)` is of + length at most 255. Otherwise throws a type check exception. +* `6F8D` — `TPOP` `(t – t' x)`, detaches the last element `x = xn` from a non- + empty Tuple `t = (x1, . . . , xn)`, and returns both the resulting Tuple `t' = + (x1, . . . , xn−1)` and the original last element `x`. +* `6FA0` — `NULLSWAPIF` `(x – x or ⊥ x)`, pushes a `Null` under the topmost + Integer `x`, but only if `x 6= 0`. +* `6FA1` — `NULLSWAPIFNOT` `(x – x or ⊥ x)`, pushes a `Null` under the topmost + Integer `x`, but only if `x = 0`. May be used for stack alignment + after quiet primitives such as `PLDUXQ`. +* `6FA2` — `NULLROTRIF` `(x y – x y or ⊥ x y)`, pushes a `Null` under the + second stack entry from the top, but only if the topmost Integer `y` is + non-zero. +* `6FA3` — `NULLROTRIFNOT` `(x y – x y or ⊥ x y)`, pushes a `Null` under the + second stack entry from the top, but only if the topmost Integer `y` is + zero. May be used for stack alignment after quiet primitives such as + `LDUXQ`. +* `6FA4` — `NULLSWAPIF2` `(x – x or ⊥ ⊥ x)`, pushes two `Null`s under the + topmost Integer `x`, but only if `x 6= 0`. Equivalent to `NULLSWAPIF; + NULLSWAPIF`. +* `6FA5` — `NULLSWAPIFNOT2` `(x – x or ⊥ ⊥ x)`, pushes two `Null`s under the + topmost Integer `x`, but only if `x = 0`. Equivalent to `NULLSWAPIFNOT; + NULLSWAPIFNOT`. +* `6FA6` — `NULLROTRIF2` `(x y – x y or ⊥ ⊥ x y)`, pushes two `Null`s under + the second stack entry from the top, but only if the topmost Integer `y` + is non-zero. Equivalent to `NULLROTRIF; NULLROTRIF`. +* `6FA7` — `NULLROTRIFNOT2` `(x y – x y or ⊥ ⊥ x y)`, pushes two `Null`s + under the second stack entry from the top, but only if the topmost + Integer `y` is zero. Equivalent to `NULLROTRIFNOT; NULLROTRIFNOT`. +* `6FBij` — `INDEX2 i,j` `(t – x)`, recovers `x = (ti+1)j+1` for `0 ≤ i, j ≤ 3`. + Equivalent to `INDEX i; INDEX j`. +* `6FB4` — `CADR` `(t – x)`, recovers `x = (t2)1`. +* `6FB5` — `CDDR` `(t – x)`, recovers `x = (t2)2`. +* `6FE_ijk` — `INDEX3 i,j,k` `(t – x)`, recovers `x = ((ti+1)j+1)k+1` for `0 ≤ + i, j, k ≤ 3`. Equivalent to `INDEX2 i,j; INDEX k`. +* `6FD4` — `CADDR` `(t – x)`, recovers `x = ((t2)2)1`. +* `6FD5` — `CDDDR` `(t – x)`, recovers `x = ((t2)2)2`. + +## A.4 Constant, or literal primitives + +The following primitives push into the stack one literal (or unnamed constant) +of some type and range, stored as a part (an immediate argument) of the +instruction. Therefore, if the immediate argument is absent or too short, an +“invalid or too short opcode” exception (code `6`) is thrown. + +### A.4.1. Integer and boolean constants. + +* `7i` — `PUSHINT x` with `−5 ≤ x ≤ 10`, pushes integer `x` into the stack; + here `i` equals four lower-order bits of `x` (i.e., `i = x mod 16`). +* `70` — `ZERO`, `FALSE`, or `PUSHINT 0`, pushes a zero. +* `71` — `ONE` or `PUSHINT 1`. +* `72` — `TWO` or `PUSHINT 2`. +* `7A` — `TEN` or `PUSHINT 10`. +* `7F` — `TRUE` or `PUSHINT -1`. +* `80xx` — `PUSHINT xx` with `−128 ≤ xx ≤ 127`. +* `81xxxx` — `PUSHINT xxxx` with `−2^15 ≤ xxxx < 2^15` a signed 16-bit + big-endian integer. +* `81FC18` — `PUSHINT −1000`. +* `82lxxx` — `PUSHINT xxx`, where 5-bit `0 ≤ l ≤ 30` determines the length + `n = 8l + 19` of signed big-endian integer `xxx`. The total length of this + instruction is `l + 4` bytes or `n + 13 = 8l + 32` bits. +* `821005F5E100` — `PUSHINT 1088`. +* `83xx` — `PUSHPOW2 xx + 1`, (quietly) pushes `2^(xx+1)` for `0 ≤ xx ≤ 255`. +* `83FF` — `PUSHNAN`, pushes a `NaN`. +* `84xx` — `PUSHPOW2DEC xx + 1`, pushes `2^(xx+1) − 1` for `0 ≤ xx ≤ 255`. +* `85xx` — `PUSHNEGPOW2 xx + 1`, pushes `−2^(xx+1)` for `0 ≤ xx ≤ 255`. +* `86, 87` — reserved for integer constants. + +### A.4.2. Constant slices, continuations, cells, and references. + +Most +of the instructions listed below push literal slices, continuations, cells, and +cell references, stored as immediate arguments to the instruction. Therefore, +if the immediate argument is absent or too short, an “invalid or too short +opcode” exception (code `6`) is thrown. + +* `88` — `PUSHREF`, pushes the first reference of `cc.code` into the stack as + a `Cell` (and removes this reference from the current continuation). +* `89` — `PUSHREFSLICE`, similar to `PUSHREF`, but converts the cell into a + `Slice`. +* `8A` — `PUSHREFCONT`, similar to `PUSHREFSLICE`, but makes a simple ordinary `Continuation` out of the cell. +* `8Bxsss` — `PUSHSLICE sss`, pushes the (prefix) subslice of `cc.code` + consisting of its first `8x + 4` bits and no references (i.e., essentially a bitstring), where `0 ≤ x ≤ 15`. A completion tag is assumed, meaning that + all trailing zeroes and the last binary one (if present) are removed from + this bitstring. If the original bitstring consists only of zeroes, an empty + slice will be pushed. +* `8B08` — `PUSHSLICE x8_`, pushes an empty slice (bitstring `‘’`). +* `8B04` — `PUSHSLICE x4_`, pushes bitstring `‘0’`. +* `8B0C` — `PUSHSLICE xC_`, pushes bitstring `‘1’`. +* `8Crxxssss` — `PUSHSLICE ssss`, pushes the (prefix) subslice of `cc.code` + consisting of its first `1 ≤ r + 1 ≤ 4` references and up to first `8xx + 1` + bits of data, with `0 ≤ xx ≤ 31`. A completion tag is also assumed. +* `8C01` is equivalent to `PUSHREFSLICE`. +* `8Drxxsssss` — `PUSHSLICE sssss`, pushes the subslice of `cc.code` consisting of `0 ≤ r ≤ 4` references and up to `8xx + 6` bits of data, with + `0 ≤ xx ≤ 127`. A completion tag is assumed. +* `8DE_` — unused (reserved). +* `8F_rxxcccc` — `PUSHCONT cccc`, where `cccc` is the simple ordinary + continuation made from the first `0 ≤ r ≤ 3` references and the first + `0 ≤ xx ≤ 127` bytes of `cc.code`. +* `9xccc` — `PUSHCONT ccc`, pushes an `x`-byte continuation for `0 ≤ x ≤ 15`. + +## A.5 Arithmetic primitives + +### A.5.1. Addition, subtraction, multiplication. + +* `A0` — `ADD` `(x y – x + y)`, adds together two integers. +* `A1` — `SUB` `(x y – x − y)`. +* `A2` — `SUBR` `(x y – y − x)`, equivalent to `SWAP; SUB`. +* `A3` — `NEGATE` `(x – −x)`, equivalent to `MULCONST −1` or to `ZERO; SUBR`. + Notice that it triggers an integer overflow exception if `x = −2^256`. +* `A4` — `INC` `(x – x + 1)`, equivalent to `ADDCONST 1`. +* `A5` — `DEC` `(x – x − 1)`, equivalent to `ADDCONST −1`. +* `A6cc` — `ADDCONST cc` `(x – x + cc)`, `−128 ≤ cc ≤ 127`. +* `A7cc` — `MULCONST cc` `(x – x · cc)`, `−128 ≤ cc ≤ 127`. +* `A8` — `MUL` `(x y – xy)`. + +### A.5.2. Division. + +The general encoding of a `DIV`, `DIVMOD`, or `MOD` operation is `A9mscdf`, with +an optional pre-multiplication and an optional replacement of the division or +multiplication by a shift. Variable one- or two-bit fields `m`, `s`, `c`, `d`, and `f` are +as follows `0 ≤ m ≤ 1` — Indicates whether there is pre-multiplication (`MULDIV` +operation and its variants), possibly replaced by a left shift. + +* `0 ≤ s ≤ 2` — Indicates whether either the multiplication or the division + have been replaced by shifts: `s = 0`—no replacement, `s = 1`—division + replaced by a right shift, `s = 2`—multiplication replaced by a left shift + (possible only for `m = 1`). +* `0 ≤ c ≤ 1` — Indicates whether there is a constant one-byte argument + `tt` for the shift operator (if `s 6= 0`). For `s = 0`, `c = 0`. If `c = 1`, then + `0 ≤ tt ≤ 255`, and the shift is performed by `tt + 1` bits. If `s 6= 0` + and `c = 0`, then the shift amount is provided to the instruction as a + top-of-stack `Integer` in range `0 . . . 256`. +* `1 ≤ d ≤ 3` — Indicates which results of division are required: `1`—only + the quotient, `2`—only the remainder, `3`—both. +* `0 ≤ f ≤ 2` — Rounding mode: `0`—floor, `1`—nearest integer, `2`—ceiling + (cf. 1.5.6). + +Examples: + +* `A904` — `DIV` `(x y – q := ⌊x/y⌋)`. +* `A905` — `DIVR` `(x y – q' := ⌊x/y + 1/2⌋)`. +* `A906` — `DIVC` `(x y – q'' := ⌈x/y⌉)`. +* `A908` — `MOD` `(x y – r)`, where `q := ⌊x/y⌋`, `r := x mod y := x − yq`. +* `A90C` — `DIVMOD` `(x y – q r)`, where `q := ⌊x/y⌋`, `r := x − yq`. +* `A90D` — `DIVMODR` `(x y – q' r')`, where `q' := ⌊x/y + 1/2⌋`, `r' := x − yq'`. +* `A90E` — `DIVMODC` `(x y – q'' r'')`, where `q'' := ⌈x/y⌉`, `r'' := x − yq''`. +* `A924` — same as `RSHIFT`: `(x y – ⌊x · 2^(−y)⌋)` for `0 ≤ y ≤ 256`. +* `A934tt` — same as `RSHIFT tt + 1`: `(x – ⌊x · 2^(−tt−1)⌋)`. +* `A938tt` — `MODPOW2 tt + 1`: `(x – x mod 2^(tt+1))`. +* `A985` — `MULDIVR` `(x y z – q')`, where `q' = ⌊xy/z + 1/2⌋`. +* `A98C` — `MULDIVMOD` `(x y z – q r)`, where `q := ⌊x · y/z⌋`, `r := x · y mod z` + (same as `*/MOD` in Forth). +* `A9A4` — `MULRSHIFT` `(x y z – ⌊xy · 2^(−z)⌋)` for `0 ≤ z ≤ 256`. +* `A9A5` — `MULRSHIFTR` `(x y z – ⌊xy · 2^(−z) + 1/2⌋)` for `0 ≤ z ≤ 256`. +* `A9B4tt` — `MULRSHIFT tt + 1` `(x y – ⌊xy · 2^(−tt−1)⌋)`. +* `A9B5tt` — `MULRSHIFTR tt + 1` `(x y – ⌊xy · 2^(−tt−1) + 1/2⌋)`. +* `A9C4` — `LSHIFTDIV` `(x y z – ⌊2^z x/y⌋)` for `0 ≤ z ≤ 256`. +* `A9C5` — `LSHIFTDIVR` `(x y z – ⌊2^z x/y + 1/2⌋)` for `0 ≤ z ≤ 256`. +* `A9D4tt` — `LSHIFTDIV tt + 1` `(x y – ⌊2^(tt+1) x/y⌋)`. +* `A9D5tt` — `LSHIFTDIVR tt + 1` `(x y – ⌊2^(tt+1) x/y + 1/2⌋)`. + +The most useful of these operations are `DIV`, `DIVMOD`, `MOD`, `DIVR`, `DIVC`, +`MODPOW2 t`, and `RSHIFTR t` (for integer arithmetic); and `MULDIVMOD`, `MULDIV`, +`MULDIVR`, `LSHIFTDIVR t`, and `MULRSHIFTR t` (for fixed-point arithmetic). + +### A.5.3. Shifts, logical operations. + +* `AAcc` — `LSHIFT cc + 1` `(x – x · 2^(cc+1))`, `0 ≤ cc ≤ 255`. +* `AA00` — `LSHIFT 1`, equivalent to `MULCONST 2` or to Forth’s `2*`. +* `ABcc` — `RSHIFT cc + 1` `(x – ⌊x · 2^(−cc−1)⌋)`, `0 ≤ cc ≤ 255`. +* `AC` — `LSHIFT` `(x y – x · 2^y)`, `0 ≤ y ≤ 1023`. +* `AD` — `RSHIFT` `(x y – ⌊x · 2^(−y)⌋)`, `0 ≤ y ≤ 1023`. +* `AE` — `POW2` `(y – 2^y)`, `0 ≤ y ≤ 1023`, equivalent to `ONE; SWAP; LSHIFT`. +* `AF` — reserved. +* `B0` — `AND` `(x y – x&y)`, bitwise “and” of two signed integers `x` and `y`, + sign-extended to infinity. +* `B1` — `OR` `(x y – x ∨ y)`, bitwise “or” of two integers. +* `B2` — `XOR` `(x y – x ⊕ y)`, bitwise “xor” of two integers. +* `B3` — `NOT` `(x – x ⊕ −1 = −1 − x)`, bitwise “not” of an integer. +* `B4cc` — `FITS cc + 1` `(x – x)`, checks whether `x` is a `cc + 1`-bit signed + integer for `0 ≤ cc ≤ 255` (i.e., whether `−2^cc ≤ x < 2^cc`). If not, either + triggers an integer overflow exception, or replaces `x` with a `NaN` (quiet + version). +* `B400` — `FITS 1` or `CHKBOOL` `(x – x)`, checks whether `x` is a “boolean + value” (i.e., either `0` or `-1`). +* `B5cc` — `UFITS cc + 1` `(x – x)`, checks whether `x` is a `cc + 1`-bit unsigned + integer for `0 ≤ cc ≤ 255` (i.e., whether `0 ≤ x < 2^(cc+1)`). +* `B500` — `UFITS 1` or `CHKBIT`, checks whether `x` is a binary digit (i.e., + zero or one). +* `B600` — `FITSX` `(x c – x)`, checks whether `x` is a `c`-bit signed integer for + `0 ≤ c ≤ 1023`. +* `B601` — `UFITSX` `(x c – x)`, checks whether `x` is a `c`-bit unsigned integer + for `0 ≤ c ≤ 1023`. +* `B602` — `BITSIZE` `(x – c)`, computes smallest `c ≥ 0` such that `x` fits into + a `c`-bit signed integer (`−2^(c−1) ≤ c < 2^(c−1)`). +* `B603` — `UBITSIZE` `(x – c)`, computes smallest `c ≥ 0` such that `x` fits + into a `c`-bit unsigned integer (`0 ≤ x < 2^c`), or throws a range check + exception. +* `B608` — `MIN` `(x y – x or y)`, computes the minimum of two integers `x` + and `y`. +* `B609` — `MAX` `(x y – x or y)`, computes the maximum of two integers `x` + and `y`. +* `B60A` — `MINMAX` or `INTSORT2` `(x y – x y or y x)`, sorts two integers. Quiet + version of this operation returns two `NaN`s if any of the arguments are + `NaN`s. +* `B60B` — `ABS` `(x – |x|)`, computes the absolute value of an integer `x`. + +### A.5.4. Quiet arithmetic primitives. + +We opted to make all arithmetic +operations “non-quiet” (signaling) by default, and create their quiet counterparts by means of a prefix. Such an encoding is definitely sub-optimal. It is +not yet clear whether it should be done in this way, or in the opposite way +by making all arithmetic operations quiet by default, or whether quiet and +non-quiet operations should be given opcodes of equal length; this can only +be settled by practice. + +* `B7xx` — `QUIET` prefix, transforming any arithmetic operation into its + “quiet” variant, indicated by prefixing a `Q` to its mnemonic. Such operations return `NaN`s instead of throwing integer overflow exceptions if + the results do not fit in `Integer`s, or if one of their arguments is a `NaN`. + Notice that this does not extend to shift amounts and other parameters that must be within a small range (e.g., `0–1023`). Also notice that + this does not disable type-checking exceptions if a value of a type other + than `Integer` is supplied. +* `B7A0` — `QADD` `(x y – x + y)`, always works if `x` and `y` are `Integer`s, but + returns a `NaN` if the addition cannot be performed. +* `B7A904` — `QDIV` `(x y – ⌊x/y⌋)`, returns a `NaN` if `y = 0`, or if `y = −1` and + `x = −2^256`, or if either of `x` or `y` is a `NaN`. +* `B7B0` — `QAND` `(x y – x&y)`, bitwise “and” (similar to `AND`), but returns + a `NaN` if either `x` or `y` is a `NaN` instead of throwing an integer overflow + exception. However, if one of the arguments is zero, and the other is a + `NaN`, the result is zero. +* `B7B1` — `QOR` `(x y – x∨y)`, bitwise “or”. If `x = −1` or `y = −1`, the result + is always `−1`, even if the other argument is a `NaN`. +* `B7B507` — `QUFITS 8` `(x – x' )`, checks whether `x` is an unsigned byte + (i.e., whether `0 ≤ x < 2^8`), and replaces `x` with a `NaN` if this is not the + case; leaves `x` intact otherwise (i.e., if `x` is an unsigned byte). + +## A.6 Comparison primitives + +### A.6.1. Integer comparison. + +All integer comparison primitives return integer `−1` (“true”) or `0` (“false”) to indicate the result of the comparison. We +do not define their “boolean circuit” counterparts, which would transfer control to `c0` or `c1` depending on the result of the comparison. If needed, such +instructions can be simulated with the aid of `RETBOOL`. +Quiet versions of integer comparison primitives are also available, encoded +with the aid of the `QUIET` prefix (`B7`). If any of the integers being compared +are `NaN`s, the result of a quiet comparison will also be a `NaN` (“undefined”), +instead of a `−1` (“yes”) or `0` (“no”), thus effectively supporting ternary logic. + +* `B8` — `SGN` `(x – sgn(x))`, computes the sign of an integer `x`: `−1` if `x < 0`, + `0` if `x = 0`, `1` if `x > 0`. +* `B9` — `LESS` `(x y – x < y)`, returns `−1` if `x < y`, `0` otherwise. +* `BA` — `EQUAL` `(x y – x = y)`, returns `−1` if `x = y`, `0` otherwise. +* `BB` — `LEQ` `(x y – x ≤ y)`. +* `BC` — `GREATER` `(x y – x > y)`. +* `BD` — `NEQ` `(x y – x 6= y)`, equivalent to `EQUAL; NOT`. +* `BE` — `GEQ` `(x y – x ≥ y)`, equivalent to `LESS; NOT`. +* `BF` — `CMP` `(x y – sgn(x − y))`, computes the sign of `x − y`: `−1` if `x < y`, + `0` if `x = y`, `1` if `x > y`. No integer overflow can occur here unless `x` or `y` + is a `NaN`. +* `C0yy` — `EQINT yy` `(x – x = yy)` for `−2^7 ≤ yy < 2^7`. +* `C000` — `ISZERO`, checks whether an integer is zero. Corresponds to + Forth’s `0=`. +* `C1yy` — `LESSINT yy` `(x – x < yy)` for `−2^7 ≤ yy < 2^7`. +* `C100` — `ISNEG`, checks whether an integer is negative. Corresponds to + Forth’s `0<`. +* `C101` — `ISNPOS`, checks whether an integer is non-positive. +* `C2yy` — `GTINT yy` `(x – x > yy)` for `−2^7 ≤ yy < 2^7`. +* `C200` — `ISPOS`, checks whether an integer is positive. Corresponds to + Forth’s `0>`. +* `C2FF` — `ISNNEG`, checks whether an integer is non-negative. +* `C3yy` — `NEQINT yy` `(x – x 6= yy)` for `−2^7 ≤ yy < 2^7`. +* `C4` — `ISNAN` `(x – x = NaN)`, checks whether `x` is a `NaN`. +* `C5` — `CHKNAN` `(x – x)`, throws an arithmetic overflow exception if `x` is a + `NaN`. +* `C6` — reserved for integer comparison. + +### A.6.2. Other comparison. + +Most of these “other comparison” primitives actually compare the data +portions of `Slice`s as bitstrings. + +* `C700` — `SEMPTY` `(s – s = ∅)`, checks whether a `Slice s` is empty (i.e., + contains no bits of data and no cell references). +* `C701` — `SDEMPTY` `(s – s ≈ ∅)`, checks whether `Slice s` has no bits of + data. +* `C702` — `SREMPTY` `(s – r(s) = 0)`, checks whether `Slice s` has no references. +* `C703` — `SDFIRST` `(s – s0 = 1)`, checks whether the first bit of `Slice s` is + a one. +* `C704` — `SDLEXCMP` `(s s0 – c)`, compares the data of `s` lexicographically + with the data of `s0`, returning `−1`, `0`, or `1` depending on the result. +* `C705` — `SDEQ` `(s s0 – s ≈ s0)`, checks whether the data parts of `s` and `s0` + coincide, equivalent to `SDLEXCMP; ISZERO`. +* `C708` — `SDPFX` `(s s0 – ? )`, checks whether `s` is a prefix of `s0`. +* `C709` — `SDPFXREV` `(s s0 – ? )`, checks whether `s0` is a prefix of `s`, equivalent + to `SWAP; SDPFX`. +* `C70A` — `SDPPFX` `(s s0 – ? )`, checks whether `s` is a proper prefix of `s0` (i.e., + a prefix distinct from `s0`). +* `C70B` — `SDPPFXREV` `(s s0 – ? )`, checks whether `s0` is a proper prefix of `s`. +* `C70C` — `SDSFX` `(s s0 – ? )`, checks whether `s` is a suffix of `s0`. +* `C70D` — `SDSFXREV` `(s s0 – ? )`, checks whether `s0` is a suffix of `s`. +* `C70E` — `SDPSFX` `(s s0 – ? )`, checks whether `s` is a proper suffix of `s0`. +* `C70F` — `SDPSFXREV` `(s s0 – ? )`, checks whether `s0` is a proper suffix of `s`. +* `C710` — `SDCNTLEAD0` `(s – n)`, returns the number of leading zeroes in + `s`. +* `C711` — `SDCNTLEAD1` `(s – n)`, returns the number of leading ones in `s`. +* `C712` — `SDCNTTRAIL0` `(s – n)`, returns the number of trailing zeroes in + `s`. +* `C713` — `SDCNTTRAIL1` `(s – n)`, returns the number of trailing ones in `s`. + +## A.7 Cell primitives + +The cell primitives are mostly either cell serialization primitives, which work +with `Builder`s, or cell deserialization primitives, which work with `Slice`s. + +### A.7.1. Cell serialization primitives. + +All these primitives first check whether there is enough space in the Builder, and only then check the range of the value being serialized. + +* `C8` — `NEWC` ( – b), creates a new empty Builder. +* `C9` — `ENDC` (b – c), converts a Builder into an ordinary Cell. +* `CAcc` — `STI cc + 1` (x b – b0), stores a signed cc + 1-bit integer x into Builder b for 0 ≤ cc ≤ 255, throws a range check exception if x does not fit into cc + 1 bits. +* `CBcc` — `STU cc + 1` (x b – b0), stores an unsigned cc + 1-bit integer x into Builder b. In all other respects it is similar to STI. +* `CC` — `STREF` (c b – b0), stores a reference to Cell c into Builder b. +* `CD` — `STBREFR` or `ENDCST` (b b00 – b), equivalent to ENDC; SWAP; STREF. +* `CE` — `STSLICE` (s b – b0), stores Slice s into Builder b. +* `CF00` — `STIX` (x b l – b0), stores a signed l-bit integer x into b for 0 ≤ l ≤ 257. +* `CF01` — `STUX` (x b l – b0), stores an unsigned l-bit integer x into b for 0 ≤ l ≤ 256. +* `CF02` — `STIXR` (b x l – b0), similar to STIX, but with arguments in a different order. +* `CF03` — `STUXR` (b x l – b0), similar to STUX, but with arguments in a different order. +* `CF04` — `STIXQ` (x b l – x b f or b0 0), a quiet version of STIX. If there is no space in b, sets b0 = b and f = −1. If x does not fit into l bits, sets b0 = b and f = 1. If the operation succeeds, b0 is the new Builder and f = 0. However, 0 ≤ l ≤ 257, with a range check exception if this is not so. +* `CF05` — `STUXQ` (x b l – b0 f). +* `CF06` — `STIXRQ` (b x l – b x f or b0 0). +* `CF07` — `STUXRQ` (b x l – b x f or b0 0). +* `CF08cc` — a longer version of `STI cc + 1`. +* `CF09cc` — a longer version of `STU cc + 1`. +* `CF0Acc` — `STIR cc + 1` (b x – b0), equivalent to SWAP; STI cc + 1. +* `CF0Bcc` — `STUR cc + 1` (b x – b0), equivalent to SWAP; STU cc + 1. +* `CF0Ccc` — `STIQ cc + 1` (x b – x b f or b0 0). +* `CF0Dcc` — `STUQ cc + 1` (x b – x b f or b0 0). +* `CF0Ecc` — `STIRQ cc + 1` (b x – b x f or b0 0). +* `CF0Fcc` — `STURQ cc + 1` (b x – b x f or b0 0). +* `CF10` — a longer version of `STREF` (c b – b0). +* `CF11` — `STBREF` (b0 b – b00), equivalent to SWAP; STBREFREV. +* `CF12` — a longer version of `STSLICE` (s b – b0). +* `CF13` — `STB` (b0 b – b00), appends all data from Builder b0 to Builder b. +* `CF14` — `STREFR` (b c – b0). +* `CF15` — `STBREFR` (b b0 – b00), a longer encoding of STBREFR. +* `CF16` — `STSLICER` (b s – b0). +* `CF17` — `STBR` (b b0 – b00), concatenates two Builder s, equivalent to SWAP; STB. +* `CF18` — `STREFQ` (c b – c b −1 or b0 0). +* `CF19` — `STBREFQ` (b0 b – b0 b −1 or b00 0). +* `CF1A` — `STSLICEQ` (s b – s b −1 or b0 0). +* `CF1B` — `STBQ` (b0 b – b0 b −1 or b00 0). +* `CF1C` — `STREFRQ` (b c – b c −1 or b0 0). +* `CF1D` — `STBREFRQ` (b b0 – b b0 −1 or b00 0). +* `CF1E` — `STSLICERQ` (b s – b s −1 or b00 0). +* `CF1F` — `STBRQ` (b b0 – b b0 −1 or b00 0). +* `CF20` — `STREFCONST`, equivalent to PUSHREF; STREFR. +* `CF21` — `STREF2CONST`, equivalent to STREFCONST; STREFCONST. +* `CF23` — `ENDXC` (b x – c), if x 6= 0, creates a special or exotic cell (cf. 3.1.2) from Builder b. The type of the exotic cell must be stored in the first 8 bits of b. If x = 0, it is equivalent to ENDC. Otherwise some validity checks on the data and references of b are performed before creating the exotic cell. +* `CF28` — `STILE4` (x b – b0), stores a little-endian signed 32-bit integer. +* `CF29` — `STULE4` (x b – b0), stores a little-endian unsigned 32-bit integer. +* `CF2A` — `STILE8` (x b – b0), stores a little-endian signed 64-bit integer. +* `CF2B` — `STULE8` (x b – b0), stores a little-endian unsigned 64-bit integer. +* `CF30` — `BDEPTH` (b – x), returns the depth of Builder b. If no cell references are stored in b, then x = 0; otherwise x is one plus the maximum of depths of cells referred to from b. +* `CF31` — `BBITS` (b – x), returns the number of data bits already stored in Builder b. +* `CF32` — `BREFS` (b – y), returns the number of cell references already stored in b. +* `CF33` — `BBITREFS` (b – x y), returns the numbers of both data bits and cell references in b. +* `CF35` — `BREMBITS` (b – x0), returns the number of data bits that can still be stored in b. +* `CF36` — `BREMREFS` (b – y0). +* `CF37` — `BREMBITREFS` (b – x0 y0). +* `CF38cc` — `BCHKBITS cc + 1` (b –), checks whether cc + 1 bits can be stored into b, where 0 ≤ cc ≤ 255. +* `CF39` — `BCHKBITS` (b x – ), checks whether x bits can be stored into b, 0 ≤ x ≤ 1023. If there is no space for x more bits in b, or if x is not within the range 0 . . . 1023, throws an exception. +* `CF3A` — `BCHKREFS` (b y – ), checks whether y references can be stored into b, 0 ≤ y ≤ 7. +* `CF3B` — `BCHKBITREFS` (b x y – ), checks whether x bits and y references can be stored into b, 0 ≤ x ≤ 1023, 0 ≤ y ≤ 7. +* `CF3Ccc` — `BCHKBITSQ cc + 1` (b – ?), checks whether cc + 1 bits can be stored into b, where 0 ≤ cc ≤ 255. +* `CF3D` — `BCHKBITSQ` (b x – ?), checks whether x bits can be stored into b, 0 ≤ x ≤ 1023. +* `CF3E` — `BCHKREFSQ` (b y – ?), checks whether y references can be stored into b, 0 ≤ y ≤ 7. +* `CF3F` — `BCHKBITREFSQ` (b x y – ?), checks whether x bits and y references can be stored into b, 0 ≤ x ≤ 1023, 0 ≤ y ≤ 7. +* `CF40` — `STZEROES` (b n – b0), stores n binary zeroes into Builder b. +* `CF41` — `STONES` (b n – b0), stores n binary ones into Builder b. +* `CF42` — `STSAME` (b n x – b0), stores n binary xes (0 ≤ x ≤ 1) into Builder b. +* `CFC0_xysss` — `STSLICECONST sss` (b – b0), stores a constant subslice sss consisting of 0 ≤ x ≤ 3 references and up to 8y + 1 data bits, with 0 ≤ y ≤ 7. Completion bit is assumed. +* `CF81` — `STSLICECONST ‘0’` or `STZERO` (b – b0), stores one binary zero. +* `CF83` — `STSLICECONST ‘1’` or `STONE` (b – b0), stores one binary one. +* `CFA2` — equivalent to `STREFCONST`. +* `CFA3` — almost equivalent to `STSLICECONST ‘1’`; `STREFCONST`. +* `CFC2` — equivalent to `STREF2CONST`. +* `CFE2` — `STREF3CONST`. + +--- + +### A.7.2. Cell deserialization primitives + +* `D0` — `CTOS` (c – s), converts a Cell into a Slice. Notice that `c` must be either an ordinary cell, or an exotic cell (cf. 3.1.2) which is automatically loaded to yield an ordinary cell `c0`, converted into a Slice afterwards. +* `D1` — `ENDS` (s – ), removes a Slice `s` from the stack, and throws an exception if it is not empty. +* `D2cc` — `LDI cc + 1` (s – x s0), loads (i.e., parses) a signed cc + 1-bit integer `x` from Slice `s`, and returns the remainder of `s` as `s0`. +* `D3cc` — `LDU cc + 1` (s – x s0), loads an unsigned cc + 1-bit integer `x` from Slice `s`. +* `D4` — `LDREF` (s – c s0), loads a cell reference `c` from `s`. +* `D5` — `LDREFRTOS` (s – s0 s00), equivalent to `LDREF`; `SWAP`; `CTOS`. +* `D6cc` — `LDSLICE cc + 1` (s – s00 s0), cuts the next cc + 1 bits of `s` into a separate Slice `s00`. +* `D700` — `LDIX` (s l – x s0), loads a signed `l`-bit (0 ≤ l ≤ 257) integer `x` from Slice `s`, and returns the remainder of `s` as `s0`. +* `D701` — `LDUX` (s l – x s0), loads an unsigned `l`-bit integer `x` from Slice `s`, 0 ≤ l ≤ 256. +* `D702` — `PLDIX` (s l – x), preloads a signed `l`-bit integer from Slice `s`, 0 ≤ l ≤ 257. +* `D703` — `PLDUX` (s l – x), preloads an unsigned `l`-bit integer from `s`, 0 ≤ l ≤ 256. +* `D704` — `LDIXQ` (s l – x s0 −1 or s0), quiet version of `LDIX`. If `s` has fewer than `l` bits, returns a flag instead of exception. +* `D705` — `LDUXQ` (s l – x s0 −1 or s0), quiet version of `LDUX`. +* `D706` — `PLDIXQ` (s l – x −1 or 0), quiet version of `PLDIX`. +* `D707` — `PLDUXQ` (s l – x −1 or 0), quiet version of `PLDUX`. +* `D708cc` — longer encoding of `LDI cc + 1`. +* `D709cc` — longer encoding of `LDU cc + 1`. +* `D70Acc` — `PLDI cc + 1` (s – x), preloads a signed cc + 1-bit integer from Slice `s`. +* `D70Bcc` — `PLDU cc + 1` (s – x), preloads an unsigned cc + 1-bit integer from `s`. +* `D70Ccc` — `LDIQ cc + 1` (s – x s0 −1 or s0), quiet version of `LDI`. +* `D70Dcc` — `LDUQ cc + 1` (s – x s0 −1 or s0), quiet version of `LDU`. +* `D70Ecc` — `PLDIQ cc + 1` (s – x −1 or 0), quiet version of `PLDI`. +* `D70Fcc` — `PLDUQ cc + 1` (s – x −1 or 0), quiet version of `PLDU`. +* `D714_c` — `PLDUZ 32(c + 1)` (s – s x), preloads first 32(c + 1) bits of Slice `s` into an unsigned integer `x`, 0 ≤ c ≤ 7. Missing bits are assumed zero. Used with `IFBITJMP` etc. +* `D718` — `LDSLICEX` (s l – s00 s0), loads first 0 ≤ l ≤ 1023 bits of `s` into a new Slice `s00`, returns the remainder as `s0`. +* `D719` — `PLDSLICEX` (s l – s00), returns first 0 ≤ l ≤ 1023 bits of `s` as `s00`. +* `D71A` — `LDSLICEXQ` (s l – s00 s0 −1 or s0), quiet version of `LDSLICEX`. +* `D71B` — `PLDSLICEXQ` (s l – s0 −1 or 0), quiet version of `PLDSLICEX`. +* `D71Ccc` — longer encoding of `LDSLICE cc + 1`. +* `D71Dcc` — `PLDSLICE cc + 1` (s – s00), returns first 0 < cc + 1 ≤ 256 bits of `s` as `s00`. +* `D71Ecc` — `LDSLICEQ cc + 1` (s – s00 s0 −1 or s0), quiet version of `LDSLICE`. +* `D71Fcc` — `PLDSLICEQ cc + 1` (s – s00 −1 or 0), quiet version of `PLDSLICE`. +* `D720` — `SDCUTFIRST` (s l – s0), returns first 0 ≤ l ≤ 1023 bits of `s`. Equivalent to `PLDSLICEX`. +* `D721` — `SDSKIPFIRST` (s l – s0), returns all but first 0 ≤ l ≤ 1023 bits of `s`. Equivalent to `LDSLICEX`; `NIP`. +* `D722` — `SDCUTLAST` (s l – s0), returns last 0 ≤ l ≤ 1023 bits of `s`. +* `D723` — `SDSKIPLAST` (s l – s0), returns all but last 0 ≤ l ≤ 1023 bits of `s`. +* `D724` — `SDSUBSTR` (s l l0 – s0), returns substring of length 0 ≤ l0 ≤ 1023 starting at offset 0 ≤ l ≤ 1023. +* `D726` — `SDBEGINSX` (s s0 – s00), checks whether `s` begins with data bits of `s0`. Removes `s0` on success. Throws exception on failure. +* `D727` — `SDBEGINSXQ` (s s0 – s00 −1 or s0), quiet version of `SDBEGINSX`. +* `D72A_xsss` — `SDBEGINS` (s – s00), checks whether `s` begins with constant bitstring `sss` of length 8x + 3 (completion bit assumed). Removes on success. +* `D72802` — `SDBEGINS ‘0’` (s – s00), checks whether `s` begins with binary zero. +* `D72806` — `SDBEGINS ‘1’` (s – s00), checks whether `s` begins with binary one. +* `D72E_xsss` — `SDBEGINSQ` (s – s00 −1 or s0), quiet version of `SDBEGINS`. +* `D730` — `SCUTFIRST` (s l r – s0), returns first 0 ≤ l ≤ 1023 bits and 0 ≤ r ≤ 4 references of `s`. +* `D731` — `SSKIPFIRST` (s l r – s0). +* `D732` — `SCUTLAST` (s l r – s0), returns last 0 ≤ l ≤ 1023 bits and last 0 ≤ r ≤ 4 references. +* `D733` — `SSKIPLAST` (s l r – s0). +* `D734` — `SUBSLICE` (s l r l0 r0 – s0), returns 0 ≤ l0 ≤ 1023 bits and 0 ≤ r0 ≤ 4 refs after skipping first l bits and r refs. +* `D736` — `SPLIT` (s l r – s0 s00), splits off first l bits and r refs of `s` into `s0`, returns remainder as `s00`. +* `D737` — `SPLITQ` (s l r – s0 s00 −1 or s0), quiet version of `SPLIT`. +* `D739` — `XCTOS` (c – s ?), converts a Cell (ordinary or exotic) into a Slice. Returns flag if exotic. +* `D73A` — `XLOAD` (c – c0), loads exotic cell `c` to ordinary `c0`. +* `D73B` — `XLOADQ` (c – c0 −1 or c0), quiet version of `XLOAD`. +* `D741` — `SCHKBITS` (s l – ), checks there are ≥ l data bits. Throws exception if not. +* `D742` — `SCHKREFS` (s r – ), checks ≥ r references. +* `D743` — `SCHKBITREFS` (s l r – ), checks ≥ l bits and ≥ r references. +* `D745` — `SCHKBITSQ` (s l – ?), quiet version of `SCHKBITS`. +* `D746` — `SCHKREFSQ` (s r – ?). +* `D747` — `SCHKBITREFSQ` (s l r – ?). +* `D748` — `PLDREFVAR` (s n – c), returns n-th cell reference of Slice `s`, 0 ≤ n ≤ 3. +* `D749` — `SBITS` (s – l), returns number of data bits. +* `D74A` — `SREFS` (s – r), returns number of references. +* `D74B` — `SBITREFS` (s – l r), returns both bit and ref counts. +* `D74E_n` — `PLDREFIDX n` (s – c), returns n-th reference, 0 ≤ n ≤ 3. +* `D74C` — `PLDREF` (s – c), preloads first reference of `s`. +* `D750` — `LDILE4` (s – x s0), loads little-endian signed 32-bit integer. +* `D751` — `LDULE4` (s – x s0), loads little-endian unsigned 32-bit integer. +* `D752` — `LDILE8` (s – x s0), loads little-endian signed 64-bit integer. +* `D753` — `LDULE8` (s – x s0), loads little-endian unsigned 64-bit integer. +* `D754` — `PLDILE4` (s – x), preloads little-endian signed 32-bit integer. +* `D755` — `PLDULE4` (s – x), preloads little-endian unsigned 32-bit integer. +* `D756` — `PLDILE8` (s – x), preloads little-endian signed 64-bit integer. +* `D757` — `PLDULE8` (s – x), preloads little-endian unsigned 64-bit integer. +* `D758` — `LDILE4Q` (s – x s0 −1 or s0), quiet 32-bit signed LE load. +* `D759` — `LDULE4Q` (s – x s0 −1 or s0), quiet 32-bit unsigned LE load. +* `D75A` — `LDILE8Q` (s – x s0 −1 or s0), quiet 64-bit signed LE load. +* `D75B` — `LDULE8Q` (s – x s0 −1 or s0), quiet 64-bit unsigned LE load. +* `D75C` — `PLDILE4Q` (s – x −1 or 0), quiet preload 32-bit signed. +* `D75D` — `PLDULE4Q` (s – x −1 or 0), quiet preload 32-bit unsigned. +* `D75E` — `PLDILE8Q` (s – x −1 or 0), quiet preload 64-bit signed. +* `D75F` — `PLDULE8Q` (s – x −1 or 0), quiet preload 64-bit unsigned. +* `D760` — `LDZEROES` (s – n s0), returns count n of leading zero bits in `s` and removes them. +* `D761` — `LDONES` (s – n s0), returns count n of leading one bits in `s` and removes them. +* `D762` — `LDSAME` (s x – n s0), returns count n of leading bits equal to `x` (0 ≤ x ≤ 1) in `s`, removes them. +* `D764` — `SDEPTH` (s – x), returns depth of Slice `s`. If no references, x = 0; else x = 1 + max depth of cells referred. +* `D765` — `CDEPTH` (c – x), returns depth of Cell `c`. If no refs, x = 0; else 1 + max depth. If `c` = Null, returns 0. + +--- + +## A.8 Continuation and control flow primitives + +### A.8.1. Unconditional control flow primitives. + +* `D8` — **EXECUTE** or **CALLX** `(c – )`, calls or executes continuation `c` (i.e., `cc ← c ◦0 cc`). +* `D9` — **JMPX** `(c – )`, jumps, or transfers control, to continuation `c` (i.e., `cc ← c ◦0 c0, or rather cc ← (c ◦0 c0) ◦1 c1`). The remainder of the previous current continuation `cc` is discarded. +* `DApr` — **CALLXARGS p,r** `(c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. +* `DB0p` — **CALLXARGS p,−1** `(c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. +* `DB1p` — **JMPXARGS p** `(c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). +* `DB2r` — **RETARGS r**, returns to `c0`, with `0 ≤ r ≤ 15` return values taken from the current stack. +* `DB30` — **RET** or **RETTRUE**, returns to the continuation at `c0` (i.e., performs `cc ← c0`). The remainder of the current continuation `cc` is discarded. Approximately equivalent to `PUSH c0; JMPX`. +* `DB31` — **RETALT** or **RETFALSE**, returns to the continuation at `c1` (i.e., `cc ← c1`). Approximately equivalent to `PUSH c1; JMPX`. +* `DB32` — **BRANCH** or **RETBOOL** `(f – )`, performs **RETTRUE** if integer `f ≠ 0`, or **RETFALSE** if `f = 0`. +* `DB34` — **CALLCC** `(c – )`, call with current continuation, transfers control to `c`, pushing the old value of `cc` into `c`’s stack (instead of discarding it or writing it into new `c0`). +* `DB35` — **JMPXDATA** `(c – )`, similar to **CALLCC**, but the remainder of the current continuation (the old value of `cc`) is converted into a Slice before pushing it into the stack of `c`. +* `DB36pr` — **CALLCCARGS p,r** `(c – )`, similar to **CALLXARGS**, but pushes the old value of `cc` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `cc.nargs` to `−1 ≤ r ≤ 14`. +* `DB38` — **CALLXVARARGS** `(c p r – )`, similar to **CALLXARGS**, but takes `−1 ≤ p, r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1 . . . 254`. +* `DB39` — **RETVARARGS** `(p r – )`, similar to **RETARGS**. +* `DB3A` — **JMPXVARARGS** `(c p r – )`, similar to **JMPXARGS**. +* `DB3B` — **CALLCCVARARGS** `(c p r – )`, similar to **CALLCCARGS**. +* `DB3C` — **CALLREF**, equivalent to `PUSHREFCONT; CALLX`. +* `DB3D` — **JMPREF**, equivalent to `PUSHREFCONT; JMPX`. +* `DB3E` — **JMPREFDATA**, equivalent to `PUSHREFCONT; JMPXDATA`. +* `DB3F` — **RETDATA**, equivalent to `PUSH c0; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. + +--- + +## A.8 Continuation and control flow primitives + +### A.8.2. Conditional control flow primitives + +* `DC` — **IFRET** `(f – )`, performs a **RET**, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. +* `DD` — **IFNOTRET** `(f – )`, performs a **RET**, but only if integer `f` is zero. +* `DE` — **IF** `(f c – )`, performs **EXECUTE** for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. +* `DF` — **IFNOT** `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. +* `E0` — **IFJMP** `(f c – )`, jumps to `c` (similarly to **JMPX**), but only if `f` is non-zero. +* `E1` — **IFNOTJMP** `(f c – )`, jumps to `c` (similarly to **JMPX**), but only if `f` is zero. +* `E2` — **IFELSE** `(f c c0 – )`, if integer `f` is non-zero, executes `c`, otherwise executes `c0`. Equivalent to `CONDSELCHK; EXECUTE`. +* `E300` — **IFREF** `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. +* `E301` — **IFNOTREF** `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. +* `E302` — **IFJMPREF** `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. +* `E303` — **IFNOTJMPREF** `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. +* `E304` — **CONDSEL** `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. +* `E305` — **CONDSELCHK** `(f x y – x or y)`, same as **CONDSEL**, but first checks whether `x` and `y` have the same type. +* `E308` — **IFRETALT** `(f – )`, performs **RETALT** if integer `f ≠ 0`. +* `E309` — **IFNOTRETALT** `(f – )`, performs **RETALT** if integer `f = 0`. +* `E30D` — **IFREFELSE** `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. +* `E30E` — **IFELSEREF** `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. +* `E30F` — **IFREFELSEREF** `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. +* `E310–E31F` — reserved for loops with break operators (cf. A.8.3). +* `E39_n` — **IFBITJMP n** `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs **JMPX** to continuation `c`. Value `x` is left in the stack. +* `E3B_n` — **IFNBITJMP n** `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `E3D_n` — **IFBITJMPREF n** `(x – x)`, performs a **JMPREF** if bit `0 ≤ n ≤ 31` is set in integer `x`. +* `E3F_n` — **IFNBITJMPREF n** `(x – x)`, performs a **JMPREF** if bit `0 ≤ n ≤ 31` is not set in integer `x`. + +--- + +### A.8.3. Control flow primitives: loops + +Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. 4.1.5), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have \*BRK versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for \*ENDBRK versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for \*ENDBRK versions). + +* `E4` — **REPEAT** `(n c – )`, executes continuation `c` `n` times, if integer `n` is non-negative. If `n ≥ 2^31` or `n < −2^31`, generates a range check exception. Notice that a **RET** inside the code of `c` works as a continue, not as a break. One should use either alternative (experimental) loops or alternative **RETALT** (along with a **SETEXITALT** before the loop) to break out of a loop. +* `E5` — **REPEATEND** `(n – )`, similar to **REPEAT**, but it is applied to the current continuation `cc`. +* `E6` — **UNTIL** `(c – )`, executes continuation `c`, then pops an integer `x` from the resulting stack. If `x` is zero, performs another iteration of this loop. Implemented with extraordinary continuation `ec_until`. +* `E7` — **UNTILEND** `( – )`, similar to **UNTIL**, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs a **RET**. +* `E8` — **WHILE** `(c0 c – )`, executes `c0` and pops an integer `x` from the resulting stack. If `x = 0`, exits the loop and transfers control to the original `cc`. If `x ≠ 0`, executes `c`, and then begins a new iteration. +* `E9` — **WHILEEND** `(c0 – )`, similar to **WHILE**, but uses the current continuation `cc` as the loop body. +* `EA` — **AGAIN** `(c – )`, similar to **REPEAT**, but executes `c` infinitely many times. A **RET** only begins a new iteration of the infinite loop, which can be exited only by an exception, or a **RETALT** (or an explicit **JMPX**). +* `EB` — **AGAINEND** `( – )`, similar to **AGAIN**, but performed with respect to the current continuation `cc`. +* `E314` — **REPEATBRK** `(n c – )`, similar to **REPEAT**, but also sets `c1` to the original `cc` after saving the old value of `c1` into the savelist of the original `cc`. In this way **RETALT** could be used to break out of the loop body. +* `E315` — **REPEATENDBRK** `(n – )`, similar to **REPEATEND**, but also sets `c1` to the original `c0` after saving the old value of `c1` into the savelist of the original `c0`. Equivalent to `SAMEALTSAVE; REPEATEND`. +* `E316` — **UNTILBRK** `(c – )`, similar to **UNTIL**, but also modifies `c1` in the same way as **REPEATBRK**. +* `E317` — **UNTILENDBRK** `( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. +* `E318` — **WHILEBRK** `(c0 c – )`, similar to **WHILE**, but also modifies `c1` in the same way as **REPEATBRK**. +* `E319` — **WHILEENDBRK** `(c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. +* `E31A` — **AGAINBRK** `(c – )`, similar to **AGAIN**, but also modifies `c1` in the same way as **REPEATBRK**. +* `E31B` — **AGAINENDBRK** `( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. + +--- + +### A.9 Exception generating and handling primitives + +#### A.9.1. Throwing exceptions + +* `F22_nn` — **THROW nn** `( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. +* `F26_nn` — **THROWIF nn** `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. +* `F2A_nn` — **THROWIFNOT nn** `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. +* `F2C4_nn` — **THROW nn** for `0 ≤ nn < 2^11`, an encoding of **THROW nn** for larger values. +* `F2CC_nn` — **THROWARG nn** `(x – x nn)`, throws exception `0 ≤ nn < 2^11` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. +* `F2D4_nn` — **THROWIF nn** `(f – )` for `0 ≤ nn < 2^11`. +* `F2DC_nn` — **THROWARGIF nn** `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f ≠ 0`. +* `F2E4_nn` — **THROWIFNOT nn** `(f – )` for `0 ≤ nn < 2^11`. +* `F2EC_nn` — **THROWARGIFNOT nn** `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f = 0`. +* `F2F0` — **THROWANY** `(n – 0 n)`, throws exception `0 ≤ n < 2^16` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. +* `F2F1` — **THROWARGANY** `(x n – x n)`, throws exception `0 ≤ n < 2^16` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. +* `F2F2` — **THROWANYIF** `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f ≠ 0`. +* `F2F3` — **THROWARGANYIF** `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f ≠ 0`. +* `F2F4` — **THROWANYIFNOT** `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f = 0`. +* `F2F5` — **THROWARGANYIFNOT** `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f = 0`. + +#### A.9.2. Catching and handling exceptions + +* `F2FF` — **TRY** `(c c0 – )`, sets `c2` to `c0`, saving the old value of `c2` both into the savelist of `c0` and into the savelist of the current continuation. Then runs `c`. If `c` does not throw any exceptions, the original value of `c2` is restored. If an exception occurs, execution is transferred to `c0`. +* `F3pr` — **TRYARGS p,r** `(c c0 – )`, similar to **TRY**, but with **CALLARGS p,r** internally used instead of **EXECUTE**. + +--- + +# A.10 Dictionary manipulation primitives + +TVM’s dictionary support is discussed at length in 3.3. The basic operations with dictionaries are listed in 3.3.10, while the taxonomy of dictionary +115 +A.10. Dictionary manipulation primitives +manipulation primitives is provided in 3.3.11. Here we use the concepts and notation introduced in those sections. + +Dictionaries admit two different representations as TVM stack values: + +* A `Slice` `s` with a serialization of a TL-B value of type `HashmapE(n, X)`. In other words, `s` consists either of one bit equal to zero (if the dictionary is empty), or of one bit equal to one and a reference to a `Cell` containing the root of the binary tree, i.e., a serialized value of type `Hashmap(n, X)`. +* A “maybe `Cell`” `c ?`, i.e., a value that is either a `Cell` (containing a serialized value of type `Hashmap(n, X)` as before) or a `Null` (corresponding to an empty dictionary). When a “maybe `Cell`” `c ?` is used to represent a dictionary, we usually denote it by `D` in the stack notation. + +Most of the dictionary primitives listed below accept and return dictionaries in the second form, which is more convenient for stack manipulation. However, serialized dictionaries inside larger TL-B objects use the first representation. + +Opcodes starting with `F4` and `F5` are reserved for dictionary operations. + +## A.10.1. Dictionary creation. + +* `6D` — **NEWDICT** `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for **PUSHNULL**, cf. A.3.1. +* `6E` — **DICTEMPTY** `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for **ISNULL**, cf. A.3.1. + +## A.10.2. Dictionary serialization and deserialization. + +* `CE` — **STDICTS** `(s b – b 0)`, stores a `Slice`-represented dictionary `s` into `Builder` `b`. It is actually a synonym for **STSLICE**. +* `F400` — **STDICT** or **STOPTREF** `(D b – b 0)`, stores dictionary `D` into `Builder` `b`, returing the resulting `Builder` `b 0`. In other words, if `D` is a cell, performs **STONE** and **STREF**; if `D` is `Null`, performs **NIP** and **STZERO**; otherwise throws a type checking exception. +* `F401` — **SKIPDICT** or **SKIPOPTREF** `(s – s 0)`, equivalent to **LDDICT**; **NIP** +* `F402` — **LDDICTS** `(s – s 0 s 00)`, loads (parses) a (`Slice`-represented) dictionary `s 0` from `Slice` `s`, and returns the remainder of `s` as `s 00`. This is a “split function” for all `HashmapE(n, X)` dictionary types. +* `F403` — **PLDDICTS** `(s – s 0)`, preloads a (`Slice`-represented) dictionary `s 0` from `Slice` `s`. Approximately equivalent to **LDDICTS**; **DROP**. +* `F404` — **LDDICT** or **LDOPTREF** `(s – D s0)`, loads (parses) a dictionary `D` from `Slice` `s`, and returns the remainder of `s` as `s 0`. May be applied to dictionaries or to values of arbitrary `(ˆY ) ?` types. +* `F405` — **PLDDICT** or **PLDOPTREF** `(s – D)`, preloads a dictionary `D` from `Slice` `s`. Approximately equivalent to **LDDICT**; **DROP**. +* `F406` — **LDDICTQ** `(s – D s0 −1 or s 0)`, a quiet version of **LDDICT**. +* `F407` — **PLDDICTQ** `(s – D −1 or 0)`, a quiet version of **PLDDICT**. + +## A.10.3. Get dictionary operations. + +* `F40A` — **DICTGET** `(k D n – x −1 or 0)`, looks up key `k` (represented by a `Slice`, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the value found as a `Slice` `x`. +* `F40B` — **DICTGETREF** `(k D n – c −1 or 0)`, similar to **DICTGET**, but with a **LDREF**; **ENDS** applied to `x` on success. This operation is useful for dictionaries of type `HashmapE(n, ˆY )`. +* `F40C` — **DICTIGET** `(i D n – x −1 or 0)`, similar to **DICTGET**, but with a signed (big-endian) n-bit `Integer` `i` as a key. If `i` does not fit into n bits, returns `0`. If `i` is a `NaN`, throws an integer overflow exception. +* `F40D` — **DICTIGETREF** `(i D n – c −1 or 0)`, combines **DICTIGET** with **DICTGETREF**: it uses signed n-bit `Integer` `i` as a key and returns a `Cell` instead of a `Slice` on success. +* `F40E` — **DICTUGET** `(i D n – x −1 or 0)`, similar to **DICTIGET**, but with unsigned (big-endian) n-bit `Integer` `i` used as a key. +* `F40F` — **DICTUGETREF** `(i D n – c −1 or 0)`, similar to **DICTIGETREF**, but with an unsigned n-bit `Integer` key `i`. + 117 + A.10. Dictionary manipulation primitives + +## A.10.4. Set/Replace/Add dictionary operations. + +The mnemonics of the following dictionary primitives are constructed in a systematic fashion according to the regular expression `DICT[, I, U](SET, REPLACE, ADD)[GET][REF]` depending on the type of the key used (a `Slice` or a signed or unsigned `Integer`), the dictionary operation to be performed, and the way the values are accepted and returned (as `Cells` or as `Slices`). Therefore, we provide a detailed description only for some primitives, assuming that this information is sufficient for the reader to understand the precise action of the remaining primitives. + +* `F412` — **DICTSET** `(x k D n – D0)`, sets the value associated with n-bit key `k` (represented by a `Slice` as in **DICTGET**) in dictionary `D` (also represented by a `Slice`) to value `x` (again a `Slice`), and returns the resulting dictionary as `D0`. +* `F413` — **DICTSETREF** `(c k D n – D0)`, similar to **DICTSET**, but with the value set to a reference to `Cell` `c`. +* `F414` — **DICTISET** `(x i D n – D0)`, similar to **DICTSET**, but with the key represented by a (big-endian) signed n-bit integer `i`. If `i` does not fit into n bits, a range check exception is generated. +* `F415` — **DICTISETREF** `(c i D n – D0)`, similar to **DICTSETREF**, but with the key a signed n-bit integer as in **DICTISET**. +* `F416` — **DICTUSET** `(x i D n – D0)`, similar to **DICTISET**, but with `i` an unsigned n-bit integer. +* `F417` — **DICTUSETREF** `(c i D n – D0)`, similar to **DICTISETREF**, but with `i` unsigned. +* `F41A` — **DICTSETGET** `(x k D n – D0 y −1 or D0 0)`, combines **DICTSET** with **DICTGET**: it sets the value corresponding to key `k` to `x`, but also returns the old value `y` associated with the key in question, if present. +* `F41B` — **DICTSETGETREF** `(c k D n – D0 c 0 −1 or D0 0)`, combines **DICTSETREF** with **DICTGETREF** similarly to **DICTSETGET**. +* `F41C` — **DICTISETGET** `(x i D n – D0 y −1 or D0 0)`, similar to **DICTSETGET**, but with the key represented by a big-endian signed n-bit `Integer` `i` +* `F41D` — **DICTISETGETREF** `(c i D n – D0 c 0 −1 or D0 0)`, a version of **DICTSETGETREF** with signed `Integer` `i` as a key. +* `F41E` — **DICTUSETGET** `(x i D n – D0 y −1 or D0 0)`, similar to **DICTISETGET**, but with `i` an unsigned n-bit integer. +* `F41F` — **DICTUSETGETREF** `(c i D n – D0 c 0 −1 or D0 0)`. +* `F422` — **DICTREPLACE** `(x k D n – D0 −1 or D 0)`, a Replace operation, which is similar to **DICTSET**, but sets the value of key `k` in dictionary `D` to `x` only if the key `k` was already present in `D`. +* `F423` — **DICTREPLACEREF** `(c k D n – D0 −1 or D 0)`, a Replace counterpart of **DICTSETREF**. +* `F424` — **DICTIREPLACE** `(x i D n – D0 −1 or D 0)`, a version of **DICTREPLACE** with signed n-bit `Integer` `i` used as a key. +* `F425` — **DICTIREPLACEREF** `(c i D n – D0 −1 or D 0)`. +* `F426` — **DICTUREPLACE** `(x i D n – D0 −1 or D 0)`. +* `F427` — **DICTUREPLACEREF** `(c i D n – D0 −1 or D 0)`. +* `F42A` — **DICTREPLACEGET** `(x k D n – D0 y −1 or D 0)`, a Replace counterpart of **DICTSETGET**: on success, also returns the old value associated with the key in question. +* `F42B` — **DICTREPLACEGETREF** `(c k D n – D0 c 0 −1 or D 0)`. +* `F42C` — **DICTIREPLACEGET** `(x i D n – D0 y −1 or D 0)`. +* `F42D` — **DICTIREPLACEGETREF** `(c i D n – D0 c 0 −1 or D 0)`. +* `F42E` — **DICTUREPLACEGET** `(x i D n – D0 y −1 or D 0)`. +* `F42F` — **DICTUREPLACEGETREF** `(c i D n – D0 c 0 −1 or D 0)`. +* `F432` — **DICTADD** `(x k D n – D0 −1 or D 0)`, an Add counterpart of **DICTSET**: sets the value associated with key `k` in dictionary `D` to `x`, but only if it is not already present in `D`. +* `F433` — **DICTADDREF** `(c k D n – D0 −1 or D 0)`. + 119 + A.10. Dictionary manipulation primitives +* `F434` — **DICTIADD** `(x i D n – D0 −1 or D 0)`. +* `F435` — **DICTIADDREF** `(c i D n – D0 −1 or D 0)`. +* `F436` — **DICTUADD** `(x i D n – D0 −1 or D 0)`. +* `F437` — **DICTUADDREF** `(c i D n – D0 −1 or D 0)`. +* `F43A` — **DICTADDGET** `(x k D n – D0 −1 or D y 0)`, an Add counterpart of **DICTSETGET**: sets the value associated with key `k` in dictionary `D` to `x`, but only if key `k` is not already present in `D`. Otherwise, just returns the old value `y` without changing the dictionary. +* `F43B` — **DICTADDGETREF** `(c k D n – D0 −1 or D c0 0)`, an Add counterpart of **DICTSETGETREF**. +* `F43C` — **DICTIADDGET** `(x i D n – D0 −1 or D y 0)`. +* `F43D` — **DICTIADDGETREF** `(c i D n – D0 −1 or D c0 0)`. +* `F43E` — **DICTUADDGET** `(x i D n – D0 −1 or D y 0)`. +* `F43F` — **DICTUADDGETREF** `(c i D n – D0 −1 or D c0 0)`. + +## A.10.5. Builder-accepting variants of Set dictionary operations. + +The following primitives accept the new value as a `Builder` `b` instead of a `Slice` `x`, which often is more convenient if the value needs to be serialized from several components computed in the stack. (This is reflected by appending a `B` to the mnemonics of the corresponding Set primitives that work with `Slices`.) The net effect is roughly equivalent to converting `b` into a `Slice` by **ENDC**; **CTOS** and executing the corresponding primitive listed in A.10.4. + +* `F441` — **DICTSETB** `(b k D n – D0)`. +* `F442` — **DICTISETB** `(b i D n – D0)`. +* `F443` — **DICTUSETB** `(b i D n – D0)`. +* `F445` — **DICTSETGETB** `(b k D n – D0 y −1 or D0 0)`. +* `F446` — **DICTISETGETB** `(b i D n – D0 y −1 or D0 0)`. +* `F447` — **DICTUSETGETB** `(b i D n – D0 y −1 or D0 0)`. +* `F449` — **DICTREPLACEB** `(b k D n – D0 −1 or D 0)`. +* `F44A` — **DICTIREPLACEB** `(b i D n – D0 −1 or D 0)`. +* `F44B` — **DICTUREPLACEB** `(b i D n – D0 −1 or D 0)`. +* `F44D` — **DICTREPLACEGETB** `(b k D n – D0 y −1 or D 0)`. +* `F44E` — **DICTIREPLACEGETB** `(b i D n – D0 y −1 or D 0)`. +* `F44F` — **DICTUREPLACEGETB** `(b i D n – D0 y −1 or D 0)`. +* `F451` — **DICTADDB** `(b k D n – D0 −1 or D 0)`. +* `F452` — **DICTIADDB** `(b i D n – D0 −1 or D 0)`. +* `F453` — **DICTUADDB** `(b i D n – D0 −1 or D 0)`. +* `F455` — **DICTADDGETB** `(b k D n – D0 −1 or D y 0)`. +* `F456` — **DICTIADDGETB** `(b i D n – D0 −1 or D y 0)`. +* `F457` — **DICTUADDGETB** `(b i D n – D0 −1 or D y 0)`. + +## A.10.6. Delete dictionary operations. + +* `F459` — **DICTDEL** `(k D n – D0 −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0` and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. +* `F45A` — **DICTIDEL** `(i D n – D0 ?)`, a version of **DICTDEL** with the key represented by a signed n-bit `Integer` `i`. If `i` does not fit into n bits, simply returns `D 0` (“key not found, dictionary unmodified”). +* `F45B` — **DICTUDEL** `(i D n – D0 ?)`, similar to **DICTIDEL**, but with `i` an unsigned n-bit integer. +* `F462` — **DICTDELGET** `(k D n – D0 x −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0`, the original value `x` associated with the key `k` (represented by a `Slice`), and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. + 121 + A.10. Dictionary manipulation primitives +* `F463` — **DICTDELGETREF** `(k D n – D0 c −1 or D 0)`, similar to **DICTDELGET**, but with **LDREF**; **ENDS** applied to `x` on success, so that the value returned `c` is a `Cell`. +* `F464` — **DICTIDELGET** `(i D n – D0 x −1 or D 0)`, a variant of primitive **DICTDELGET** with signed n-bit integer `i` as a key. +* `F465` — **DICTIDELGETREF** `(i D n – D0 c −1 or D 0)`, a variant of primitive **DICTIDELGET** returning a `Cell` instead of a `Slice`. +* `F466` — **DICTUDELGET** `(i D n – D0 x −1 or D 0)`, a variant of primitive **DICTDELGET** with unsigned n-bit integer `i` as a key. +* `F467` — **DICTUDELGETREF** `(i D n – D0 c −1 or D 0)`, a variant of primitive **DICTUDELGET** returning a `Cell` instead of a `Slice`. + +## A.10.7. “Maybe reference” dictionary operations. + +The following operations assume that a dictionary is used to store values `c ?` of type `Cell ?` (“Maybe `Cell`”), which can be used in particular to store dictionaries as values in other dictionaries. The representation is as follows: if `c ?` is a `Cell`, it is stored as a value with no data bits and exactly one reference to this `Cell`. If `c ?` is `Null`, then the corresponding key must be absent from the dictionary altogether. + +* `F469` — **DICTGETOPTREF** `(k D n – c ? )`, a variant of **DICTGETREF** that returns `Null` instead of the value `c ?` if the key `k` is absent from dictionary `D`. +* `F46A` — **DICTIGETOPTREF** `(i D n – c ? )`, similar to **DICTGETOPTREF**, but with the key given by signed n-bit `Integer` `i`. If the key `i` is out of range, also returns `Null`. +* `F46B` — **DICTUGETOPTREF** `(i D n – c ? )`, similar to **DICTGETOPTREF**, but with the key given by unsigned n-bit `Integer` `i`. +* `F46D` — **DICTSETGETOPTREF** `(c ? k D n – D0 c˜ ? )`, a variant of both **DICTGETOPTREF** and **DICTSETGETREF** that sets the value corresponding to key `k` in dictionary `D` to `c ?` (if `c ?` is `Null`, then the key is deleted instead), and returns the old value `c˜ ?` (if the key `k` was absent before, returns `Null` instead). +* `F46E` — **DICTISETGETOPTREF** `(c ? i D n – D0 c˜ ? )`, similar to primitive **DICTSETGETOPTREF**, but using signed n-bit `Integer` `i` as a key. If `i` does not fit into n bits, throws a range checking exception. +* `F46F` — **DICTUSETGETOPTREF** `(c ? i D n – D0 c˜ ? )`, similar to primitive **DICTSETGETOPTREF**, but using unsigned n-bit `Integer` `i` as a key. + +## A.10.8. Prefix code dictionary operations. + +These are some basic operations for constructing prefix code dictionaries (cf. 3.4.2). The primary application for prefix code dictionaries is deserializing TL-B serialized data structures, or, more generally, parsing prefix codes. Therefore, most prefix code dictionaries will be constant and created at compile time, not by the following primitives. +Some Get operations for prefix code dictionaries may be found in A.10.11. +Other prefix code dictionary operations include: + +* `F470` — **PFXDICTSET** `(x k D n – D0 −1 or D 0)`. +* `F471` — **PFXDICTREPLACE** `(x k D n – D0 −1 or D 0)`. +* `F472` — **PFXDICTADD** `(x k D n – D0 −1 or D 0)`. +* `F473` — **PFXDICTDEL** `(k D n – D0 −1 or D 0)`. + +These primitives are completely similar to their non-prefix code counterparts **DICTSET** etc (cf. A.10.4), with the obvious difference that even a Set may fail in a prefix code dictionary, so a success flag must be returned by **PFXDICTSET** as well. + +## A.10.9. Variants of GetNext and GetPrev operations. + +* `F474` — **DICTGETNEXT** `(k D n – x 0 k 0 −1 or 0)`, computes the minimal key `k 0` in dictionary `D` that is lexicographically greater than `k`, and returns `k 0` (represented by a `Slice`) along with associated value `x 0` (also represented by a `Slice`). +* `F475` — **DICTGETNEXTEQ** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETNEXT**, but computes the minimal key `k 0` that is lexicographically greater than or equal to `k`. +* `F476` — **DICTGETPREV** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETNEXT**, but computes the maximal key `k 0` lexicographically smaller than `k`. + 123 + A.10. Dictionary manipulation primitives +* `F477` — **DICTGETPREVEQ** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETPREV**, but computes the maximal key `k 0` lexicographically smaller than or equal to `k`. +* `F478` — **DICTIGETNEXT** `(i D n – x 0 i 0 −1 or 0)`, similar to **DICTGETNEXT**, but interprets all keys in dictionary `D` as big-endian signed n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits). +* `F479` — **DICTIGETNEXTEQ** `(i D n – x 0 i 0 −1 or 0)`. +* `F47A` — **DICTIGETPREV** `(i D n – x 0 i 0 −1 or 0)`. +* `F47B` — **DICTIGETPREVEQ** `(i D n – x 0 i 0 −1 or 0)`. +* `F47C` — **DICTUGETNEXT** `(i D n – x 0 i 0 −1 or 0)`, similar to **DICTGETNEXT**, but interprets all keys in dictionary `D` as big-endian unsigned n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits, and is not necessarily nonnegative). +* `F47D` — **DICTUGETNEXTEQ** `(i D n – x 0 i 0 −1 or 0)`. +* `F47E` — **DICTUGETPREV** `(i D n – x 0 i 0 −1 or 0)`. +* `F47F` — **DICTUGETPREVEQ** `(i D n – x 0 i 0 −1 or 0)`. + +## A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. + +* `F482` — **DICTMIN** `(D n – x k −1 or 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. +* `F483` — **DICTMINREF** `(D n – c k −1 or 0)`, similar to **DICTMIN**, but returns the only reference in the value as a `Cell` `c`. +* `F484` — **DICTIMIN** `(D n – x i −1 or 0)`, somewhat similar to **DICTMIN**, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by **DICTMIN** and **DICTUMIN** +* `F485` — **DICTIMINREF** `(D n – c i −1 or 0)`. +* `F486` — **DICTUMIN** `(D n – x i −1 or 0)`, similar to **DICTMIN**, but returns the key as an unsigned n-bit `Integer` `i`. +* `F487` — **DICTUMINREF** `(D n – c i −1 or 0)`. +* `F48A` — **DICTMAX** `(D n – x k −1 or 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. +* `F48B` — **DICTMAXREF** `(D n – c k −1 or 0)`. +* `F48C` — **DICTIMAX** `(D n – x i −1 or 0)`. +* `F48D` — **DICTIMAXREF** `(D n – c i −1 or 0)`. +* `F48E` — **DICTUMAX** `(D n – x i −1 or 0)`. +* `F48F` — **DICTUMAXREF** `(D n – c i −1 or 0)`. +* `F492` — **DICTREMMIN** `(D n – D0 x k −1 or D 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. +* `F493` — **DICTREMMINREF** `(D n – D0 c k −1 or D 0)`, similar to **DICTREMMIN**, but returns the only reference in the value as a `Cell` `c`. +* `F494` — **DICTIREMMIN** `(D n – D0 x i −1 or D 0)`, somewhat similar to **DICTREMMIN**, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by **DICTREMMIN** and **DICTUREMMIN**. +* `F495` — **DICTIREMMINREF** `(D n – D0 c i −1 or D 0)`. +* `F496` — **DICTUREMMIN** `(D n – D0 x i −1 or D 0)`, similar to **DICTREMMIN**, but returns the key as an unsigned n-bit `Integer` `i`. +* `F497` — **DICTUREMMINREF** `(D n – D0 c i −1 or D 0)`. + 125 + A.10. Dictionary manipulation primitives +* `F49A` — **DICTREMMAX** `(D n – D0 x k −1 or D 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. +* `F49B` — **DICTREMMAXREF** `(D n – D0 c k −1 or D 0)`. +* `F49C` — **DICTIREMMAX** `(D n – D0 x i −1 or D 0)`. +* `F49D` — **DICTIREMMAXREF** `(D n – D0 c i −1 or D 0)`. +* `F49E` — **DICTUREMMAX** `(D n – D0 x i −1 or D 0)`. +* `F49F` — **DICTUREMMAXREF** `(D n – D0 c i −1 or D 0)`. + +## A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. + +* `F4A0` — **DICTIGETJMP** `(i D n – )`, similar to **DICTIGET** (cf. A.10.12), but with `x` **BLESS**ed into a continuation with a subsequent **JMPX** to it on success. On failure, does nothing. This is useful for implementing switch/case constructions. +* `F4A1` — **DICTUGETJMP** `(i D n – )`, similar to **DICTIGETJMP**, but performs **DICTUGET** instead of **DICTIGET**. +* `F4A2` — **DICTIGETEXEC** `(i D n – )`, similar to **DICTIGETJMP**, but with **EXECUTE** instead of **JMPX**. +* `F4A3` — **DICTUGETEXEC** `(i D n – )`, similar to **DICTUGETJMP**, but with **EXECUTE** instead of **JMPX**. +* `F4A6_n` — **DICTPUSHCONST n** `( – D n)`, pushes a non-empty constant dictionary `D` (as a `Cell ?`) along with its key length `0 ≤ n ≤ 1023`, stored as a part of the instruction. The dictionary itself is created from the first of remaining references of the current continuation. In this way, the complete **DICTPUSHCONST** instruction can be obtained by first serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and a cell reference), and then the unsigned 10-bit integer `n` (as if by a **STU 10** instruction). An empty dictionary can be pushed by a **NEWDICT** primitive (cf. A.10.1) instead. +* `F4A8` — **PFXDICTGETQ** `(s D n – s 0 x s00 −1 or s 0)`, looks up the unique prefix of `Slice` `s` present in the prefix code dictionary (cf. 3.4.2) represented by `Cell ?` `D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is returned as `s 0`, and the corresponding value (also a `Slice`) as `x`. The remainder of `s` is returned as a `Slice` `s 00`. If no prefix of `s` is a key in prefix code dictionary `D`, returns the unchanged `s` and a zero flag to indicate failure. +* `F4A9` — **PFXDICTGET** `(s D n – s 0 x s00)`, similar to **PFXDICTGET**, but throws a cell deserialization failure exception on failure. +* `F4AA` — **PFXDICTGETJMP** `(s D n – s 0 s 00 or s)`, similar to **PFXDICTGETQ**, but on success **BLESS**es the value `x` into a `Continuation` and transfers control to it as if by a **JMPX**. On failure, returns `s` unchanged and continues execution. +* `F4AB` — **PFXDICTGETEXEC** `(s D n – s 0 s 00)`, similar to **PFXDICTGETJMP**, but **EXEC**utes the continuation found instead of jumping to it. On failure, throws a cell deserialization exception. +* `F4AE_n` — **PFXDICTCONSTGETJMP n** or **PFXDICTSWITCH n** `(s – s 0 s 00 or s)`, combines **DICTPUSHCONST n** for `0 ≤ n ≤ 1023` with **PFXDICTGETJMP**. +* `F4BC` — **DICTIGETJMPZ** `(i D n – i or nothing)`, a variant of **DICTIGETJMP** that returns index `i` on failure. +* `F4BD` — **DICTUGETJMPZ** `(i D n – i or nothing)`, a variant of **DICTUGETJMP** that returns index `i` on failure. +* `F4BE` — **DICTIGETEXECZ** `(i D n – i or nothing)`, a variant of **DICTIGETEXEC** that returns index `i` on failure. +* `F4BF` — **DICTUGETEXECZ** `(i D n – i or nothing)`, a variant of **DICTUGETEXEC** that returns index `i` on failure. + +## A.10.12. SubDict dictionary operations. + +* `F4B1` — **SUBDICTGET** `(k l D n – D0)`, constructs a subdictionary consisting of all keys beginning with prefix `k` (represented by a `Slice`, the first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, + 127 + A.11. Application-specific primitives + returns the new subdictionary of the same type `HashmapE(n, X)` as a `Slice` `D0`. +* `F4B2` — **SUBDICTIGET** `(x l D n – D0)`, variant of **SUBDICTGET** with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. +* `F4B3` — **SUBDICTUGET** `(x l D n – D0)`, variant of **SUBDICTGET** with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. +* `F4B5` — **SUBDICTRPGET** `(k l D n – D0)`, similar to **SUBDICTGET**, but removes the common prefix `k` from all keys of the new dictionary `D0`, which becomes of type `HashmapE(n − l, X)`. +* `F4B6` — **SUBDICTIRPGET** `(x l D n – D0)`, variant of **SUBDICTRPGET** with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. +* `F4B7` — **SUBDICTURPGET** `(x l D n – D0)`, variant of **SUBDICTRPGET** with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. +* `F4BC–F4BF` — used by **DICT...Z** primitives in A.10.11. + +--- +# A.11 Application-specific primitives + +Opcode range `F8...FB` is reserved for the application-specific primitives. When TVM is used to execute TON Blockchain smart contracts, these application-specific primitives are in fact TON Blockchain-specific. + +## A.11.1. External actions and access to blockchain configuration data. + +Some of the primitives listed below pretend to produce some externally visible actions, such as sending a message to another smart contract. In fact, the execution of a smart contract in TVM never has any effect apart from a modification of the TVM state. All external actions are collected into a linked list stored in special register `c5` (“output actions”). Additionally, some primitives use the data kept in the first component of the Tuple stored in `c7` (“root of temporary data”, cf. 1.3.2). Smart contracts are free to modify any other data kept in the cell `c7`, provided the first reference remains intact (otherwise some application-specific primitives would be likely to throw exceptions when invoked). + +Most of the primitives listed below use 16-bit opcodes. + +A.11. Application-specific primitives + +## A.11.2. Gas-related primitives. + +Of the following primitives, only the first two are “pure” in the sense that they do not use `c5` or `c7`. + +* `F800` — **ACCEPT**, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. 1.4), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence no gas) with themselves. +* `F801` — **SETGASLIMIT** `(g – )`, sets current gas limit `gl` to the minimum of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed so far (including the present instruction) exceeds the resulting value of `gl`, an (unhandled) out of gas exception is thrown before setting new gas limits. Notice that **SETGASLIMIT** with an argument `g ≥ 2^63 − 1` is equivalent to **ACCEPT**. +* `F802` — **BUYGAS** `(x – )`, computes the amount of gas that can be bought for `x` nanograms, and sets `gl` accordingly in the same way as **SETGASLIMIT**. +* `F804` — **GRAMTOGAS** `(x – g)`, computes the amount of gas that can be bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `2^63−1`, it is replaced with this value. +* `F805` — **GASTOGRAM** `(g – x)`, computes the price of `g` gas in nanograms. +* `F806–F80E` — Reserved for gas-related primitives. +* `F80F` — **COMMIT** `( – )`, commits the current state of registers `c4` (“persistent data”) and `c5` (“actions”) so that the current execution is considered “successful” with the saved values even if an exception is thrown later. + +## A.11.3. Pseudo-random number generator primitives. + +The pseudo-random number generator uses the random seed (parameter `#6`, cf. A.11.4), an unsigned 256-bit `Integer`, and (sometimes) other data kept in `c7`. +The initial value of the random seed before a smart contract is executed in TON Blockchain is a hash of the smart contract address and the global block random seed. If there are several runs of the same smart contract inside a block, then all of these runs will have the same random seed. This can be fixed, for example, by running **LTIME**; **ADDRAND** before using the pseudo-random number generator for the first time. + +* `F810` — **RANDU256** `( – x)`, generates a new pseudo-random unsigned 256-bit `Integer` `x`. The algorithm is as follows: if `r` is the old value of the random seed, considered as a 32-byte array (by constructing the big-endian representation of an unsigned 256-bit integer), then its `sha512(r)` is computed; the first 32 bytes of this hash are stored as the new value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`. +* `F811` — **RAND** `(y – z)`, generates a new pseudo-random integer `z` in the range `0 ... y − 1` (or `y ... − 1`, if `y < 0`). More precisely, an unsigned random value `x` is generated as in **RAND256U**; then `z := ⌊x·y/2^256⌋` is computed. Equivalent to **RANDU256**; **MULRSHIFT** `256`. +* `F814` — **SETRAND** `(x – )`, sets the random seed to unsigned 256-bit `Integer` `x`. +* `F815` — **ADDRAND** `(x – )`, mixes unsigned 256-bit `Integer` `x` into the random seed `r` by setting the random seed to `sha256` of the concatenation of two 32-byte strings: the first with the big-endian representation of the old seed `r`, and the second with the big-endian representation of `x`. +* `F810–F81F` — Reserved for pseudo-random number generator primitives. + `129` + A.11. Application-specific primitives + +## A.11.4. Configuration primitives. + +The following primitives read configuration data provided in the Tuple stored in the first component of the Tuple at `c7`. Whenever TVM is invoked for executing TON Blockchain smart contracts, this Tuple is initialized by a `SmartContractInfo` structure; configuration primitives assume that it has remained intact. + +* `F82i` — **GETPARAM** `i` `( – x)`, returns the `i`-th parameter from the Tuple provided at `c7` for `0 ≤ i < 16`. Equivalent to **PUSH** `c7`; **FIRST**; **INDEX** `i`. If one of these internal operations fails, throws an appropriate type checking or range checking exception +* `F823` — **NOW** `( – x)`, returns the current Unix time as an `Integer`. If it is impossible to recover the requested value starting from `c7`, throws a type checking or range checking exception as appropriate. Equivalent to **GETPARAM** `3`. +* `F824` — **BLOCKLT** `( – x)`, returns the starting logical time of the current block. Equivalent to **GETPARAM** `4`. +* `F825` — **LTIME** `( – x)`, returns the logical time of the current transaction. Equivalent to **GETPARAM** `5`. +* `F826` — **RANDSEED** `( – x)`, returns the current random seed as an unsigned 256-bit `Integer`. Equivalent to **GETPARAM** `6`. +* `F827` — **BALANCE** `( – t)`, returns the remaining balance of the smart contract as a `Tuple` consisting of an `Integer` (the remaining Gram balance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys representing the balance of “extra currencies”). Equivalent to **GETPARAM** `7`. Note that RAW primitives such as **SENDRAWMSG** do not update this field. +* `F828` — **MYADDR** `( – s)`, returns the internal address of the current smart contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed further using primitives such as **PARSESTDADDR** or **REWRITESTDADDR**. Equivalent to **GETPARAM** `8`. +* `F829` — **CONFIGROOT** `( – D)`, returns the `Maybe Cell` `D` with the current global configuration dictionary. Equivalent to **GETPARAM** `9`. +* `F830` — **CONFIGDICT** `( – D 32)`, returns the global configuration dictionary along with its key length (`32`). Equivalent to **CONFIGROOT**; **PUSHINT** `32`. +* `F832` — **CONFIGPARAM** `(i – c −1 or 0)`, returns the value of the global configuration parameter with integer index `i` as a `Cell` `c`, and a flag to indicate success. Equivalent to **CONFIGDICT**; **DICTIGETREF**. +* `F833` — **CONFIGOPTPARAM** `(i – c ? )`, returns the value of the global configuration parameter with integer index `i` as a `Maybe Cell` `c ?`. Equivalent to **CONFIGDICT**; **DICTIGETOPTREF**. +* `F820–F83F` — Reserved for configuration primitives. + `131` + A.11. Application-specific primitives + +## A.11.5. Global variable primitives. + +The “global variables” may be helpful in implementing some high-level smart-contract languages. They are in fact stored as components of the Tuple at `c7`: the `k`-th global variable simply is the `k`-th component of this Tuple, for `1 ≤ k ≤ 254`. By convention, the `0`-th component is used for the “configuration parameters” of A.11.4, so it is not available as a global variable. + +* `F840` — **GETGLOBVAR** `(k – x)`, returns the `k`-th global variable for `0 ≤ k < 255`. Equivalent to **PUSH** `c7`; **SWAP**; **INDEXVARQ** (cf. A.3.2). +* `F85_k` — **GETGLOB** `k` `( – x)`, returns the `k`-th global variable for `1 ≤ k ≤ 31`. Equivalent to **PUSH** `c7`; **INDEXQ** `k`. +* `F860` — **SETGLOBVAR** `(x k – )`, assigns `x` to the `k`-th global variable for `0 ≤ k < 255`. Equivalent to **PUSH** `c7`; **ROTREV**; **SETINDEXVARQ**; **POP** `c7`. +* `F87_k` — **SETGLOB** `k` `(x – )`, assigns `x` to the `k`-th global variable for `1 ≤ k ≤ 31`. Equivalent to **PUSH** `c7`; **SWAP**; **SETINDEXQ** `k`; **POP** `c7`. + +## A.11.6. Hashing and cryptography primitives. + +* `F900` — **HASHCU** `(c – x)`, computes the representation hash (cf. 3.1.5) of a `Cell` `c` and returns it as a 256-bit unsigned integer `x`. Useful for signing and checking signatures of arbitrary entities represented by a tree of cells. +* `F901` — **HASHSU** `(s – x)`, computes the hash of a `Slice` `s` and returns it as a 256-bit unsigned integer `x`. The result is the same as if an ordinary cell containing only data and references from `s` had been created and its hash computed by **HASHCU**. +* `F902` — **SHA256U** `(s – x)`, computes `sha256` of the data bits of `Slice` `s`. If the bit length of `s` is not divisible by eight, throws a cell underflow exception. The hash value is returned as a 256-bit unsigned integer `x`. +* `F910` — **CHKSIGNU** `(h s k – ? )`, checks the Ed25519-signature `s` of a hash `h` (a 256-bit unsigned integer, usually computed as the hash of some data) using public key `k` (also represented by a 256-bit unsigned integer). The signature `s` must be a `Slice` containing at least 512 databits; only the first 512 bits are used. The result is `−1` if the signature is valid, `0` otherwise. Notice that **CHKSIGNU** is equivalent to **ROT**; **NEWB**; **STU** `256`; **ENDB**; **NEWC**; **ROTREV**; **CHKSIGNS**, i.e., to **CHKSIGNS** with the first argument `d` set to 256-bit `Slice` containing `h`. Therefore, if `h` is computed as the hash of some data, these data are hashed twice, the second hashing occurring inside **CHKSIGNS**. +* `F911` — **CHKSIGNS** `(d s k – ? )`, checks whether `s` is a valid Ed25519-signature of the data portion of `Slice` `d` using public key `k`, similarly to **CHKSIGNU**. If the bit length of `Slice` `d` is not divisible by eight, throws a cell underflow exception. The verification of Ed25519 signatures is the standard one, with `sha256` used to reduce `d` to the 256-bit number that is actually signed. +* `F912–F93F` — Reserved for hashing and cryptography primitives. + +## A.11.7. Miscellaneous primitives. + +* `F940` — **CDATASIZEQ** `(c n – x y z −1 or 0)`, recursively computes the count of distinct cells `x`, data bits `y`, and cell references `z` in the dag rooted at `Cell` `c`, effectively returning the total storage used by this dag taking into account the identification of equal cells. The values of `x`, `y`, and `z` are computed by a depth-first traversal of this dag, with a hash table of visited cell hashes used to prevent visits of already-visited cells. The total count of visited cells `x` cannot exceed non-negative `Integer` `n`; otherwise the computation is aborted before visiting the `(n + 1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, returns `x = y = z = 0`. +* `F941` — **CDATASIZE** `(c n – x y z)`, a non-quiet version of **CDATASIZEQ** that throws a cell overflow exception (8) on failure. +* `F942` — **SDATASIZEQ** `(s n – x y z −1 or 0)`, similar to **CDATASIZEQ**, but accepting a `Slice` `s` instead of a `Cell`. The returned value of `x` does not take into account the cell that contains the slice `s` itself; however, the data bits and the cell references of `s` are accounted for in `y` and `z`. +* `F943` — **SDATASIZE** `(s n – x y z)`, a non-quiet version of **SDATASIZEQ** that throws a cell overflow exception (8) on failure. +* `F944–F97F` — Reserved for miscellaneous TON-specific primitives that do not fall into any other specific category. + `133` + A.11. Application-specific primitives + +## A.11.8. Currency manipulation primitives. + +* `FA00` — **LDGRAMS** or **LDVARUINT16** `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to **LDU** `4`; **SWAP**; **LSHIFT** `3`; **LDUX**. +* `FA01` — **LDVARINT16** `(s – x s0)`, similar to **LDVARUINT16**, but loads a signed `Integer` `x`. Approximately equivalent to **LDU** `4`; **SWAP**; **LSHIFT** `3`; **LDIX**. +* `FA02` — **STGRAMS** or **STVARUINT16** `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2^120−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2^(8l)`, followed by an `8l`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. +* `FA03` — **STVARINT16** `(b x – b 0)`, similar to **STVARUINT16**, but serializes a signed `Integer` `x` in the range `−2^119 ... 2^119 − 1`. +* `FA04` — **LDVARUINT32** `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2^248`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to **LDU** `5`; **SWAP**; **SHIFT** `3`; **LDUX**. +* `FA05` — **LDVARINT32** `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2^247 ≤ x < 2^247`. +* `FA06` — **STVARUINT32** `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2^248` as a `VarUInteger 32`. +* `FA07` — **STVARINT32** `(b x – b 0)`, serializes an `Integer` `−2^247 ≤ x < 2^247` as a `VarInteger 32`. +* `FA08–FA1F` — Reserved for currency manipulation primitives. + +## A.11.9. Message and address manipulation primitives. + +The message and address manipulation primitives listed below serialize and deserialize values according to the following TL-B scheme (cf. 3.3.4): + +``` +addr_none$00 = MsgAddressExt; +addr_extern$01 len:(## 8) external_address:(bits len) = MsgAddressExt; +anycast_info$_ depth:(#<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; +addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt; +addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) workchain_id:int32 address:(bits addr_len) = MsgAddressInt; +_ _:MsgAddressInt = MsgAddress; +_ _:MsgAddressExt = MsgAddress; + +int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + src:MsgAddress dest:MsgAddressInt + value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams + created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; + +ext_out_msg_info$11 src:MsgAddress dest:MsgAddressExt + created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; +``` + +A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: + +* `addr_none` is represented by `t = (0)`, i.e., a `Tuple` containing exactly one `Integer` equal to zero. +* `addr_extern` is represented by `t = (1, s)`, where `Slice` `s` contains the field `external_address`. In other words, `t` is a pair (a `Tuple` consisting of two entries), containing an `Integer` equal to one and `Slice` `s`. +* `addr_std` is represented by `t = (2, u, x, s)`, where `u` is either a `Null` (if `anycast` is absent) or a `Slice` `s0` containing `rewrite_pfx` (if `anycast` is present). Next, `Integer` `x` is the `workchain_id`, and `Slice` `s` contains the address. + `135` + A.11. Application-specific primitives +* `addr_var` is represented by `t = (3, u, x, s)`, where `u`, `x`, and `s` have the same meaning as for `addr_std`. + +The following primitives, which use the above conventions, are defined: + +* `FA40` — **LDMSGADDR** `(s – s 0 s 00)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s 0` and the remainder `s 00` of `s` as `CellSlices`. +* `FA41` — **LDMSGADDRQ** `(s – s 0 s 00 −1 or s 0)`, a quiet version of **LDMSGADDR**: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. +* `FA42` — **PARSEMSGADDR** `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. +* `FA43` — **PARSEMSGADDRQ** `(s – t −1 or 0)`, a quiet version of **PARSEMSGADDR**: returns a zero on error instead of throwing an exception. +* `FA44` — **REWRITESTDADDR** `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. +* `FA45` — **REWRITESTDADDRQ** `(s – x y −1 or 0)`, a quiet version of primitive **REWRITESTDADDR**. +* `FA46` — **REWRITEVARADDR** `(s – x s0)`, a variant of **REWRITESTDADDR** that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). +* `FA47` — **REWRITEVARADDRQ** `(s – x s0 −1 or 0)`, a quiet version of primitive **REWRITEVARADDR**. +* `FA48–FA5F` — Reserved for message and address manipulation primitives. + +## A.11.10. Outbound message and output action primitives. + +* `FB00` — **SENDRAWMSG** `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. +* `FB02` — **RAWRESERVE** `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. +* `FB03` — **RAWRESERVEX** `(x D y – )`, similar to **RAWRESERVE**, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. + `137` + A.12. Debug primitives +* `FB04` — **SETCODE** `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. +* `FB06` — **SETLIBCODE** `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. +* `FB07` — **CHANGELIB** `(h x – )`, creates an output action similarly to **SETLIBCODE**, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. +* `FB08–FB3F` — Reserved for output action primitives. + +--- +# A.12 Debug primitives + +Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) **NOP** operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. + +## A.12.1. Debug primitives as multibyte NOPs. + +`138` +A.12. Debug primitives + +* `FEnn` — **DEBUG** `nn`, for `0 ≤ nn < 240`, is a two-byte **NOP**. +* `FEFnssss` — **DEBUGSTR** `ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte **NOP**, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. + +## A.12.2. Debug primitives as operations without side-effect. + +Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte **NOP**s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as **NOP**s, but they cannot throw exceptions. + +* `FE00` — **DUMPSTK**, dumps the stack (at most the top 255 values) and shows the total stack depth. +* `FE0n` — **DUMPSTKTOP** `n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. +* `FE10` — **HEXDUMP**, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. +* `FE11` — **HEXPRINT**, similar to **HEXDUMP**, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. +* `FE12` — **BINDUMP**, dumps `s0` in binary form, similarly to **HEXDUMP**. +* `FE13` — **BINPRINT**, outputs the binary representation of `s0` to a text buffer. +* `FE14` — **STRDUMP**, dumps the `Slice` at `s0` as an UTF-8 string. +* `FE15` — **STRPRINT**, similar to **STRDUMP**, but outputs the string into a text buffer (without carriage return). +* `FE1E` — **DEBUGOFF**, disables all debug output until it is re-enabled by a **DEBUGON**. More precisely, this primitive increases an internal counter, which disables all debug operations (except **DEBUGOFF** and **DEBUGON**) when strictly positive. + `139` + A.13. Codepage primitives +* `FE1F` — **DEBUGON**, enables debug output (in a debug version of TVM). +* `FE2n` — **DUMP s(n)**, `0 ≤ n < 15`, dumps `s(n)`. +* `FE3n` — **PRINT s(n)**, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. +* `FEC0–FEEF` — Use these opcodes for custom/experimental debug operations. +* `FEFnssss` — **DUMPTOSFMT** `ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). +* `FEFn00ssss` — **LOGSTR** `ssss`, string `ssss` is `n` bytes long. +* `FEF000` — **LOGFLUSH**, flushes all pending debug output from the buffer into the debug log. +* `FEFn01ssss` — **PRINTSTR** `ssss`, string `ssss` is `n` bytes long. + +# A.13 Codepage primitives + +The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. 5.1.8). + +* `FFnn` — **SETCP** `nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. +* `FF00` — **SETCP0**, selects TVM (test) codepage zero as described in this document +* `FFFz` — **SETCP** `z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 . . . − 1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in B.2.6. Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. +* `FFF0` — **SETCPX** `(c – )`, selects codepage `c` with `−2^15 ≤ c < 2^15` passed in the top of the stack. + +--- + +# B Formal properties and specifications of TVM + +This appendix discusses certain formal properties of TVM that are necessary for executing smart contracts in the TON Blockchain and validating such executions afterwards. + +## B.1 Serialization of the TVM state + +Recall that a virtual machine used for executing smart contracts in a blockchain must be deterministic, otherwise the validation of each execution would require the inclusion of all intermediate steps of the execution into a block, or at least of the choices made when indeterministic operations have been performed. + +Furthermore, the state of such a virtual machine must be (uniquely) serializable, so that even if the state itself is not usually included in a block, its hash is still well-defined and can be included into a block for verification purposes. + +### B.1.1. TVM stack values. + +TVM stack values can be serialized as follows: + +``` +vm_stk_tinyint#01 value:int64 = VmStackValue; +vm_stk_int#0201_ value:int257 = VmStackValue; +vm_stk_nan#02FF = VmStackValue; +vm_stk_cell#03 cell:^Cell = VmStackValue; +_ cell:^Cell st_bits:(## 10) end_bits:(## 10) + { st_bits <= end_bits } + st_ref:(#<= 4) end_ref:(#<= 4) + { st_ref <= end_ref } = VmCellSlice; +vm_stk_slice#04 _:VmCellSlice = VmStackValue; +vm_stk_builder#05 cell:^Cell = VmStackValue; +vm_stk_cont#06 cont:VmCont = VmStackValue; +``` + +Of these, `vm_stk_tinyint` is never used by TVM in codepage zero; it is used only in restricted modes. + +### B.1.2. TVM stack. + +The TVM stack can be serialized as follows: + +``` +vm_stack#_ depth:(## 24) stack:(VmStackList depth) = VmStack; +vm_stk_cons#_ {n:#} head:VmStackValue tail:^(VmStackList n) + = VmStackList (n + 1); +vm_stk_nil#_ = VmStackList 0; +``` + +### B.1.3. TVM control registers. + +Control registers in TVM can be serialized as follows: + +``` +_ cregs:(HashmapE 4 VmStackValue) = VmSaveList; +``` + +### B.1.4. TVM gas limits. + +Gas limits in TVM can be serialized as follows: + +``` +gas_limits#_ remaining:int64 _:^[ + max_limit:int64 cur_limit:int64 credit:int64 ] += VmGasLimits; +``` + +### B.1.5. TVM library environment. + +The TVM library environment can be serialized as follows: + +``` +_ libraries:(HashmapE 256 ^Cell) = VmLibraries; +``` + +### B.1.6. TVM continuations. + +Continuations in TVM can be serialized as follows: + +``` +vmc_std$00 nargs:(## 22) stack:(Maybe VmStack) save:VmSaveList + cp:int16 code:VmCellSlice = VmCont; +vmc_envelope$01 nargs:(## 22) stack:(Maybe VmStack) + save:VmSaveList next:^VmCont = VmCont; +vmc_quit$1000 exit_code:int32 = VmCont; +vmc_quit_exc$1001 = VmCont; +vmc_until$1010 body:^VmCont after:^VmCont = VmCont; +vmc_again$1011 body:^VmCont = VmCont; +vmc_while_cond$1100 cond:^VmCont body:^VmCont + after:^VmCont = VmCont; +vmc_while_body$1101 cond:^VmCont body:^VmCont + after:^VmCont = VmCont; +vmc_pushint$1111 value:int32 next:^VmCont = VmCont; +``` + +### B.1.7. TVM state. + +The total state of TVM can be serialized as follows: + +``` +vms_init$00 cp:int16 step:int32 gas:GasLimits + stack:(Maybe VmStack) save:VmSaveList code:VmCellSlice + lib:VmLibraries = VmState; + +vms_exception$01 cp:int16 step:int32 gas:GasLimits + exc_no:int32 exc_arg:VmStackValue + save:VmSaveList lib:VmLibraries = VmState; + +vms_running$10 cp:int16 step:int32 gas:GasLimits stack:VmStack + save:VmSaveList code:VmCellSlice lib:VmLibraries + = VmState; + +vms_finished$11 cp:int16 step:int32 gas:GasLimits + exit_code:int32 no_gas:Boolean stack:VmStack + save:VmSaveList lib:VmLibraries = VmState; +``` + +When TVM is initialized, its state is described by a `vms_init`, usually with `step` set to zero. The step function of TVM does nothing to a `vms_finished` state, and transforms all other states into `vms_running`, `vms_exception`, or `vms_finished`, with `step` increased by one. + +## B.2 Step function of TVM + +A formal specification of TVM would be completed by the definition of a step function `f : VmState → VmState`. This function deterministically transforms a valid VM state into a valid subsequent VM state, and is allowed to throw exceptions or return an invalid subsequent state if the original state was invalid. + +### B.2.1. A high-level definition of the step function. + +We might present a very long formal definition of the TVM step function in a high-level functional programming language. Such a specification, however, would mostly be useful as a reference for the (human) developers. We have chosen another approach, better adapted to automated formal verification by computers. + +### B.2.2. An operational definition of the step function. + +Notice that the step function `f` is a well-defined computable function from trees of cells into trees of cells. As such, it can be computed by a universal Turing machine. Then a program `P` computing `f` on such a machine would provide a machine-checkable specification of the step function `f`. This program `P` effectively is an emulator of TVM on this Turing machine. + +### B.2.3. A reference implementation of the TVM emulator inside TVM. + +We see that the step function of TVM may be defined by a reference implementation of a TVM emulator on another machine. An obvious idea is to use TVM itself, since it is well-adapted to working with trees of cells. However, an emulator of TVM inside itself is not very useful if we have doubts about a particular implementation of TVM and want to check it. For instance, if such an emulator interpreted a **DICTISET** instruction simply by invoking this instruction itself, then a bug in the underlying implementation of TVM would remain unnoticed. + +### B.2.4. Reference implementation inside a minimal version of TVM. + +We see that using TVM itself as a host machine for a reference implementation of TVM emulator would yield little insight. A better idea is to define a stripped-down version of TVM, which supports only the bare minimum of primitives and 64-bit integer arithmetic, and provide a reference implementation `P` of the TVM step function `f` for this stripped-down version of TVM. + +In that case, one must carefully implement and check only a handful of primitives to obtain a stripped-down version of TVM, and compare the reference implementation `P` running on this stripped-down version to the full custom TVM implementation being verified. In particular, if there are any doubts about the validity of a specific run of a custom TVM implementation, they can now be easily resolved with the aid of the reference implementation. + +### B.2.5. Relevance for the TON Blockchain. + +The TON Blockchain adopts this approach to validate the runs of TVM (e.g., those used for processing inbound messages by smart contracts) when the validators’ results do not match one another. In this case, a reference implementation of TVM, stored inside the masterchain as a configurable parameter (thus defining the current revision of TVM), is used to obtain the correct result. + +### B.2.6. Codepage −1. + +Codepage `−1` of TVM is reserved for the stripped-down version of TVM. Its main purpose is to execute the reference implementation of the step function of the full TVM. This codepage contains only special versions of arithmetic primitives working with “tiny integers” (64-bit signed integers); therefore, TVM’s 257-bit `Integer` arithmetic must be defined in terms of 64-bit arithmetic. Elliptic curve cryptography primitives are also implemented directly in codepage `−1`, without using any third-party libraries. Finally, a reference implementation of the `sha256` hash function is also provided in codepage `−1`. + +### B.2.7. Codepage −2. + +This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage `−2`”. All 64-bit arithmetic used in codepage `−1` would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage `−1`. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer. + +--- + +# C Code density of stack and register machines + +This appendix extends the general consideration of stack manipulation primitives provided in 2.2, explaining the choice of such primitives for TVM, with a comparison of stack machines and register machines in terms of the quantity of primitives used and the code density. We do this by comparing the machine code that might be generated by an optimizing compiler for the same source files, for different (abstract) stack and register machines. + +It turns out that the stack machines (at least those equipped with the basic stack manipulation primitives described in 2.2.1) have far superior code density. Furthermore, the stack machines have excellent extendability with respect to additional arithmetic and arbitrary data processing operations, especially if one considers machine code automatically generated by optimizing compilers. + +## C.1 Sample leaf function + +We start with a comparison of machine code generated by an (imaginary) optimizing compiler for several abstract register and stack machines, corresponding to the same high-level language source code that contains the definition of a leaf function (i.e., a function that does not call any other functions). For both the register machines and stack machines, we observe the notation and conventions introduced in 2.1. + +### C.1.1. Sample source file for a leaf function. + +The source file we consider contains one function f that takes six (integer) arguments, a, b, c, d, e, f, and returns two (integer) values, x and y, which are the solutions of the system of two linear equations + +``` +( +ax + by = e +cx + dy = f +(6) +``` + +The source code of the function, in a programming language similar to C, might look as follows: + +```c +(int, int) f(int a, int b, int c, int d, int e, int f) { +int D = a*d - b*c; +int Dx = e*d - b*f; +int Dy = a*f - e*c; +147 +C.1. Sample leaf function +return (Dx / D, Dy / D); +} +``` + +We assume (cf. 2.1) that the register machines we consider accept the six parameters a. . . f in registers r0. . . r5, and return the two values x and y in r0 and r1. We also assume that the register machines have 16 registers, and that the stack machine can directly access s0 to s15 by its stack manipulation primitives; the stack machine will accept the parameters in s5 to s0, and return the two values in s0 and s1, somewhat similarly to the register machine. Finally, we assume at first that the register machine is allowed to destroy values in all registers (which is slightly unfair towards the stack machine); this assumption will be revisited later. + +### C.1.2. Three-address register machine. + +The machine code (or rather the corresponding assembly code) for a three-address register machine (cf. 2.1.7) might look as follows: + +``` +IMUL r6,r0,r3 // r6 := r0 * r3 = ad +IMUL r7,r1,r2 // r7 := bc +SUB r6,r6,r7 // r6 := ad-bc = D +IMUL r3,r4,r3 // r3 := ed +IMUL r1,r1,r5 // r1 := bf +SUB r3,r3,r1 // r3 := ed-bf = Dx +IMUL r1,r0,r5 // r1 := af +IMUL r7,r4,r2 // r7 := ec +SUB r1,r1,r7 // r1 := af-ec = Dy +IDIV r0,r3,r6 // x := Dx/D +IDIV r1,r1,r6 // y := Dy/D +RET +``` + +We have used 12 operations and at least 23 bytes (each operation uses 3×4 = 12 bits to indicate the three registers involved, and at least 4 bits to indicate the operation performed; thus we need two or three bytes to encode each operation). A more realistic estimate would be 34 (three bytes for each arithmetic operation) or 31 bytes (two bytes for addition and subtraction, three bytes for multiplication and division). + +### C.1.3. Two-address register machine. + +The machine code for a two-address register machine might look as follows: + +``` +MOV r6,r0 // r6 := r0 = a +MOV r7,r1 // r7 := b +IMUL r6,r3 // r6 := r6*r3 = ad +IMUL r7,r2 // r7 := bc +IMUL r3,r4 // r3 := de +IMUL r1,r5 // r1 := bf +SUB r6,r7 // r6 := ad-bc = D +IMUL r5,r0 // r5 := af +SUB r3,r1 // r3 := de-bf = Dx +IMUL r2,r4 // r2 := ce +MOV r0,r3 // r0 := Dx +SUB r5,r2 // r5 := af-ce = Dy +IDIV r0,r6 // r0 := x = Dx/D +MOV r1,r5 // r1 := Dy +IDIV r1,r6 // r1 := Dy/D +RET +``` + +We have used 16 operations; optimistically assuming each of them (with the exception of RET) can be encoded by two bytes, this code would require 31 bytes.31 + +### C.1.4. One-address register machine. + +The machine code for a one-address register machine might look as follows: + +``` +MOV r8,r0 // r8 := r0 = a +XCHG r1 // r0 <-> r1; r0 := b, r1 := a +MOV r6,r0 // r6 := b +IMUL r2 // r0 := r0*r2; r0 := bc +MOV r7,r0 // r7 := bc +MOV r0,r8 // r0 := a +IMUL r3 // r0 := ad +31It is interesting to compare this code with that generated by optimizing C compilers +for the x86-64 architecture. +First of all, the integer division operation for x86-64 uses the one-address form, with +the (double-length) dividend to be supplied in accumulator pair r2:r0. The quotient is +also returned in r0. As a consequence, two single-to-double extension operations (CDQ or +CQO) and at least one move operation need to be added. +Secondly, the encoding used for arithmetic and move operations is less optimistic than +in our example above, requiring about three bytes per operation on average. As a result, +we obtain a total of 43 bytes for 32-bit integers, and 68 bytes for 64-bit integers. +C.1. Sample leaf function +SUB r7 // r0 := ad-bc = D +XCHG r1 // r1 := D, r0 := b +IMUL r5 // r0 := bf +XCHG r3 // r0 := d, r3 := bf +IMUL r4 // r0 := de +SUB r3 // r0 := de-bf = Dx +IDIV r1 // r0 := Dx/D = x +XCHG r2 // r0 := c, r2 := x +IMUL r4 // r0 := ce +XCHG r5 // r0 := f, r5 := ce +IMUL r8 // r0 := af +SUB r5 // r0 := af-ce = Dy +IDIV r1 // r0 := Dy/D = y +MOV r1,r0 // r1 := y +MOV r0,r2 // r0 := x +RET +``` + +We have used 23 operations; if we assume one-byte encoding for all arithmetic operations and XCHG, and two-byte encodings for MOV, the total size of the code will be 29 bytes. Notice, however, that to obtain the compact code shown above we had to choose a specific order of computation, and made heavy use of the commutativity of multiplication. (For example, we compute bc before af, and af − bc immediately after af.) It is not clear whether a compiler would be able to make all such optimizations by itself. + +### C.1.5. Stack machine with basic stack primitives. + +The machine code for a stack machine equipped with basic stack manipulation primitives described in 2.2.1 might look as follows: + +``` +PUSH s5 // a b c d e f a +PUSH s3 // a b c d e f a d +IMUL // a b c d e f ad +PUSH s5 // a b c d e f ad b +PUSH s5 // a b c d e f ad b c +IMUL // a b c d e f ad bc +SUB // a b c d e f ad-bc +XCHG s3 // a b c ad-bc e f d +PUSH s2 // a b c ad-bc e f d e +IMUL // a b c ad-bc e f de +XCHG s5 // a de c ad-bc e f b +PUSH s1 // a de c ad-bc e f b f +IMUL // a de c ad-bc e f bf +XCHG s1,s5 // a f c ad-bc e de bf +SUB // a f c ad-bc e de-bf +XCHG s3 // a f de-bf ad-bc e c +IMUL // a f de-bf ad-bc ec +XCHG s3 // a ec de-bf ad-bc f +XCHG s1,s4 // ad-bc ec de-bf a f +IMUL // D ec Dx af +XCHG s1 // D ec af Dx +XCHG s2 // D Dx af ec +SUB // D Dx Dy +XCHG s1 // D Dy Dx +PUSH s2 // D Dy Dx D +IDIV // D Dy x +XCHG s2 // x Dy D +IDIV // x y +RET +``` + +We have used 29 operations; assuming one-byte encodings for all stack operations involved (including XCHG s1,s(i)), we have used 29 code bytes as well. Notice that with one-byte encoding, the “unsystematic” operation ROT (equivalent to XCHG s1; XCHG s2) would reduce the operation and byte count to 28. This shows that such “unsystematic” operations, borrowed from Forth, may indeed reduce the code size on some occasions. + +Notice as well that we have implicitly used the commutativity of multiplication in this code, computing de − bf instead of ed − bf as specified in high-level language source code. If we were not allowed to do so, an extra XCHG s1 would need to be inserted before the third IMUL, increasing the total size of the code by one operation and one byte. + +The code presented above might have been produced by a rather unsophisticated compiler that simply computed all expressions and subexpressions in the order they appear, then rearranged the arguments near the top of the stack before each operation as outlined in 2.2.2. The only “manual” optimization done here involves computing ec before af; one can check that the other order would lead to slightly shorter code of 28 operations and bytes (or 29, if we are not allowed to use the commutativity of multiplication), but +151 +C.1. Sample leaf function +the ROT optimization would not be applicable. + +### C.1.6. Stack machine with compound stack primitives. + +A stack machine with compound stack primitives (cf. 2.2.3) would not significantly improve code density of the code presented above, at least in terms of bytes used. The only difference is that, if we were not allowed to use commutativity of multiplication, the extra XCHG s1 inserted before the third IMUL might be combined with two previous operations XCHG s3, PUSH s2 into one compound operation PUXC s2,s3; we provide the resulting code below. To make this less redundant, we show a version of the code that computes subexpression af before ec as specified in the original source file. We see that this replaces six operations (starting from line 15) with five other operations, and disables the ROT optimization: + +``` +PUSH s5 // a b c d e f a +PUSH s3 // a b c d e f a d +IMUL // a b c d e f ad +PUSH s5 // a b c d e f ad b +PUSH s5 // a b c d e f ad b c +IMUL // a b c d e f ad bc +SUB // a b c d e f ad-bc +PUXC s2,s3 // a b c ad-bc e f e d +IMUL // a b c ad-bc e f ed +XCHG s5 // a ed c ad-bc e f b +PUSH s1 // a ed c ad-bc e f b f +IMUL // a ed c ad-bc e f bf +XCHG s1,s5 // a f c ad-bc e ed bf +SUB // a f c ad-bc e ed-bf +XCHG s4 // a ed-bf c ad-bc e f +XCHG s1,s5 // e Dx c D a f +IMUL // e Dx c D af +XCHG s2 // e Dx af D c +XCHG s1,s4 // D Dx af e c +IMUL // D Dx af ec +SUB // D Dx Dy +XCHG s1 // D Dy Dx +PUSH s2 // D Dy Dx D +IDIV // D Dy x +XCHG s2 // x Dy D +IDIV // x y +RET +``` + +We have used a total of 27 operations and 28 bytes, the same as the previous version (with the ROT optimization). However, we did not use the commutativity of multiplication here, so we can say that compound stack manipulation primitives enable us to reduce the code size from 29 to 28 bytes. + +Yet again, notice that the above code might have been generated by an unsophisticated compiler. Manual optimizations might lead to more compact code; for instance, we could use compound operations such as XCHG3 to prepare in advance not only the correct values of s0 and s1 for the next arithmetic operation, but also the value of s2 for the arithmetic operation after that. The next section provides an example of such an optimization. + +### C.1.7. Stack machine with compound stack primitives and manually optimized code. + +The previous version of code for a stack machine with compound stack primitives can be manually optimized as follows. + +By interchanging XCHG operations with preceding XCHG, PUSH, and arithmetic operations whenever possible, we obtain code fragment XCHG s2,s6; XCHG s1,s0; XCHG s0,s5, which can then be replaced by compound operation XCHG3 s6,s0,s5. This compound operation would admit a two-byte encoding, thus leading to 27-byte code using only 21 operations: + +``` +PUSH2 s5,s2 // a b c d e f a d +IMUL // a b c d e f ad +PUSH2 s5,s4 // a b c d e f ad b c +IMUL // a b c d e f ad bc +SUB // a b c d e f ad-bc +PUXC s2,s3 // a b c ad-bc e f e d +IMUL // a b c D e f ed +XCHG3 s6,s0,s5 // (same as XCHG s2,s6; XCHG s1,s0; XCHG s0,s5) +// e f c D a ed b +PUSH s5 // e f c D a ed b f +IMUL // e f c D a ed bf +SUB // e f c D a ed-bf +XCHG s4 // e Dx c D a f +IMUL // e Dx c D af +XCHG2 s4,s2 // D Dx af e c +IMUL // D Dx af ec +153 +C.2. Comparison of machine code for sample leaf function +SUB // D Dx Dy +XCPU s1,s2 // D Dy Dx D +IDIV // D Dy x +XCHG s2 // x Dy D +IDIV // x y +RET +``` + +It is interesting to note that this version of stack machine code contains only 9 stack manipulation primitives for 11 arithmetic operations. It is not clear, however, whether an optimizing compiler would be able to reorganize the code in such a manner by itself. + +---- + +# C.2 Comparison of machine code for sample leaf function + +Table 1 summarizes the properties of machine code corresponding to the same source file described in C.1.1, generated for a hypothetical three-address register machine (cf. C.1.2), with both “optimistic” and “realistic” instruction encodings; a two-address machine (cf. C.1.3); a one-address machine (cf. C.1.4); and a stack machine, similar to TVM, using either only the basic stack manipulation primitives (cf. C.1.5) or both the basic and the composite stack primitives (cf. C.1.7). + +The meaning of the columns in Table 1 is as follows: + +* “Operations” — The quantity of instructions used, split into “data” (i.e., register move and exchange instructions for register machines, and stack manipulation instructions for stack machines) and “arithmetic” (instructions for adding, subtracting, multiplying and dividing integer numbers). The “total” is one more than the sum of these two, because there is also a one-byte RET instruction at the end of machine code. +* “Code bytes” — The total amount of code bytes used. +* “Opcode space” — The portion of “opcode space” (i.e., of possible choices for the first byte of the encoding of an instruction) used by data and arithmetic instructions in the assumed instruction encoding. For example, the “optimistic” encoding for the three-address machine assumes two-byte encodings for all arithmetic instructions `op r(i), r(j), r(k)`. Each arithmetic instruction would then consume portion `16/256 = 1/16` of the opcode space. Notice that for the stack machine we have assumed one-byte encodings for `XCHG s(i)`, `PUSH s(i)` and `POP s(i)` in all cases, augmented by `XCHG s1,s(i)` for the basic stack instructions case only. As for the compound stack operations, we have assumed two-byte encodings for `PUSH3`, `XCHG3`, `XCHG2`, `XCPU`, `PUXC`, `PUSH2`, but not for `XCHG s1,s(i)`. + +The “code bytes” column reflects the density of the code for the specific sample source. However, “opcode space” is also important, because it reflects the extendability of the achieved density to other classes of operations (e.g., if one were to complement arithmetic operations with string manipulation operations and so on). Here the “arithmetic” subcolumn is more important than the “data” subcolumn, because no further data manipulation operations would be required for such extensions. + +We see that the three-address register machine with the “optimistic” encoding, assuming two-byte encodings for all three-register arithmetic operations, achieves the best code density, requiring only 23 bytes. However, this comes at a price: each arithmetic operation consumes 1/16 of the opcode space, so the four operations already use a quarter of the opcode space. At most 11 other operations, arithmetic or not, might be added to this architecture while preserving such high code density. On the other hand, when we consider the “realistic” encoding for the three-address machine, using two-byte encodings only for the most frequently used addition/subtraction operations (and longer encodings for less frequently used multiplication/division operations, reflecting the fact that the possible extension operations would likely fall in this class), then the three-address machine ceases to offer such attractive code density. + +In fact, the two-address machine becomes equally attractive at this point: it is capable of achieving the same code size of 31 bytes as the three-address machine with the “realistic” encoding, using only 6/256 of the opcode space for this! However, 31 bytes is the worst result in this table. + +The one-address machine uses 29 bytes, slightly less than the two-address machine. However, it utilizes a quarter of the opcode space for its arithmetic operations, hampering its extendability. In this respect it is similar to the three-address machine with the “optimistic” encoding, but requires 29 bytes instead of 23! So there is no reason to use the one-address machine at all, in terms of extendability (reflected by opcode space used for arithmetic operations) compared to code density. + +Finally, the stack machine wins the competition in terms of code density (27 or 28 bytes), losing only to the three-address machine with the “optimistic” encoding (which, however, is terrible in terms of extendability). + +To summarize: the two-address machine and stack machine achieve the best extendability with respect to additional arithmetic or data processing instructions (using only 1/256 of code space for each such instruction), while the stack machine additionally achieves the best code density by a small margin. The stack machine utilizes a significant part of its code space (more than a quarter) for data (i.e., stack) manipulation instructions; however, this does not seriously hamper extendability, because the stack manipulation instructions occupy a constant part of the opcode stace, regardless of all other instructions and extensions. + +While one might still be tempted to use a two-address register machine, we will explain shortly (cf. C.3) why the two-address register machine offers worse code density and extendability in practice than it appears based on this table. + +As for the choice between a stack machine with only basic stack manipulation primitives or one supporting compound stack primitives as well, the case for the more sophisticated stack machine appears to be weaker: it offers only one or two fewer bytes of code at the expense of using considerably more opcode space for stack manipulation, and the optimized code using these additional instructions is hard for programmers to write and for compilers to automatically generate. + +### Table 1 + +| Machine | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | +| --------------- | ------------------- | -------------------- | -------------------- | ------------------- | -------------------- | -------------------- | --------------------- | ---------------------- | ---------------------- | +| 3-addr. (opt.) | 0 | 11 | 12 | 0 | 22 | 23 | 0/256 | 64/256 | 65/256 | +| 3-addr. (real.) | 0 | 11 | 12 | 0 | 30 | 31 | 0/256 | 34/256 | 35/256 | +| 2-addr. | 4 | 11 | 16 | 8 | 22 | 31 | 1/256 | 4/256 | 6/256 | +| 1-addr. | 11 | 11 | 23 | 17 | 11 | 29 | 17/256 | 64/256 | 82/256 | +| stack (basic) | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | +| stack (comp.) | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | + +Table 1: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. C.1.1). The two most important columns, reflecting code density and extendability to other operations, are marked by bold font. Smaller values are better in both of these columns. + +--- + +### C.2.1. Register calling conventions: some registers must be preserved by functions. + +Up to this point, we have considered the machinecode of only one function, without taking into account the interplay between this function and other functions in the same program. + +Usually a program consists of more than one function, and when a function is not a “simple” or “leaf” function, it must call other functions. Therefore, it becomes important whether a called function preserves all or at least some registers. If it preserves all registers except those used to return results, the caller can safely keep its local and temporary variables in certain registers; however, the callee needs to save all the registers it will use for its temporary values somewhere (usually into the stack, which also exists on register machines), and then restore the original values. On the other hand, if the called function is allowed to destroy all registers, it can be written in the manner described in C.1.2, C.1.3, and C.1.4, but the caller will now be responsible for saving all its temporary values into the stack before the call, and restoring these values afterwards. + +In most cases, calling conventions for register machines require preservation of some but not all registers. We will assume that m ≤ n registers will be preserved by functions (unless they are used for return values), and that these registers are r(n − m). . . r(n − 1). Case m = 0 corresponds to the case “the callee is free to destroy all registers” considered so far; it is quite painful for the caller. Case m = n corresponds to the case “the callee must preserve all registers”; it is quite painful for the callee, as we will see in a moment. Usually a value of m around n/2 is used in practice. + +The following sections consider cases m = 0, m = 8, and m = 16 for our register machines with n = 16 registers. + +### C.2.2. Case m = 0: no registers to preserve. + +This case has been considered and summarized in C.2 and Table 1 above. + +### C.2.3. Case m = n = 16: all registers must be preserved. + +This case is the most painful one for the called function. It is especially difficult for leaf functions like the one we have been considering, which do not benefit at all from the fact that other functions preserve some registers when called—they do not call any functions, but instead must preserve all registers themselves. + +In order to estimate the consequences of assuming m = n = 16, we will assume that all our register machines are equipped with a stack, and with one-byte instructions `PUSH r(i)` and `POP r(i)`, which push or pop a register into/from the stack. For example, the three-address machine code provided in C.1.2 destroys the values in registers r2, r3, r6, and r7; this means that the code of this function must be augmented by four instructions `PUSH r2; PUSH r3; PUSH r6; PUSH r7` at the beginning, and by four instructions `POP r7; POP r6; POP r3; POP r2` right before the `RET` instruction, in order to restore the original values of these registers from the stack. These four additional `PUSH/POP` pairs would increase the operation count and code size in bytes by `4 × 2 = 8`. A similar analysis can be done for other register machines as well, leading to Table 2. + +We see that under these assumptions the stack machines are the obvious winners in terms of code density, and are in the winning group with respect to extendability. + +### Table 2 + +| Machine | r | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | +| --------------- | - | ------------------- | -------------------- | -------------------- | ------------------- | -------------------- | -------------------- | --------------------- | ---------------------- | ---------------------- | +| 3-addr. (opt.) | 4 | 8 | 11 | 20 | 8 | 22 | 31 | 32/256 | 64/256 | 97/256 | +| 3-addr. (real.) | 4 | 8 | 11 | 20 | 8 | 30 | 39 | 32/256 | 34/256 | 67/256 | +| 2-addr. | 5 | 14 | 11 | 26 | 18 | 22 | 41 | 33/256 | 4/256 | 38/256 | +| 1-addr. | 6 | 23 | 11 | 35 | 29 | 11 | 41 | 49/256 | 64/256 | 114/256 | +| stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | +| stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | + +Table 2: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. C.1.1), assuming all of the 16 registers must be preserved by called functions (m = n = 16). The new column labeled r denotes the number of registers to be saved and restored, leading to 2r more operations and code bytes compared to Table 1. Newly-added PUSH and POP instructions for register machines also utilize 32/256 of the opcode space. The two rows corresponding to stack machines remain unchanged. + +### C.2.4. Case m = 8, n = 16: registers r8. . . r15 must be preserved. + +The analysis of this case is similar to the previous one. The results are summarized in Table 3. + +Notice that the resulting table is very similar to Table 1, apart from the “Opcode space” columns and the row for the one-address machine. Therefore, the conclusions of C.2 still apply in this case, with some minor modifications. We must emphasize, however, that these conclusions are valid only for leaf functions, i.e., functions that do not call other functions. Any program aside from the very simplest will have many non-leaf functions, especially if we are minimizing resulting machine code size (which prevents inlining of functions in most cases). + +### Table 3 + +| Machine | r | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | +| --------------- | - | ------------------- | -------------------- | -------------------- | ------------------- | -------------------- | -------------------- | --------------------- | ---------------------- | ---------------------- | +| 3-addr. (opt.) | 0 | 0 | 11 | 12 | 0 | 22 | 23 | 32/256 | 64/256 | 97/256 | +| 3-addr. (real.) | 0 | 0 | 11 | 12 | 0 | 30 | 31 | 32/256 | 34/256 | 67/256 | +| 2-addr. | 0 | 4 | 11 | 16 | 8 | 22 | 31 | 33/256 | 4/256 | 38/256 | +| 1-addr. | 1 | 13 | 11 | 25 | 19 | 11 | 31 | 49/256 | 64/256 | 114/256 | +| stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | +| stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | + +Table 3: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address and stack machines, generated for a sample leaf function (cf. C.1.1), assuming that only the last 8 of the 16 registers must be preserved by called functions (m = 8, n = 16). This table is similar to Table 2, but has smaller values of r. + +### C.2.5. A fairer comparison using a binary code instead of a byte code. + +The reader may have noticed that our preceding discussion of kaddress register machines and stack machines depended very much on our insistence that complete instructions be encoded by an integer number of bytes. If we had been allowed to use a “bit” or “binary code” instead of a byte code for encoding instructions, we could more evenly balance the opcode space used by different machines. For instance, the opcode of SUB for a threeaddress machine had to be either 4-bit (good for code density, bad for opcode space) or 12-bit (very bad for code density), because the complete instruction has to occupy a multiple of eight bits (e.g., 16 or 24 bits), and 3 · 4 = 12 of those bits have to be used for the three register names. + +Therefore, let us get rid of this restriction. + +Now that we can use any number of bits to encode an instruction, we can choose all opcodes of the same length for all the machines considered. For instance, all arithmetic instructions can have 8-bit opcodes, as the stack machine does, using 1/256 of the opcode space each; then the three-address register machine will use 20 bits to encode each complete arithmetic instruction. All MOVs, XCHGs, PUSHes, and POPs on register machines can be assumed to have 4-bit opcodes, because this is what we do for the most common stack manipulation primitives on a stack machine. The results of these changes are shown in Table 4. + +We can see that the performance of the various machines is much more balanced, with the stack machine still the winner in terms of the code density, but with the three-address machine enjoying the second place it really merits. If we were to consider the decoding speed and the possibility of parallel execution of instructions, we would have to choose the three-address machine, because it uses only 12 instructions instead of 21. + +### Table 4 + +| Machine | r | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | +| ------------- | - | ------------------- | -------------------- | -------------------- | ------------------- | -------------------- | -------------------- | --------------------- | ---------------------- | ---------------------- | +| 3-addr. | 0 | 0 | 11 | 12 | 0 | 27.5 | 28.5 | 64/256 | 4/256 | 69/256 | +| 2-addr. | 0 | 4 | 11 | 16 | 6 | 22 | 29 | 64/256 | 4/256 | 69/256 | +| 1-addr. | 1 | 13 | 11 | 25 | 16 | 16.5 | 32.5 | 64/256 | 4/256 | 69/256 | +| stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | +| stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | + +Table 4: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address and stack machines, generated for a sample leaf function (cf. C.1.1), assuming that only 8 of the 16 registers must be preserved by functions (m = 8, n = 16). This time we can use fractions of bytes to encode instructions, so as to match opcode space used by different machines. All arithmetic instructions have 8-bit opcodes, all data/stack manipulation instructions have 4-bit opcodes. In other respects this table is similar to Table 3. + +# C.3 Sample non-leaf function + +This section compares the machine code for different register machines for a sample non-leaf function. Again, we assume that either m = 0, m = 8, or m = 16 registers are preserved by called functions, with m = 8 representing the compromise made by most modern compilers and operating systems. + +## C.3.1. Sample source code for a non-leaf function. + +A sample source file may be obtained by replacing the built-in integer type with a custom Rational type, represented by a pointer to an object in memory, in our function for solving systems of two linear equations (cf. C.1.1): + +```c +struct Rational; +typedef struct Rational *num; +extern num r_add(num, num); +extern num r_sub(num, num); +extern num r_mul(num, num); +extern num r_div(num, num); +(num, num) r_f(num a, num b, num c, num d, num e, num f) { +num D = r_sub(r_mul(a, d), r_mul(b, c)); // a*d-b*c +num Dx = r_sub(r_mul(e, d), r_mul(b, f)); // e*d-b*f +num Dy = r_sub(r_mul(a, f), r_mul(e, c)); // a*f-e*c +return (r_div(Dx, D), r_div(Dy, D)); // Dx/D, Dy/D +} +``` + +We will ignore all questions related to allocating new objects of type Rational in memory (e.g., in heap), and to preventing memory leaks. We may assume that the called subroutines r\_sub, r\_mul, and so on allocate new objects simply by advancing some pointer in a pre-allocated buffer, and that unused objects are later freed by a garbage collector, external to the code being analysed. + +Rational numbers will now be represented by pointers, addresses, or references, which will fit into registers of our hypothetical register machines or into the stack of our stack machines. If we want to use TVM as an instance of these stack machines, we should use values of type Cell to represent such references to objects of type Rational in memory. + +We assume that subroutines (or functions) are called by a special CALL instruction, which is encoded by three bytes, including the specification of the function to be called (e.g., the index in a “global function table”). + +## C.3.2. Three-address and two-address register machines, m = 0 preserved registers. + +Because our sample function does not use built-in arithmetic instructions at all, compilers for our hypothetical three-address and two-address register machines will produce the same machine code. Apart from the previously introduced PUSH r(i) and POP r(i) one-byte instructions, we assume that our two- and three-address machines support the following two-byte instructions: MOV r(i),s(j), MOV s(j),r(i), and XCHG r(i),s(j), for 0 ≤ i, j ≤ 15. Such instructions occupy only 3/256 of the opcode space, so their addition seems quite natural. + +We first assume that m = 0 (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for r\_f does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. A size-optimizing compiler might produce the following code: + +``` +PUSH r4 // STACK: e +PUSH r1 // STACK: e b +PUSH r0 // .. e b a +PUSH r6 // .. e b a f +PUSH r2 // .. e b a f c +PUSH r3 // .. e b a f c d +MOV r0,r1 // b +MOV r1,r2 // c +CALL r_mul // bc +161 +C.3. Sample non-leaf function +PUSH r0 // .. e b a f c d bc +MOV r0,s4 // a +MOV r1,s1 // d +CALL r_mul // ad +POP r1 // bc; .. e b a f c d +CALL r_sub // D:=ad-bc +XCHG r0,s4 // b ; .. e D a f c d +MOV r1,s2 // f +CALL r_mul // bf +POP r1 // d ; .. e D a f c +PUSH r0 // .. e D a f c bf +MOV r0,s5 // e +CALL r_mul // ed +POP r1 // bf; .. e D a f c +CALL r_sub // Dx:=ed-bf +XCHG r0,s4 // e ; .. Dx D a f c +POP r1 // c ; .. Dx D a f +CALL r_mul // ec +XCHG r0,s1 // a ; .. Dx D ec f +POP r1 // f ; .. Dx D ec +CALL r_mul // af +POP r1 // ec; .. Dx D +CALL r_sub // Dy:=af-ec +XCHG r0,s1 // Dx; .. Dy D +MOV r1,s0 // D +CALL r_div // x:=Dx/D +XCHG r0,s1 // Dy; .. x D +POP r1 // D ; .. x +CALL r_div // y:=Dy/D +MOV r1,r0 // y +POP r0 // x ; .. +RET +``` + +We have used 41 instructions: 17 one-byte (eight PUSH/POP pairs and one RET), 13 two-byte (MOV and XCHG; out of them 11 “new” ones, involving the stack),and 11 three-byte (CALL), for a total of 17 · 1 + 13 · 2 + 11 · 3 = 76 bytes. + +## C.3.3. Three-address and two-address register machines, m = 8 preserved registers. + +Now we have eight registers, r8 to r15, that are preserved by subroutine calls. We might keep some intermediate values there instead of pushing them into the stack. However, the penalty for doing so consists in a PUSH/POP pair for every such register that we choose to use, because our function is also required to preserve its original value. It seems that using these registers under such a penalty does not improve the density of the code, so the optimal code for three- and two-address machines for m = 8 preserved registers is the same as that provided in C.3.2, with a total of 42 instructions and 74 code bytes. + +## C.3.4. Three-address and two-address register machines, m = 16 preserved registers. + +This time all registers must be preserved by the subroutines, excluding those used for returning the results. This means that our code must preserve the original values of r2 to r5, as well as any other registers it uses for temporary values. A straightforward way of writing the code of our subroutine would be to push registers r2 up to, say, r8 into the stack, then perform all the operations required, using r6–r8 for intermediate values, and finally restore registers from the stack. However, this would not optimize code size. We choose another approach: + +``` +PUSH r0 // STACK: a +PUSH r1 // STACK: a b +MOV r0,r1 // b +MOV r1,r2 // c +CALL r_mul // bc +PUSH r0 // .. a b bc +MOV r0,s2 // a +MOV r1,r3 // d +CALL r_mul // ad +POP r1 // bc; .. a b +CALL r_sub // D:=ad-bc +XCHG r0,s0 // b; .. a D +MOV r1,r5 // f +CALL r_mul // bf +PUSH r0 // .. a D bf +with size-optimization enabled actually occupied 150 bytes, due mostly to the fact that +actual instruction encodings are about twice as long as we had optimistically assumed. +163 +C.3. Sample non-leaf function +MOV r0,r4 // e +MOV r1,r3 // d +CALL r_mul // ed +POP r1 // bf; .. a D +CALL r_sub // Dx:=ed-bf +XCHG r0,s1 // a ; .. Dx D +MOV r1,r5 // f +CALL r_mul // af +PUSH r0 // .. Dx D af +MOV r0,r4 // e +MOV r1,r2 // c +CALL r_mul // ec +MOV r1,r0 // ec +POP r0 // af; .. Dx D +CALL r_sub // Dy:=af-ec +XCHG r0,s1 // Dx; .. Dy D +MOV r1,s0 // D +CALL r_div // x:=Dx/D +XCHG r0,s1 // Dy; .. x D +POP r1 // D ; .. x +CALL r_div // y:=Dy/D +MOV r1,r0 // y +POP r0 // x +RET +``` + +We have used 39 instructions: 11 one-byte, 17 two-byte (among them 5 “new” instructions), and 11 three-byte, for a total of 11 · 1 + 17 · 2 + 11 · 3 = 78 bytes. Somewhat paradoxically, the code size in bytes is slightly longer than in the previous case (cf. C.3.2), contrary to what one might have expected. This is partially due to the fact that we have assumed two-byte encodings for “new” MOV and XCHG instructions involving the stack, similarly to the “old” instructions. Most existing architectures (such as x86-64) use longer encodings (maybe even twice as long) for their counterparts of our “new” move and exchange instructions compared to the “usual” register-register ones. Taking this into account, we see that we would have obtained here 83 bytes (versus 87 for the code in C.3.2) assuming three-byte encodings of new operations, and 88 bytes (versus 98) assuming four-byte encodings. This shows that, for two-address architectures without optimized encodings for register-stackmove and exchange operations, m = 16 preserved registers might result in slightly shorter code for some non-leaf functions, at the expense of leaf functions (cf. C.2.3 and C.2.4), which would become considerably longer. + +## C.3.5. One-address register machine, m = 0 preserved registers. + +For our one-address register machine, we assume that new register-stack instructions work through the accumulator only. Therefore, we have three new instructions, LD s(j) (equivalent to MOV r0,s(j) of two-address machines), ST s(j) (equivalent to MOV s(j),r0), and XCHG s(j) (equivalent to XCHG r0,s(j)). To make the comparison with two-address machines more interesting, we assume one-byte encodings for these new instructions, even though this would consume 48/256 = 3/16 of the opcode space. + +By adapting the code provided in C.3.2 to the one-address machine, we obtain the following: + +``` +PUSH r4 // STACK: e +PUSH r1 // STACK: e b +PUSH r0 // .. e b a +PUSH r6 // .. e b a f +PUSH r2 // .. e b a f c +PUSH r3 // .. e b a f c d +LD s1 // r0:=c +XCHG r1 // r0:=b, r1:=c +CALL r_mul // bc +PUSH r0 // .. e b a f c d bc +LD s1 // d +XCHG r1 // r1:=d +LD s4 // a +CALL r_mul // ad +POP r1 // bc; .. e b a f c d +CALL r_sub // D:=ad-bc +XCHG s4 // b ; .. e D a f c d +XCHG r1 +LD s2 // f +XCHG r1 // r0:=b, r1:=f +CALL r_mul // bf +POP r1 // d ; .. e D a f c +PUSH r0 // .. e D a f c bf +LD s5 // e +165 +C.3. Sample non-leaf function +CALL r_mul // ed +POP r1 // bf; .. e D a f c +CALL r_sub // Dx:=ed-bf +XCHG s4 // e ; .. Dx D a f c +POP r1 // c ; .. Dx D a f +CALL r_mul // ec +XCHG s1 // a ; .. Dx D ec f +POP r1 // f ; .. Dx D ec +CALL r_mul // af +POP r1 // ec; .. Dx D +CALL r_sub // Dy:=af-ec +XCHG s1 // Dx; .. Dy D +POP r1 // D ; .. Dy +PUSH r1 // .. Dy D +CALL r_div // x:=Dx/D +XCHG s1 // Dy; .. x D +POP r1 // D ; .. x +CALL r_div // y:=Dy/D +XCHG r1 // r1:=y +POP r0 // r0:=x ; .. +RET +``` + +We have used 45 instructions: 34 one-byte and 11 three-byte, for a total of 67 bytes. Compared to the 76 bytes used by two- and three-address machines in C.3.2, we see that, again, the one-address register machine code may be denser than that of two-register machines, at the expense of utilizing more opcode space (just as shown in C.2). However, this time the extra 3/16 of the opcode space was used for data manipulation instructions, which do not depend on specific arithmetic operations or user functions invoked. + +## C.3.6. One-address register machine, m = 8 preserved registers. + +As explained in C.3.3, the preservation of r8–r15 between subroutine calls does not improve the size of our previously written code, so the one-address machine will use for m = 8 the same code provided in C.3.5. + +## C.3.7. One-address register machine, m = 16 preserved registers. + +We simply adapt the code provided in C.3.4 to the one-address register machine: + +``` +PUSH r0 // STACK: aPUSH r1 // STACK: a b +MOV r0,r1 // b +MOV r1,r2 // c +CALL r_mul // bc +PUSH r0 // .. a b bc +LD s2 // a +MOV r1,r3 // d +CALL r_mul // ad +POP r1 // bc; .. a b +CALL r_sub // D:=ad-bc +XCHG s0 // b; .. a D +MOV r1,r5 // f +CALL r_mul // bf +PUSH r0 // .. a D bf +MOV r0,r4 // e +MOV r1,r3 // d +CALL r_mul // ed +POP r1 // bf; .. a D +CALL r_sub // Dx:=ed-bf +XCHG s1 // a ; .. Dx D +MOV r1,r5 // f +CALL r_mul // af +PUSH r0 // .. Dx D af +MOV r0,r4 // e +MOV r1,r2 // c +CALL r_mul // ec +MOV r1,r0 // ec +POP r0 // af; .. Dx D +CALL r_sub // Dy:=af-ec +XCHG s1 // Dx; .. Dy D +POP r1 // D ; .. Dy +PUSH r1 // .. Dy D +CALL r_div // x:=Dx/D +XCHG s1 // Dy; .. x D +POP r1 // D ; .. x +CALL r_div // y:=Dy/D +MOV r1,r0 // y +POP r0 // x +167 +C.3. Sample non-leaf function +RET +``` + +We have used 40 instructions: 18 one-byte, 11 two-byte, and 11 three-byte, for a total of 18 · 1 + 11 · 2 + 11 · 3 = 73 bytes. + +## C.3.8. Stack machine with basic stack primitives. + +We reuse the code provided in C.1.5, simply replacing arithmetic primitives (VM instructions) with subroutine calls. The only substantive modification is the insertion of the previously optional XCHG s1 before the third multiplication, because even an optimizing compiler cannot now know whether CALL r\_mul is a commutative operation. We have also used the “tail recursion optimization” by replacing the final CALL r\_div followed by RET with JMP r\_div. + +``` +PUSH s5 // a b c d e f a +PUSH s3 // a b c d e f a d +CALL r_mul // a b c d e f ad +PUSH s5 // a b c d e f ad b +PUSH s5 // a b c d e f ad b c +CALL r_mul // a b c d e f ad bc +CALL r_sub // a b c d e f ad-bc +XCHG s3 // a b c ad-bc e f d +PUSH s2 // a b c ad-bc e f d e +XCHG s1 // a b c ad-bc e f e d +CALL r_mul // a b c ad-bc e f ed +XCHG s5 // a ed c ad-bc e f b +PUSH s1 // a ed c ad-bc e f b f +CALL r_mul // a ed c ad-bc e f bf +XCHG s1,s5 // a f c ad-bc e ed bf +CALL r_sub // a f c ad-bc e ed-bf +XCHG s3 // a f ed-bf ad-bc e c +CALL r_mul // a f ed-bf ad-bc ec +XCHG s3 // a ec ed-bf ad-bc f +XCHG s1,s4 // ad-bc ec ed-bf a f +CALL r_mul // D ec Dx af +XCHG s1 // D ec af Dx +XCHG s2 // D Dx af ec +CALL r_sub // D Dx Dy +XCHG s1 // D Dy Dx +PUSH s2 // D Dy Dx D +CALL r_div // D Dy x +XCHG s2 // x Dy D +JMP r_div // x y +``` + +We have used 29 instructions; assuming one-byte encodings for all stack operations, and three-byte encodings for CALL and JMP instructions, we end up with 51 bytes. + +## C.3.9. Stack machine with compound stack primitives. + +We again reuse the code provided in C.1.7, replacing arithmetic primitives with subroutine calls and making the tail recursion optimization: + +``` +PUSH2 s5,s2 // a b c d e f a d +CALL r_mul // a b c d e f ad +PUSH2 s5,s4 // a b c d e f ad b c +CALL r_mul // a b c d e f ad bc +CALL r_sub // a b c d e f ad-bc +PUXC s2,s3 // a b c ad-bc e f e d +CALL r_mul // a b c D e f ed +XCHG3 s6,s0,s5 // (same as XCHG s2,s6; XCHG s1,s0; XCHG s0,s5) +// e f c D a ed b +PUSH s5 // e f c D a ed b f +CALL r_mul // e f c D a ed bf +CALL r_sub // e f c D a ed-bf +XCHG s4 // e Dx c D a f +CALL r_mul // e Dx c D af +XCHG2 s4,s2 // D Dx af e c +CALL r_mul // D Dx af ec +CALL r_sub // D Dx Dy +XCPU s1,s2 // D Dy Dx D +CALL r_div // D Dy x +XCHG s2 // x Dy D +JMP r_div // x y +``` + +This code uses only 20 instructions, 9 stack-related and 11 control flowrelated (CALL and JMP), for a total of 48 bytes. + +--- + +### Table 5 + +| Machine | m | data | cont. | total | data | cont. | total | data/256 | arith/256 | total/256 | +| ------------- | --- | ---- | ----- | ----- | ---- | ----- | ----- | -------- | --------- | --------- | +| 3-addr. | 0,8 | 29 | 12 | 41 | 42 | 34 | 76 | 35/256 | 34/256 | 72/256 | +| | 16 | 27 | 12 | 39 | 44 | 34 | 78 | | | | +| 2-addr. | 0,8 | 29 | 12 | 41 | 42 | 34 | 76 | 37/256 | 4/256 | 44/256 | +| | 16 | 27 | 12 | 39 | 44 | 34 | 78 | | | | +| 1-addr. | 0,8 | 33 | 12 | 45 | 33 | 34 | 67 | 97/256 | 64/256 | 164/256 | +| | 16 | 28 | 12 | 40 | 39 | 34 | 73 | | | | +| stack (basic) | − | 18 | 11 | 29 | 18 | 33 | 51 | 64/256 | 4/256 | 71/256 | +| stack (comp.) | − | 9 | 11 | 20 | 15 | 33 | 48 | 84/256 | 4/256 | 91/256 | + +Table 5: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. C.3.1), assuming m of the 16 registers must be preserved by called subroutines. + +--- + +# C.4 Comparison of machine code for sample non-leaf + +function + +Table 5 summarizes the properties of machine code corresponding to the same source file provided in C.3.1. We consider only the “realistically” encoded three-address machines. Three-address and two-address machines have the same code density properties, but differ in the utilization of opcode space. The one-address machine, somewhat surprisingly, managed to produced shorter code than the two-address and three-address machines, at the expense of using up more than half of all opcode space. The stack machine is the obvious winner in this code density contest, without compromizing its excellent extendability (measured in opcode space used for arithmetic and other data transformation instructions). + +## C.4.1. Combining with results for leaf functions. + +It is instructive to compare this table with the results in C.2 for a sample leaf function, summarized in Table 1 (for m = 0 preserved registers) and the very similar Table 3 (for m = 8 preserved registers), and, if one is still interested in case m = 16 (which turned out to be worse than m = 8 in almost all situations), also to Table 2. +We see that the stack machine beats all register machines on non-leaf functions. As for the leaf functions, only the three-address machine with the “optimistic” encoding of arithmetic instructions was able to beat the stack machine, winning by 15%, by compromising its extendability. However, the same three-address machine produces 25% longer code for non-leaf functions. + +### C.4. Comparison of machine code for sample non-leaf function + +**Operations** | **Code bytes** | **Opcode space** + +| Machine | m | data | cont. | total | data | cont. | total | data | arith | total | +| ------------- | --- | ---- | ----- | ----- | ---- | ----- | ----- | ------- | ----- | ------- | +| 3-addr. | 0,8 | 29 | 12 | 41 | 35.5 | 34 | 69.5 | 110/256 | 4/256 | 117/256 | +| 3-addr. | 16 | 27 | 12 | 39 | 35.5 | 34 | 69.5 | | | | +| 2-addr. | 0,8 | 29 | 12 | 41 | 35.5 | 34 | 69.5 | 110/256 | 4/256 | 117/256 | +| 2-addr. | 16 | 27 | 12 | 39 | 35.5 | 34 | 69.5 | | | | +| 1-addr. | 0,8 | 33 | 12 | 45 | 33 | 34 | 67 | 112/256 | 4/256 | 119/256 | +| 1-addr. | 16 | 28 | 12 | 40 | 33.5 | 34 | 67.5 | | | | +| stack (basic) | − | 18 | 11 | 29 | 18 | 33 | 51 | 64/256 | 4/256 | 71/256 | +| stack (comp.) | − | 9 | 11 | 20 | 15 | 33 | 48 | 84/256 | 4/256 | 91/256 | + +Table 6: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. C.3.1), assuming m of the 16 registers must be preserved by called subroutines. This time we use fractions of bytes to encode instructions, enabling a fairer comparison. Otherwise, this table is similar to Table 5. + +If a typical program consists of a mixture of leaf and non-leaf functions in approximately equal proportion, then the stack machine will still win. + +## C.4.2. A fairer comparison using a binary code instead of a byte code. + +Similarly to C.2.5, we may offer a fairer comparison of different register machines and the stack machine by using arbitrary binary codes instead of byte codes to encode instructions, and matching the opcode space used for data manipulation and arithmetic instructions by different machines. The results of this modified comparison are summarized in Table 6. We see that the stack machines still win by a large margin, while using less opcode space for stack/data manipulation. + +## C.4.3. Comparison with real machines. + +Note that our hypothetical register machines have been considerably optimized to produce shorter code than actually existing register machines; the latter are subject to other design considerations apart from code density and extendability, such as backward compatibility, faster instruction decoding, parallel execution of neighboring instructions, ease of automatically producing optimized code by compilers, and so on. +For example, the very popular two-address register architecture x86-64 produces code that is approximately twice as long as our “ideal” results for the two-address machines. On the other hand, our results for the stack machines are directly applicable to TVM, which has been explicitly designed with the considerations presented in this appendix in mind. Furthermore, the actual TVM code is even shorter (in bytes) than shown in Table 5 because of the presence of the two-byte CALL instruction, allowing TVM to call up to 256 user-defined functions from the dictionary at c3. This means that one should subtract 10 bytes from the results for stack machines in Table 5 if one wants to specifically consider TVM, rather than an abstract stack machine; this produces a code size of approximately 40 bytes (or shorter), almost half that of an abstract two-address or three-address machine. + +## C.4.4. Automatic generation of optimized code. + +An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in 2.2.2 and 2.2.5. The only exception is the unimportant “manual” XCHG3 optimization described in C.1.7, which enabled us to shorten the code by one more byte. +By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. \ No newline at end of file From b5d28a24c4314621f62e174eff2785ae620b172a Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Sat, 6 Sep 2025 23:55:54 +0100 Subject: [PATCH 09/18] update chapter 1 of the tvm --- docs.json | 1 + ton/tvm.mdx | 132 ++++++++++++++++++++++++++++------------------------ 2 files changed, 71 insertions(+), 62 deletions(-) diff --git a/docs.json b/docs.json index 131ddbad..d0683aa5 100644 --- a/docs.json +++ b/docs.json @@ -250,6 +250,7 @@ "ton/consensus", "ton/precompiled", "ton/network", + "ton/tvm", "ton/glossary" ] }, diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 8aaf890a..98510fb1 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -1,20 +1,33 @@ --- -title: "TVM" +title: "Telegram Open Network Virtual Machine" +sidebarTitle: "TVM" --- +*Nikolai Durov* +*March 23, 2020* -## Introduction -The primary purpose of the Telegram Open Network Virtual Machine (TON VM or TVM) is to execute smart-contract code in the TON Blockchain. TVM must support all operations required to parse incoming messages and persistent data, and to create new messages and modify persistent data. +## Abstract + +The aim of this text is to provide a description of the Telegram Open Network Virtual Machine (TON VM or TVM), used to execute smart contracts in the TON Blockchain. + +## 1 Introduction + +The primary purpose of the Telegram Open Network Virtual Machine (TON VM or TVM) is to execute smart-contract code in the TON Blockchain. +TVM must support all operations required to parse incoming messages and persistent data, and to create new messages and modify persistent data. Additionally, TVM must meet the following requirements: -* It must provide for possible future extensions and improvements while retaining backward compatibility and interoperability, because the code of a smart contract, once committed into the blockchain, must continue working in a predictable manner regardless of any future modifications to the VM. -* It must strive to attain high "(virtual) machine code" density, so that the code of a typical smart contract occupies as little persistent blockchain storage as possible. -* It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used.[^1] -The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM,[^2] the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. +- **Backward compatibility:** It must provide for possible future extensions and improvements while retaining backward compatibility and interoperability, because the code of a smart contract, once committed into the blockchain, must continue working in a predictable manner regardless of any future modifications to the VM. +- **Code density:** It must strive to attain high “(virtual) machine code” density, so that the code of a typical smart contract occupies as little persistent blockchain storage as possible. +- **Determinism:** It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used. [^1](#footnote-1) + +The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM, [^2](#footnote-2), the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. TVM is not intended to be implemented in hardware (e.g., in a specialized microprocessor chip); rather, it should be implemented in software running on conventional hardware. This consideration lets us incorporate some high-level concepts and operations in TVM that would require convoluted microcode in a hardware implementation but pose no significant problems for a software implementation. Such operations are useful for achieving high code density and minimizing the byte (or storage cell) profile of smart-contract code when deployed in the TON Blockchain. --- +# 1 Overview + +This chapter provides an overview of the main features and design principles of TVM. More detail on each topic is provided in subsequent chapters. ## 1.0 Notation for bitstrings @@ -22,28 +35,24 @@ The following notation is used for bit strings (or bitstrings)—i.e., finite st ### 1.0.1 Hexadecimal notation for bitstrings -When the length of a bitstring is a multiple of four, we subdivide it into groups of four bits and represent each group by one of sixteen hexadecimal digits 0–9, A–F in the usual manner: - -* 0₁₆ ↔ 0000 -* 1₁₆ ↔ 0001 -* … -* F₁₆ ↔ 1111 +When the length of a bitstring is a multiple of four, we subdivide it into groups of four bits and represent each group by one of sixteen hexadecimal digits 0–9, A–F in the usual manner: +`0₁₆ ↔ 0000, 1₁₆ ↔ 0001, …, F₁₆ ↔ 1111`. The resulting hexadecimal string is our equivalent representation for the original binary string. ### 1.0.2 Bitstrings of lengths not divisible by four -If the length of a binary string is not divisible by four, we augment it by one `1` and several (maybe zero) `0`s at the end, so that its length becomes divisible by four, and then transform it into a string of hexadecimal digits as described above. To indicate that such a transformation has taken place, a special **completion tag** `_` is added to the end of the hexadecimal string. +If the length of a binary string is not divisible by four, we augment it by one `1` and several (maybe zero) `0`s at the end, so that its length becomes divisible by four, and then transform it into a string of hexadecimal digits as described above. To indicate that such a transformation has taken place, a special **completion tag** `_` is added to the end of the hexadecimal string. The reverse transformation (applied if the completion tag is present) consists in first replacing each hexadecimal digit by four corresponding bits, and then removing all trailing zeroes (if any) and the last `1` immediately preceding them (if the resulting bitstring is non-empty at this point). -Notice that there are several admissible hexadecimal representations for the same bitstring. Among them, the shortest one is **canonical**. It can be deterministically obtained by the above procedure. +Notice that there are several admissible hexadecimal representations for the same bitstring. Among them, the shortest one is “canonical”. It can be deterministically obtained by the above procedure. -For example: +For example: +- `8A` corresponds to binary string `10001010`. +- `8A_` and `8A0_` both correspond to `100010`. -* `8A` corresponds to binary string `10001010`. -* `8A_` and `8A0_` both correspond to `100010`. -* An empty bitstring may be represented by either `''`, `8_`, `0_`, `_`, or `00_`. +An empty bitstring may be represented by either `''`, `8_`, `0_`, `_`, or `00_`. ### 1.0.3 Emphasizing that a string is a hexadecimal representation of a bitstring @@ -53,72 +62,59 @@ This should not be confused with hexadecimal numbers, usually prepended by `0x` ### 1.0.4 Serializing a bitstring into a sequence of octets -When a bitstring needs to be represented as a sequence of 8-bit bytes (octets), which take values in integers 0…255, this is achieved essentially in the same fashion as above: we split the bitstring into groups of eight bits and interpret each group as the binary representation of an integer 0…255. +When a bitstring needs to be represented as a sequence of 8-bit bytes (octets), which take values in integers 0…255, this is achieved essentially in the same fashion as above: we split the bitstring into groups of eight bits and interpret each group as the binary representation of an integer 0…255. -If the length of the bitstring is not a multiple of eight, the bitstring is augmented by a binary `1` and up to seven binary `0`s before being split into groups. The fact that such a completion has been applied is usually reflected by a **completion tag** bit. +If the length of the bitstring is not a multiple of eight, the bitstring is augmented by a binary `1` and up to seven binary `0`s before being split into groups. The fact that such a completion has been applied is usually reflected by a “completion tag” bit. -For instance, `00101101100` corresponds to the sequence of two octets: - -* `(0x2d, 0x90)` in hexadecimal -* `(45, 144)` in decimal - -…along with a completion tag bit equal to `1` (meaning that the completion has been applied), which must be stored separately. +For instance, `00101101100` corresponds to the sequence of two octets `(0x2d, 0x90)` (hexadecimal), or `(45, 144)` (decimal), along with a completion tag bit equal to 1 (meaning that the completion has been applied), which must be stored separately. In some cases, it is more convenient to assume the completion is enabled by default rather than store an additional completion tag bit separately. Under such conventions, `8n`-bit strings are represented by `n + 1` octets, with the last octet always equal to `0x80 = 128`. -Perfect — I’ll keep the **exact wording** from your excerpt, only formatting it in Markdown for readability (headings, lists, code style for inline values). Numbering stays **exactly as in the source**. - --- -# 1.1 TVM is a stack machine +## 1.1 TVM is a stack machine -First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective.³ +First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective. [^3](#footnote-3) Most operations and user-defined functions take their arguments from the top of the stack, and replace them with their result. For example, the integer addition primitive (built-in operation) `ADD` does not take any arguments describing which registers or immediate values should be added together and where the result should be stored. Instead, the two top values are taken from the stack, they are added together, and their sum is pushed into the stack in their place. -³ A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. - ---- +### 1.1.1 TVM values -## 1.1.1 TVM values +The entities that can be stored in the TVM stack will be called **TVM values**, or simply **values** for brevity. They belong to one of several predefined value types. Each value belongs to exactly one value type. -The entities that can be stored in the TVM stack will be called **TVM values**, or simply **values** for brevity. They belong to one of several predefined value types. Each value belongs to exactly one value type. The values are always kept on the stack along with tags uniquely determining their types, and all built-in TVM operations (or primitives) only accept values of predefined types. +The values are always kept on the stack along with tags uniquely determining their types, and all built-in TVM operations (or primitives) only accept values of predefined types. For example, the integer addition primitive `ADD` accepts only two integer values, and returns one integer value as a result. One cannot supply `ADD` with two strings instead of two integers expecting it to concatenate these strings or to implicitly transform the strings into their decimal integer values; any attempt to do so will result in a run-time type-checking exception. ---- - -## 1.1.2 Static typing, dynamic typing, and run-time type checking +### 1.1.2 Static typing, dynamic typing, and run-time type checking In some respects TVM performs a kind of dynamic typing using run-time type checking. However, this does not make the TVM code a “dynamically typed language” like PHP or Javascript, because all primitives accept values and return results of predefined (value) types, each value belongs to strictly one type, and values are never implicitly converted from one type to another. -If, on the other hand, one compares the TVM code to the conventional microprocessor machine code, one sees that the TVM mechanism of value tagging prevents, for example, using the address of a string as a number—or, potentially even more disastrously, using a number as the address of a string—thus eliminating the possibility of all sorts of bugs and security vulnerabilities related to invalid memory accesses, usually leading to memory corruption and segmentation faults. +If, on the other hand, one compares the TVM code to the conventional microprocessor machine code, one sees that the TVM mechanism of value tagging prevents, for example, using the address of a string as a number—or, potentially even more disastrously, using a number as the address of a string—thus eliminating the possibility of all sorts of bugs and security vulnerabilities related to invalid memory accesses, usually leading to memory corruption and segmentation faults. This property is highly desirable for a VM used to execute smart contracts in a blockchain. In this respect, TVM’s insistence on tagging all values with their appropriate types, instead of reinterpreting the bit sequence in a register depending on the needs of the operation it is used in, is just an additional run-time type-safety mechanism. An alternative would be to somehow analyze the smart-contract code for type correctness and type safety before allowing its execution in the VM, or even before allowing it to be uploaded into the blockchain as the code of a smart contract. Such a static analysis of code for a Turing-complete machine appears to be a time-consuming and non-trivial problem (likely to be equivalent to the stopping problem for Turing machines), something we would rather avoid in a blockchain smart-contract context. -One should bear in mind that one always can implement compilers from statically typed high-level smart-contract languages into the TVM code (and we do expect that most smart contracts for TON will be written in such languages), just as one can compile statically typed languages into conventional machine code (e.g., x86 architecture). If the compiler works correctly, the resulting machine code will never generate any run-time type-checking exceptions. +One should bear in mind that one always can implement compilers from statically typed high-level smart-contract languages into the TVM code (and we do expect that most smart contracts for TON will be written in such languages), just as one can compile statically typed languages into conventional machine code (e.g., x86 architecture). If the compiler works correctly, the resulting machine code will never generate any run-time type-checking exceptions. All type tags attached to values processed by TVM will always have expected values and may be safely ignored during the analysis of the resulting TVM code, apart from the fact that the run-time generation and verification of these type tags by TVM will slightly slow down the execution of the TVM code. ---- - -## 1.1.3 Preliminary list of value types +### 1.1.3 Preliminary list of value types A preliminary list of value types supported by TVM is as follows: -* **Integer** — Signed 257-bit integers, representing integer numbers in the range −2²⁵⁶ … 2²⁵⁶−1, as well as a special “not-a-number” value `NaN`. -* **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. \[1, 2.5.14]). -* **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. -* **Null** — A type with exactly one value ⊥, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. -* **Slice** — A TVM cell slice, or slice for short, is a contiguous “sub-cell” of an existing cell, containing some of its bits of data and some of its references. Essentially, a slice is a read-only view for a subcell of a cell. Slices are used for unpacking data previously stored (or serialized) in a cell or a tree of cells. -* **Builder** — A TVM cell builder, or builder for short, is an “incomplete” cell that supports fast operations of appending bitstrings and cell references at its end. Builders are used for packing (or serializing) data from the top of the stack into new cells (e.g., before transferring them to persistent storage). -* **Continuation** — A special value containing TVM code and execution context that can be invoked (executed) later. As such, it generalizes function addresses (i.e., function pointers and references), subroutine return addresses, instruction pointer addresses, exception handler addresses, closures, partial applications, anonymous functions, and so on. +- **Integer** — Signed 257-bit integers, representing integer numbers in the range `−2^256 … 2^256 − 1`, as well as a special “not-a-number” value `NaN`. +- **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. [1, 2.5.14]). +- **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. +- **Null** — A type with exactly one value `⊥`, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. +- **Slice** — A TVM cell slice, or slice for short, is a contiguous “sub-cell” of an existing cell, containing some of its bits of data and some of its references. Essentially, a slice is a read-only view for a subcell of a cell. Slices are used for unpacking data previously stored (or serialized) in a cell or a tree of cells. +- **Builder** — A TVM cell builder, or builder for short, is an “incomplete” cell that supports fast operations of appending bitstrings and cell references at its end. Builders are used for packing (or serializing) data from the top of the stack into new cells (e.g., before transferring them to persistent storage). +- **Continuation** — Represents an “execution token” for TVM, which may be invoked (executed) later. As such, it generalizes function addresses (i.e., function pointers and references), subroutine return addresses, instruction pointer addresses, exception handler addresses, closures, partial applications, anonymous functions, and so on. -This list of value types is incomplete and may be extended in future revisions of TVM without breaking the old TVM code, due mostly to the fact that all originally defined primitives accept only values of types known to them and will fail (generate a type-checking exception) if invoked on values of new types. +This list of value types is incomplete and may be extended in future revisions of TVM without breaking the old TVM code, due mostly to the fact that all originally defined primitives accept only values of types known to them and will fail (generate a type-checking exception) if invoked on values of new types. -Furthermore, existing value types themselves can also be extended in the future: for example, 257-bit `Integer` might become 513-bit `LongInteger`, with originally defined arithmetic primitives failing if either of the arguments or the result does not fit into the original subtype `Integer`. +Furthermore, existing value types themselves can also be extended in the future: for example, 257-bit `Integer` might become 513-bit `LongInteger`, with originally defined arithmetic primitives failing if either of the arguments or the result does not fit into the original subtype `Integer`. Backward compatibility with respect to the introduction of new value types and extension of existing value types will be discussed in more detail later (cf. 5.1.4). @@ -126,15 +122,17 @@ Backward compatibility with respect to the introduction of new value types and e ## 1.2 Categories of TVM instructions -TVM instructions, also called **primitives** and sometimes **(built-in) operations**, are the smallest operations atomically performed by TVM that can be present in the TVM code. They fall into several categories, depending on the types of values (cf. 1.1.3) they work on. The most important of these categories are: +TVM instructions, also called **primitives** and sometimes **(built-in) operations**, are the smallest operations atomically performed by TVM that can be present in the TVM code. + +They fall into several categories, depending on the types of values (cf. 1.1.3) they work on. The most important of these categories are: -* **Stack (manipulation) primitives** — Rearrange data in the TVM stack, so that the other primitives and user-defined functions can later be called with correct arguments. Unlike most other primitives, they are polymorphic, i.e., work with values of arbitrary types. -* **Tuple (manipulation) primitives** — Construct, modify, and decompose Tuples. Similarly to the stack primitives, they are polymorphic. -* **Constant or literal primitives** — Push into the stack some “constant” or “literal” values embedded into the TVM code itself, thus providing arguments to the other primitives. They are somewhat similar to stack primitives, but are less generic because they work with values of specific types. -* **Arithmetic primitives** — Perform the usual integer arithmetic operations on values of type Integer. -* **Cell (manipulation) primitives** — Create new cells and store data in them (cell creation primitives) or read data from previously created cells (cell parsing primitives). Because all memory and persistent storage of TVM consists of cells, these cell manipulation primitives actually correspond to “memory access instructions” of other architectures. Cell creation primitives usually work with values of type Builder, while cell parsing primitives work with Slices. -* **Continuation and control flow primitives** — Create and modify Continuations, as well as execute existing Continuations in different ways, including conditional and repeated execution. -* **Custom or application-specific primitives** — Efficiently perform specific high-level actions required by the application (in our case, the TON Blockchain), such as computing hash functions, performing elliptic curve cryptography, sending new blockchain messages, creating new smart contracts, and so on. These primitives correspond to standard library functions rather than microprocessor instructions. +- **Stack (manipulation) primitives** — Rearrange data in the TVM stack, so that the other primitives and user-defined functions can later be called with correct arguments. Unlike most other primitives, they are polymorphic, i.e., work with values of arbitrary types. +- **Tuple (manipulation) primitives** — Construct, modify, and decompose Tuples. Similarly to the stack primitives, they are polymorphic. +- **Constant or literal primitives** — Push into the stack some “constant” or “literal” values embedded into the TVM code itself, thus providing arguments to the other primitives. They are somewhat similar to stack primitives, but are less generic because they work with values of specific types. +- **Arithmetic primitives** — Perform the usual integer arithmetic operations on values of type `Integer`. +- **Cell (manipulation) primitives** — Create new cells and store data in them (cell creation primitives) or read data from previously created cells (cell parsing primitives). Because all memory and persistent storage of TVM consists of cells, these cell manipulation primitives actually correspond to “memory access instructions” of other architectures. Cell creation primitives usually work with values of type `Builder`, while cell parsing primitives work with `Slices`. +- **Continuation and control flow primitives** — Create and modify `Continuations`, as well as execute existing `Continuations` in different ways, including conditional and repeated execution. +- **Custom or application-specific primitives** — Efficiently perform specific high-level actions required by the application (in our case, the TON Blockchain), such as computing hash functions, performing elliptic curve cryptography, sending new blockchain messages, creating new smart contracts, and so on. These primitives correspond to standard library functions rather than microprocessor instructions. --- @@ -4760,4 +4758,14 @@ For example, the very popular two-address register architecture x86-64 produces ## C.4.4. Automatic generation of optimized code. An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in 2.2.2 and 2.2.5. The only exception is the unimportant “manual” XCHG3 optimization described in C.1.7, which enabled us to shorten the code by one more byte. -By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. \ No newline at end of file +By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. + + + +## Footnotes + + **1.** There are no floating-point arithmetic operations (which could be efficiently implemented using hardware-supported `double` type on most modern CPUs) present in TVM, because the result of performing such operations is dependent on the specific underlying hardware implementation and rounding mode settings. Instead, TVM supports special integer arithmetic operations, which can be used to simulate fixed-point arithmetic if needed. [Back ↑](#1-introduction) + + **2.** The production version will likely require some tweaks and modifications prior to launch, which will become apparent only after using the experimental version in the test environment for some time. [Back ↑](#1-introduction) + + **3.** A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. [Back ↑](#11-tvm-is-a-stack-machine) From 1da1b7a98c5f48b1792d19964d69de7c609fb217 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Sun, 7 Sep 2025 04:22:30 +0100 Subject: [PATCH 10/18] update tvm formatting --- ton/tvm.mdx | 3758 ++++++++++++++++++--------------------------------- 1 file changed, 1336 insertions(+), 2422 deletions(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 98510fb1..75fedb0c 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -18,9 +18,9 @@ Additionally, TVM must meet the following requirements: - **Backward compatibility:** It must provide for possible future extensions and improvements while retaining backward compatibility and interoperability, because the code of a smart contract, once committed into the blockchain, must continue working in a predictable manner regardless of any future modifications to the VM. - **Code density:** It must strive to attain high “(virtual) machine code” density, so that the code of a typical smart contract occupies as little persistent blockchain storage as possible. -- **Determinism:** It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used. [^1](#footnote-1) +- **Determinism:** It must be completely deterministic. In other words, each run of the same code with the same input data must produce the same result, regardless of specific software and hardware used. [1](#footnote-1) -The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM, [^2](#footnote-2), the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. +The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM, [2](#footnote-2), the backward compatibility mechanisms built into the system allow us to be relatively unconcerned with the efficiency of the operation encoding used for TVM code in this preliminary version. TVM is not intended to be implemented in hardware (e.g., in a specialized microprocessor chip); rather, it should be implemented in software running on conventional hardware. This consideration lets us incorporate some high-level concepts and operations in TVM that would require convoluted microcode in a hardware implementation but pose no significant problems for a software implementation. Such operations are useful for achieving high code density and minimizing the byte (or storage cell) profile of smart-contract code when deployed in the TON Blockchain. @@ -74,7 +74,7 @@ In some cases, it is more convenient to assume the completion is enabled by defa ## 1.1 TVM is a stack machine -First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective. [^3](#footnote-3) +First of all, TVM is a stack machine. This means that, instead of keeping values in some “variables” or “general-purpose registers”, they are kept in a (LIFO) stack, at least from the “low-level” (TVM) perspective.[3](#footnote-3) Most operations and user-defined functions take their arguments from the top of the stack, and replace them with their result. For example, the integer addition primitive (built-in operation) `ADD` does not take any arguments describing which registers or immediate values should be added together and where the result should be stored. Instead, the two top values are taken from the stack, they are added together, and their sum is pushed into the stack in their place. @@ -105,7 +105,7 @@ All type tags attached to values processed by TVM will always have expected valu A preliminary list of value types supported by TVM is as follows: - **Integer** — Signed 257-bit integers, representing integer numbers in the range `−2^256 … 2^256 − 1`, as well as a special “not-a-number” value `NaN`. -- **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. [1, 2.5.14]). +- **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. [1](#reference-1) 2.5.14]). - **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. - **Null** — A type with exactly one value `⊥`, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. - **Slice** — A TVM cell slice, or slice for short, is a contiguous “sub-cell” of an existing cell, containing some of its bits of data and some of its references. Essentially, a slice is a read-only view for a subcell of a cell. Slices are used for unpacking data previously stored (or serialized) in a cell or a tree of cells. @@ -116,7 +116,7 @@ This list of value types is incomplete and may be extended in future revisions o Furthermore, existing value types themselves can also be extended in the future: for example, 257-bit `Integer` might become 513-bit `LongInteger`, with originally defined arithmetic primitives failing if either of the arguments or the result does not fit into the original subtype `Integer`. -Backward compatibility with respect to the introduction of new value types and extension of existing value types will be discussed in more detail later (cf. 5.1.4). +Backward compatibility with respect to the introduction of new value types and extension of existing value types will be discussed in more detail later (cf. [5.1.4](#5-1-4-changing-the-behavior-of-old-operations)). --- @@ -124,7 +124,7 @@ Backward compatibility with respect to the introduction of new value types and e TVM instructions, also called **primitives** and sometimes **(built-in) operations**, are the smallest operations atomically performed by TVM that can be present in the TVM code. -They fall into several categories, depending on the types of values (cf. 1.1.3) they work on. The most important of these categories are: +They fall into several categories, depending on the types of values (cf. [1.1.3](#1-1-3-preliminary-list-of-value-types)) they work on. The most important of these categories are: - **Stack (manipulation) primitives** — Rearrange data in the TVM stack, so that the other primitives and user-defined functions can later be called with correct arguments. Unlike most other primitives, they are polymorphic, i.e., work with values of arbitrary types. - **Tuple (manipulation) primitives** — Construct, modify, and decompose Tuples. Similarly to the stack primitives, they are polymorphic. @@ -135,34 +135,27 @@ They fall into several categories, depending on the types of values (cf. 1.1.3) - **Custom or application-specific primitives** — Efficiently perform specific high-level actions required by the application (in our case, the TON Blockchain), such as computing hash functions, performing elliptic curve cryptography, sending new blockchain messages, creating new smart contracts, and so on. These primitives correspond to standard library functions rather than microprocessor instructions. --- - ## 1.3 Control registers While TVM is a stack machine, some rarely changed values needed in almost all functions are better passed in certain special registers, and not near the top of the stack. Otherwise, a prohibitive number of stack reordering operations would be required to manage all these values. -To this end, the TVM model includes, apart from the stack, up to **16 special control registers**, denoted by `c0` to `c15`, or `c(0)` to `c(15)`. The original version of TVM makes use of only some of these registers; the rest may be supported later. - ---- +To this end, the TVM model includes, apart from the stack, up to 16 special control registers, denoted by `c0` to `c15`, or `c(0)` to `c(15)`. The original version of TVM makes use of only some of these registers; the rest may be supported later. ### 1.3.1 Values kept in control registers The values kept in control registers are of the same types as those kept on the stack. However, some control registers accept only values of specific types, and any attempt to load a value of a different type will lead to an exception. ---- - ### 1.3.2 List of control registers The original version of TVM defines and uses the following control registers: -* **c0** — Contains the return continuation (similar to the subroutine return address in conventional designs). This value must be a Continuation. -* **c1** — Contains the alternative (return) continuation; this value must be a Continuation. It is used in some (experimental) control flow primitives, allowing TVM to define and call “subroutines with two exit points”. -* **c2** — Contains the exception handler. This value is a Continuation, invoked whenever an exception is triggered. -* **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in 4.6, this value is also a Continuation, not a Cell as one might expect. -* **c4** — Contains the root of persistent data, or simply the data. This value is a Cell. When the code of a smart contract is invoked, `c4` points to the root cell of its persistent data kept in the blockchain state. If the smart contract needs to modify this data, it changes `c4` before returning. -* **c5** — Contains the output actions. It is also a Cell initialized by a reference to an empty cell, but its final value is considered one of the smart contract outputs. For instance, the `SENDMSG` primitive, specific for the TON Blockchain, simply inserts the message into a list stored in the output actions. -* **c7** — Contains the root of temporary data. It is a Tuple, initialized by a reference to an empty Tuple before invoking the smart contract and discarded after its termination.⁴ - -⁴ In the TON Blockchain context, `c7` is initialized with a singleton Tuple, the only component of which is a Tuple containing blockchain-specific data. The smart contract is free to modify `c7` to store its temporary data provided the first component of this Tuple remains intact. +- **c0** — Contains the next continuation or return continuation (similar to the subroutine return address in conventional designs). This value must be a `Continuation`. +- **c1** — Contains the alternative (return) continuation; this value must be a `Continuation`. It is used in some (experimental) control flow primitives, allowing TVM to define and call “subroutines with two exit points”. +- **c2** — Contains the exception handler. This value is a `Continuation`, invoked whenever an exception is triggered. +- **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in [4.6](#4-6-...-reference), this value is also a `Continuation`, not a `Cell` as one might expect. +- **c4** — Contains the root of persistent data, or simply the data. This value is a `Cell`. When the code of a smart contract is invoked, `c4` points to the root cell of its persistent data kept in the blockchain state. If the smart contract needs to modify this data, it changes `c4` before returning. +- **c5** — Contains the output actions. It is also a `Cell` initialized by a reference to an empty cell, but its final value is considered one of the smart contract outputs. For instance, the `SENDMSG` primitive, specific for the TON Blockchain, simply inserts the message into a list stored in the output actions. +- **c7** — Contains the root of temporary data. It is a `Tuple`, initialized by a reference to an empty `Tuple` before invoking the smart contract and discarded after its termination.[4](#footnote-4) More control registers may be defined in the future for specific TON Blockchain or high-level programming language purposes, if necessary. @@ -172,1035 +165,541 @@ More control registers may be defined in the future for specific TON Blockchain The total state of TVM consists of the following components: -* **Stack** (cf. 1.1) — Contains zero or more values (cf. 1.1.1), each belonging to one of value types listed in 1.1.3. -* **Control registers `c0–c15`** — Contain some specific values as described in 1.3.2. (Only seven control registers are used in the current version.) -* **Current continuation `cc`** — Contains the current continuation (i.e., the code that would be normally executed after the current primitive is completed). This component is similar to the instruction pointer register (`ip`) in other architectures. -* **Current codepage `cp`** — A special signed 16-bit integer value that selects the way the next TVM opcode will be decoded. For example, future versions of TVM might use different codepages to add new opcodes while preserving backward compatibility. -* **Gas limits `gas`** — Contains four signed 64-bit integers: the current gas limit `gl`, the maximal gas limit `gm`, the remaining gas `gr`, and the gas credit `gc`. Always `0 ≤ gl ≤ gm`, `gc ≥ 0`, and `gr ≤ gl + gc`; `gc` is usually initialized by zero, `gr` is initialized by `gl + gc` and gradually decreases as the TVM runs. When `gr` becomes negative or if the final value of `gr` is less than `gc`, an out of gas exception is triggered. - -Notice that there is no “return stack” containing the return addresses of all previously called but unfinished functions. Instead, only control register `c0` is used. The reason for this will be explained later in 4.1.9. +- **Stack (cf. [1.1](#1-1-tvm-is-a-stack-machine))** — Contains zero or more values (cf. [1.1.1](#1-1-1-tvm-values)), each belonging to one of value types listed in [1.1.3](#1-1-3-preliminary-list-of-value-types). +- **Control registers c0–c15** — Contain some specific values as described in [1.3.2](#1-3-2-list-of-control-registers). (Only seven control registers are used in the current version.) +- **Current continuation `cc`** — Contains the current continuation (i.e., the code that would be normally executed after the current primitive is completed). This component is similar to the instruction pointer register (`ip`) in other architectures. +- **Current codepage `cp`** — A special signed 16-bit integer value that selects the way the next TVM opcode will be decoded. For example, future versions of TVM might use different codepages to add new opcodes while preserving backward compatibility. +- **Gas limits `gas`** — Contains four signed 64-bit integers: the current gas limit `gl`, the maximal gas limit `gm`, the remaining gas `gr`, and the gas credit `gc`. Always `0 ≤ gl ≤ gm`, `gc ≥ 0`, and `gr ≤ gl + gc`; `gc` is usually initialized by zero, `gr` is initialized by `gl + gc` and gradually decreases as the TVM runs. When `gr` becomes negative or if the final value of `gr` is less than `gc`, an out of gas exception is triggered. -Also notice that there are no general-purpose registers, because TVM is a stack machine (cf. 1.1). So the above list, which can be summarized as “stack, control, continuation, codepage, and gas” (**SCCCG**), similarly to the classical SECD machine state (“stack, environment, control, dump”), is indeed the total state of TVM. +Notice that there is no “return stack” containing the return addresses of all previously called but unfinished functions. Instead, only control register `c0` is used. The reason for this will be explained later in [4.1.9](#4-1-9-subroutine-calls%3A-callx-or-execute-primitives). -Perfect — here’s the next part, keeping the **exact wording** but properly formatted into Markdown. +Also notice that there are no general-purpose registers, because TVM is a stack machine (cf. [1.1](#1-1-tvm-is-a-stack-machine)). So the above list, which can be summarized as **“stack, control, continuation, codepage, and gas” (SCCCG)**, similarly to the classical SECD machine state (“stack, environment, control, dump”), is indeed the total state of TVM.[5](#footnote-5) --- ## 1.5 Integer arithmetic -All arithmetic primitives of TVM operate on several arguments of type **Integer**, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that Integer represents all integer values in the range `−2²⁵⁶ ≤ x < 2²⁵⁶`, and additionally contains a special value **NaN** (“not-a-number”). +All arithmetic primitives of TVM operate on several arguments of type `Integer`, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that `Integer` represents all integer values in the range `−2^256 ≤ x < 2^256`, and additionally contains a special value `NaN` (“not-a-number”). -If one of the results does not fit into the supported range of integers—or if one of the arguments is a NaN—then this result or all of the results are replaced by a NaN, and (by default) an integer overflow exception is generated. However, special “quiet” versions of arithmetic operations will simply produce NaNs and keep going. If these NaNs end up being used in a “non-quiet” arithmetic operation, or in a non-arithmetic operation, an integer overflow exception will occur. - ---- +If one of the results does not fit into the supported range of integers—or if one of the arguments is a `NaN`—then this result or all of the results are replaced by a `NaN`, and (by default) an integer overflow exception is generated. However, special “quiet” versions of arithmetic operations will simply produce `NaN`s and keep going. If these `NaN`s end up being used in a “non-quiet” arithmetic operation, or in a non-arithmetic operation, an integer overflow exception will occur. ### 1.5.1 Absence of automatic conversion of integers -Notice that TVM Integers are “mathematical” integers, and not 257-bit strings interpreted differently depending on the primitive used, as is common for other machine code designs. For example, TVM has only one multiplication primitive `MUL`, rather than two (`MUL` for unsigned multiplication and `IMUL` for signed multiplication) as occurs, for example, in the popular x86 architecture. - ---- +Notice that TVM `Integer`s are “mathematical” integers, and not 257-bit strings interpreted differently depending on the primitive used, as is common for other machine code designs. For example, TVM has only one multiplication primitive `MUL`, rather than two (`MUL` for unsigned multiplication and `IMUL` for signed multiplication) as occurs, for example, in the popular x86 architecture. ### 1.5.2 Automatic overflow checks -Notice that all TVM arithmetic primitives perform overflow checks of the results. If a result does not fit into the Integer type, it is replaced by a NaN, and (usually) an exception occurs. In particular, the result is not automatically reduced modulo `2²⁵⁶` or `2²⁵⁷`, as is common for most hardware machine code architectures. +Notice that all TVM arithmetic primitives perform overflow checks of the results. If a result does not fit into the `Integer` type, it is replaced by a `NaN`, and (usually) an exception occurs. ---- +In particular, the result is not automatically reduced modulo `2^256` or `2^257`, as is common for most hardware machine code architectures. ### 1.5.3 Custom overflow checks -In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. - -* `FITS n` checks whether the value on the top of the stack is an integer `x` in the range `−2ⁿ⁻¹ ≤ x < 2ⁿ⁻¹`. -* `UFITS n` checks whether the value is in the range `0 ≤ x < 2ⁿ`. - -If the value does not fit, it is replaced with a NaN and (optionally) an integer overflow exception is generated. +In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. These primitives check whether the value on (the top of) the stack is an integer `x` in the range `−2^(n−1) ≤ x < 2^(n−1)` or `0 ≤ x < 2^n`, respectively, and replace the value with a `NaN` and (optionally) generate an integer overflow exception if this is not the case. -This greatly simplifies the implementation of arbitrary `n`-bit integer types, signed or unsigned: the programmer or the compiler must insert appropriate `FITS` or `UFITS` primitives either after each arithmetic operation (which is more reasonable, but requires more checks) or before storing computed values and returning them from functions. This is important for smart contracts, where unexpected integer overflows happen to be among the most common source of bugs. +This greatly simplifies the implementation of arbitrary n-bit integer types, signed or unsigned: the programmer or the compiler must insert appropriate `FITS` or `UFITS` primitives either after each arithmetic operation (which is more reasonable, but requires more checks) or before storing computed values and returning them from functions. ---- +This is important for smart contracts, where unexpected integer overflows happen to be among the most common source of bugs. ### 1.5.4 Reduction modulo 2ⁿ -TVM also has a primitive `MODPOW2 n`, which reduces the integer at the top of the stack modulo `2ⁿ`, with the result ranging from `0` to `2ⁿ − 1`. - ---- +TVM also has a primitive `MODPOW2 n`, which reduces the integer at the top of the stack modulo `2^n`, with the result ranging from `0` to `2^n − 1`. ### 1.5.5 Integer is 257-bit, not 256-bit -One can understand now why TVM’s Integer is (signed) 257-bit, not 256-bit. The reason is that it is the smallest integer type containing both signed 256-bit integers and unsigned 256-bit integers, which does not require automatic reinterpreting of the same 256-bit string depending on the operation used (cf. 1.5.1). - ---- +One can understand now why TVM’s `Integer` is (signed) 257-bit, not 256-bit. The reason is that it is the smallest integer type containing both signed 256-bit integers and unsigned 256-bit integers, which does not require automatic reinterpreting of the same 256-bit string depending on the operation used (cf. [1.5.1](#1-5-1-absence-of-automatic-conversion-of-integers)). ### 1.5.6 Division and rounding -The most important division primitives are `DIV`, `MOD`, and `DIVMOD`. All of them take two numbers from the stack, `x` and `y` (`y` is taken from the top of the stack, and `x` is originally under it), compute the quotient `q` and remainder `r` of the division of `x` by `y` (i.e., two integers such that `x = yq + r` and `|r| < |y|`), and return either `q`, `r`, or both of them. +The most important division primitives are `DIV`, `MOD`, and `DIVMOD`. All of them take two numbers from the stack, `x` and `y` (`y` is taken from the top of the stack, and `x` is originally under it), compute the quotient `q` and remainder `r` of the division of `x` by `y` (i.e., two integers such that `x = yq + r` and `|r| < |y|`), and return either `q`, `r`, or both of them. -* If `y` is zero, then all of the expected results are replaced by NaNs, and (usually) an integer overflow exception is generated. -* By default, these primitives round to `−∞`, meaning that `q = ⌊x / y⌋`, and `r` has the same sign as `y`. (Most conventional implementations of division use “rounding to zero” instead, meaning that `r` has the same sign as `x`.) +If `y` is zero, then all of the expected results are replaced by `NaN`s, and (usually) an integer overflow exception is generated. -Apart from this **floor rounding**, two other rounding modes are available: +The implementation of division in TVM somewhat differs from most other implementations with regards to rounding. By default, these primitives round to `−∞`, meaning that `q = ⌊x/y⌋`, and `r` has the same sign as `y`. (Most conventional implementations of division use “rounding to zero” instead, meaning that `r` has the same sign as `x`.) -* **Ceiling rounding**: `q = ⌈x / y⌉`, and `r` and `y` have opposite signs. -* **Nearest rounding**: `q = ⌊x / y + 1/2⌋` and `|r| ≤ |y| / 2`. +Apart from this “floor rounding”, two other rounding modes are available, called **ceiling rounding** (with `q = ⌈x/y⌉`, and `r` and `y` having opposite signs) and **nearest rounding** (with `q = ⌊x/y + 1/2⌋` and `|r| ≤ |y|/2`). These rounding modes are selected by using other division primitives, with letters `C` and `R` appended to their mnemonics. For example, `DIVMODR` computes both the quotient and the remainder using rounding to the nearest integer. ---- - ### 1.5.7 Combined multiply-divide, multiply-shift, and shift-divide operations -To simplify implementation of fixed-point arithmetic, TVM supports combined multiply-divide, multiply-shift, and shift-divide operations with double-length (i.e., 514-bit) intermediate product. +To simplify implementation of fixed-point arithmetic, TVM supports combined multiply-divide, multiply-shift, and shift-divide operations with double-length (i.e., 514-bit) intermediate product. -For example, `MULDIVMODR` takes three integer arguments from the stack, `a`, `b`, and `c`, first computes `ab` using a 514-bit intermediate result, and then divides `ab` by `c` using rounding to the nearest integer. +For example, `MULDIVMODR` takes three integer arguments from the stack, `a`, `b`, and `c`, first computes `ab` using a 514-bit intermediate result, and then divides `ab` by `c` using rounding to the nearest integer. -* If `c` is zero or if the quotient does not fit into Integer, either two NaNs are returned, or an integer overflow exception is generated, depending on whether a quiet version of the operation has been used. -* Otherwise, both the quotient and the remainder are pushed into the stack. +If `c` is zero or if the quotient does not fit into `Integer`, either two `NaN`s are returned, or an integer overflow exception is generated, depending on whether a quiet version of the operation has been used. Otherwise, both the quotient and the remainder are pushed into the stack. --- # 2 The stack -This chapter contains a general discussion and comparison of register and -stack machines, expanded further in Appendix C, and describes the two -main classes of stack manipulation primitives employed by TVM: the basic -and the compound stack manipulation primitives. An informal explanation of -their sufficiency for all stack reordering required for correctly invoking other -primitives and user-defined functions is also provided. Finally, the problem -of efficiently implementing TVM stack manipulation primitives is discussed -in 2.3. +This chapter contains a general discussion and comparison of register and stack machines, expanded further in [Appendix C](#appendix-c), and describes the two main classes of stack manipulation primitives employed by TVM: the basic and the compound stack manipulation primitives. An informal explanation of their sufficiency for all stack reordering required for correctly invoking other primitives and user-defined functions is also provided. Finally, the problem of efficiently implementing TVM stack manipulation primitives is discussed in [2.3](#2-3-...). ## 2.1 Stack calling conventions -A stack machine, such as TVM, uses the stack—and especially the values -near the top of the stack—to pass arguments to called functions and primitives (such as built-in arithmetic operations) and receive their results. This -section discusses the TVM stack calling conventions, introduces some notation, and compares TVM stack calling conventions with those of certain -register machines. - -### 2.1.1. Notation for “stack registers”. - -Recall that a stack machine, as -opposed to a more conventional register machine, lacks general-purpose registers. However, one can treat the values near the top of the stack as a kind -of “stack registers”. -We denote by s0 or s(0) the value at the top of the stack, by s1 or s(1) -the value immediately under it, and so on. The total number of values in the -stack is called its depth. If the depth of the stack is n, then s(0), s(1), . . . , -s(n − 1) are well-defined, while s(n) and all subsequent s(i) with i > n are -not. Any attempt to use s(i) with i ≥ n should produce a stack underflow -exception. -A compiler, or a human programmer in “TVM code”, would use these -“stack registers” to hold all declared variables and intermediate values, similarly to the way general-purpose registers are used on a register machine. - -### 2.1.2. Pushing and popping values. - -When a value x is pushed into a -stack of depth n, it becomes the new s0; at the same time, the old s0 becomes -the new s1, the old s1—the new s2, and so on. The depth of the resulting -stack is n + 1. -Similarly, when a value x is popped from a stack of depth n ≥ 1, it is the -old value of s0 (i.e., the old value at the top of the stack). After this, it is -removed from the stack, and the old s1 becomes the new s0 (the new value -at the top of the stack), the old s2 becomes the new s1, and so on. The -depth of the resulting stack is n − 1. -If originally n = 0, then the stack is empty, and a value cannot be popped -from it. If a primitive attempts to pop a value from an empty stack, a stack -underflow exception occurs. - -### 2.1.3. Notation for hypothetical general-purpose registers. - -In order -to compare stack machines with sufficiently general register machines, we will -denote the general-purpose registers of a register machine by r0, r1, and so -on, or by r(0), r(1), . . . , r(n − 1), where n is the total number of registers. -When we need a specific value of n, we will use n = 16, corresponding to the -very popular x86-64 architecture. - -### 2.1.4. The top-of-stack register s0 vs. the accumulator register r0. - -Some register machine architectures require one of the arguments for most -arithmetic and logical operations to reside in a special register called the -accumulator. In our comparison, we will assume that the accumulator is -the general-purpose register r0; otherwise we could simply renumber the -registers. In this respect, the accumulator is somewhat similar to the top-ofstack “register” s0 of a stack machine, because virtually all operations of a -stack machine both use s0 as one of their arguments and return their result -as s0. - -### 2.1.5. Register calling conventions. - -When compiled for a register machine, high-level language functions usually receive their arguments in certain -registers in a predefined order. If there are too many arguments, these functions take the remainder from the stack (yes, a register machine usually has -a stack, too!). Some register calling conventions pass no arguments in registers at all, however, and only use the stack (for example, the original calling -conventions used in implementations of Pascal and C, although modern implementations of C use some registers as well). -For simplicity, we will assume that up to m ≤ n function arguments are -passed in registers, and that these registers are r0, r1, . . . , r(m − 1), in that -order (if some other registers are used, we can simply renumber them).6 -6Our inclusion of r0 here creates a minor conflict with our assumption that the ac - -### 2.1.6. Order of function arguments. - -If a function or primitive requires -m arguments x1, . . . , xm, they are pushed by the caller into the stack in the -same order, starting from x1. Therefore, when the function or primitive is -invoked, its first argument x1 is in s(m − 1), its second argument x2 is in -s(m − 2), and so on. The last argument xm is in s0 (i.e., at the top of the -stack). It is the called function or primitive’s responsibility to remove its -arguments from the stack. -In this respect the TVM stack calling conventions—obeyed, at least, by -TMV primitives—match those of Pascal and Forth, and are the opposite of -those of C (in which the arguments are pushed into the stack in the reverse -order, and are removed by the caller after it regains control, not the callee). -Of course, an implementation of a high-level language for TVM might -choose some other calling conventions for its functions, different from the -default ones. This might be useful for certain functions—for instance, if the -total number of arguments depends on the value of the first argument, as -happens for “variadic functions” such as scanf and printf. In such cases, -the first one or several arguments are better passed near the top of the stack, -not somewhere at some unknown location deep in the stack. - -### 2.1.7. Arguments to arithmetic primitives on register machines. - -On a stack machine, built-in arithmetic primitives (such as ADD or DIVMOD) -follow the same calling conventions as user-defined functions. In this respect, -user-defined functions (for example, a function computing the square root of -a number) might be considered as “extensions” or “custom upgrades” of the -stack machine. This is one of the clearest advantages of stack machines -(and of stack programming languages such as Forth) compared to register -machines. - -In contrast, arithmetic instructions (built-in operations) on register machines usually get their parameters from general-purpose registers encoded -in the full opcode. A binary operation, such as SUB, thus requires two arguments, r(i) and r(j), with i and j specified by the instruction. A register -r(k) for storing the result also must be specified. Arithmetic operations can -take several possible forms, depending on whether i, j, and k are allowed to -take arbitrary values: - -* Three-address form — Allows the programmer to arbitrarily choose - not only the two source registers r(i) and r(j), but also a separate - destination register r(k). This form is common for most RISC processors, and for the XMM and AVX SIMD instruction sets in the x86-64 - architecture. -* Two-address form — Uses one of the two operand registers (usually - r(i)) to store the result of an operation, so that k = i is never indicated - explicitly. Only i and j are encoded inside the instruction. This is the - most common form of arithmetic operations on register machines, and - is quite popular on microprocessors (including the x86 family). -* One-address form — Always takes one of the arguments from the accumulator r0, and stores the result in r0 as well; then i = k = 0, and - only j needs to be specified by the instruction. This form is used by - some simpler microprocessors (such as Intel 8080). - -Note that this flexibility is available only for built-in operations, but not for user-defined functions. In this respect, register machines are not as easily “upgradable” as stack machines.7 - -Got it ✅ — you want all the inline code-like things (mnemonics, variables, stack notation, etc.) properly wrapped in backticks (`` ` ``) for Markdown. I’ll take the exact text from Chapter 2 (as we’ve been doing), but ensure things like `s0`, `s(i)`, `XCHG`, `PUSH`, `DIV`, etc. are in backticks so they render as code. - -Here’s the **cleaned version with backticks applied** (continuing from §2.1.8 to the end of Chapter 2): +A stack machine, such as TVM, uses the stack—and especially the values near the top of the stack—to pass arguments to called functions and primitives (such as built-in arithmetic operations) and receive their results. This section discusses the TVM stack calling conventions, introduces some notation, and compares TVM stack calling conventions with those of certain register machines. ---- +### 2.1.1 Notation for “stack registers” -### 2.1.8. Return values of functions. - -In stack machines such as TVM, -when a function or primitive needs to return a result value, it simply pushes -it into the stack (from which all arguments to the function have already been -removed). Therefore, the caller will be able to access the result value through -the top-of-stack “register” `s0`. -This is in complete accordance with Forth calling conventions, but differs slightly from Pascal and C calling conventions, where the accumulator -register `r0` is normally used for the return value. - -### 2.1.9. Returning several values. - -Some functions might want to return -several values `y1, . . . , yk`, with `k` not necessarily equal to one. In these cases, -the `k` return values are pushed into the stack in their natural order, starting -from `y1`. -For example, the “divide with remainder” primitive `DIVMOD` needs to return two values, the quotient `q` and the remainder `r`. Therefore, `DIVMOD` -pushes `q` and `r` into the stack, in that order, so that the quotient is available -thereafter at `s1` and the remainder at `s0`. The net effect of `DIVMOD` is to -divide the original value of `s1` by the original value of `s0`, and return the -quotient in `s1` and the remainder in `s0`. In this particular case the depth -of the stack and the values of all other “stack registers” remain unchanged, -because `DIVMOD` takes two arguments and returns two results. In general, the -values of other “stack registers” that lie in the stack below the arguments -passed and the values returned are shifted according to the change of the -depth of the stack. -In principle, some primitives and user-defined functions might return a -variable number of result values. In this respect, the remarks above about -variadic functions (cf. 2.1.6) apply: the total number of result values and -their types should be determined by the values near the top of the stack. -(For example, one might push the return values `y1, . . . , yk`, and then push -their total number `k` as an integer. The caller would then determine the total -number of returned values by inspecting `s0`.) -In this respect TVM, again, faithfully observes Forth calling conventions. +Recall that a stack machine, as opposed to a more conventional register machine, lacks general-purpose registers. However, one can treat the values near the top of the stack as a kind of “stack registers”. -### 2.1.10. Stack notation. - -When a stack of depth `n` contains values `z1, . . . , -zn`, in that order, with `z1` the deepest element and `zn` the top of the stack, -the contents of the stack are often represented by a list `z1 z2 . . . zn`, in that -order. When a primitive transforms the original stack state `S0` -into a new -state `S00`, this is often written as `S0 – S00`; this is the so-called stack notation. -For example, the action of the division primitive `DIV` can be described by -`S x y – S ⌊x/y⌋`, where `S` is any list of values. This is usually abbreviated as -`x y – ⌊x/y⌋`, tacitly assuming that all other values deeper in the stack remain -intact. -Alternatively, one can describe `DIV` as a primitive that runs on a stack `S0` -of depth `n ≥ 2`, divides `s1` by `s0`, and returns the floor-rounded quotient as -`s0` of the new stack `S00` of depth `n − 1`. The new value of `s(i)` equals the old -value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but -saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `. . . x y` into `. . . ⌊x/y⌋`, is more -concise. -The stack notation is extensively used throughout Appendix A, where all -currently defined TVM primitives are listed. - -### 2.1.11. Explicitly defining the number of arguments to a function. - -Stack machines usually pass the current stack in its entirety to the invoked -primitive or function. That primitive or function accesses only the several -values near the top of the stack that represent its arguments, and pushes the -return values in their place, by convention leaving all deeper values intact. -Then the resulting stack, again in its entirety, is returned to the caller. -Most TVM primitives behave in this way, and we expect most user-defined -functions to be implemented under such conventions. However, TVM provides mechanisms to specify how many arguments must be passed to a called -function (cf. 4.1.10). When these mechanisms are employed, the specified -number of values are moved from the caller’s stack into the (usually initially -empty) stack of the called function, while deeper values remain in the caller’s -stack and are inaccessible to the callee. The caller can also specify how many -return values it expects from the called function. -Such argument-checking mechanisms might be useful, for example, for a -library function that calls user-provided functions passed as arguments to it. +We denote by `s0` or `s(0)` the value at the top of the stack, by `s1` or `s(1)` the value immediately under it, and so on. The total number of values in the stack is called its depth. If the depth of the stack is `n`, then `s(0)`, `s(1)`, …, `s(n − 1)` are well-defined, while `s(n)` and all subsequent `s(i)` with `i > n` are not. Any attempt to use `s(i)` with `i ≥ n` should produce a stack underflow exception. ---- +A compiler, or a human programmer in “TVM code”, would use these “stack registers” to hold all declared variables and intermediate values, similarly to the way general-purpose registers are used on a register machine. -## 2.2 Stack manipulation primitives +### 2.1.2 Pushing and popping values -A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, -so that they become located near the top of the stack in correct order. This -section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some -examples of code using these primitives can be found in Appendix C. +When a value `x` is pushed into a stack of depth `n`, it becomes the new `s0`; at the same time, the old `s0` becomes the new `s1`, the old `s1`—the new `s2`, and so on. The depth of the resulting stack is `n + 1`. -### 2.2.1. Basic stack manipulation primitives. +Similarly, when a value `x` is popped from a stack of depth `n ≥ 1`, it is the old value of `s0` (i.e., the old value at the top of the stack). After this, it is removed from the stack, and the old `s1` becomes the new `s0` (the new value at the top of the stack), the old `s2` becomes the new `s1`, and so on. The depth of the resulting stack is `n − 1`. -The most important stack -manipulation primitives used by TVM are the following: +If originally `n = 0`, then the stack is empty, and a value cannot be popped from it. If a primitive attempts to pop a value from an empty stack, a stack underflow exception occurs. -* Top-of-stack exchange operation: `XCHG s0,s(i)` or `XCHG s(i)` — Exchanges values of `s0` and `s(i)`. When `i = 1`, operation `XCHG s1` is - traditionally denoted by `SWAP`. When `i = 0`, this is a `NOP` (an operation - that does nothing, at least if the stack is non-empty). +### 2.1.3 Notation for hypothetical general-purpose registers -* Arbitrary exchange operation: `XCHG s(i),s(j)` — Exchanges values of - `s(i)` and `s(j)`. Notice that this operation is not strictly necessary, because it can be simulated by three top-of-stack exchanges: - `XCHG s(i); XCHG s(j); XCHG s(i)`. However, it is useful to have arbitrary exchanges - as primitives, because they are required quite often. +In order to compare stack machines with sufficiently general register machines, we will denote the general-purpose registers of a register machine by `r0`, `r1`, and so on, or by `r(0)`, `r(1)`, …, `r(n − 1)`, where `n` is the total number of registers. When we need a specific value of `n`, we will use `n = 16`, corresponding to the very popular x86-64 architecture. -* Push operation: `PUSH s(i)` — Pushes a copy of the (old) value of `s(i)` - into the stack. Traditionally, `PUSH s0` is also denoted by `DUP` (it duplicates the value at the top of the stack), and `PUSH s1` by `OVER`. +### 2.1.4 The top-of-stack register s0 vs. the accumulator register r0 -* Pop operation: `POP s(i)` — Removes the top-of-stack value and puts it - into the (new) `s(i − 1)`, or the old `s(i)`. Traditionally, `POP s0` is also - denoted by `DROP` (it simply drops the top-of-stack value), and `POP s1` - by `NIP`. +Some register machine architectures require one of the arguments for most arithmetic and logical operations to reside in a special register called the accumulator. In our comparison, we will assume that the accumulator is the general-purpose register `r0`; otherwise we could simply renumber the registers. In this respect, the accumulator is somewhat similar to the top-of-stack “register” `s0` of a stack machine, because virtually all operations of a stack machine both use `s0` as one of their arguments and return their result as `s0`. -Some other “unsystematic” stack manipulation operations might be also -defined (e.g., `ROT`, with stack notation `a b c – b c a`). While such operations are defined in stack languages like Forth (where `DUP`, `DROP`, `OVER`, `NIP` -and `SWAP` are also present), they are not strictly necessary because the basic -stack manipulation primitives listed above suffice to rearrange stack registers -to allow any arithmetic primitives and user-defined functions to be invoked -correctly. +### 2.1.5 Register calling conventions -Perfect 👍 — let’s continue from **§2.2.2** through the end of Chapter 2, with all mnemonics, variables, and stack notation in backticks for Markdown. +When compiled for a register machine, high-level language functions usually receive their arguments in certain registers in a predefined order. If there are too many arguments, these functions take the remainder from the stack (yes, a register machine usually has a stack, too!). Some register calling conventions pass no arguments in registers at all, however, and only use the stack (for example, the original calling conventions used in implementations of Pascal and C, although modern implementations of C use some registers as well). ---- +For simplicity, we will assume that up to `m ≤ n` function arguments are passed in registers, and that these registers are `r0, r1, …, r(m − 1)`, in that order (if some other registers are used, we can simply renumber them).[6](#footnote-6) -### 2.2.2. Basic stack manipulation primitives suffice. - -A compiler or a -human TVM-code programmer might use the basic stack primitives as follows. -Suppose that the function or primitive to be invoked is to be passed, say, -three arguments `x`, `y`, and `z`, currently located in stack registers `s(i)`, `s(j)`, -and `s(k)`. In this circumstance, the compiler (or programmer) might issue -operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) -or `XCHG s(i)` (if it will not be needed afterwards) to put the first argument -`x` into the top of the stack. Then, the compiler (or programmer) could use -either `PUSH s(j0)` or `XCHG s(j0)`, where `j0 = j` or `j + 1`, to put `y` into the new -top of the stack. - -Proceeding in this manner, we see that we can put the original values of -`x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using -a sequence of push and exchange operations (cf. 2.2.4 and 2.2.5 for a more -detailed explanation). In order to generate this sequence, the compiler will -need to know only the three values `i`, `j` and `k`, describing the old locations of -variables or temporary values in question, and some flags describing whether -each value will be needed thereafter or is needed only for this primitive or -function call. The locations of other variables and temporary values will be -affected in the process, but a compiler (or a human programmer) can easily -track their new locations. - -Similarly, if the results returned from a function need to be discarded -or moved to other stack registers, a suitable sequence of exchange and pop -operations will do the job. In the typical case of one return value in `s0`, -this is achieved either by an `XCHG s(i)` or a `POP s(i)` (in most cases, a `DROP`) -operation. - -Rearranging the result value or values before returning from a function is -essentially the same problem as arranging arguments for a function call, and -is achieved similarly. - -### 2.2.3. Compound stack manipulation primitives. - -In order to improve -the density of the TVM code and simplify development of compilers, compound stack manipulation primitives may be defined, each combining up to -four exchange and push or exchange and pop basic primitives. Such compound stack operations might include, for example: - -* `XCHG2 s(i),s(j)` — Equivalent to `XCHG s1,s(i); XCHG s(j)`. -* `PUSH2 s(i),s(j)` — Equivalent to `PUSH s(i); PUSH s(j + 1)`. -* `XCPU s(i),s(j)` — Equivalent to `XCHG s(i); PUSH s(j)`. -* `PUXC s(i),s(j)` — Equivalent to `PUSH s(i); SWAP; XCHG s(j+1)`. When - `j ≠ i` and `j ≠ 0`, it is also equivalent to `XCHG s(j); PUSH s(i); SWAP`. -* `XCHG3 s(i),s(j),s(k)` — Equivalent to `XCHG s2,s(i); XCHG s1,s(j); - XCHG s(k)`. -* `PUSH3 s(i),s(j),s(k)` — Equivalent to `PUSH s(i); PUSH s(j + 1); PUSH - s(k + 2)`. - -Of course, such operations make sense only if they admit a more compact -encoding than the equivalent sequence of basic operations. For example, -if all top-of-stack exchanges, `XCHG s1,s(i)` exchanges, and push and pop -operations admit one-byte encodings, the only compound stack operations -suggested above that might merit inclusion in the set of stack manipulation -primitives are `PUXC`, `XCHG3`, and `PUSH3`. - -Notice that the most common `XCHG s(i)` operation is not really required here if we -do not insist on keeping the same temporary value or variable always in the same stack -location, but rather keep track of its subsequent locations. We will move it to some other -location while preparing the arguments to the next primitive or function call. - -### 2.2.4. Mnemonics of compound stack operations. - -The mnemonics -of compound stack operations, some examples of which have been provided -in 2.2.3, are created as follows. -The `γ ≥ 2` formal arguments `s(i1), . . . , s(iγ)` to such an operation `O` -represent the values in the original stack that will end up in `s(γ − 1), . . . , -s0` after the execution of this compound operation, at least if all `iν, 1 ≤ -ν ≤ γ`, are distinct and at least γ. The mnemonic itself of the operation -`O` is a sequence of γ two-letter strings `PU` and `XC`, with `PU` meaning that -the corresponding argument is to be PUshed (i.e., a copy is to be created), -and `XC` meaning that the value is to be eXChanged (i.e., no other copy of -the original value is created). Sequences of several `PU` or `XC` strings may be -abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, -we write `PUXC2PU` instead of `PUXCXCPU`.) -As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, -so that the compound operation is equivalent to a sequence of `m` `PUSH`es or -`XCHG`s, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. - -### 2.2.5. Semantics of compound stack operations. - -Each compound `γ`- -ary operation `O s(i1),. . . ,s(iγ)` is translated into an equivalent sequence of -basic stack operations by induction in `γ` as follows: - -* As a base of induction, if `γ = 0`, the only nullary compound stack - operation corresponds to an empty sequence of basic stack operations. -* Equivalently, we might begin the induction from `γ = 1`. Then `PU s(i)` - corresponds to the sequence consisting of one basic operation `PUSH - s(i)`, and `XC s(i)` corresponds to the one-element sequence consisting - of `XCHG s(i)`. -* For `γ ≥ 1` (or for `γ ≥ 2`, if we use `γ = 1` as induction base), there are - two subcases: - - 1. `O s(i1), . . . , s(iγ)`, with `O = XCO0`, where `O0` - is a compound operation of arity `γ−1` (i.e., the mnemonic of `O0` - consists of `γ−1` strings - `XC` and `PU`). Let `α` be the total quantity of PUshes in `O`, and `β` be - that of eXChanges, so that `α+β = γ`. Then the original operation - is translated into `XCHG s(β −1),s(i1)`, followed by the translation - of `O0 s(i2), . . . , s(iγ)`, defined by the induction hypothesis. - - 2. `O s(i1), . . . , s(iγ)`, with `O = PUO0`, - where `O0` - is a compound operation of arity `γ − 1`. Then the original operation is translated into - `PUSH s(i1); XCHG s(β)`, followed by the translation of - `O0 s(i2 + 1), . . . , s(iγ + 1)`, defined by the induction hypothesis. - -An alternative, arguably better, translation of -`PUO0 s(i1), . . . , s(iγ)` consists of the -translation of `O0 s(i2), . . . , s(iγ)`, followed by -`PUSH s(i1 + α − 1); XCHG s(γ − 1)`. - -### 2.2.6. Stack manipulation instructions are polymorphic. - -Notice that -the stack manipulation instructions are almost the only “polymorphic” primitives in TVM—i.e., they work with values of arbitrary types (including the -value types that will appear only in future revisions of TVM). For example, `SWAP` always interchanges the two top values of the stack, even if one of -them is an integer and the other is a cell. Almost all other instructions, especially the data processing instructions (including arithmetic instructions), -require each of their arguments to be of some fixed type (possibly different -for different arguments). +### 2.1.6 Order of function arguments ---- +If a function or primitive requires `m` arguments `x1, …, xm`, they are pushed by the caller into the stack in the same order, starting from `x1`. Therefore, when the function or primitive is invoked, its first argument `x1` is in `s(m − 1)`, its second argument `x2` is in `s(m − 2)`, and so on. The last argument `xm` is in `s0` (i.e., at the top of the stack). It is the called function or primitive’s responsibility to remove its arguments from the stack. -## 2.3 Efficiency of stack manipulation primitives +In this respect the TVM stack calling conventions—obeyed, at least, by TMV primitives—match those of Pascal and Forth, and are the opposite of those of C (in which the arguments are pushed into the stack in the reverse order, and are removed by the caller after it regains control, not the callee). -Stack manipulation primitives employed by a stack machine, such as TVM, -have to be implemented very efficiently, because they constitute more than -half of all the instructions used in a typical program. In fact, TVM performs -all these instructions in a (small) constant time, regardless of the values -involved (even if they represent very large integers or very large trees of -cells). - -### 2.3.1. Implementation of stack manipulation primitives: using references for operations instead of objects. - -The efficiency of TVM’s -implementation of stack manipulation primitives results from the fact that a -typical TVM implementation keeps in the stack not the value objects themselves, but only the references (pointers) to such objects. Therefore, a `SWAP` -instruction only needs to interchange the references at `s0` and `s1`, not the -actual objects they refer to. - -### 2.3.2. Efficient implementation of DUP and PUSH instructions using copy-on-write. - -Furthermore, a `DUP` (or, more generally, `PUSH s(i)`) instruction, which appears to make a copy of a potentially large object, also works -in small constant time, because it uses a copy-on-write technique of delayed -copying: it copies only the reference instead of the object itself, but increases -the “reference counter” inside the object, thus sharing the object between the -two references. If an attempt to modify an object with a reference counter -greater than one is detected, a separate copy of the object in question is made -first (incurring a certain “non-uniqueness penalty” or “copying penalty” for -the data manipulation instruction that triggered the creation of a new copy). - -### 2.3.3. Garbage collecting and reference counting. - -When the reference counter of a TVM object becomes zero (for example, because the last -reference to such an object has been consumed by a `DROP` operation or an -arithmetic instruction), it is immediately freed. Because cyclic references -are impossible in TVM data structures, this method of reference counting -provides a fast and convenient way of freeing unused objects, replacing slow -and unpredictable garbage collectors. - -### 2.3.4. Transparency of the implementation: Stack values are “values”, not “references”. - -Regardless of the implementation details just discussed, all stack values are really “values”, not “references”, from the perspective of the TVM programmer, similarly to the values of all types in functional -programming languages. Any attempt to modify an existing object referred -to from any other objects or stack locations will result in a transparent replacement of this object by its perfect copy before the modification is actually -performed. -In other words, the programmer should always act as if the objects themselves were directly manipulated by stack, arithmetic, and other data transformation primitives, and treat the previous discussion only as an explanation -of the high efficiency of the stack manipulation primitives. - -### 2.3.5. Absence of circular references. - -One might attempt to create a -circular reference between two cells, `A` and `B`, as follows: first create `A` and -write some data into it; then create `B` and write some data into it, along -with a reference to previously constructed cell `A`; finally, add a reference to -`B` into `A`. While it may seem that after this sequence of operations we obtain -a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. -In fact, we obtain a new cell `A0`, which contains a copy of the data originally -stored into cell `A` along with a reference to cell `B`, which contains a reference -to (the original) cell `A`. -In this way the transparent copy-on-write mechanism and the “everything -is a value” paradigm enable us to create new cells using only previously -constructed cells, thus forbidding the appearance of circular references. This -property also applies to all other data structures: for instance, the absence -of circular references enables TVM to use reference counting to immediately -free unused memory instead of relying on garbage collectors. Similarly, this -property is crucial for storing data in the TON Blockchain. - -Great — here’s **Chapter 3 (Cells, memory, and persistent storage)** reformatted to Markdown with all mnemonics, variables, and notation in backticks. +Of course, an implementation of a high-level language for TVM might choose some other calling conventions for its functions, different from the default ones. This might be useful for certain functions—for instance, if the total number of arguments depends on the value of the first argument, as happens for “variadic functions” such as `scanf` and `printf`. In such cases, the first one or several arguments are better passed near the top of the stack, not somewhere at some unknown location deep in the stack. ---- +### 2.1.7 Arguments to arithmetic primitives on register machines -# 3 Cells, memory, and persistent storage +On a stack machine, built-in arithmetic primitives (such as `ADD` or `DIVMOD`) follow the same calling conventions as user-defined functions. In this respect, user-defined functions (for example, a function computing the square root of a number) might be considered as “extensions” or “custom upgrades” of the stack machine. This is one of the clearest advantages of stack machines (and of stack programming languages such as Forth) compared to register machines. -This chapter briefly describes TVM cells, used to represent all data structures -inside the TVM memory and its persistent storage, and the basic operations -used to create cells, write (or serialize) data into them, and read (or deserialize) data from them. +In contrast, arithmetic instructions (built-in operations) on register machines usually get their parameters from general-purpose registers encoded in the full opcode. A binary operation, such as `SUB`, thus requires two arguments, `r(i)` and `r(j)`, with `i` and `j` specified by the instruction. A register `r(k)` for storing the result also must be specified. Arithmetic operations can take several possible forms, depending on whether `i`, `j`, and `k` are allowed to take arbitrary values: -## 3.1 Generalities on cells +- **Three-address form** — Allows the programmer to arbitrarily choose not only the two source registers `r(i)` and `r(j)`, but also a separate destination register `r(k)`. This form is common for most RISC processors, and for the XMM and AVX SIMD instruction sets in the x86-64 architecture. +- **Two-address form** — Uses one of the two operand registers (usually `r(i)`) to store the result of an operation, so that `k = i` is never indicated explicitly. Only `i` and `j` are encoded inside the instruction. This is the most common form of arithmetic operations on register machines, and is quite popular on microprocessors (including the x86 family). +- **One-address form** — Always takes one of the arguments from the accumulator `r0`, and stores the result in `r0` as well; then `i = k = 0`, and only `j` needs to be specified by the instruction. This form is used by some simpler microprocessors (such as Intel 8080). -### 3.1.1. TVM memory and persistent storage consist of cells. +Note that this flexibility is available only for built-in operations, but not for user-defined functions. In this respect, register machines are not as easily “upgradable” as stack machines.[7](#footnote-7) -Recall -that the TVM memory and persistent storage consist of (TVM) cells. Each -cell contains up to `1023` bits of data and up to four references to other cells. -Circular references are forbidden and cannot be created by means of TVM -(cf. 2.3.5). In this way, all cells kept in TVM memory and persistent storage -constitute a directed acyclic graph (DAG). +### 2.1.8 Return values of functions -### 3.1.2. Ordinary and exotic cells. +In stack machines such as TVM, when a function or primitive needs to return a result value, it simply pushes it into the stack (from which all arguments to the function have already been removed). Therefore, the caller will be able to access the result value through the top-of-stack “register” `s0`. -Apart from the data and references, -a cell has a cell type, encoded by an integer `−1 ... 255`. A cell of type `−1` -is called ordinary; such cells do not require any special processing. Cells of -other types are called exotic, and may be loaded—automatically replaced by -other cells when an attempt to deserialize them (i.e., to convert them into -a `Slice` by a `CTOS` instruction) is made. They may also exhibit a non-trivial -behavior when their hashes are computed. +This is in complete accordance with Forth calling conventions, but differs slightly from Pascal and C calling conventions, where the accumulator register `r0` is normally used for the return value. -The most common use for exotic cells is to represent some other cells—for -instance, cells present in an external library, or pruned from the original tree -of cells when a Merkle proof has been created. +### 2.1.9 Returning several values -The type of an exotic cell is stored as the first eight bits of its data. If an -exotic cell has less than eight data bits, it is invalid. +Some functions might want to return several values `y1, …, yk`, with `k` not necessarily equal to one. In these cases, the `k` return values are pushed into the stack in their natural order, starting from `y1`. -### 3.1.3. The level of a cell. +For example, the “divide with remainder” primitive `DIVMOD` needs to return two values, the quotient `q` and the remainder `r`. Therefore, `DIVMOD` pushes `q` and `r` into the stack, in that order, so that the quotient is available thereafter at `s1` and the remainder at `s0`. The net effect of `DIVMOD` is to divide the original value of `s1` by the original value of `s0`, and return the quotient in `s1` and the remainder in `s0`. In this particular case the depth of the stack and the values of all other “stack registers” remain unchanged, because `DIVMOD` takes two arguments and returns two results. In general, the values of other “stack registers” that lie in the stack below the arguments passed and the values returned are shifted according to the change of the depth of the stack. -Every cell `c` has another attribute `Lvl(c)` called -its (de Brujn) level, which currently takes integer values in the range `0...3`. -The level of an ordinary cell is always equal to the maximum of the levels of -all its children `ci`: +In principle, some primitives and user-defined functions might return a variable number of result values. In this respect, the remarks above about variadic functions (cf. [2.1.6](#2-1-6-order-of-function-arguments)) apply: the total number of result values and their types should be determined by the values near the top of the stack. (For example, one might push the return values `y1, …, yk`, and then push their total number `k` as an integer. The caller would then determine the total number of returned values by inspecting `s0`.) -``` -Lvl(c) = max ( Lvl(ci) ) for 1 ≤ i ≤ r -``` +In this respect TVM, again, faithfully observes Forth calling conventions. -for an ordinary cell `c` containing `r` references to cells `c1, ..., cr`. -If `r = 0`, then `Lvl(c) = 0`. Exotic cells may have different rules for setting their level. +### 2.1.10 Stack notation -A cell’s level affects the number of higher hashes it has. More precisely, -a level `l` cell has `l` higher hashes `Hash1(c), ..., Hashl(c)` in addition to its -representation hash `Hash(c) = Hash∞(c)`. Cells of non-zero level appear -inside Merkle proofs and Merkle updates, after some branches of the tree of -cells representing a value of an abstract data type are pruned. +When a stack of depth `n` contains values `z1, …, zn`, in that order, with `z1` the deepest element and `zn` the top of the stack, the contents of the stack are often represented by a list `z1 z2 … zn`, in that order. When a primitive transforms the original stack state `S₀` into a new state `S₀₀`, this is often written as `S₀ – S₀₀`; this is the so-called **stack notation**. -### 3.1.4. Standard cell representation. +For example, the action of the division primitive `DIV` can be described by `S x y – S ⌊x/y⌋`, where `S` is any list of values. This is usually abbreviated as `x y – ⌊x/y⌋`, tacitly assuming that all other values deeper in the stack remain intact. -When a cell needs to be transferred -by a network protocol or stored in a disk file, it must be serialized. -The standard representation `CellRepr(c) = CellRepr∞(c)` of a cell `c` as an -octet (byte) sequence is constructed as follows: +Alternatively, one can describe `DIV` as a primitive that runs on a stack `S₀` of depth `n ≥ 2`, divides `s1` by `s0`, and returns the floor-rounded quotient as `s0` of the new stack `S₀₀` of depth `n − 1`. The new value of `s(i)` equals the old value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `… x y` into `… ⌊x/y⌋`, is more concise. -1. Two descriptor bytes `d1` and `d2` are serialized first. +The stack notation is extensively used throughout [Appendix A](#appendix-a), where all currently defined TVM primitives are listed. - * `d1 = r + 8s + 32l`, where `0 ≤ r ≤ 4` is the number of cell references contained - in the cell, `0 ≤ l ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is `1` for - exotic cells and `0` for ordinary cells. - * `d2 = ⌊b/8⌋ + ⌈b/8⌉`, where `0 ≤ b ≤ 1023` is the number of data bits in `c`. +### 2.1.11 Explicitly defining the number of arguments to a function -2. Then the data bits are serialized as `⌈b/8⌉` 8-bit octets (bytes). - If `b` is not a multiple of eight, a binary `1` and up to six binary `0`s are appended to - the data bits. After that, the data is split into `⌈b/8⌉` eight-bit groups, - and each group is interpreted as an unsigned big-endian integer `0...255` - and stored into an octet. +Stack machines usually pass the current stack in its entirety to the invoked primitive or function. That primitive or function accesses only the several values near the top of the stack that represent its arguments, and pushes the return values in their place, by convention leaving all deeper values intact. Then the resulting stack, again in its entirety, is returned to the caller. -3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(ci)` of the cell `ci` referred to. +Most TVM primitives behave in this way, and we expect most user-defined functions to be implemented under such conventions. However, TVM provides mechanisms to specify how many arguments must be passed to a called function (cf. [4.1.10](#4-1-10-determining-the-number-of-arguments-passed-to-and%2For-return-values-accepted-from-a-subroutine)). When these mechanisms are employed, the specified number of values are moved from the caller’s stack into the (usually initially empty) stack of the called function, while deeper values remain in the caller’s stack and are inaccessible to the callee. The caller can also specify how many return values it expects from the called function. -In this way, `2 + ⌈b/8⌉ + 32r` bytes of `CellRepr(c)` are obtained. +Such argument-checking mechanisms might be useful, for example, for a library function that calls user-provided functions passed as arguments to it. -### 3.1.5. The representation hash of a cell. +## 2.2 Stack manipulation primitives -The 256-bit representation -hash or simply hash `Hash(c)` of a cell `c` is recursively defined as the `sha256` -of the standard representation of the cell `c`: +A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, so that they become located near the top of the stack in correct order. This section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some examples of code using these primitives can be found in [Appendix C](#appendix-c). -``` -Hash(c) := sha256(CellRepr(c)) -``` +### 2.2.1 Basic stack manipulation primitives -Notice that cyclic cell references are not allowed and cannot be created by -means of the TVM (cf. 2.3.5), so this recursion always ends, and the representation hash of any cell is well-defined. +The most important stack manipulation primitives used by TVM are the following: -### 3.1.6. The higher hashes of a cell. +- **Top-of-stack exchange operation:** `XCHG s0,s(i)` or `XCHG s(i)` — Exchanges values of `s0` and `s(i)`. When `i = 1`, operation `XCHG s1` is traditionally denoted by `SWAP`. When `i = 0`, this is a `NOP` (an operation that does nothing, at least if the stack is non-empty). +- **Arbitrary exchange operation:** `XCHG s(i),s(j)` — Exchanges values of `s(i)` and `s(j)`. Notice that this operation is not strictly necessary, because it can be simulated by three top-of-stack exchanges: `XCHG s(i)`; `XCHG s(j)`; `XCHG s(i)`. However, it is useful to have arbitrary exchanges as primitives, because they are required quite often. +- **Push operation:** `PUSH s(i)` — Pushes a copy of the (old) value of `s(i)` into the stack. Traditionally, `PUSH s0` is also denoted by `DUP` (it duplicates the value at the top of the stack), and `PUSH s1` by `OVER`. +- **Pop operation:** `POP s(i)` — Removes the top-of-stack value and puts it into the (new) `s(i − 1)`, or the old `s(i)`. Traditionally, `POP s0` is also denoted by `DROP` (it simply drops the top-of-stack value), and `POP s1` by `NIP`. -Recall that a cell `c` of level `l` has `l` -higher hashes `Hashi(c)`, `1 ≤ i ≤ l`. Exotic cells have their own rules -for computing their higher hashes. Higher hashes `Hashi(c)` of an ordinary -cell `c` are computed similarly to its representation hash, but using the higher -hashes `Hashi(cj)` of its children `cj` instead of their representation hashes -`Hash(cj)`. By convention, we set `Hash∞(c) := Hash(c)`, and `Hashi(c) := Hash(c)` -for all `i > l`. +Some other “unsystematic” stack manipulation operations might be also defined (e.g., `ROT`, with stack notation `a b c – b c a`). While such operations are defined in stack languages like Forth (where `DUP`, `DROP`, `OVER`, `NIP` and `SWAP` are also present), they are not strictly necessary because the basic stack manipulation primitives listed above suffice to rearrange stack registers to allow any arithmetic primitives and user-defined functions to be invoked correctly. -Perfect — here’s the continuation of **Chapter 3**, keeping **all text exactly the same** but fully in Markdown, with mnemonics, variables, and formulas wrapped in backticks: +### 2.2.2 Basic stack manipulation primitives suffice ---- +A compiler or a human TVM-code programmer might use the basic stack primitives as follows. Suppose that the function or primitive to be invoked is to be passed, say, three arguments `x, y, z`, currently located in stack registers `s(i)`, `s(j)`, and `s(k)`. In this circumstance, the compiler (or programmer) might issue operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) or `XCHG s(i)` (if it will not be needed thereafter) to put the first argument `x` into the top of the stack. Then, the compiler (or programmer) could use either `PUSH s(j₀)` or `XCHG s(j₀)`, where `j₀ = j` or `j + 1`, to put `y` into the new top of the stack.[8](#footnote-8) -### 3.1.7. Types of exotic cells. +Proceeding in this manner, we see that we can put the original values of `x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using a sequence of push and exchange operations (cf. [2.2.4](#2-2-4-mnemonics-of-compound-stack-operations) and [2.2.5](#2-2-5-... ) for a more detailed explanation). In order to generate this sequence, the compiler will need to know only the three values `i, j, k`, describing the old locations of variables or temporary values in question, and some flags describing whether each value will be needed thereafter or is needed only for this primitive or function call. The locations of other variables and temporary values will be affected in the process, but a compiler (or a human programmer) can easily track their new locations. -TVM currently supports the following cell -types: +Similarly, if the results returned from a function need to be discarded or moved to other stack registers, a suitable sequence of exchange and pop operations will do the job. In the typical case of one return value in `s0`, this is achieved either by an `XCHG s(i)` or a `POP s(i)` (in most cases, a `DROP`) operation.[9](#footnote-9) -* **Type −1: Ordinary cell** — Contains up to `1023` bits of data and up to - four cell references. -* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ l ≤ 3`. It - contains exactly `8 + 256l` data bits: first an 8-bit integer equal to `1` - (representing the cell’s type), then its `l` higher hashes `Hash1(c), ..., - Hashl(c)`. The level `l` of a pruned branch cell may be called its *de - Brujn index*, because it determines the outer Merkle proof or Merkle - update during the construction of which the branch has been pruned. - An attempt to load a pruned branch cell usually leads to an exception. -* **Type 2: Library reference cell** — Always has level `0`, and contains `8+256` - data bits, including its 8-bit type integer `2` and the representation hash - `Hash(c0)` of the library cell being referred to. When loaded, a library - reference cell may be transparently replaced by the cell it refers to, if - found in the current library context. -* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c1` and level - `0 ≤ l ≤ 3`, which must be one less than the level of its only child `c1`: +Rearranging the result value or values before returning from a function is essentially the same problem as arranging arguments for a function call, and is achieved similarly. - ``` - Lvl(c) = max(Lvl(c1) − 1, 0) - ``` +### 2.2.3 Compound stack manipulation primitives - The `8 + 256` data bits of a Merkle proof cell contain its 8-bit type - integer `3`, followed by `Hash1(c1)` (assumed to be equal to `Hash(c1)` if - `Lvl(c1) = 0`). The higher hashes `Hashi(c)` of `c` are computed similarly - to the higher hashes of an ordinary cell, but with `Hashi+1(c1)` used - instead of `Hashi(c1)`. When loaded, a Merkle proof cell is replaced by - `c1`. -* **Type 4: Merkle update cell `c`** — Has two children `c1` and `c2`. Its level - `0 ≤ l ≤ 3` is given by: +In order to improve the density of the TVM code and simplify development of compilers, compound stack manipulation primitives may be defined, each combining up to four exchange and push or exchange and pop basic primitives. Such compound stack operations might include, for example: - ``` - Lvl(c) = max(Lvl(c1) − 1, Lvl(c2) − 1, 0) - ``` +- `XCHG2 s(i),s(j)` — Equivalent to `XCHG s1,s(i); XCHG s(j)`. +- `PUSH2 s(i),s(j)` — Equivalent to `PUSH s(i); PUSH s(j + 1)`. +- `XCPU s(i),s(j)` — Equivalent to `XCHG s(i); PUSH s(j)`. +- `PUXC s(i),s(j)` — Equivalent to `PUSH s(i); SWAP; XCHG s(j+1)`. When `j ≠ i` and `j ≠ 0`, it is also equivalent to `XCHG s(j); PUSH s(i); SWAP`. +- `XCHG3 s(i),s(j),s(k)` — Equivalent to `XCHG s2,s(i); XCHG s1,s(j); XCHG s(k)`. +- `PUSH3 s(i),s(j),s(k)` — Equivalent to `PUSH s(i); PUSH s(j + 1); PUSH s(k + 2)`. - A Merkle update behaves like a Merkle proof for both `c1` and `c2`, and - contains `8 + 256 + 256` data bits with `Hash1(c1)` and `Hash1(c2)`. - However, an extra requirement is that all pruned branch cells `c0` that are - descendants of `c2` and are bound by `c` must also be descendants of `c1`. - When a Merkle update cell is loaded, it is replaced by `c2`. +Of course, such operations make sense only if they admit a more compact encoding than the equivalent sequence of basic operations. For example, if all top-of-stack exchanges, `XCHG s1,s(i)` exchanges, and push and pop operations admit one-byte encodings, the only compound stack operations suggested above that might merit inclusion in the set of stack manipulation primitives are `PUXC`, `XCHG3`, and `PUSH3`. ---- +These compound stack operations essentially augment other primitives (instructions) in the code with the “true” locations of their operands, somewhat similarly to what happens with two-address or three-address register machine code. However, instead of encoding these locations inside the opcode of the arithmetic or another instruction, as is customary for register machines, we indicate these locations in a preceding compound stack manipulation operation. As already described in [2.1.7](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines), the advantage of such an approach is that user-defined functions (or rarely used specific primitives added in a future version of TVM) can benefit from it as well (cf. [C.3](#c-3-...) for a more detailed discussion with examples). -### 3.1.8. All values of algebraic data types are trees of cells. +### 2.2.4 Mnemonics of compound stack operations -Arbitrary -values of arbitrary algebraic data types (e.g., all types used in functional -programming languages) can be serialized into trees of cells (of level `0`), and -such representations are used for representing such values within TVM. +The mnemonics of compound stack operations, some examples of which have been provided in [2.2.3](#2-2-3-compound-stack-manipulation-primitives), are created as follows. -The copy-on-write mechanism (cf. 2.3.2) allows TVM to identify cells containing -the same data and references, and to keep only one copy of such cells. This -actually transforms a tree of cells into a directed acyclic graph (with the -additional property that all its vertices be accessible from a marked vertex -called the “root”). However, this is a storage optimization rather than an -essential property of TVM. From the perspective of a TVM code programmer, -one should think of TVM data structures as trees of cells. +The `γ ≥ 2` formal arguments `s(i₁), …, s(i_γ)` to such an operation `O` represent the values in the original stack that will end up in `s(γ − 1), …, s0` after the execution of this compound operation, at least if all `iν`, `1 ≤ ν ≤ γ`, are distinct and at least `γ`. The mnemonic itself of the operation `O` is a sequence of `γ` two-letter strings `PU` and `XC`, with `PU` meaning that the corresponding argument is to be **PU**shed (i.e., a copy is to be created), and `XC` meaning that the value is to be **eX**Changed (i.e., no other copy of the original value is created). Sequences of several `PU` or `XC` strings may be abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, we write `PUXC2PU` instead of `PUXCXCPU`.) + +As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, so that the compound operation is equivalent to a sequence of `m` `PUSH`es or `eXCHanGe`s, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. + +### 2.2.5 Semantics of compound stack operations + +Each compound γ-ary operation `O s(i₁), …, s(iγ)` is translated into an equivalent sequence of basic stack operations by induction in γ as follows: + +- As a base of induction, if γ = 0, the only nullary compound stack operation corresponds to an empty sequence of basic stack operations. +- Equivalently, we might begin the induction from γ = 1. Then `PU s(i)` corresponds to the sequence consisting of one basic operation `PUSH s(i)`, and `XC s(i)` corresponds to the one-element sequence consisting of `XCHG s(i)`. +- For γ ≥ 1 (or for γ ≥ 2, if we use γ = 1 as induction base), there are two subcases: + + 1. `O s(i₁), …, s(iγ)`, with `O = XC O₀`, where `O₀` is a compound operation of arity γ − 1 (i.e., the mnemonic of `O₀` consists of γ − 1 strings `XC` and `PU`). + Let α be the total quantity of **PU**shes in `O`, and β be that of eXChanges, so that α + β = γ. Then the original operation is translated into `XCHG s(β − 1), s(i₁)`, followed by the translation of `O₀ s(i₂), …, s(iγ)`, defined by the induction hypothesis. + + 2. `O s(i₁), …, s(iγ)`, with `O = PU O₀`, where `O₀` is a compound operation of arity γ − 1. + Then the original operation is translated into `PUSH s(i₁); XCHG s(β)`, followed by the translation of `O₀ s(i₂ + 1), …, s(iγ + 1)`, defined by the induction hypothesis.[10](#footnote-10) --- -### 3.1.9. TVM code is a tree of cells. +### 2.2.6 Stack manipulation instructions are polymorphic -The TVM code itself is also represented by a tree of cells. Indeed, TVM code is simply a value of some -complex algebraic data type, and as such, it can be serialized into a tree of -cells. +Notice that the stack manipulation instructions are almost the only “polymorphic” primitives in TVM—i.e., they work with values of arbitrary types (including the value types that will appear only in future revisions of TVM). -The exact way in which the TVM code (e.g., TVM assembly code) is -transformed into a tree of cells is explained later (cf. 4.1.4 and 5.2), in sections discussing control flow instructions, continuations, and TVM instruction encoding. +For example, `SWAP` always interchanges the two top values of the stack, even if one of them is an integer and the other is a cell. Almost all other instructions, especially the data processing instructions (including arithmetic instructions), require each of their arguments to be of some fixed type (possibly different for different arguments). --- -### 3.1.10. “Everything is a bag of cells” paradigm. +## 2.3 Efficiency of stack manipulation primitives -As described in `[1, -2.5.14]`, all the data used by the TON Blockchain, including the blocks -themselves and the blockchain state, can be represented—and are represented—as -collections, or “bags”, of cells. +Stack manipulation primitives employed by a stack machine, such as TVM, have to be implemented very efficiently, because they constitute more than half of all the instructions used in a typical program. In fact, TVM performs all these instructions in a (small) constant time, regardless of the values involved (even if they represent very large integers or very large trees of cells). -We see that TVM’s structure of data (cf. 3.1.8) -and code (cf. 3.1.9) nicely fits into this “everything is a bag of cells” paradigm. -In this way, TVM can naturally be used to execute smart contracts in the -TON Blockchain, and the TON Blockchain can be used to store the code -and persistent data of these smart contracts between invocations of TVM. +### 2.3.1 Implementation of stack manipulation primitives: using references for operations instead of objects -(Of course, both TVM and the TON Blockchain have been designed so that -this would become possible.) -Got it — here’s the continuation with **3.2 Data manipulation instructions and cells** in proper Markdown, keeping **all text exactly the same** but formatted (mnemonics, values, variables in backticks): +The efficiency of TVM’s implementation of stack manipulation primitives results from the fact that a typical TVM implementation keeps in the stack not the value objects themselves, but only the references (pointers) to such objects. ---- +Therefore, a `SWAP` instruction only needs to interchange the references at `s0` and `s1`, not the actual objects they refer to. -## 3.2 Data manipulation instructions and cells +### 2.3.2 Efficient implementation of DUP and PUSH instructions using copy-on-write -The next large group of TVM instructions consists of data manipulation -instructions, also known as cell manipulation instructions or simply cell -instructions. They correspond to memory access instructions of other architectures. +Furthermore, a `DUP` (or, more generally, `PUSH s(i)`) instruction, which appears to make a copy of a potentially large object, also works in small constant time, because it uses a copy-on-write technique of delayed copying: it copies only the reference instead of the object itself, but increases the “reference counter” inside the object, thus sharing the object between the two references. ---- +If an attempt to modify an object with a reference counter greater than one is detected, a separate copy of the object in question is made first (incurring a certain “non-uniqueness penalty” or “copying penalty” for the data manipulation instruction that triggered the creation of a new copy). -### 3.2.1. Classes of cell manipulation instructions. +### 2.3.3 Garbage collecting and reference counting -The TVM cell instructions are naturally subdivided into two principal classes: +When the reference counter of a TVM object becomes zero (for example, because the last reference to such an object has been consumed by a `DROP` operation or an arithmetic instruction), it is immediately freed. -* **Cell creation instructions** or **serialization instructions**, used to construct new cells from values previously kept in the stack and previously - constructed cells. -* **Cell parsing instructions** or **deserialization instructions**, used to extract - data previously stored into cells by cell creation instructions. +Because cyclic references are impossible in TVM data structures, this method of reference counting provides a fast and convenient way of freeing unused objects, replacing slow and unpredictable garbage collectors. -Additionally, there are exotic cell instructions used to create and inspect -exotic cells (cf. 3.1.2), which in particular are used to represent pruned -branches of Merkle proofs and Merkle proofs themselves. +### 2.3.4 Transparency of the implementation: Stack values are “values”, not “references” ---- +Regardless of the implementation details just discussed, all stack values are really “values”, not “references”, from the perspective of the TVM programmer, similarly to the values of all types in functional programming languages. -### 3.2.2. Builder and Slice values. +Any attempt to modify an existing object referred to from any other objects or stack locations will result in a transparent replacement of this object by its perfect copy before the modification is actually performed. -Cell creation instructions usually work -with `Builder` values, which can be kept only in the stack (cf. 1.1.3). Such -values represent partially constructed cells, for which fast operations for appending bitstrings, integers, other cells, and references to other cells can be -defined. Similarly, cell parsing instructions make heavy use of `Slice` values, -which represent either the remainder of a partially parsed cell, or a value -(subcell) residing inside such a cell and extracted from it by a parsing instruction. +In other words, the programmer should always act as if the objects themselves were directly manipulated by stack, arithmetic, and other data transformation primitives, and treat the previous discussion only as an explanation of the high efficiency of the stack manipulation primitives. ---- +### 2.3.5 Absence of circular references + +One might attempt to create a circular reference between two cells, `A` and `B`, as follows: first create `A` and write some data into it; then create `B` and write some data into it, along with a reference to previously constructed cell `A`; finally, add a reference to `B` into `A`. -### 3.2.3. Builder and Slice values exist only as stack values. +While it may seem that after this sequence of operations we obtain a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. In fact, we obtain a new cell `A₀`, which contains a copy of the data originally stored into cell `A` along with a reference to cell `B`, which contains a reference to (the original) cell `A`. -Notice that -`Builder` and `Slice` objects appear only as values in a TVM stack. They cannot -be stored in “memory” (i.e., trees of cells) or “persistent storage” (which is -also a bag of cells). In this sense, there are far more `Cell` objects than `Builder` -or `Slice` objects in a TVM environment, but, somewhat paradoxically, a TVM -program sees `Builder` and `Slice` objects in its stack more often than `Cell`s. +In this way the transparent copy-on-write mechanism and the “everything is a value” paradigm enable us to create new cells using only previously constructed cells, thus forbidding the appearance of circular references. -In fact, a TVM program does not have much use for `Cell` values, because they -are immutable and opaque; all cell manipulation primitives require that a -`Cell` value be transformed into either a `Builder` or a `Slice` first, before it can -be modified or inspected. +This property also applies to all other data structures: for instance, the absence of circular references enables TVM to use reference counting to immediately free unused memory instead of relying on garbage collectors. Similarly this property is crucial for storing data in the TON Blockchain. --- -### 3.2.4. TVM has no separate Bitstring value type. +# 3 Cells, memory, and persistent storage -Notice that TVM -offers no separate bitstring value type. Instead, bitstrings are represented by -`Slice`s that happen to have no references at all, but can still contain up to -`1023` data bits. +This chapter briefly describes TVM cells, used to represent all data structures inside the TVM memory and its persistent storage, and the basic operations used to create cells, write (or serialize) data into them, and read (or deserialize) data from them. ---- +## 3.1 Generalities on cells -### 3.2.5. Cells and cell primitives are bit-oriented, not byte-oriented. +This section presents a classification and general descriptions of cell types. -An important point is that TVM regards data kept in cells as sequences -(strings, streams) of (up to `1023`) bits, not of bytes. In other words, TVM -is a bit-oriented machine, not a byte-oriented machine. If necessary, an -application is free to use, say, `21`-bit integer fields inside records serialized into -TVM cells, thus using fewer persistent storage bytes to represent the same -data. +### 3.1.1 TVM memory and persistent storage consist of cells ---- +Recall that the TVM memory and persistent storage consist of (TVM) cells. Each cell contains up to 1023 bits of data and up to four references to other cells.[11](#footnote-11) -### 3.2.6. Taxonomy of cell creation (serialization) primitives. +Circular references are forbidden and cannot be created by means of TVM (cf. [2.3.5](#2-3-5-absence-of-circular-references)). In this way, all cells kept in TVM memory and persistent storage constitute a directed acyclic graph (DAG). -Cell creation primitives usually accept a `Builder` argument and an argument representing the value to be serialized. Additional arguments controlling some -aspects of the serialization process (e.g., how many bits should be used for -serialization) can be also provided, either in the stack or as an immediate -value inside the instruction. +### 3.1.2 Ordinary and exotic cells -The result of a cell creation primitive is usually -another `Builder`, representing the concatenation of the original builder and -the serialization of the value provided. +Apart from the data and references, a cell has a cell type, encoded by an integer −1…255. A cell of type −1 is called **ordinary**; such cells do not require any special processing. Cells of other types are called **exotic**, and may be loaded—automatically replaced by other cells when an attempt to deserialize them (i.e., to convert them into a `Slice` by a `CTOS` instruction) is made. They may also exhibit a non-trivial behavior when their hashes are computed. -Therefore, one can suggest a classification of cell serialization primitives -according to the answers to the following questions: +The most common use for exotic cells is to represent some other cells—for instance, cells present in an external library, or pruned from the original tree of cells when a Merkle proof has been created. -* Which is the type of values being serialized? -* How many bits are used for serialization? If this is a variable number, - does it come from the stack, or from the instruction itself? -* What happens if the value does not fit into the prescribed number of - bits? Is an exception generated, or is a success flag equal to zero silently - returned in the top of stack? -* What happens if there is insufficient space left in the `Builder`? Is an - exception generated, or is a zero success flag returned along with the - unmodified original `Builder`? +The type of an exotic cell is stored as the first eight bits of its data. If an exotic cell has less than eight data bits, it is invalid. -The mnemonics of cell serialization primitives usually begin with `ST`. Subsequent letters describe the following attributes: +### 3.1.3 The level of a cell -* The type of values being serialized and the serialization format (e.g., `I` - for signed integers, `U` for unsigned integers). -* The source of the field width in bits to be used (e.g., `X` for integer - serialization instructions means that the bit width `n` is supplied in - the stack; otherwise it has to be embedded into the instruction as an - immediate value). -* The action to be performed if the operation cannot be completed (by - default, an exception is generated; “quiet” versions of serialization instructions are marked by a `Q` letter in their mnemonics). +Every cell `c` has another attribute `Lvl(c)` called its (de Brujn) **level**, which currently takes integer values in the range 0…3. -This classification scheme is used to create a more complete taxonomy of cell -serialization primitives, which can be found in **A.7.1**. +The level of an ordinary cell is always equal to the maximum of the levels of all its children `ci`: ---- +```math +Lvl(c) = max_{1 ≤ i ≤ r} Lvl(ci) +```` -### 3.2.7. Integer serialization primitives. +for an ordinary cell `c` containing `r` references to cells `c1, …, cr`. +If `r = 0`, then `Lvl(c) = 0`. Exotic cells may have different rules for setting their level. -Integer serialization primitives -can be classified according to the above taxonomy as well. For example: +A cell’s level affects the number of higher hashes it has. More precisely, a level `l` cell has `l` higher hashes `Hash₁(c), …, Hash_l(c)` in addition to its representation hash `Hash(c) = Hash∞(c)`. -* There are signed and unsigned (big-endian) integer serialization primitives. -* The size `n` of the bit field to be used (`1 ≤ n ≤ 257` for signed integers, - `0 ≤ n ≤ 256` for unsigned integers) can either come from the top of - stack or be embedded into the instruction itself. -* If the integer `x` to be serialized is not in the range `−2^(n−1) ≤ x < 2^(n−1)` - (for signed integer serialization) or `0 ≤ x < 2^n` (for unsigned integer - serialization), a range check exception is usually generated, and if `n` bits - cannot be stored into the provided `Builder`, a cell overflow exception is - generated. -* Quiet versions of serialization instructions do not throw exceptions; - instead, they push `-1` on top of the resulting `Builder` upon success, or - return the original `Builder` with `0` on top of it to indicate failure. +Cells of non-zero level appear inside Merkle proofs and Merkle updates, after some branches of the tree of cells representing a value of an abstract data type are pruned. -Integer serialization instructions have mnemonics like `STU 20` (“store an -unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of -variable length provided in the stack”). +### 3.1.4 Standard cell representation -The full list of these instructions— -including their mnemonics, descriptions, and opcodes—is provided in **A.7.1**. +When a cell needs to be transferred by a network protocol or stored in a disk file, it must be serialized. The standard representation `CellRepr(c) = CellRepr∞(c)` of a cell `c` as an octet (byte) sequence is constructed as follows: ---- +1. Two descriptor bytes `d1` and `d2` are serialized first. -### 3.2.8. Integers in cells are big-endian by default. + * `d1 = r + 8s + 32l`, where `0 ≤ r ≤ 4` is the number of cell references contained in the cell, `0 ≤ l ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is 1 for exotic cells and 0 for ordinary cells. + * `d2 = ⌊b/8⌋ + ⌈b/8⌉`, where `0 ≤ b ≤ 1023` is the number of data bits in `c`. -Notice that the -default order of bits in `Integer`s serialized into `Cell`s is big-endian, not little- -endian. +2. Then the data bits are serialized as `⌈b/8⌉` 8-bit octets (bytes). If `b` is not a multiple of eight, a binary `1` and up to six binary `0`s are appended to the data bits. After that, the data is split into `⌈b/8⌉` eight-bit groups, and each group is interpreted as an unsigned big-endian integer 0…255 and stored into an octet. -In this respect TVM is a big-endian machine. However, this affects -only the serialization of integers inside cells. The internal representation of -the `Integer` value type is implementation-dependent and irrelevant for the -operation of TVM. +3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(ci)` (explained in [3.1.5](#3-1-5-the-representation-hash-of-a-cell)) of the cell `ci` referred to. -Besides, there are some special primitives such as `STULE` -for (de)serializing little-endian integers, which must be stored into an integral -number of bytes (otherwise “little-endianness” does not make sense, unless -one is also willing to revert the order of bits inside octets). +In this way, `2 + ⌈b/8⌉ + 32r` bytes of `CellRepr(c)` are obtained. -Such primitives are -useful for interfacing with the little-endian world—for instance, for parsing -custom-format messages arriving to a TON Blockchain smart contract from -the outside world. +### 3.1.5 The representation hash of a cell ---- +The 256-bit **representation hash** (or simply **hash**) `Hash(c)` of a cell `c` is recursively defined as the `sha256` of the standard representation of the cell `c`: -### 3.2.9. Other serialization primitives. +```math +Hash(c) := sha256(CellRepr(c)) +``` -Other cell creation primitives serialize bitstrings (i.e., cell slices without references), either taken from the stack -or supplied as literal arguments; cell slices (which are concatenated to the -cell builder in an obvious way); other `Builder`s (which are also concatenated); -and cell references (`STREF`). +Notice that cyclic cell references are not allowed and cannot be created by means of the TVM (cf. [2.3.5](#2-3-5-absence-of-circular-references)), so this recursion always ends, and the representation hash of any cell is well-defined. ---- +### 3.1.6 The higher hashes of a cell -### 3.2.10. Other cell creation primitives. +Recall that a cell `c` of level `l` has `l` higher hashes `Hashᵢ(c), 1 ≤ i ≤ l`, as well. Exotic cells have their own rules for computing their higher hashes. -In addition to the cell serialization primitives for certain built-in value types described above, there are -simple primitives that create a new empty `Builder` and push it into the stack -(`NEWC`), or transform a `Builder` into a `Cell` (`ENDC`), thus finishing the cell -creation process. +Higher hashes `Hashᵢ(c)` of an ordinary cell `c` are computed similarly to its representation hash, but using the higher hashes `Hashᵢ(cj)` of its children `cj` instead of their representation hashes `Hash(cj)`. -An `ENDC` can be combined with a `STREF` into a single instruction `ENDCST`, which finishes the creation of a cell and immediately stores -a reference to it in an “outer” `Builder`. +By convention: -There are also primitives that obtain -the quantity of data bits or references already stored in a `Builder`, and check how many data bits or references can be stored. +* `Hash∞(c) := Hash(c)` +* `Hashᵢ(c) := Hash∞(c) = Hash(c)` for all `i > l`. ---- +### 3.1.7 Types of exotic cells -### 3.2.11. Taxonomy of cell deserialisation primitives. +TVM currently supports the following cell types: -Cell parsing, or -deserialization, primitives can be classified as described in 3.2.6, with the -following modifications: +* **Type −1: Ordinary cell** — Contains up to 1023 bits of data and up to four cell references. -* They work with `Slice`s (representing the remainder of the cell being - parsed) instead of `Builder`s. -* They return deserialized values instead of accepting them as arguments. -* They may come in two flavors, depending on whether they remove the - deserialized portion from the `Slice` supplied (“fetch operations”) or leave - it unmodified (“prefetch operations”). -* Their mnemonics usually begin with `LD` (or `PLD` for prefetch operations) - instead of `ST`. +* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ l ≤ 3`. + Contains exactly `8 + 256l` data bits: first an 8-bit integer equal to `1` (the cell’s type), then its `l` higher hashes `Hash₁(c), …, Hash_l(c)`. + The level `l` may be called its **de Brujn index**, because it determines the outer Merkle proof or Merkle update during which the branch has been pruned. + An attempt to load a pruned branch cell usually leads to an exception. -For example, an unsigned big-endian 20-bit integer previously serialized into -a cell by a `STU 20` instruction is likely to be deserialized later by a matching -`LDU 20` instruction. +* **Type 2: Library reference cell** — Always has level 0, and contains `8 + 256` data bits, including its 8-bit type integer `2` and the representation hash `Hash(c₀)` of the library cell being referred to. + When loaded, a library reference cell may be transparently replaced by the cell it refers to, if found in the current library context. -Again, more detailed information about these instructions is provided in **A.7.2**. +* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c₁` and level `0 ≤ l ≤ 3`, which must be one less than the level of its only child `c₁`: ---- + ```math + Lvl(c) = max(Lvl(c₁) − 1, 0) + ``` -### 3.2.12. Other cell slice primitives. + The 8 + 256 data bits of a Merkle proof cell contain its 8-bit type integer `3`, followed by `Hash₁(c₁)` (assumed equal to `Hash(c₁)` if `Lvl(c₁) = 0`). -In addition to the cell deserialisation -primitives outlined above, TVM provides some obvious primitives for initializing and completing the cell deserialization process. + The higher hashes `Hashᵢ(c)` of `c` are computed similarly to the higher hashes of an ordinary cell, but with `Hashᵢ₊₁(c₁)` used instead of `Hashᵢ(c₁)`. + When loaded, a Merkle proof cell is replaced by `c₁`. -For instance, one can -convert a `Cell` into a `Slice` (`CTOS`), so that its deserialisation might begin; -or check whether a `Slice` is empty, and generate an exception if it is not -(`ENDS`); or deserialize a cell reference and immediately convert it into a `Slice` -(`LDREFTOS`, equivalent to two instructions `LDREF` and `CTOS`). +* **Type 4: Merkle update cell `c`** — Has two children `c₁` and `c₂`. Its level `0 ≤ l ≤ 3` is given by: ---- + ```math + Lvl(c) = max(Lvl(c₁) − 1, Lvl(c₂) − 1, 0) + ``` -### 3.2.13. Modifying a serialized value in a cell. + A Merkle update behaves like a Merkle proof for both `c₁` and `c₂`, and contains `8 + 256 + 256` data bits with `Hash₁(c₁)` and `Hash₁(c₂)`. -The reader might wonder -how the values serialized inside a cell may be modified. + However, an extra requirement is that all pruned branch cells `c₀` that are descendants of `c₂` and are bound by `c` must also be descendants of `c₁`. -Suppose a cell contains three serialized 29-bit integers, `(x, y, z)`, representing the coordinates of -a point in space, and we want to replace `y` with `y' = y + 1`, leaving the other -coordinates intact. How would we achieve this? + When a Merkle update cell is loaded, it is replaced by `c₂`.[13](#footnote-13) -TVM does not offer any ways to modify existing values (cf. 2.3.4 and -2.3.5), so our example can only be accomplished with a series of operations -as follows: +### 3.1.8 All values of algebraic data types are trees of cells -1. Deserialize the original cell into three `Integer`s `x`, `y`, `z` in the stack (e.g., - by `CTOS; LDI 29; LDI 29; LDI 29; ENDS`). -2. Increase `y` by one (e.g., by `SWAP; INC; SWAP`). -3. Finally, serialize the resulting `Integer`s into a new cell (e.g., by `XCHG s2; NEWC; STI 29; STI 29; STI 29; ENDC`). +Arbitrary values of algebraic data types can be serialized into trees of cells (of level 0), and such representations are used for representing such values within TVM. ---- +The copy-on-write mechanism (cf. [2.3.2](#2-3-2-efficient-implementation-of-dup-and-push-instructions-using-copy-on-write)) allows TVM to identify cells containing the same data and references, and to keep only one copy of such cells. -### 3.2.14. Modifying the persistent storage of a smart contract. +This actually transforms a tree of cells into a directed acyclic graph (with the additional property that all its vertices be accessible from a marked vertex called the “root”). However, this is a storage optimization rather than an essential property of TVM. -If the -TVM code wants to modify its persistent storage, represented by the tree of -cells rooted at `c4`, it simply needs to rewrite control register `c4` by the root -of the tree of cells containing the new value of its persistent storage. (If only -part of the persistent storage needs to be modified, cf. 3.2.13.) +From the perspective of a TVM code programmer, one should think of TVM data structures as trees of cells. ---- +### 3.1.9 TVM code is a tree of cells -## 3.3 Hashmaps, or dictionaries +The TVM code itself is also represented by a tree of cells. Indeed, TVM code is simply a value of some complex algebraic data type, and as such, it can be serialized into a tree of cells. -Hashmaps, or dictionaries, are a specific data structure represented by a tree -of cells. Essentially, a hashmap represents a map from keys, which are bitstrings of either fixed or variable length, into values of an arbitrary type `X`, -in such a way that fast lookups and modifications be possible. While any -such structure might be inspected or modified with the aid of generic cell serialization and deserialization primitives, TVM introduces special primitives -to facilitate working with these hashmaps. +The exact way in which the TVM code (e.g., TVM assembly code) is transformed into a tree of cells is explained later (cf. [4.1.4](#4-1-4-normal-work-of-tvm%2C-or-the-main-loop) and [5.2](#5-2-instruction-encoding)), in sections discussing control flow instructions, continuations, and TVM instruction encoding. ---- +### 3.1.10 “Everything is a bag of cells” paradigm -### 3.3.1. Basic hashmap types. +As described in [1](#reference-1), all the data used by the TON Blockchain, including the blocks themselves and the blockchain state, can be represented—and are represented—as collections, or “bags”, of cells. -The two most basic hashmap types predefined in TVM are `HashmapE n X` or `HashmapE(n, X)`, which represents -a partially defined map from n-bit strings (called keys) for some fixed `0 ≤ n ≤ 1023` into values of some type `X`, and `Hashmap(n, X)`, which is similar -to `HashmapE(n, X)` but is not allowed to be empty (i.e., it must contain at -least one key-value pair). +We see that TVM’s structure of data (cf. [3.1.8](#3-1-8-all-values-of-algebraic-data-types-are-trees-of-cells)) and code (cf. [3.1.9](#3-1-9-tvm-code-is-a-tree-of-cells)) nicely fits into this “everything is a bag of cells” paradigm. -Other hashmap types are also available—for example, one with keys of -arbitrary length up to some predefined bound (up to 1023 bits). +In this way, TVM can naturally be used to execute smart contracts in the TON Blockchain, and the TON Blockchain can be used to store the code and persistent data of these smart contracts between invocations of TVM. (Of course, both TVM and the TON Blockchain have been designed so that this would become possible.) --- -### 3.3.2. Hashmaps as Patricia trees. +## 3.2 Data manipulation instructions and cells + +The next large group of TVM instructions consists of data manipulation instructions, also known as cell manipulation instructions or simply cell instructions. They correspond to memory access instructions of other architectures. + +### 3.2.1 Classes of cell manipulation instructions + +The TVM cell instructions are naturally subdivided into two principal classes: + +- **Cell creation instructions** or **serialization instructions**, used to construct new cells from values previously kept in the stack and previously constructed cells. +- **Cell parsing instructions** or **deserialization instructions**, used to extract data previously stored into cells by cell creation instructions. + +Additionally, there are exotic cell instructions used to create and inspect exotic cells (cf. [3.1.2](#3-1-2-ordinary-and-exotic-cells)), which in particular are used to represent pruned branches of Merkle proofs and Merkle proofs themselves. + +### 3.2.2 Builder and Slice values + +Cell creation instructions usually work with **Builder** values, which can be kept only in the stack (cf. [1.1.3](#1-1-3-preliminary-list-of-value-types)). Such values represent partially constructed cells, for which fast operations for appending bitstrings, integers, other cells, and references to other cells can be defined. Similarly, cell parsing instructions make heavy use of **Slice** values, which represent either the remainder of a partially parsed cell, or a value (subcell) residing inside such a cell and extracted from it by a parsing instruction. + +### 3.2.3 Builder and Slice values exist only as stack values + +Notice that Builder and Slice objects appear only as values in a TVM stack. They cannot be stored in “memory” (i.e., trees of cells) or “persistent storage” (which is also a bag of cells). In this sense, there are far more Cell objects than Builder or Slice objects in a TVM environment, but, somewhat paradoxically, a TVM program sees Builder and Slice objects in its stack more often than Cells. In fact, a TVM program does not have much use for Cell values, because they are immutable and opaque; all cell manipulation primitives require that a Cell value be transformed into either a Builder or a Slice first, before it can be modified or inspected. + +### 3.2.4 TVM has no separate Bitstring value type + +Notice that TVM offers no separate bitstring value type. Instead, bitstrings are represented by Slices that happen to have no references at all, but can still contain up to 1023 data bits. + +### 3.2.5 Cells and cell primitives are bit-oriented, not byte-oriented + +An important point is that TVM regards data kept in cells as sequences (strings, streams) of (up to 1023) bits, not of bytes. In other words, TVM is a bit-oriented machine, not a byte-oriented machine. If necessary, an application is free to use, say, 21-bit integer fields inside records serialized into TVM cells, thus using fewer persistent storage bytes to represent the same data. + +### 3.2.6 Taxonomy of cell creation (serialization) primitives + +Cell creation primitives usually accept a Builder argument and an argument representing the value to be serialized. Additional arguments controlling some aspects of the serialization process (e.g., how many bits should be used for serialization) can be also provided, either in the stack or as an immediate value inside the instruction. The result of a cell creation primitive is usually another Builder, representing the concatenation of the original builder and the serialization of the value provided. + +Therefore, one can suggest a classification of cell serialization primitives according to the answers to the following questions: + +- Which is the type of values being serialized? +- How many bits are used for serialization? If this is a variable number, does it come from the stack, or from the instruction itself? +- What happens if the value does not fit into the prescribed number of bits? Is an exception generated, or is a success flag equal to zero silently returned in the top of stack? +- What happens if there is insufficient space left in the Builder? Is an exception generated, or is a zero success flag returned along with the unmodified original Builder? + +The mnemonics of cell serialization primitives usually begin with `ST`. Subsequent letters describe the following attributes: + +- The type of values being serialized and the serialization format (e.g., `I` for signed integers, `U` for unsigned integers). +- The source of the field width in bits to be used (e.g., `X` for integer serialization instructions means that the bit width `n` is supplied in the stack; otherwise it has to be embedded into the instruction as an immediate value). +- The action to be performed if the operation cannot be completed (by default, an exception is generated; “quiet” versions of serialization instructions are marked by a `Q` letter in their mnemonics). -The abstract representation of a -hashmap in TVM is a Patricia tree, or a compact binary trie. It is a binary -tree with edges labelled by bitstrings, such that the concatenation of all edge -labels on a path from the root to a leaf equals a key of the hashmap. The -corresponding value is kept in this leaf (for hashmaps with keys of fixed -length), or optionally in the intermediate vertices as well (for hashmaps with -keys of variable length). +This classification scheme is used to create a more complete taxonomy of cell serialization primitives, which can be found in [A.7.1](#a-7-1). -Furthermore, any intermediate vertex must have -two children, and the label of the left child must begin with a binary zero, -while the label of the right child must begin with a binary one. This enables -us not to store the first bit of the edge labels explicitly. +### 3.2.7 Integer serialization primitives -It is easy to see that any collection of key-value pairs (with distinct keys) -is represented by a unique Patricia tree. +Integer serialization primitives can be classified according to the above taxonomy as well. For example: + +- There are signed and unsigned (big-endian) integer serialization primitives. +- The size `n` of the bit field to be used (`1 ≤ n ≤ 257` for signed integers, `0 ≤ n ≤ 256` for unsigned integers) can either come from the top of stack or be embedded into the instruction itself. +- If the integer `x` to be serialized is not in the range `−2^(n−1) ≤ x < 2^(n−1)` (for signed integer serialization) or `0 ≤ x < 2^n` (for unsigned integer serialization), a range check exception is usually generated, and if `n` bits cannot be stored into the provided Builder, a cell overflow exception is generated. +- Quiet versions of serialization instructions do not throw exceptions; instead, they push `-1` on top of the resulting Builder upon success, or return the original Builder with `0` on top of it to indicate failure. + +Integer serialization instructions have mnemonics like `STU 20` (“store an unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of variable length provided in the stack”). The full list of these instructions—including their mnemonics, descriptions, and opcodes—is provided in [A.7.1](#a-7-1). + +### 3.2.8 Integers in cells are big-endian by default + +Notice that the default order of bits in Integers serialized into Cells is big-endian, not little-endian.[14](#footnote-14) In this respect TVM is a big-endian machine. However, this affects only the serialization of integers inside cells. The internal representation of the Integer value type is implementation-dependent and irrelevant for the operation of TVM. Besides, there are some special primitives such as `STULE` for (de)serializing little-endian integers, which must be stored into an integral number of bytes (otherwise “little-endianness” does not make sense, unless one is also willing to revert the order of bits inside octets). Such primitives are useful for interfacing with the little-endian world—for instance, for parsing custom-format messages arriving to a TON Blockchain smart contract from the outside world. + +### 3.2.9 Other serialization primitives + +Other cell creation primitives serialize bitstrings (i.e., cell slices without references), either taken from the stack or supplied as literal arguments; cell slices (which are concatenated to the cell builder in an obvious way); other Builders (which are also concatenated); and cell references (`STREF`). + +### 3.2.10 Other cell creation primitives + +In addition to the cell serialization primitives for certain built-in value types described above, there are simple primitives that create a new empty Builder and push it into the stack (`NEWC`), or transform a Builder into a Cell (`ENDC`), thus finishing the cell creation process. An `ENDC` can be combined with a `STREF` into a single instruction `ENDCST`, which finishes the creation of a cell and immediately stores a reference to it in an “outer” Builder. There are also primitives that obtain the quantity of data bits or references already stored in a Builder, and check how many data bits or references can be stored. + +### 3.2.11 Taxonomy of cell deserialisation primitives + +Cell parsing, or deserialization, primitives can be classified as described in [3.2.6](#3-2-6-taxonomy-of-cell-creation-serialization-primitives), with the following modifications: + +- They work with Slices (representing the remainder of the cell being parsed) instead of Builders. +- They return deserialized values instead of accepting them as arguments. +- They may come in two flavors, depending on whether they remove the deserialized portion from the Slice supplied (“fetch operations”) or leave it unmodified (“prefetch operations”). +- Their mnemonics usually begin with `LD` (or `PLD` for prefetch operations) instead of `ST`. + +For example, an unsigned big-endian 20-bit integer previously serialized into a cell by a `STU 20` instruction is likely to be deserialized later by a matching `LDU 20` instruction. + +Again, more detailed information about these instructions is provided in [A.7.2](#a-7-2). + +### 3.2.12 Other cell slice primitives + +In addition to the cell deserialisation primitives outlined above, TVM provides some obvious primitives for initializing and completing the cell deserialization process. For instance, one can convert a Cell into a Slice (`CTOS`), so that its deserialisation might begin; or check whether a Slice is empty, and generate an exception if it is not (`ENDS`); or deserialize a cell reference and immediately convert it into a Slice (`LDREFTOS`, equivalent to two instructions `LDREF` and `CTOS`). + +### 3.2.13 Modifying a serialized value in a cell + +The reader might wonder how the values serialized inside a cell may be modified. Suppose a cell contains three serialized 29-bit integers, `(x, y, z)`, representing the coordinates of a point in space, and we want to replace `y` with `y' = y + 1`, leaving the other coordinates intact. How would we achieve this? + +TVM does not offer any ways to modify existing values (cf. [2.3.4](#2-3-4-transparency-of-the-implementation-stack-values-are-values-not-references) and [2.3.5](#2-3-5-absence-of-circular-references)), so our example can only be accomplished with a series of operations as follows: + +1. Deserialize the original cell into three Integers `x, y, z` in the stack (e.g., by `CTOS; LDI 29; LDI 29; LDI 29; ENDS`). +2. Increase `y` by one (e.g., by `SWAP; INC; SWAP`). +3. Finally, serialize the resulting Integers into a new cell (e.g., by `XCHG s2; NEWC; STI 29; STI 29; STI 29; ENDC`). + +### 3.2.14 Modifying the persistent storage of a smart contract + +If the TVM code wants to modify its persistent storage, represented by the tree of cells rooted at `c4`, it simply needs to rewrite control register `c4` by the root of the tree of cells containing the new value of its persistent storage. (If only part of the persistent storage needs to be modified, cf. [3.2.13](#3-2-13-modifying-a-serialized-value-in-a-cell).) --- -### 3.3.3. Serialization of hashmaps. +## 3.3 Hashmaps, or dictionaries + +Hashmaps, or dictionaries, are a specific data structure represented by a tree of cells. Essentially, a hashmap represents a map from keys, which are bitstrings of either fixed or variable length, into values of an arbitrary type `X`, in such a way that fast lookups and modifications be possible. While any such structure might be inspected or modified with the aid of generic cell serialization and deserialization primitives, TVM introduces special primitives to facilitate working with these hashmaps. -The serialization of a hashmap into a -tree of cells (or, more generally, into a `Slice`) is defined by the following TL-B -scheme: +### 3.3.1 Basic hashmap types -``` +The two most basic hashmap types predefined in TVM are `HashmapE n X` or `HashmapE(n, X)`, which represents a partially defined map from `n`-bit strings (called keys) for some fixed `0 ≤ n ≤ 1023` into values of some type `X`, and `Hashmap(n, X)`, which is similar to `HashmapE(n, X)` but is not allowed to be empty (i.e., it must contain at least one key-value pair). + +Other hashmap types are also available—for example, one with keys of arbitrary length up to some predefined bound (up to 1023 bits). + +### 3.3.2 Hashmaps as Patricia trees + +The abstract representation of a hashmap in TVM is a Patricia tree, or a compact binary trie. It is a binary tree with edges labelled by bitstrings, such that the concatenation of all edge labels on a path from the root to a leaf equals a key of the hashmap. The corresponding value is kept in this leaf (for hashmaps with keys of fixed length), or optionally in the intermediate vertices as well (for hashmaps with keys of variable length). Furthermore, any intermediate vertex must have two children, and the label of the left child must begin with a binary zero, while the label of the right child must begin with a binary one. This enables us not to store the first bit of the edge labels explicitly. + +It is easy to see that any collection of key-value pairs (with distinct keys) is represented by a unique Patricia tree. + +### 3.3.3 Serialization of hashmaps + +The serialization of a hashmap into a tree of cells (or, more generally, into a `Slice`) is defined by the following TL-B scheme:[15](#footnote-15) + +```tlb bit#_ _:(## 1) = Bit; hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(HashmapNode m X) = Hashmap n X; @@ -1219,173 +718,57 @@ true#_ = True; _ {n:#} _:(Hashmap n True) = BitstringSet n; ``` ---- +### 3.3.4 Brief explanation of TL-B schemes -### 3.3.4. Brief explanation of TL-B schemes. - -A TL-B scheme, like the -one above, includes the following components. - -The right-hand side of each “equation” is a type, either simple (such as -`Bit` or `True`) or parametrized (such as `Hashmap n X`). The parameters of a -type must be either natural numbers (i.e., non-negative integers, which are -required to fit into 32 bits in practice), such as `n` in `Hashmap n X`, or other -types, such as `X` in `Hashmap n X`. - -The left-hand side of each equation describes a way to define, or even to -serialize, a value of the type indicated in the right-hand side. Such a description begins with the name of a constructor, such as `hm_edge` or `hml_long`, -immediately followed by an optional constructor tag, such as `#_` or `$10`, which -describes the bitstring used to encode (serialize) the constructor in question. - -Such tags may be given in either binary (after a dollar sign) or hexadecimal -notation (after a hash sign), using the conventions described in 1.0. - -If a tag is not explicitly provided, TL-B computes a default 32-bit constructor tag -by hashing the text of the “equation” defining this constructor in a certain -fashion. Therefore, empty tags must be explicitly provided by `#_` or `$_`. All -constructor names must be distinct, and constructor tags for the same type -must constitute a prefix code (otherwise the deserialization would not be -unique). - -The constructor and its optional tag are followed by field definitions. Each -field definition is of the form `ident : type-expr`, where `ident` is an identifier -with the name of the field (replaced by an underscore for anonymous fields), -and `type-expr` is the field’s type. - -The type provided here is a type expression, -which may include simple types or parametrized types with suitable parameters. - -Variables—i.e., the identifiers of the previously defined fields of types -`#` (natural numbers) or `Type` (type of types)—may be used as parameters -for the parametrized types. The serialization process recursively serializes -each field according to its type, and the serialization of a value ultimately -consists of the concatenation of bitstrings representing the constructor (i.e., -the constructor tag) and the field values. - -Some fields may be implicit. Their definitions are surrounded by curly -braces, which indicate that the field is not actually present in the serialization, -but that its value must be deduced from other data (usually the parameters -of the type being serialized). - -Some occurrences of “variables” (i.e., already-defined fields) are prefixed -by a tilde. This indicates that the variable’s occurrence is used in the opposite way of the default behavior: in the left-hand side of the equation, it -means that the variable will be deduced (computed) based on this occurrence, -instead of substituting its previously computed value; in the right-hand side, -conversely, it means that the variable will not be deduced from the type being -serialized, but rather that it will be computed during the deserialization process. - -In other words, a tilde transforms an “input argument” into an “output -argument”, and vice versa.17 - -Finally, some equalities may be included in curly brackets as well. These -are certain “equations”, which must be satisfied by the “variables” included in -them. If one of the variables is prefixed by a tilde, its value will be uniquely -determined by the values of all other variables participating in the equation -(which must be known at this point) when the definition is processed from -the left to the right. - -A caret (`^`) preceding a type `X` means that instead of serializing a value -of type `X` as a bitstring inside the current cell, we place this value into a -separate cell, and add a reference to it into the current cell. Therefore `^X` -means “the type of references to cells containing values of type X”. - -Parametrized type `#<= p` with `p : #` (this notation means “p of type #”, -i.e., a natural number) denotes the subtype of the natural numbers type -`#`, consisting of integers `0 . . . p`; it is serialized into `⌈log2(p + 1)⌉` bits as an -unsigned big-endian integer. - -Type `#` by itself is serialized as an unsigned -32-bit integer. Parametrized type `## b` with `b : #<=31` is equivalent to `#<= 2^b − 1` (i.e., it is an unsigned b-bit integer). +A TL-B scheme, like the one above, includes the following components. ---- +The right-hand side of each “equation” is a type, either simple (such as `Bit` or `True`) or parametrized (such as `Hashmap n X`). The parameters of a type must be either natural numbers (i.e., non-negative integers, which are required to fit into 32 bits in practice), such as `n` in `Hashmap n X`, or other types, such as `X` in `Hashmap n X`. -### 3.3.5. Application to the serialization of hashmaps. - -Let us explain -the net result of applying the general rules described in 3.3.4 to the TL-B -scheme presented in 3.3.3. - -Suppose we wish to serialize a value of type `HashmapE n X` for some -integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with n-bit keys -and values of type `X`, admitting an abstract representation as a Patricia tree -(cf. 3.3.2)). - -First of all, if our dictionary is empty, it is serialized into a single binary `0`, -which is the tag of nullary constructor `hme_empty`. Otherwise, its serialization -consists of a binary `1` (the tag of `hme_root`), along with a reference to a cell -containing the serialization of a value of type `Hashmap n X` (i.e., a necessarily -non-empty dictionary). - -The only way to serialize a value of type `Hashmap n X` is given by the -`hm_edge` constructor, which instructs us to serialize first the label `label` of -the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel l ⊥ n`, which means that it is a bitstring of length at most n, serialized in such -a way that the true length l of the label, `0 ≤ l ≤ n`, becomes known from -the serialization of the label. (This special serialization method is described -separately in 3.3.6.) - -The label must be followed by the serialization of a node of type -`HashmapNode m X`, where `m = n − l`. It corresponds to a vertex of the Patricia tree, -representing a non-empty subdictionary of the original dictionary with m-bit -keys, obtained by removing from all the keys of the original subdictionary -their common prefix of length l. - -If `m = 0`, a value of type `HashmapNode 0 X` is given by the `hmn_leaf` -constructor, which describes a leaf of the Patricia tree—or, equivalently, a -subdictionary with 0-bit keys. A leaf simply consists of the corresponding -value of type `X` and is serialized accordingly. - -On the other hand, if `m > 0`, a value of type `HashmapNode m X` corresponds to a fork (i.e., an intermediate node) in the Patricia tree, and is -given by the `hmn_fork` constructor. Its serialization consists of `left` and -`right`, two references to cells containing values of type `Hashmap m − 1 X`, -which correspond to the left and the right child of the intermediate node in -question—or, equivalently, to the two subdictionaries of the original dictionary consisting of key-value pairs with keys beginning with a binary `0` or -a binary `1`, respectively. Because the first bit of all keys in each of these -subdictionaries is known and fixed, it is removed, and the resulting (necessarily non-empty) subdictionaries are recursively serialized as values of type -`Hashmap m − 1 X`. +The left-hand side of each equation describes a way to define, or even to serialize, a value of the type indicated in the right-hand side. Such a description begins with the name of a constructor, such as `hm_edge` or `hml_long`, immediately followed by an optional constructor tag, such as `#_` or `$10`, which describes the bitstring used to encode (serialize) the constructor in question. Such tags may be given in either binary (after a dollar sign) or hexadecimal notation (after a hash sign), using the conventions described in [1.0](#1-0-notation-for-bitstrings). If a tag is not explicitly provided, TL-B computes a default 32-bit constructor tag by hashing the text of the “equation” defining this constructor in a certain fashion. Therefore, empty tags must be explicitly provided by `#_` or `$_`. All constructor names must be distinct, and constructor tags for the same type must constitute a prefix code (otherwise the deserialization would not be unique). ---- +The constructor and its optional tag are followed by field definitions. Each field definition is of the form `ident : type-expr`, where ident is an identifier with the name of the field[16](#footnote-16) (replaced by an underscore for anonymous fields), and `type-expr` is the field’s type. The type provided here is a type expression, which may include simple types or parametrized types with suitable parameters. Variables—i.e., the (identifiers of the) previously defined fields of types `#` (natural numbers) or `Type` (type of types)—may be used as parameters for the parametrized types. The serialization process recursively serializes each field according to its type, and the serialization of a value ultimately consists of the concatenation of bitstrings representing the constructor (i.e., the constructor tag) and the field values. -### 3.3.6. Serialization of labels. +Some fields may be implicit. Their definitions are surrounded by curly braces, which indicate that the field is not actually present in the serialization, but that its value must be deduced from other data (usually the parameters of the type being serialized). -There are several ways to serialize a label -of length at most n, if its exact length is `l ≤ n` (recall that the exact length -must be deducible from the serialization of the label itself, while the upper -bound n is known before the label is serialized or deserialized). These ways -are described by the three constructors `hml_short`, `hml_long`, and `hml_same` -of type `HmLabel l ⊥ n`: +Some occurrences of “variables” (i.e., already-defined fields) are prefixed by a tilde. This indicates that the variable’s occurrence is used in the opposite way of the default behavior: in the left-hand side of the equation, it means that the variable will be deduced (computed) based on this occurrence, instead of substituting its previously computed value; in the right-hand side, conversely, it means that the variable will not be deduced from the type being serialized, but rather that it will be computed during the deserialization process. In other words, a tilde transforms an “input argument” into an “output argument”, and vice versa.[17](#footnote-17) -* `hml_short` — Describes a way to serialize “short” labels, of small length - `l ≤ n`. Such a serialization consists of a binary `0` (the constructor tag - of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary - representation of the length l), followed by l bits comprising the label - itself. +Finally, some equalities may be included in curly brackets as well. These are certain “equations”, which must be satisfied by the “variables” included in them. If one of the variables is prefixed by a tilde, its value will be uniquely determined by the values of all other variables participating in the equation (which must be known at this point) when the definition is processed from the left to the right. -* `hml_long` — Describes a way to serialize “long” labels, of arbitrary - length `l ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation - of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by l bits comprising the label itself. +A caret (`^`) preceding a type `X` means that instead of serializing a value of type `X` as a bitstring inside the current cell, we place this value into a separate cell, and add a reference to it into the current cell. Therefore `^X` means “the type of references to cells containing values of type `X`”. -* `hml_same` — Describes a way to serialize “long” labels, consisting of l - repetitions of the same bit v. Such a serialization consists of `11` (the - constructor tag of `hml_same`), followed by the bit `v`, followed by the - length l stored in `⌈log2(n + 1)⌉` bits as before. +Parametrized type `#<= p` with `p : #` (this notation means “p of type #”, i.e., a natural number) denotes the subtype of the natural numbers type `#`, consisting of integers `0 … p`; it is serialized into `⌈log2(p + 1)⌉` bits as an unsigned big-endian integer. Type `#` by itself is serialized as an unsigned 32-bit integer. Parametrized type `## b` with `b : #<=31` is equivalent to `#<= 2^b − 1` (i.e., it is an unsigned `b`-bit integer). -Each label can always be serialized in at least two different fashions, using -`hml_short` or `hml_long` constructors. Usually the shortest serialization (and -in the case of a tie—the lexicographically smallest among the shortest) is -preferred and is generated by TVM hashmap primitives, while the other -variants are still considered valid. +### 3.3.5 Application to the serialization of hashmaps -This label encoding scheme has been designed to be efficient for dictionaries -with “random” keys (e.g., hashes of some data), as well as for dictionaries with -“regular” keys (e.g., big-endian representations of integers in some range). +Let us explain the net result of applying the general rules described in [3.3.4](#3-3-4-brief-explanation-of-tl-b-schemes) to the TL-B scheme presented in [3.3.3](#3-3-3-serialization-of-hashmaps). ---- +Suppose we wish to serialize a value of type `HashmapE n X` for some integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with `n`-bit keys and values of type `X`, admitting an abstract representation as a Patricia tree (cf. [3.3.2](#3-3-2-hashmaps-as-patricia-trees))). + +First of all, if our dictionary is empty, it is serialized into a single binary `0`, which is the tag of nullary constructor `hme_empty`. Otherwise, its serialization consists of a binary `1` (the tag of `hme_root`), along with a reference to a cell containing the serialization of a value of type `Hashmap n X` (i.e., a necessarily non-empty dictionary). + +The only way to serialize a value of type `Hashmap n X` is given by the `hm_edge` constructor, which instructs us to serialize first the label `label` of the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel ~l n`, which means that it is a bitstring of length at most `n`, serialized in such a way that the true length `l` of the label, `0 ≤ l ≤ n`, becomes known from the serialization of the label. (This special serialization method is described separately in [3.3.6](#3-3-6-serialization-of-labels).) + +The label must be followed by the serialization of a node of type `HashmapNode m X`, where `m = n − l`. It corresponds to a vertex of the Patricia tree, representing a non-empty subdictionary of the original dictionary with `m`-bit keys, obtained by removing from all the keys of the original subdictionary their common prefix of length `l`. + +If `m = 0`, a value of type `HashmapNode 0 X` is given by the `hmn_leaf` constructor, which describes a leaf of the Patricia tree—or, equivalently, a subdictionary with `0`-bit keys. A leaf simply consists of the corresponding value of type `X` and is serialized accordingly. + +On the other hand, if `m > 0`, a value of type `HashmapNode m X` corresponds to a fork (i.e., an intermediate node) in the Patricia tree, and is given by the `hmn_fork` constructor. Its serialization consists of `left` and `right`, two references to cells containing values of type `Hashmap n X` **with `n` reduced by one** (i.e., `Hashmap (n − 1) X`), which correspond to the left and the right child of the intermediate node in question—or, equivalently, to the two subdictionaries of the original dictionary consisting of key-value pairs with keys beginning with a binary `0` or a binary `1`, respectively. Because the first bit of all keys in each of these subdictionaries is known and fixed, it is removed, and the resulting (necessarily non-empty) subdictionaries are recursively serialized as values of type `Hashmap (n − 1) X`. + +### 3.3.6 Serialization of labels -### 3.3.7. An example of dictionary serialization. +There are several ways to serialize a label of length at most `n`, if its exact length is `l ≤ n` (recall that the exact length must be deducible from the serialization of the label itself, while the upper bound `n` is known before the label is serialized or deserialized). These ways are described by the three constructors `hml_short`, `hml_long`, and `hml_same` of type `HmLabel ~l n`: -Consider a dictionary -with three 16-bit keys 13, 17, and 239 (considered as big-endian integers) -and corresponding 16-bit values 169, 289, and 57121. +* **`hml_short`** — Describes a way to serialize “short” labels, of small length `l ≤ n`. Such a serialization consists of a binary `0` (the constructor tag of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary representation of the length `l`), followed by `l` bits comprising the label itself. +* **`hml_long`** — Describes a way to serialize “long” labels, of arbitrary length `l ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by `l` bits comprising the label itself. +* **`hml_same`** — Describes a way to serialize “long” labels, consisting of `l` repetitions of the same bit `v`. Such a serialization consists of `11` (the constructor tag of `hml_same`), followed by the bit `v`, followed by the length `l` stored in `⌈log2(n + 1)⌉` bits as before. + +Each label can always be serialized in at least two different fashions, using `hml_short` or `hml_long` constructors. Usually the shortest serialization (and in the case of a tie—the lexicographically smallest among the shortest) is preferred and is generated by TVM hashmap primitives, while the other variants are still considered valid. + +This label encoding scheme has been designed to be efficient for dictionaries with “random” keys (e.g., hashes of some data), as well as for dictionaries with “regular” keys (e.g., big-endian representations of integers in some range). + +### 3.3.7 An example of dictionary serialization + +Consider a dictionary with three 16-bit keys `13`, `17`, and `239` (considered as big-endian integers) and corresponding 16-bit values `169`, `289`, and `57121`. In binary form: @@ -1395,45 +778,34 @@ In binary form: 0000000011101111 => 1101111100100001 ``` -The corresponding Patricia tree consists of a root `A`, two intermediate -nodes `B` and `C`, and three leaf nodes `D`, `E`, and `F`, corresponding to 13, 17, -and 239, respectively. The root `A` has only one child, `B`; the label on the -edge `AB` is `00000000 = 08`. The node `B` has two children: its left child is -an intermediate node `C` with the edge `BC` labelled by `(0)00`, while its right -child is the leaf `F` with `BF` labelled by `(1)1101111`. Finally, `C` has two leaf -children `D` and `E`, with `CD` labelled by `(0)1101` and `CE`—by `(1)0001`. +The corresponding Patricia tree consists of a root `A`, two intermediate nodes `B` and `C`, and three leaf nodes `D`, `E`, and `F`, corresponding to `13`, `17`, and `239`, respectively. The root `A` has only one child, `B`; the label on the edge `AB` is `00000000 = 0₈`. The node `B` has two children: its left child is an intermediate node `C` with the edge `BC` labelled by `(0)00`, while its right child is the leaf `F` with `BF` labelled by `(1)1101111`. Finally, `C` has two leaf children `D` and `E`, with `CD` labelled by `(0)1101` and `CE`—by `(1)0001`. -The corresponding value of type `HashmapE 16 (## 16)` may be written -in human-readable form as: +The corresponding value of type `HashmapE 16 (## 16)` may be written in human-readable form as: ``` (hme_root$1 - root:^(hm_edge label:(hml_same$11 v:0 n:8) node:(hm_fork - left:^(hm_edge label:(hml_short$0 len:$110 s:$00) node:(hm_fork - left:^(hm_edge label:(hml_long$10 n:4 s:$1101) - node:(hm_leaf value:169)) - right:^(hm_edge label:(hml_long$10 n:4 s:$0001) - node:(hm_leaf value:289)))) - right:^(hm_edge label:(hml_long$10 n:7 s:$1101111) - node:(hm_leaf value:57121))))) + root:^(hm_edge label:(hml_same$11 v:0 n:8) node:(hm_fork + left:^(hm_edge label:(hml_short$0 len:$110 s:$00) node:(hm_fork + left:^(hm_edge label:(hml_long$10 n:4 s:$1101) + node:(hm_leaf value:169)) + right:^(hm_edge label:(hml_long$10 n:4 s:$0001) + node:(hm_leaf value:289)))) + right:^(hm_edge label:(hml_long$10 n:7 s:$1101111) + node:(hm_leaf value:57121))))) ``` -The serialization of this data structure into a tree of cells consists of six -cells with the following binary data contained in them: +The serialization of this data structure into a tree of cells consists of six cells with the following binary data contained in them: ``` -A := 1 -A.0 := 11 0 01000 -A.0.0 := 0 110 00 -A.0.0.0 := 10 100 1101 0000000010101001 -A.0.0.1 := 10 100 0001 0000000100100001 -A.0.1 := 10 111 1101111 1101111100100001 +A := 1 +A.0 := 11 0 01000 +A.0.0 := 0 110 00 +A.0.0.0 := 10 100 1101 0000000010101001 +A.0.0.1 := 10 100 0001 0000000100100001 +A.0.1 := 10 111 1101111 1101111100100001 ``` -Here `A` is the root cell, `A.0` is the cell at the first reference of `A`, `A.1` is -the cell at the second reference of `A`, and so on. This tree of cells can be -represented more compactly using the hexadecimal notation described in 1.0, -using indentation to reflect the tree-of-cells structure: +Here `A` is the root cell, `A.0` is the cell at the first reference of `A`, `A.1` is the cell at the second reference of `A`, and so on. This tree of cells can be represented more compactly using the hexadecimal notation described in [1.0](#1-0-notation-for-bitstrings), using indentation to reflect the tree-of-cells structure: ``` C_ @@ -1444,157 +816,70 @@ A08090C_ BEFDF21 ``` -A total of 93 data bits and 5 references in 6 cells have been used to serialize -this dictionary. Notice that a straightforward representation of three 16- -bit keys and their corresponding 16-bit values would already require 96 bits -(albeit without any references), so this particular serialization turns out to -be quite efficient. +A total of 93 data bits and 5 references in 6 cells have been used to serialize this dictionary. Notice that a straightforward representation of three 16-bit keys and their corresponding 16-bit values would already require 96 bits (albeit without any references), so this particular serialization turns out to be quite efficient. ---- +### 3.3.8 Ways to describe the serialization of type X -### 3.3.8. Ways to describe the serialization of type X. - -Notice that the -built-in TVM primitives for dictionary manipulation need to know something -about the serialization of type `X`; otherwise, they would not be able to work -correctly with `Hashmap n X`, because values of type `X` are immediately -contained in the Patricia tree leaf cells. There are several options available -to describe the serialization of type `X`: - -* The simplest case is when `X = ^Y` for some other type `Y`. In this case - the serialization of `X` itself always consists of one reference to a cell, - which in fact must contain a value of type `Y`, something that is not - relevant for dictionary manipulation primitives. - -* Another simple case is when the serialization of any value of type `X` - always consists of `0 ≤ b ≤ 1023` data bits and `0 ≤ r ≤ 4` references. Integers `b` and `r` can then be passed to a dictionary manipulation primitive - as a simple description of `X`. (Notice that the previous case corresponds - to `b = 0, r = 1`.) - -* A more sophisticated case can be described by four integers - `1 ≤ b0, b1 ≤ 1023`, `0 ≤ r0, r1 ≤ 4`, with `bi` and `ri` used when the first bit of the - serialization equals `i`. When `b0 = b1` and `r0 = r1`, this case reduces to - the previous one. - -* Finally, the most general description of the serialization of a type `X` - is given by a splitting function `splitX` for `X`, which accepts one `Slice` - parameter `s`, and returns two `Slice`s, `s'` and `s''`, where `s'` - is the only prefix of `s` that is the serialization of a value of type `X`, and `s''` is - the remainder of `s`. If no such prefix exists, the splitting function is - expected to throw an exception. Notice that a compiler for a high-level - language, which supports some or all algebraic TL-B types, is likely to - automatically generate splitting functions for all types defined in the - program. +Notice that the built-in TVM primitives for dictionary manipulation need to know something about the serialization of type `X`; otherwise, they would not be able to work correctly with `Hashmap n X`, because values of type `X` are immediately contained in the Patricia tree leaf cells. There are several options available to describe the serialization of type `X`: ---- +* The simplest case is when `X = ^Y` for some other type `Y`. In this case the serialization of `X` itself always consists of one reference to a cell, which in fact must contain a value of type `Y`, something that is not relevant for dictionary manipulation primitives. +* Another simple case is when the serialization of any value of type `X` always consists of `0 ≤ b ≤ 1023` data bits and `0 ≤ r ≤ 4` references. Integers `b` and `r` can then be passed to a dictionary manipulation primitive as a simple description of `X`. (Notice that the previous case corresponds to `b = 0, r = 1`.) +* A more sophisticated case can be described by four integers `1 ≤ b0, b1 ≤ 1023`, `0 ≤ r0, r1 ≤ 4`, with `b_i` and `r_i` used when the first bit of the serialization equals `i`. When `b0 = b1` and `r0 = r1`, this case reduces to the previous one. +* Finally, the most general description of the serialization of a type `X` is given by a splitting function `split_X` for `X`, which accepts one `Slice` parameter `s`, and returns two `Slice`s, `s'` and `s''`, where `s'` is the only prefix of `s` that is the serialization of a value of type `X`, and `s''` is the remainder of `s`. If no such prefix exists, the splitting function is expected to throw an exception. Notice that a compiler for a high-level language, which supports some or all algebraic TL-B types, is likely to automatically generate splitting functions for all types defined in the program. -### 3.3.9. A simplifying assumption on the serialization of `X`. +### 3.3.9 A simplifying assumption on the serialization of X -One -may notice that values of type `X` always occupy the remaining part of an -`hm_edge`/`hme_leaf` cell inside the serialization of a `HashmapE n X`. Therefore, if we do not insist on strict validation of all dictionaries accessed, we -may assume that everything left unparsed in an `hm_edge`/`hme_leaf` cell after deserializing its label is a value of type `X`. This greatly simplifies the -creation of dictionary manipulation primitives, because in most cases they -turn out not to need any information about `X` at all. +One may notice that values of type `X` always occupy the remaining part of an `hm_edge/hmn_leaf` cell inside the serialization of a `HashmapE n X`. Therefore, if we do not insist on strict validation of all dictionaries accessed, we may assume that everything left unparsed in an `hm_edge/hmn_leaf` cell after deserializing its label is a value of type `X`. This greatly simplifies the creation of dictionary manipulation primitives, because in most cases they turn out not to need any information about `X` at all. ---- +### 3.3.10. Basic dictionary operations -### 3.3.10. Basic dictionary operations. - -Let us present a classification of -basic operations with dictionaries (i.e., values `D` of type `HashmapE n X`): - -* `Get(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns - the corresponding value `D[k] : X?` kept in `D`. -* `Set(D, k, x)` — Given `D : HashmapE(n, X)`, a key `k : n · bit`, and a - value `x : X`, sets `D0[k]` to `x` in a copy `D0` of `D`, and returns the resulting - dictionary `D0` (cf. 2.3.4). -* `Add(D, k, x)` — Similar to `Set`, but adds the key-value pair `(k, x)` to - `D` only if key `k` is absent in `D`. -* `Replace(D, k, x)` — Similar to `Set`, but changes `D0[k]` to `x` only if key - `k` is already present in `D`. -* `GetSet`, `GetAdd`, `GetReplace` — Similar to `Set`, `Add`, and `Replace`, - respectively, but returns the old value of `D[k]` as well. -* `Delete(D, k)` — Deletes key `k` from dictionary `D`, and returns the - resulting dictionary `D0`. -* `GetMin(D)`, `GetMax(D)` — Gets the minimal or maximal key `k` - from dictionary `D`, along with the associated value `x : X`. -* `RemoveMin(D)`, `RemoveMax(D)` — Similar to `GetMin` and `GetMax`, but also removes the key in question from dictionary `D`, and - returns the modified dictionary `D0`. May be used to iterate over all - elements of `D`, effectively using (a copy of) `D` itself as an iterator. -* `GetNext(D, k)` — Computes the minimal key `k0 > k` (or `k0 ≥ k` in a - variant) and returns it along with the corresponding value `x0 : X`. May - be used to iterate over all elements of `D`. -* `GetPrev(D, k)` — Computes the maximal key `k0 < k` (or `k0 ≤ k` in a - variant) and returns it along with the corresponding value `x0 : X`. -* `Empty(n)` — Creates an empty dictionary `D : HashmapE(n, X)`. -* `IsEmpty(D)` — Checks whether a dictionary is empty. -* `Create(n, {(ki , xi)})` — Given `n`, creates a dictionary from a list `(ki , xi)` - of key-value pairs passed in stack. -* `GetSubdict(D, l, k0)` — Given `D : HashmapE(n, X)` and some `l`-bit - string `k0 : l · bit` for `0 ≤ l ≤ n`, returns subdictionary `D0 = D/k0` of `D`, - consisting of keys beginning with `k0`. The result `D0` may be of either - type `HashmapE(n, X)` or type `HashmapE(n − l, X)`. -* `ReplaceSubdict(D, l, k0, D0)` — Given `D : HashmapE(n, X)`, `0 ≤ - l ≤ n`, `k0 : l · bit`, and `D0 : HashmapE(n − l, X)`, replaces with `D0` - the subdictionary `D/k0` of `D` consisting of keys beginning with `k0`, and - returns the resulting dictionary `D00 : HashmapE(n, X)`. Some variants - of `ReplaceSubdict` may also return the old value of the subdictionary - `D/k0` in question. -* `DeleteSubdict(D, l, k0)` — Equivalent to `ReplaceSubdict` with `D0` - being an empty dictionary. -* `Split(D)` — Given `D : HashmapE(n, X)`, returns `D0 := D/0` and - `D1 := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with 0 and 1, respectively. -* `Merge(D0, D1)` — Given `D0` and `D1 : HashmapE(n−1, X)`, computes - `D : HashmapE(n, X)`, such that `D/0 = D0` and `D/1 = D1`. -* `Foreach(D, f)` — Executes a function `f` with two arguments `k` and - `x`, with `(k, x)` running over all key-value pairs of a dictionary `D` in - lexicographical order.18 -* `ForeachRev(D, f)` — Similar to `Foreach`, but processes all keyvalue pairs in reverse order. -* `TreeReduce(D, o, f, g)` — Given `D : HashmapE(n, X)`, a value `o : X`, - and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree - reduction” of `D` by first applying `f` to all the leaves, and then using `g` - to compute the value corresponding to a fork starting from the values - assigned to its children.19 +Let us present a classification of basic operations with dictionaries (i.e., values D of type `HashmapE n X`): ---- - -### 3.3.11. Taxonomy of dictionary primitives. - -The dictionary primitives, -described in detail in A.10, can be classified according to the following categories: +- `GET(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns the corresponding value `D[k] : X?` kept in `D`. +- `SET(D, k, x)` — Given `D : HashmapE(n, X)`, a key `k : n·bit`, and a value `x : X`, sets `D′[k]` to `x` in a copy `D′` of `D`, and returns the resulting dictionary `D′` (cf. [2.3.4](#234-transparency-of-the-implementation-stack-values-are-values-not-references)). +- `ADD(D, k, x)` — Similar to `SET`, but adds the key-value pair `(k, x)` to `D` only if key `k` is absent in `D`. +- `REPLACE(D, k, x)` — Similar to `SET`, but changes `D′[k]` to `x` only if key `k` is already present in `D`. +- `GETSET`, `GETADD`, `GETREPLACE` — Similar to `SET`, `ADD`, and `REPLACE`, respectively, but returns the old value of `D[k]` as well. +- `DELETE(D, k)` — Deletes key `k` from dictionary `D`, and returns the resulting dictionary `D′`. +- `GETMIN(D)`, `GETMAX(D)` — Gets the minimal or maximal key `k` from dictionary `D`, along with the associated value `x : X`. +- `REMOVEMIN(D)`, `REMOVEMAX(D)` — Similar to `GETMIN` and `GETMAX`, but also removes the key in question from dictionary `D`, and returns the modified dictionary `D′`. May be used to iterate over all elements of `D`, effectively using (a copy of) `D` itself as an iterator. +- `GETNEXT(D, k)` — Computes the minimal key `k′ > k` (or `k′ ≥ k` in a variant) and returns it along with the corresponding value `x′ : X`. May be used to iterate over all elements of `D`. +- `GETPREV(D, k)` — Computes the maximal key `k′ < k` (or `k′ ≤ k` in a variant) and returns it along with the corresponding value `x′ : X`. +- `EMPTY(n)` — Creates an empty dictionary `D : HashmapE(n, X)`. +- `ISEMPTY(D)` — Checks whether a dictionary is empty. +- `CREATE(n, {(ki, xi)})` — Given `n`, creates a dictionary from a list `(ki, xi)` of key-value pairs passed in stack. +- `GETSUBDICT(D, l, k0)` — Given `D : HashmapE(n, X)` and some `l`-bit string `k0 : l·bit` for `0 ≤ l ≤ n`, returns subdictionary `D′ = D/k0` of `D`, consisting of keys beginning with `k0`. The result `D′` may be of either type `HashmapE(n, X)` or type `HashmapE(n − l, X)`. +- `REPLACESUBDICT(D, l, k0, D0)` — Given `D : HashmapE(n, X)`, `0 ≤ l ≤ n`, `k0 : l · bit`, and `D0 : HashmapE(n − l, X)`, replaces with `D0` the subdictionary `D/k0` of `D` consisting of keys beginning with `k0`, and returns the resulting dictionary `D′′ : HashmapE(n, X)`. Some variants of `REPLACESUBDICT` may also return the old value of the subdictionary `D/k0` in question. +- `DELETESUBDICT(D, l, k0)` — Equivalent to `REPLACESUBDICT` with `D0` being an empty dictionary. +- `SPLIT(D)` — Given `D : HashmapE(n, X)`, returns `D0 := D/0` and `D1 := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with `0` and `1`, respectively. +- `MERGE(D0, D1)` — Given `D0` and `D1 : HashmapE(n − 1, X)`, computes `D : HashmapE(n, X)`, such that `D/0 = D0` and `D/1 = D1`. +- `FOREACH(D, f)` — Executes a function `f` with two arguments `k` and `x`, with `(k, x)` running over all key-value pairs of a dictionary `D` in lexicographical order.[18](#footnote-18) +- `FOREACHREV(D, f)` — Similar to `FOREACH`, but processes all key-value pairs in reverse order. +- `TREEREDUCE(D, o, f, g)` — Given `D : HashmapE(n, X)`, a value `o : X`, and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree reduction” of `D` by first applying `f` to all the leaves, and then using `g` to compute the value corresponding to a fork starting from the values assigned to its children.[19](#footnote-19) -* Which dictionary operation (cf. 3.3.10) do they perform? -* Are they specialized for the case `X = ^Y`? If so, do they represent values of type `Y` by `Cells` or by `Slices`? (Generic versions always represent - values of type `X` as `Slices`.) -* Are the dictionaries themselves passed and returned as `Cells` or as - `Slices`? (Most primitives represent dictionaries as `Slices`.) -* Is the key length `n` fixed inside the primitive, or is it passed in the - stack? -* Are the keys represented by `Slices`, or by signed or unsigned `Integer`s? +### 3.3.11 Taxonomy of dictionary primitives -In addition, TVM includes special serialization/deserialization primitives, -such as `STDICT`, `LDDICT`, and `PLDDICT`. They can be used to extract a dictionary from a serialization of an encompassing object, or to insert a dictionary -into such a serialization. +The dictionary primitives, described in detail in [A.10](#a-10), can be classified according to the following categories: ---- +* Which dictionary operation (cf. [3.3.10](#3-3-10-basic-dictionary-operations)) do they perform? +* Are they specialized for the case `X = ^Y`? If so, do they represent values of type `Y` by `Cell`s or by `Slice`s? (Generic versions always represent values of type `X` as `Slice`s.) +* Are the dictionaries themselves passed and returned as `Cell`s or as `Slice`s? (Most primitives represent dictionaries as `Slice`s.) +* Is the key length `n` fixed inside the primitive, or is it passed in the stack? +* Are the keys represented by `Slice`s, or by signed or unsigned `Integer`s? -Great — here’s **3.4 Hashmaps with variable-length keys** in Markdown, text unchanged and with inline code backticked where needed: +In addition, TVM includes special serialization/deserialization primitives, such as `STDICT`, `LDDICT`, and `PLDDICT`. They can be used to extract a dictionary from a serialization of an encompassing object, or to insert a dictionary into such a serialization. --- -### 3.4 Hashmaps with variable-length keys +## 3.4 Hashmaps with variable-length keys -TVM provides some support for dictionaries, or hashmaps, with variablelength keys, in addition to its support for dictionaries with fixed-length keys -(as described in 3.3 above). +TVM provides some support for dictionaries, or hashmaps, with variable-length keys, in addition to its support for dictionaries with fixed-length keys (as described in [3.3](#33-hashmaps-or-dictionaries)). -#### 3.4.1. Serialization of dictionaries with variable-length keys. +### 3.4.1. Serialization of dictionaries with variable-length keys -The -serialization of a `VarHashmap` into a tree of cells (or, more generally, into a -`Slice`) is defined by a TL-B scheme, similar to that described in 3.3.3: +The serialization of a `VarHashmap` into a tree of cells (or, more generally, into a `Slice`) is defined by a TL-B scheme, similar to that described in [3.3.3](#333-serialization-of-hashmaps): -``` +```tl-b vhm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(VarHashmapNode m X) = VarHashmap n X; @@ -1617,328 +902,223 @@ vhme_empty$0 {n:#} {X:Type} = VarHashmapE n X; vhme_root$1 {n:#} {X:Type} root:^(VarHashmap n X) = VarHashmapE n X; ``` +--- + +### 3.4.2. Serialization of prefix codes + +One special case of a dictionary with variable-length keys is that of a **prefix code**, where the keys cannot be prefixes of each other. Values in such dictionaries may occur only in the leaves of a Patricia tree. + +The serialization of a prefix code is defined by the following TL-B scheme: + +```tl-b +phm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) +{n = (~m) + l} node:(PfxHashmapNode m X) += PfxHashmap n X; + +phmn_leaf$0 {n:#} {X:Type} value:X = PfxHashmapNode n X; + +phmn_fork$1 {n:#} {X:Type} left:^(PfxHashmap n X) +right:^(PfxHashmap n X) = PfxHashmapNode (n + 1) X; + +phme_empty$0 {n:#} {X:Type} = PfxHashmapE n X; + +phme_root$1 {n:#} {X:Type} root:^(PfxHashmap n X) += PfxHashmapE n X; +``` +--- # 4 Control flow, continuations, and exceptions -This chapter describes continuations, which may represent execution tokens -and exception handlers in TVM. Continuations are deeply involved with the -control flow of a TVM program; in particular, subroutine calls and conditional and iterated execution are implemented in TVM using special primitives that accept one or more continuations as their arguments. -We conclude this chapter with a discussion of the problem of recursion -and of families of mutually recursive functions, exacerbated by the fact that -cyclic references are not allowed in TVM data structures (including TVM -code). +This chapter describes continuations, which may represent execution tokens and exception handlers in TVM. Continuations are deeply involved with the control flow of a TVM program; in particular, subroutine calls and conditional and iterated execution are implemented in TVM using special primitives that accept one or more continuations as their arguments. + +We conclude this chapter with a discussion of the problem of recursion and of families of mutually recursive functions, exacerbated by the fact that cyclic references are not allowed in TVM data structures (including TVM code). + +--- ## 4.1 Continuations and subroutines -Recall (cf.1.1.3) that `Continuation` values represent “execution tokens” that -can be executed later—for example, by `EXECUTE=CALLX` (“execute” or “call -indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations -are responsible for the execution of the program, and are heavily used by -control flow primitives, enabling subroutine calls, conditional expressions, -loops, and so on. - -### 4.1.1. Ordinary continuations. - -The most common kind of continuations -are the ordinary continuations, containing the following data: -• A `Slice` code (cf. 1.1.3 and 3.2.2), containing (the remainder of) the -TVM code to be executed. -• A (possibly empty) `Stack` stack, containing the original contents of -the stack for the code to be executed. -• A (possibly empty) list `save` of pairs (`c(i)`, `vi`) (also called “savelist”), -containing the values of control registers to be restored before the execution of the code. -• A 16-bit integer value `cp`, selecting the TVM codepage used to interpret -the TVM code from code. -• An optional non-negative integer `nargs`, indicating the number of arguments expected by the continuation. - -### 4.1.2. Simple ordinary continuations. - -In most cases, the ordinary continuations are the simplest ones, having empty stack and `save`. They consist -essentially of a reference `code` to (the remainder of) the code to be executed, -and of the codepage `cp` to be used while decoding the instructions from this -code. - -### 4.1.3. Current continuation `cc`. - -The “current continuation” `cc` is an important part of the total state of TVM, representing the code being executed -right now (cf. 1.1). In particular, what we call “the current stack” (or simply -“the stack”) when discussing all other primitives is in fact the stack of the -current continuation. All other components of the total state of TVM may -be also thought of as parts of the current continuation `cc`; however, they -may be extracted from the current continuation and kept separately as part -of the total state for performance reasons. This is why we describe the stack, -the control registers, and the codepage as separate parts of the TVM state -in 1.4. - -### 4.1.4. Normal work of TVM, or the main loop. - -TVM usually performs -the following operations: -If the current continuation `cc` is an ordinary one, it decodes the first -instruction from the `Slice` `code`, similarly to the way other cells are deserialized by TVM `LD*` primitives (cf. 3.2 and 3.2.11): it decodes the opcode -first, and then the parameters of the instruction (e.g., 4-bit fields indicating -“stack registers” involved for stack manipulation primitives, or constant values for “push constant” or “literal” primitives). The remainder of the `Slice` -is then put into the `code` of the new `cc`, and the decoded operation is executed on the current stack. This entire process is repeated until there are no -operations left in `cc.code`. -If the code is empty (i.e., contains no bits of data and no references), or if -a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, -the current continuation is discarded, and the “return continuation” from -control register `c0` is loaded into `cc` instead (this process is discussed in -more detail starting in 4.1.6).20 Then the execution continues by parsing -operations from the new current continuation. - -### 4.1.5. Extraordinary continuations. - -In addition to the ordinary continuations considered so far (cf. 4.1.1), TVM includes some extraordinary continuations, representing certain less common states. Examples of extraordinary -continuations include: -• The continuation `ec_quit` with its parameter set to zero, which represents the end of the work of TVM. This continuation is the original -value of `c0` when TVM begins executing the code of a smart contract. -• The continuation `ec_until`, which contains references to two other -continuations (ordinary or not) representing the body of the loop being -executed and the code to be executed after the loop. -Execution of an extraordinary continuation by TVM depends on its specific -class, and differs from the operations for ordinary continuations described in -4.1.4. -21 - -### 4.1.6. Switching to another continuation: `JMP` and `RET`. - -The process of -switching to another continuation `c` may be performed by such instructions -as `JMPX` (which takes `c` from the stack) or `RET` (which uses `c0` as `c`). This -process is slightly more complex than simply setting the value of `cc` to `c`: -before doing this, either all values or the top `n` values in the current stack -are moved to the stack of the continuation `c`, and only then is the remainder -of the current stack discarded. -If all values need to be moved (the most common case), and if the continuation `c` has an empty stack (also the most common case; notice that -extraordinary continuations are assumed to have an empty stack), then the -new stack of `c` equals the stack of the current continuation, so we can simply -transfer the current stack in its entirety to `c`. (If we keep the current stack -as a separate part of the total state of TVM, we have to do nothing at all.) - -### 4.1.7. Determining the number `n` of arguments passed to the next continuation `c`. - -By default, `n` equals the depth of the current stack. However, if `c` has an explicit value of `nargs` (number of arguments to be provided), -then `n` is computed as `n0`, equal to `c.nargs` minus the current depth of `c`’s -stack. -Furthermore, there are special forms of `JMPX` and `RET` that provide an -explicit value `n00`, the number of parameters from the current stack to be -passed to continuation `c`. If `n00` is provided, it must be less than or equal to -the depth of the current stack, or else a stack underflow exception occurs. If -both `n0` and `n00` are provided, we must have `n0 ≤ n00`, in which case `n = n0` is -used. If `n00` is provided and `n0` -is not, then `n = n00` is used. -One could also imagine that the default value of `n00` equals the depth of -the original stack, and that `n00` values are always removed from the top of -the original stack even if only `n0` of them are actually moved to the stack of -the next continuation `c`. Even though the remainder of the current stack is -discarded afterwards, this description will become useful later. - -### 4.1.8. Restoring control registers from the new continuation `c`. - -After -the new stack is computed, the values of control registers present in `c.save` -are restored accordingly, and the current codepage `cp` is also set to `c.cp`. -Only then does TVM set `cc` equal to the new `c` and begin its execution.22 - -### 4.1.9. Subroutine calls: `CALLX` or `EXECUTE` primitives. - -The execution -of continuations as subroutines is slightly more complicated than switching -to continuations. -Consider the `CALLX` or `EXECUTE` primitive, which takes a continuation `c` -from the (current) stack and executes it as a subroutine. -Apart from doing the stack manipulations described in 4.1.6 and 4.1.7 -and setting the new control registers and codepage as described in 4.1.8, -these primitives perform several additional steps: - -1. After the top `n00` values are removed from the current stack (cf. 4.1.7), - the (usually empty) remainder is not discarded, but instead is stored - in the (old) current continuation `cc`. -2. The old value of the special register `c0` is saved into the (previously - empty) savelist `cc.save`. -3. The continuation `cc` thus modified is not discarded, but instead is set - as the new `c0`, which performs the role of “next continuation” or “return - continuation” for the subroutine being called. -4. After that, the switching to `c` continues as before. In particular, some - control registers are restored from `c.save`, potentially overwriting the - value of `c0` set in the previous step. (Therefore, a good optimization - would be to check that `c0` is present in `c.save` from the very beginning, - and skip the three previous steps as useless in this case.) - In this way, the called subroutine can return control to the caller by - switching the current continuation to the return continuation saved in `c0`. - Nested subroutine calls work correctly because the previous value of `c0` ends - up saved into the new `c0`’s control register savelist `c0.save`, from which it is - restored later. - -### 4.1.10. Determining the number of arguments passed to and/or return values accepted from a subroutine. - -Similarly to `JMPX` and `RET`, -`CALLX` also has special (rarely used) forms, which allow us to explicitly specify -the number `n00` of arguments passed from the current stack to the called -subroutine (by default, `n00` equals the depth of the current stack, i.e., it is -passed in its entirety). Furthermore, a second number `n000` can be specified, -used to set `nargs` of the modified `cc` continuation before storing it into the -new `c0`; the new `nargs` equals the depth of the old stack minus `n00` plus `n000`. -This means that the caller is willing to pass exactly `n00` arguments to the -called subroutine, and is willing to accept exactly `n000` results in their stead. -Such forms of `CALLX` and `RET` are mostly intended for library functions -that accept functional arguments and want to invoke them safely. Another -application is related to the “virtualization support” of TVM, which enables -TVM code to run other TVM code inside a “virtual TVM machine”. Such -virtualization techniques might be useful for implementing sophisticated payment channels in the TON Blockchain (cf. \[1, 5]). - -### 4.1.11. `CALLCC`: call with current continuation. - -Notice that TVM supports a form of the “call with current continuation” primitive. Namely, primitive `CALLCC` is similar to `CALLX` or `JMPX` in that it takes a continuation `c` from -the stack and switches to it; however, `CALLCC` does not discard the previous -current continuation `c0` -(as `JMPX` does) and does not write `c0` -to `c0` (as `CALLX` -does), but rather pushes `c0` -into the (new) stack as an extra argument to `c`. -The primitive `JMPXDATA` does a similar thing, but pushes only the (remainder -of the) code of the previous current continuation as a `Slice`. - -## 4.2 Control flow primitives: conditional and iterated - -execution - -### 4.2.1. Conditional execution: `IF`, `IFNOT`, `IFELSE`. - -An important modification of `EXECUTE` (or `CALLX`) consists in its conditional forms. For example, -`IF` accepts an integer `x` and a continuation `c`, and executes `c` (in the same -way as `EXECUTE` would do it) only if `x` is non-zero; otherwise both values -are simply discarded from the stack. Similarly, `IFNOT` accepts `x` and `c`, but -executes `c` only if `x = 0`. Finally, `IFELSE` accepts `x`, `c`, and `c0`, removes these -values from the stack, and executes `c` if `x 6= 0` or `c0` if `x = 0`. - -### 4.2.2. Iterated execution and loops. - -More sophisticated modifications -of `EXECUTE` include: -• `REPEAT` — Takes an integer `n` and a continuation `c`, and executes `c` `n` -times.23 -• `WHILE` — Takes `c0` and `c00`, executes `c0`, and then takes the top value `x` -from the stack. If `x` is non-zero, it executes `c00` and then begins a new -loop by executing `c0` again; if `x` is zero, it stops. -• `UNTIL` — Takes `c`, executes it, and then takes the top integer `x` from -the stack. If `x` is zero, a new iteration begins; if `x` is non-zero, the -previously executed code is resumed. - -### 4.2.3. Constant, or literal, continuations. - -We see that we can create -arbitrarily complex conditional expressions and loops in the TVM code, provided we have a means to push constant continuations into the stack. In fact, -TVM includes special versions of “literal” or “constant” primitives that cut -the next `n` bytes or bits from the remainder of the current code `cc.code` into -a cell slice, and then push it into the stack not as a `Slice` (as a `PUSHSLICE` -does) but as a simple ordinary `Continuation` (which has only `code` and `cp`). -The simplest of these primitives is `PUSHCONT`, which has an immediate -argument `n` describing the number of subsequent bytes (in a byte-oriented -version of TVM) or bits to be converted into a simple continuation. Another -primitive is `PUSHREFCONT`, which removes the first cell reference from the -current continuation `cc.code`, converts the cell referred to into a cell slice, -and finally converts the cell slice into a simple continuation. - -### 4.2.4. Constant continuations combined with conditional or iterated execution primitives. - -Because constant continuations are very often -used as arguments to conditional or iterated execution primitives, combined -versions of these primitives (e.g., `IFCONT` or `UNTILREFCONT`) may be defined -in a future revision of TVM, which combine a `PUSHCONT` or `PUSHREFCONT` -with another primitive. If one inspects the resulting code, `IFCONT` looks very -much like the more customary “conditional-branch-forward” instruction. +Recall (cf. [1.1.3](#113-preliminary-list-of-value-types)) that Continuation values represent “execution tokens” that can be executed later—for example, by `EXECUTE` = `CALLX` (“execute” or “call indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations are responsible for the execution of the program, and are heavily used by control flow primitives, enabling subroutine calls, conditional expressions, loops, and so on. -## 4.3 Operations with continuations +### 4.1.1 Ordinary continuations + +The most common kind of continuations are the ordinary continuations, containing the following data: + +* A Slice `code` (cf. [1.1.3](#113-preliminary-list-of-value-types) and [3.2.2](#322-builder-and-slice-values)), containing (the remainder of) the TVM code to be executed. +* A (possibly empty) Stack `stack`, containing the original contents of the stack for the code to be executed. +* A (possibly empty) list `save` of pairs `(c(i), vi)` (also called “savelist”), containing the values of control registers to be restored before the execution of the code. +* A 16-bit integer value `cp`, selecting the TVM codepage used to interpret the TVM code from `code`. +* An optional non-negative integer `nargs`, indicating the number of arguments expected by the continuation. + +### 4.1.2 Simple ordinary continuations + +In most cases, the ordinary continuations are the simplest ones, having empty `stack` and `save`. They consist essentially of a reference `code` to (the remainder of) the code to be executed, and of the codepage `cp` to be used while decoding the instructions from this code. + +### 4.1.3 Current continuation cc + +The “current continuation” `cc` is an important part of the total state of TVM, representing the code being executed right now (cf. [1.1](#1-1-tvm-is-a-stack-machine)). In particular, what we call “the current stack” (or simply “the stack”) when discussing all other primitives is in fact the stack of the current continuation. All other components of the total state of TVM may be also thought of as parts of the current continuation `cc`; however, they may be extracted from the current continuation and kept separately as part of the total state for performance reasons. This is why we describe the stack, the control registers, and the codepage as separate parts of the TVM state in [1.4](#14-total-state-of-tvm-scccg). + +### 4.1.4 Normal work of TVM, or the main loop + +TVM usually performs the following operations: + +If the current continuation `cc` is an ordinary one, it decodes the first instruction from the Slice `code`, similarly to the way other cells are deserialized by TVM `LD*` primitives (cf. [3.2](#3-2-data-manipulation-instructions-and-cells) and [3.2.11](#3-2-11-taxonomy-of-cell-deserialisation-primitives)): it decodes the opcode first, and then the parameters of the instruction (e.g., 4-bit fields indicating “stack registers” involved for stack manipulation primitives, or constant values for “push constant” or “literal” primitives). The remainder of the Slice is then put into the code of the new `cc`, and the decoded operation is executed on the current stack. This entire process is repeated until there are no operations left in `cc.code`. + +If the code is empty (i.e., contains no bits of data and no references), or if a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, the current continuation is discarded, and the “return continuation” from control register `c0` is loaded into `cc` instead (this process is discussed in more detail starting in [4.1.6](#416-switching-to-another-continuation-jmp-and-ret)).[20](#footnote-20) Then the execution continues by parsing operations from the new current continuation. + +### 4.1.5 Extraordinary continuations + +In addition to the ordinary continuations considered so far (cf. [4.1.1](#4-1-1-ordinary-continuations)), TVM includes some extraordinary continuations, representing certain less common states. Examples of extraordinary continuations include: + +* The continuation `ec_quit` with its parameter set to zero, which represents the end of the work of TVM. This continuation is the original value of `c0` when TVM begins executing the code of a smart contract. +* The continuation `ec_until`, which contains references to two other continuations (ordinary or not) representing the body of the loop being executed and the code to be executed after the loop. + +Execution of an extraordinary continuation by TVM depends on its specific class, and differs from the operations for ordinary continuations described in [4.1.4](#4-1-4-normal-work-of-tvm-or-the-main-loop).[21](#footnote-21) -### 4.3.1. Continuations are opaque. - -Notice that all continuations are opaque, -at least in the current version of TVM, meaning that there is no way to -modify a continuation or inspect its internal data. Almost the only use of a -continuation is to supply it to a control flow primitive. -While there are some arguments in favor of including support for nonopaque continuations in TVM (along with opaque continuations, which are -required for virtualization), the current revision offers no such support. - -### 4.3.2. Allowed operations with continuations. - -However, some operations with opaque continuations are still possible, mostly because they are -equivalent to operations of the kind “create a new continuation, which will -do something special, and then invoke the original continuation”. Allowed -operations with continuations include: -• Push one or several values into the stack of a continuation `c` (thus -creating a partial application of a function, or a closure). -• Set the saved value of a control register `c(i)` inside the savelist `c.save` -of a continuation `c`. If there is already a value for the control register -in question, this operation silently does nothing. - -### 4.3.3. Example: operations with control registers. - -TVM has some -primitives to set and inspect the values of control registers. The most important of them are `PUSH c(i)` (pushes the current value of `c(i)` into the stack) -and `POP c(i)` (sets the value of `c(i)` from the stack, if the supplied value is -of the correct type). However, there is also a modified version of the latter -instruction, called `POPSAVE c(i)`, which saves the old value of `c(i)` (for `i > 0`) -into the continuation at `c0` as described in 4.3.2 before setting the new value. - -### 4.3.4. Example: setting the number of arguments to a function in its code. - -The primitive `LEAVEARGS n` demonstrates another application of -continuations in an operation: it leaves only the top `n` values of the current stack, and moves the remainder to the stack of the continuation in `c0`. -This primitive enables a called function to “return” unneeded arguments to -its caller’s stack, which is useful in some situations (e.g., those related to -exception handling). - -### 4.3.5. Boolean circuits. - -A continuation `c` may be thought of as a piece -of code with two optional exit points kept in the savelist of `c`: the principal -exit point given by `c.c0 := c.save(c0)`, and the auxiliary exit point given -by `c.c1 := c.save(c1)`. If executed, a continuation performs whatever action -it was created for, and then (usually) transfers control to the principal exit -point, or, on some occasions, to the auxiliary exit point. We sometimes say -that a continuation `c` with both exit points `c.c0` and `c.c1` defined is a two-exit -continuation, or a boolean circuit, especially if the choice of the exit point -depends on some internally-checked condition. - -### 4.3.6. Composition of continuations. - -One can compose two continuations `c` and `c0` simply by setting `c.c0` or `c.c1` to `c0`. This creates a new -continuation denoted by `c ◦0 c0` or `c ◦1 c0`, which differs from `c` in its savelist. -(Recall that if the savelist of `c` already has an entry corresponding to the control register in question, such an operation silently does nothing as explained -in 4.3.2). -By composing continuations, one can build chains or other graphs, possibly with loops, representing the control flow. In fact, the resulting graph -resembles a flow chart, with the boolean circuits corresponding to the “condition nodes” (containing code that will transfer control either to `c0` or to `c1` -depending on some condition), and the one-exit continuations corresponding -to the “action nodes”. - -### 4.3.7. Basic continuation composition primitives. - -Two basic primitives for composing continuations are `COMPOS` (also known as `SETCONT c0` and -`BOOLAND`) and `COMPOSALT` (also known as `SETCONT c1` and `BOOLOR`), which -take `c` and `c0` from the stack, set `c.c0` or `c.c1` to `c0`, and return the resulting continuation `c00 = c ◦0 c0` or `c ◦1 c0`. All other continuation composition -operations can be expressed in terms of these two primitives. +### 4.1.6 Switching to another continuation: JMP and RET + +The process of switching to another continuation `c` may be performed by such instructions as `JMPX` (which takes `c` from the stack) or `RET` (which uses `c0` as `c`). This process is slightly more complex than simply setting the value of `cc` to `c`: before doing this, either all values or the top `n` values in the current stack are moved to the stack of the continuation `c`, and only then is the remainder of the current stack discarded. + +If all values need to be moved (the most common case), and if the continuation `c` has an empty stack (also the most common case; notice that extraordinary continuations are assumed to have an empty stack), then the new stack of `c` equals the stack of the current continuation, so we can simply transfer the current stack in its entirety to `c`. (If we keep the current stack as a separate part of the total state of TVM, we have to do nothing at all.) + +### 4.1.7 Determining the number n of arguments passed to the next continuation c + +By default, `n` equals the depth of the current stack. However, if `c` has an explicit value of `nargs` (number of arguments to be provided), then `n` is computed as `n'`, equal to `c.nargs` minus the current depth of `c`’s stack. + +Furthermore, there are special forms of `JMPX` and `RET` that provide an explicit value `n''`, the number of parameters from the current stack to be passed to continuation `c`. If `n''` is provided, it must be less than or equal to the depth of the current stack, or else a stack underflow exception occurs. If both `n'` and `n''` are provided, we must have `n' ≤ n''`, in which case `n = n'` is used. If `n''` is provided and `n'` is not, then `n = n''` is used. + +One could also imagine that the default value of `n''` equals the depth of the original stack, and that `n''` values are always removed from the top of the original stack even if only `n'` of them are actually moved to the stack of the next continuation `c`. Even though the remainder of the current stack is discarded afterwards, this description will become useful later. + +### 4.1.8 Restoring control registers from the new continuation c + +After the new stack is computed, the values of control registers present in `c.save` are restored accordingly, and the current codepage `cp` is also set to `c.cp`. Only then does TVM set `cc` equal to the new `c` and begin its execution.[22](#footnote-22) + +### 4.1.9 Subroutine calls: CALLX or EXECUTE primitives + +The execution of continuations as subroutines is slightly more complicated than switching to continuations. + +Consider the `CALLX` or `EXECUTE` primitive, which takes a continuation `c` from the (current) stack and executes it as a subroutine. + +Apart from doing the stack manipulations described in [4.1.6](#4-1-6-switching-to-another-continuation-jmp-and-ret) and [4.1.7](#417-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c) and setting the new control registers and codepage as described in [4.1.8](#4-1-8-restoring-control-registers-from-the-new-continuation-c), these primitives perform several additional steps: + +1. After the top `n''` values are removed from the current stack (cf. [4.1.7](#4-1-7-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c)), the (usually empty) remainder is not discarded, but instead is stored in the (old) current continuation `cc`. +2. The old value of the special register `c0` is saved into the (previously empty) savelist `cc.save`. +3. The continuation `cc` thus modified is not discarded, but instead is set as the new `c0`, which performs the role of “next continuation” or “return continuation” for the subroutine being called. +4. After that, the switching to `c` continues as before. In particular, some control registers are restored from `c.save`, potentially overwriting the value of `c0` set in the previous step. (Therefore, a good optimization would be to check that `c0` is present in `c.save` from the very beginning, and skip the three previous steps as useless in this case.) + +In this way, the called subroutine can return control to the caller by switching the current continuation to the return continuation saved in `c0`. Nested subroutine calls work correctly because the previous value of `c0` ends up saved into the new `c0`’s control register savelist `c0.save`, from which it is restored later. + +### 4.1.10 Determining the number of arguments passed to and/or return values accepted from a subroutine + +Similarly to `JMPX` and `RET`, `CALLX` also has special (rarely used) forms, which allow us to explicitly specify the number `n''` of arguments passed from the current stack to the called subroutine (by default, `n''` equals the depth of the current stack, i.e., it is passed in its entirety). Furthermore, a second number `n'''` can be specified, used to set `nargs` of the modified `cc` continuation before storing it into the new `c0`; the new `nargs` equals the depth of the old stack minus `n''` plus `n'''`. + +This means that the caller is willing to pass exactly `n''` arguments to the called subroutine, and is willing to accept exactly `n'''` results in their stead. + +Such forms of `CALLX` and `RET` are mostly intended for library functions that accept functional arguments and want to invoke them safely. Another application is related to the “virtualization support” of TVM, which enables TVM code to run other TVM code inside a “virtual TVM machine”. Such virtualization techniques might be useful for implementing sophisticated payment channels in the TON Blockchain (cf. [1, 5](#reference-1)). + +### 4.1.11 CALLCC: call with current continuation + +Notice that TVM supports a form of the “call with current continuation” primitive. Namely, primitive `CALLCC` is similar to `CALLX` or `JMPX` in that it takes a continuation `c` from the stack and switches to it; however, `CALLCC` does not discard the previous current continuation `c'` (as `JMPX` does) and does not write `c'` to `c0` (as `CALLX` does), but rather pushes `c'` into the (new) stack as an extra argument to `c`. + +The primitive `JMPXDATA` does a similar thing, but pushes only the (remainder of the) code of the previous current continuation as a Slice. --- -### 4.3.8. Advanced continuation composition primitives. +## 4.2 Control flow primitives: conditional and iterated execution + +### 4.2.1 Conditional execution: IF, IFNOT, IFELSE + +An important modification of `EXECUTE` (or `CALLX`) consists in its conditional forms. For example, `IF` accepts an integer `x` and a continuation `c`, and executes `c` (in the same way as `EXECUTE` would do it) only if `x` is non-zero; otherwise both values are simply discarded from the stack. Similarly, `IFNOT` accepts `x` and `c`, but executes `c` only if `x = 0`. Finally, `IFELSE` accepts `x`, `c`, and `c'`, removes these values from the stack, and executes `c` if `x ≠ 0` or `c'` if `x = 0`. + +### 4.2.2 Iterated execution and loops + +More sophisticated modifications of `EXECUTE` include: + +* **REPEAT** — Takes an integer `n` and a continuation `c`, and executes `c` `n` times.[23](#footnote-23) +* **WHILE** — Takes `c'` and `c''`, executes `c'`, and then takes the top value `x` from the stack. If `x` is non-zero, it executes `c''` and then begins a new loop by executing `c'` again; if `x` is zero, it stops. +* **UNTIL** — Takes `c`, executes it, and then takes the top integer `x` from the stack. If `x` is zero, a new iteration begins; if `x` is non-zero, the previously executed code is resumed. + +### 4.2.3 Constant, or literal, continuations + +We see that we can create arbitrarily complex conditional expressions and loops in the TVM code, provided we have a means to push constant continuations into the stack. In fact, TVM includes special versions of “literal” or “constant” primitives that cut the next `n` bytes or bits from the remainder of the current code `cc.code` into a cell slice, and then push it into the stack not as a Slice (as a `PUSHSLICE` does) but as a simple ordinary Continuation (which has only `code` and `cp`). + +The simplest of these primitives is `PUSHCONT`, which has an immediate argument `n` describing the number of subsequent bytes (in a byte-oriented version of TVM) or bits to be converted into a simple continuation. Another primitive is `PUSHREFCONT`, which removes the first cell reference from the current continuation `cc.code`, converts the cell referred to into a cell slice, and finally converts the cell slice into a simple continuation. + +### 4.2.4 Constant continuations combined with conditional or iterated execution primitives + +Because constant continuations are very often used as arguments to conditional or iterated execution primitives, combined versions of these primitives (e.g., `IFCONT` or `UNTILREFCONT`) may be defined in a future revision of TVM, which combine a `PUSHCONT` or `PUSHREFCONT` with another primitive. If one inspects the resulting code, `IFCONT` looks very much like the more customary “conditional-branch-forward” instruction. + +--- + +# 4 Control flow, continuations, and exceptions + +## 4.3 Operations with continuations + +### 4.3.1 Continuations are opaque + +Notice that all continuations are opaque, at least in the current version of TVM, meaning that there is no way to modify a continuation or inspect its internal data. Almost the only use of a continuation is to supply it to a control flow primitive. + +While there are some arguments in favor of including support for non-opaque continuations in TVM (along with opaque continuations, which are required for virtualization), the current revision offers no such support. + +### 4.3.2 Allowed operations with continuations + +However, some operations with opaque continuations are still possible, mostly because they are equivalent to operations of the kind “create a new continuation, which will do something special, and then invoke the original continuation”. Allowed operations with continuations include: + +* Push one or several values into the stack of a continuation `c` (thus creating a partial application of a function, or a closure). +* Set the saved value of a control register `c(i)` inside the savelist `c.save` of a continuation `c`. If there is already a value for the control register in question, this operation silently does nothing. + +### 4.3.3 Example: operations with control registers + +TVM has some primitives to set and inspect the values of control registers. The most important of them are `PUSH c(i)` (pushes the current value of `c(i)` into the stack) and `POP c(i)` (sets the value of `c(i)` from the stack, if the supplied value is of the correct type). However, there is also a modified version of the latter instruction, called `POPSAVE c(i)`, which saves the old value of `c(i)` (for i > 0) into the continuation at `c0` as described in [4.3.2](#4-3-2-allowed-operations-with-continuations) before setting the new value. + +### 4.3.4 Example: setting the number of arguments to a function in its code + +The primitive `LEAVEARGS n` demonstrates another application of continuations in an operation: it leaves only the top `n` values of the current stack, and moves the remainder to the stack of the continuation in `c0`. + +This primitive enables a called function to “return” unneeded arguments to its caller’s stack, which is useful in some situations (e.g., those related to exception handling). + +### 4.3.5 Boolean circuits + +A continuation `c` may be thought of as a piece of code with two optional exit points kept in the savelist of `c`: + +* the principal exit point given by `c.c0 := c.save(c0)` +* the auxiliary exit point given by `c.c1 := c.save(c1)` + +If executed, a continuation performs whatever action it was created for, and then (usually) transfers control to the principal exit point, or, on some occasions, to the auxiliary exit point. + +We sometimes say that a continuation `c` with both exit points `c.c0` and `c.c1` defined is a two-exit continuation, or a boolean circuit, especially if the choice of the exit point depends on some internally-checked condition. + +### 4.3.6 Composition of continuations + +One can compose two continuations `c` and `c'` simply by setting `c.c0` or `c.c1` to `c'`. This creates a new continuation denoted by `c ◦0 c'` or `c ◦1 c'`, which differs from `c` in its savelist. (Recall that if the savelist of `c` already has an entry corresponding to the control register in question, such an operation silently does nothing as explained in [4.3.2](#4-3-2-allowed-operations-with-continuations)). + +By composing continuations, one can build chains or other graphs, possibly with loops, representing the control flow. In fact, the resulting graph resembles a flow chart, with the boolean circuits corresponding to the “condition nodes” (containing code that will transfer control either to `c0` or to `c1` depending on some condition), and the one-exit continuations corresponding to the “action nodes”. + +### 4.3.7 Basic continuation composition primitives + +Two basic primitives for composing continuations are `COMPOS` (also known as `SETCONT c0` and `BOOLAND`) and `COMPOSALT` (also known as `SETCONT c1` and `BOOLOR`), which take `c` and `c'` from the stack, set `c.c0` or `c.c1` to `c'`, and return the resulting continuation `c'' = c ◦0 c'` or `c ◦1 c'`. All other continuation composition operations can be expressed in terms of these two primitives. + +### 4.3.8 Advanced continuation composition primitives However, TVM can compose continuations not only taken from stack, but also taken from `c0` or `c1`, or from the current continuation `cc`; likewise, the result may be pushed into the stack, stored into either `c0` or `c1`, or used as the new current continuation (i.e., the control may be transferred to it). Furthermore, TVM can define conditional composition primitives, performing some of the above actions only if an integer value taken from the stack is non-zero. -For instance, `EXECUTE` can be described as `cc ← c ◦0 cc`, with continuation `c` taken from the original stack. Similarly, `JMPX` is `cc ← c`, and `RET` (also known as `RETTRUE` in a boolean circuit context) is `cc ← c0`. Other interesting primitives include `THENRET` (`c0 ← c ◦0 c0`) and `ATEXIT` (`c0 ← c ◦0 c0`). +For instance: -Finally, some “experimental” primitives also involve `c1` and `◦1`. For example: +* `EXECUTE` can be described as `cc ← c ◦0 cc`, with continuation `c` taken from the original stack. +* `JMPX` is `cc ← c`. +* `RET` (also known as `RETTRUE` in a boolean circuit context) is `cc ← c0`. +* Other interesting primitives include `THENRET (c0 ← c ◦0 c0)` and `ATEXIT (c0 ← c ◦0 c0)`. + +Some “experimental” primitives also involve `c1` and `◦1`. For example: * `RETALT` or `RETFALSE` does `cc ← c1`. -* Conditional versions of `RET` and `RETALT` may also be useful: `RETBOOL` takes an integer `x` from the stack, and performs `RETTRUE` if `x 6= 0`, `RETFALSE` otherwise. +* Conditional versions of `RET` and `RETALT` may also be useful: `RETBOOL` takes an integer `x` from the stack, and performs `RETTRUE` if `x ≠ 0`, `RETFALSE` otherwise. * `INVERT` does `c0 ↔ c1`; if the two continuations in `c0` and `c1` represent the two branches we should select depending on some boolean expression, `INVERT` negates this expression on the outer level. * `INVERTCONT` does `c.c0 ↔ c.c1` to a continuation `c` taken from the stack. -* Variants of `ATEXIT` include `ATEXITALT` (`c1 ← c ◦1 c1`) and `SETEXITALT` (`c1 ← (c ◦0 c0) ◦1 c1`). +* Variants of `ATEXIT` include `ATEXITALT (c1 ← c ◦1 c1)` and `SETEXITALT (c1 ← (c ◦0 c0) ◦1 c1)`. * `BOOLEVAL` takes a continuation `c` from the stack and does: ``` - cc ← ((c ◦0 (PUSH − 1)) ◦1 (PUSH0)) ◦0 cc + cc ← (c ◦0 (PUSH −1)) ◦1 (PUSH0) ◦0 cc ``` If `c` represents a boolean circuit, the net effect is to evaluate it and push either `−1` or `0` into the stack before continuing. @@ -1947,175 +1127,97 @@ Finally, some “experimental” primitives also involve `c1` and `◦1`. For ex ## 4.4 Continuations as objects -### 4.4.1. Representing objects using continuations. - -Object-oriented programming in Smalltalk (or Objective C) style may be implemented with the -aid of continuations. For this, an object is represented by a special continuation `o`. If it has any data fields, they can be kept in the stack of `o`, making -`o` a partial application (i.e., a continuation with a non-empty stack). -When somebody wants to invoke a method `m` of `o` with arguments `x1, x2, -. . . , xn`, she pushes the arguments into the stack, then pushes a magic number -corresponding to the method `m`, and then executes `o` passing `n+1` arguments -(cf. 4.1.10). Then `o` uses the top-of-stack integer `m` to select the branch with -5 - -### 4.5. Exception handling - -the required method, and executes it. If `o` needs to modify its state, it simply -computes a new continuation `o0` of the same sort (perhaps with the same code -as `o`, but with a different initial stack). The new continuation `o0` -is returned -to the caller along with whatever other return values need to be returned. - -### 4.4.2. Serializable objects. - -Another way of representing Smalltalk-style -objects as continuations, or even as trees of cells, consists in using the -`JMPREFDATA` primitive (a variant of `JMPXDATA`, cf. 4.1.11), which takes the -first cell reference from the code of the current continuation, transforms the -cell referred to into a simple ordinary continuation, and transfers control to -it, first pushing the remainder of the current continuation as a `Slice` into the -stack. In this way, an object might be represented by a cell `o˜` that contains -`JMPREFDATA` at the beginning of its data, and the actual code of the object -in the first reference (one might say that the first reference of cell `o˜` is the -class of object `o˜`). Remaining data and references of this cell will be used for -storing the fields of the object. -Such objects have the advantage of being trees of cells, and not just -continuations, meaning that they can be stored into the persistent storage of -a TON smart contract. - -### 4.4.3. Unique continuations and capabilities. - -It might make sense (in -a future revision of TVM) to mark some continuations as unique, meaning -that they cannot be copied, even in a delayed manner, by increasing their -reference counter to a value greater than one. If an opaque continuation is -unique, it essentially becomes a capability, which can either be used by its -owner exactly once or be transferred to somebody else. -For example, imagine a continuation that represents the output stream to -a printer (this is an example of a continuation used as an object, cf. 4.4.1). -When invoked with one integer argument `n`, this continuation outputs the -character with code `n` to the printer, and returns a new continuation of -the same kind reflecting the new state of the stream. Obviously, copying -such a continuation and using the two copies in parallel would lead to some -unintended side effects; marking it as unique would prohibit such adverse -usage. - -## 4.5 Exception handling - -TVM’s exception handling is quite simple and consists in a transfer of control -to the continuation kept in control register `c2`. - -### 4.5.1. Two arguments of the exception handler: exception parameter and exception number. - -Every exception is characterized by two -arguments: the exception number (an `Integer`) and the exception parameter -(any value, most often a zero `Integer`). Exception numbers 0–31 are reserved -for TVM, while all other exception numbers are available for user-defined -exceptions. - -### 4.5.2. Primitives for throwing an exception. - -There are several special primitives used for throwing an exception. The most general of them, -`THROWANY`, takes two arguments, `v` and `0 ≤ n < 2^16`, from the stack, and -throws the exception with number `n` and value `v`. There are variants of -this primitive that assume `v` to be a zero integer, store `n` as a literal value, -and/or are conditional on an integer value taken from the stack. User-defined -exceptions may use arbitrary values as `v` (e.g., trees of cells) if needed. - -### 4.5.3. Exceptions generated by TVM. - -Of course, some exceptions are -generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit -into a signed 257-bit integer. In such cases, the arguments of the exception, -`v` and `n`, are determined by TVM itself. - -### 4.5.4. Exception handling. - -The exception handling itself consists in a -control transfer to the exception handler—i.e., the continuation specified in -control register `c2`, with `v` and `n` supplied as the two arguments to this -continuation, as if a `JMP` to `c2` had been requested with `n00 = 2` arguments -(cf. 4.1.7 and 4.1.6). As a consequence, `v` and `n` end up in the top of the -stack of the exception handler. The remainder of the old stack is discarded. -Notice that if the continuation in `c2` has a value for `c2` in its savelist, it -will be used to set up the new value of `c2` before executing the exception -handler. In particular, if the exception handler invokes `THROWANY`, it will rethrow the original exception with the restored value of `c2`. This trick enables -the exception handler to handle only some exceptions, and pass the rest to -an outer exception handler. - -### 4.5.5. Default exception handler. - -When an instance of TVM is created, -`c2` contains a reference to the “default exception handler continuation”, which -is an `ec_fatal` extraordinary continuation (cf. 4.1.5). Its execution leads -to the termination of the execution of TVM, with the arguments `v` and `n` -of the exception returned to the outside caller. In the context of the TON -Blockchain, `n` will be stored as a part of the transaction’s result. -59 - -### 4.5.6. `TRY` primitive. - -A `TRY` primitive can be used to implement C++-like -exception handling. This primitive accepts two continuations, `c` and `c0`. It -stores the old value of `c2` into the savelist of `c0`, sets `c2` to `c0`, and executes `c` -just as `EXECUTE` would, but additionally saving the old value of `c2` into the -savelist of the new `c0` as well. Usually a version of the `TRY` primitive with an -explicit number of arguments `n00` passed to the continuation `c` is used. -The net result is roughly equivalent to C++’s `try { c } catch(...) { c0 }` operator. +### 4.4.1 Representing objects using continuations -### 4.5.7. List of predefined exceptions +Object-oriented programming in Smalltalk (or Objective C) style may be implemented with the aid of continuations. For this, an object is represented by a special continuation `o`. If it has any data fields, they can be kept in the stack of `o`, making `o` a partial application (i.e., a continuation with a non-empty stack). -Predefined exceptions of TVM correspond to exception numbers `n` in the range `0–31`. They include: +When somebody wants to invoke a method `m` of `o` with arguments `x1, x2, …, xn`, she pushes the arguments into the stack, then pushes a magic number corresponding to the method `m`, and then executes `o` passing `n+1` arguments (cf. [4.1.10](#4-1-10-determining-the-number-of-arguments-passed-to-andor-return-values-accepted-from-a-subroutine)). Then `o` uses the top-of-stack integer `m` to select the branch with the required method, and executes it. -* **Normal termination (`n = 0`)** — Should never be generated, but it is useful for some tricks. -* **Alternative termination (`n = 1`)** — Again, should never be generated. -* **Stack underflow (`n = 2`)** — Not enough arguments in the stack for a primitive. -* **Stack overflow (`n = 3`)** — More values have been stored on a stack than allowed by this version of TVM. -* **Integer overflow (`n = 4`)** — Integer does not fit into `−2^256 ≤ x < 2^256`, or a division by zero has occurred. -* **Range check error (`n = 5`)** — Integer out of expected range. -* **Invalid opcode (`n = 6`)** — Instruction or its immediate arguments cannot be decoded. -* **Type check error (`n = 7`)** — An argument to a primitive is of incorrect value type. -* **Cell overflow (`n = 8`)** — Error in one of the serialization primitives. -* **Cell underflow (`n = 9`)** — Deserialization error. -* **Dictionary error (`n = 10`)** — Error while deserializing a dictionary object. -* **Unknown error (`n = 11`)** — Unknown error, may be thrown by user programs. -* **Fatal error (`n = 12`)** — Thrown by TVM in situations deemed impossible. -* **Out of gas (`n = 13`)** — Thrown by TVM when the remaining gas (`gr`) becomes negative. This exception usually cannot be caught and leads to an immediate termination of TVM. +If `o` needs to modify its state, it simply computes a new continuation `o'` of the same sort (perhaps with the same code as `o`, but with a different initial stack). The new continuation `o'` is returned to the caller along with whatever other return values need to be returned. -Most of these exceptions have no parameter (i.e., use a zero integer instead). -The order in which these exceptions are checked is outlined below in **4.5.8**. +### 4.4.2 Serializable objects ---- +Another way of representing Smalltalk-style objects as continuations, or even as trees of cells, consists in using the `JMPREFDATA` primitive (a variant of `JMPXDATA`, cf. [4.1.11](#4-1-11-callcc-call-with-current-continuation)), which takes the first cell reference from the code of the current continuation, transforms the cell referred to into a simple ordinary continuation, and transfers control to it, first pushing the remainder of the current continuation as a Slice into the stack. -### 4.5.8. Order of stack underflow, type check, and range check exceptions. - -All TVM primitives first check whether the stack contains the -required number of arguments, generating a stack underflow exception if this -is not the case. Only then are the type tags of the arguments and their ranges -(e.g., if a primitive expects an argument not only to be an `Integer`, but also -to be in the range from 0 to 256) checked, starting from the value in the top -of the stack (the last argument) and proceeding deeper into the stack. If an -argument’s type is incorrect, a type-checking exception is generated; if the -type is correct, but the value does not fall into the expected range, a range -check exception is generated. -Some primitives accept a variable number of arguments, depending on the -values of some small fixed subset of arguments located near the top of the -stack. In this case, the above procedure is first run for all arguments from -this small subset. Then it is repeated for the remaining arguments, once -their number and types have been determined from the arguments already -processed. +In this way, an object might be represented by a cell `o~` that contains `JMPREFDATA` at the beginning of its data, and the actual code of the object in the first reference (one might say that the first reference of cell `o~` is the class of object `o~`). Remaining data and references of this cell will be used for storing the fields of the object. +Such objects have the advantage of being trees of cells, and not just continuations, meaning that they can be stored into the persistent storage of a TON smart contract. + +### 4.4.3 Unique continuations and capabilities + +It might make sense (in a future revision of TVM) to mark some continuations as unique, meaning that they cannot be copied, even in a delayed manner, by increasing their reference counter to a value greater than one. If an opaque continuation is unique, it essentially becomes a capability, which can either be used by its owner exactly once or be transferred to somebody else. + +For example, imagine a continuation that represents the output stream to a printer (this is an example of a continuation used as an object, cf. [4.4.1](#4-4-1-representing-objects-using-continuations)). When invoked with one integer argument `n`, this continuation outputs the character with code `n` to the printer, and returns a new continuation of the same kind reflecting the new state of the stream. Obviously, copying such a continuation and using the two copies in parallel would lead to some unintended side effects; marking it as unique would prohibit such adverse usage. --- -# 4.6 Functions, recursion, and dictionaries +# 4.5 Exception handling + +TVM’s exception handling is quite simple and consists in a transfer of control to the continuation kept in control register c2. + +## 4.5.1. Two arguments of the exception handler: exception parameter and exception number + +Every exception is characterized by two arguments: the exception number (an Integer) and the exception parameter (any value, most often a zero Integer). Exception numbers 0–31 are reserved for TVM, while all other exception numbers are available for user-defined exceptions. + +## 4.5.2. Primitives for throwing an exception + +There are several special primitives used for throwing an exception. The most general of them, THROWANY, takes two arguments, v and 0 ≤ n < 2^16, from the stack, and throws the exception with number n and value v. There are variants of this primitive that assume v to be a zero integer, store n as a literal value, and/or are conditional on an integer value taken from the stack. User-defined exceptions may use arbitrary values as v (e.g., trees of cells) if needed. + +## 4.5.3. Exceptions generated by TVM + +Of course, some exceptions are generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit into a signed 257-bit integer. In such cases, the arguments of the exception, v and n, are determined by TVM itself. + +## 4.5.4. Exception handling + +The exception handling itself consists in a control transfer to the exception handler—i.e., the continuation specified in control register c2, with v and n supplied as the two arguments to this continuation, as if a JMP to c2 had been requested with n00 = 2 arguments (cf. [4.1.7](#4-1-7-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c) and [4.1.6](#4-1-6-switching-to-another-continuation-jmp-and-ret)). As a consequence, v and n end up in the top of the stack of the exception handler. The remainder of the old stack is discarded. + +Notice that if the continuation in c2 has a value for c2 in its savelist, it will be used to set up the new value of c2 before executing the exception handler. In particular, if the exception handler invokes THROWANY, it will rethrow the original exception with the restored value of c2. This trick enables the exception handler to handle only some exceptions, and pass the rest to an outer exception handler. + +## 4.5.5. Default exception handler + +When an instance of TVM is created, c2 contains a reference to the “default exception handler continuation”, which is an ec_fatal extraordinary continuation (cf. [4.1.5](#4-1-5-extraordinary-continuations)). Its execution leads to the termination of the execution of TVM, with the arguments v and n of the exception returned to the outside caller. In the context of the TON Blockchain, n will be stored as a part of the transaction’s result. + +## 4.5.6. TRY primitive + +A TRY primitive can be used to implement C++-like exception handling. This primitive accepts two continuations, c and c0. It stores the old value of c2 into the savelist of c0, sets c2 to c0, and executes c just as EXECUTE would, but additionally saving the old value of c2 into the savelist of the new c0 as well. Usually a version of the TRY primitive with an explicit number of arguments n00 passed to the continuation c is used. + +The net result is roughly equivalent to C++’s `try { c } catch(...) { c0 }` operator. -### 4.6.1. The problem of recursion. +## 4.5.7. List of predefined exceptions -The conditional and iterated execution primitives described in 4.2—along with the unconditional branch, call, and return primitives described in 4.1— enable one to implement more or less arbitrary code with nested loops and conditional expressions, with one notable exception: one can only create new constant continuations from parts of the current continuation. (In particular, one cannot invoke a subroutine from itself in this way.) Therefore, the code being executed—i.e., the current continuation—gradually becomes smaller and smaller. +Predefined exceptions of TVM correspond to exception numbers n in the range 0–31. They include: -### 4.6.2. Y -combinator solution: pass a continuation as an argument to itself. +- **Normal termination (n = 0)** — Should never be generated, but it is useful for some tricks. +- **Alternative termination (n = 1)** — Again, should never be generated. +- **Stack underflow (n = 2)** — Not enough arguments in the stack for a primitive. +- **Stack overflow (n = 3)** — More values have been stored on a stack than allowed by this version of TVM. +- **Integer overflow (n = 4)** — Integer does not fit into −2^256 ≤ x < 2^256, or a division by zero has occurred. +- **Range check error (n = 5)** — Integer out of expected range. +- **Invalid opcode (n = 6)** — Instruction or its immediate arguments cannot be decoded. +- **Type check error (n = 7)** — An argument to a primitive is of incorrect value type. +- **Cell overflow (n = 8)** — Error in one of the serialization primitives. +- **Cell underflow (n = 9)** — Deserialization error. +- **Dictionary error (n = 10)** — Error while deserializing a dictionary object. +- **Unknown error (n = 11)** — Unknown error, may be thrown by user programs. +- **Fatal error (n = 12)** — Thrown by TVM in situations deemed impossible. +- **Out of gas (n = 13)** — Thrown by TVM when the remaining gas (gr) becomes negative. This exception usually cannot be caught and leads to an immediate termination of TVM. +Most of these exceptions have no parameter (i.e., use a zero integer instead). The order in which these exceptions are checked is outlined below in 4.5.8. + +## 4.5.8. Order of stack underflow, type check, and range check exceptions + +All TVM primitives first check whether the stack contains the required number of arguments, generating a stack underflow exception if this is not the case. Only then are the type tags of the arguments and their ranges (e.g., if a primitive expects an argument not only to be an Integer, but also to be in the range from 0 to 256) checked, starting from the value in the top of the stack (the last argument) and proceeding deeper into the stack. If an argument’s type is incorrect, a type-checking exception is generated; if the type is correct, but the value does not fall into the expected range, a range check exception is generated. + +Some primitives accept a variable number of arguments, depending on the values of some small fixed subset of argument + +--- + +# 4.6 Functions, recursion, and dictionaries + +## 4.6.1 The problem of recursion +The conditional and iterated execution primitives described in [4.2](#4-2-control-flow-primitives-conditional-and-iterated-execution)—along with the unconditional branch, call, and return primitives described in [4.1](#4-1-continuations-and-subroutines)—enable one to implement more or less arbitrary code with nested loops and conditional expressions, with one notable exception: one can only create new constant continuations from parts of the current continuation. (In particular, one cannot invoke a subroutine from itself in this way.) Therefore, the code being executed—i.e., the current continuation—gradually becomes smaller and smaller.[24](#footnote-24) + +## 4.6.2 Y-combinator solution: pass a continuation as an argument to itself One way of dealing with the problem of recursion is by passing a copy of the continuation representing the body of a recursive function as an extra argument to itself. Consider, for example, the following code for a factorial function: ``` @@ -2140,17 +1242,17 @@ D8 EXECUTE 31 NIP ``` -This roughly corresponds to defining an auxiliary function body with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, n·x, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. +This roughly corresponds to defining an auxiliary function `body` with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, n·x, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. -### 4.6.3. A variant of Y -combinator solution. +## 4.6.3 A variant of Y-combinator solution +Another way of recursively computing the factorial, more closely following the classical recursive definition: -Another way of recursively computing the factorial, more closely following the classical recursive definition - -``` -fact(n) := ( -1 if n < 2, -n · fact(n − 1) otherwise -) +```math +\text{fact}(n) := +\begin{cases} +1 & \text{if } n < 2, \\ +n \cdot \text{fact}(n - 1) & \text{otherwise} +\end{cases} ``` is as follows: @@ -2177,7 +1279,7 @@ D9 JMPX This definition of the factorial function is two bytes shorter than the previous one, but it uses general recursion instead of tail recursion, so it cannot be easily transformed into a loop. -### 4.6.4. Comparison: non-recursive definition of the factorial function. +## 4.6.4 Comparison: non-recursive definition of the factorial function Incidentally, a non-recursive definition of the factorial with the aid of a `REPEAT` loop is also possible, and it is much shorter than both recursive definitions: @@ -2195,442 +1297,180 @@ E4 REPEAT 30 DROP ``` -### 4.6.5. Several mutually recursive functions. +## 4.6.5 Several mutually recursive functions -If one has a collection `f1, . . . , fn` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fi}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. +If one has a collection `f1, …, fn` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fi}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. -### 4.6.6. Combining several functions into one tuple. +## 4.6.6 Combining several functions into one tuple -One might also combine a collection of continuations representing functions `f1, . . . , fn` into a “tuple” `f := (f1, . . . , fn)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fi`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. +One might also combine a collection of continuations representing functions `f1, …, fn` into a “tuple” `f := (f1, …, fn)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fi`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. -### 4.6.7. Combining several functions into a selector function. +## 4.6.7 Combining several functions into a selector function -Another approach is to combine several functions `f1, . . . , fn` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fi` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. +Another approach is to combine several functions `f1, …, fn` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fi` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. -### 4.6.8. Using a dedicated register to keep the selector function. +## 4.6.8 Using a dedicated register to keep the selector function However, even if we use one of the two previous approaches to combine all functions into one extra argument, passing this argument to all mutually recursive functions is still quite cumbersome and requires a lot of additional stack manipulation operations. Because this argument changes very rarely, one might use a dedicated register to keep it and transparently pass it to all functions called. This is the approach used by TVM by default. -### 4.6.9. Special register c3 for the selector function. +## 4.6.9 Special register c3 for the selector function -In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. A.8.7) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. +In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. [A.8.7](#a-8-7)) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). -In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). - -### 4.6.10. Initialization of c3. +## 4.6.10 Initialization of c3 A TVM program might initialize `c3` by means of a `POP c3` instruction. However, because this usually is the very first action undertaken by a program (e.g., a smart contract), TVM makes some provisions for the automatic initialization of `c3`. Namely, `c3` is initialized by the code (the initial value of `cc`) of the program itself, and an extra zero (or, in some cases, some other predefined number `s`) is pushed into the stack before the program’s execution. This is approximately equivalent to invoking `JMPDICT 0` (or `JMPDICT s`) at the very beginning of a program—i.e., the function with index zero is effectively the `main()` function for the program. -### 4.6.11. Creating selector functions and switch statements. - -TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. A.8.2). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. - -Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. A.7.2). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. +## 4.6.11 Creating selector functions and switch statements -### 4.6.12. Alternative: using a hashmap to select the correct function. +TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. [A.8.2](#a-8-2)). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. -Yet another alternative is to use a `Hashmap` (cf. 3.3) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. A.10) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. A.8.5) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. A.10.11). This approach may be more efficient for larger programs and switch statements. +Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. [A.7.2](#a-7-2)). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. +## 4.6.12 Alternative: using a hashmap to select the correct function -Got it ✅ — here’s **Chapter 5: Codepages and instruction encoding** converted cleanly into Markdown. -I kept the **text exactly as-is** (no paraphrasing), just formatted with proper Markdown: headings, subheadings, inline backticks for mnemonics/opcodes, and bullet lists where appropriate. +Yet another alternative is to use a Hashmap (cf. [3.3](#3-3-hashmaps-or-dictionaries)) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. [A.10](#a-10-dictionary-manipulation-primitives)) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. [A.8.5](#a-8-5)) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. [A.10.11](#a-10-11)). --- # 5 Codepages and instruction encoding -This chapter describes the codepage mechanism, which allows TVM to be -flexible and extendable while preserving backward compatibility with respect -to previously generated code. -We also discuss some general considerations about instruction encodings -(applicable to arbitrary machine code, not just TVM), as well as the implications of these considerations for TVM and the choices made while designing -TVM’s (experimental) codepage zero. The instruction encodings themselves -are presented later in Appendix A. +This chapter describes the codepage mechanism, which allows TVM to be flexible and extendable while preserving backward compatibility with respect to previously generated code. -## 5.1 Codepages and interoperability of different TVM versions - -The codepages are an essential mechanism of backward compatibility and -of future extensions to TVM. They enable transparent execution of code -written for different revisions of TVM, with transparent interaction between -instances of such code. The mechanism of the codepages, however, is general -and powerful enough to enable some other originally unintended applications. - -### 5.1.1. Codepages in continuations - -Every ordinary continuation contains -a 16-bit codepage field `cp` (cf. 4.1.1), which determines the codepage that -will be used to execute its code. If a continuation is created by a `PUSHCONT` -(cf. 4.2.3) or similar primitive, it usually inherits the current codepage (i.e., -the codepage of `cc`).25 - -### 5.1.2. Current codepage - -The current codepage `cp` (cf. 1.4) is the codepage of the current continuation `cc`. It determines the way the next instruction will be decoded from `cc.code`, the remainder of the current continuation’s code. Once the instruction has been decoded and executed, it -determines the next value of the current codepage. In most cases, the current codepage is left unchanged. - -On the other hand, all primitives that switch the current continuation -load the new value of `cp` from the new current continuation. In this way, all -code in continuations is always interpreted exactly as it was intended to be. - ---- - -### 5.1.3. Different versions of TVM may use different codepages - -Different versions of TVM may use different codepages for their code. For -example, the original version of TVM might use codepage zero. A newer -version might use codepage one, which contains all the previously defined -opcodes, along with some newly defined ones, using some of the previously -unused opcode space. A subsequent version might use yet another codepage, -and so on. - -However, a newer version of TVM will execute old code for codepage zero -exactly as before. If the old code contained an opcode used for some new -operations that were undefined in the original version of TVM, it will still -generate an invalid opcode exception, because the new operations are absent -in codepage zero. - ---- +We also discuss some general considerations about instruction encodings (applicable to arbitrary machine code, not just TVM), as well as the implications of these considerations for TVM and the choices made while designing TVM’s (experimental) codepage zero. The instruction encodings themselves are presented later in Appendix A. -### 5.1.4. Changing the behavior of old operations +## 5.1 Codepages and interoperability of different TVM versions -New codepages can -also change the effects of some operations present in the old codepages while -preserving their opcodes and mnemonics. +The codepages are an essential mechanism of backward compatibility and of future extensions to TVM. They enable transparent execution of code written for different revisions of TVM, with transparent interaction between instances of such code. The mechanism of the codepages, however, is general and powerful enough to enable some other originally unintended applications. -For example, imagine a future 513-bit upgrade of TVM (replacing the -current 257-bit design). It might use a 513-bit Integer type within the same -arithmetic primitives as before. However, while the opcodes and instructions -in the new codepage would look exactly like the old ones, they would work -differently, accepting 513-bit integer arguments and results. On the other -hand, during the execution of the same code in codepage zero, the new -machine would generate exceptions whenever the integers used in arithmetic -and other primitives do not fit into 257 bits.26 In this way, the upgrade would -not change the behavior of the old code. +### 5.1.1 Codepages in continuations +Every ordinary continuation contains a 16-bit codepage field `cp` (cf. [4.1.1](#4-1-1-ordinary-continuations)), which determines the codepage that will be used to execute its code. If a continuation is created by a `PUSHCONT` (cf. [4.2.3](#4-2-3-constant-or-literal-continuations)) or similar primitive, it usually inherits the current codepage (i.e., the codepage of `cc`).[25](#footnote-25) ---- +### 5.1.2 Current codepage +The current codepage `cp` (cf. [1.4](#1-4-total-state-of-tvm)) is the codepage of the current continuation `cc`. It determines the way the next instruction will be decoded from `cc.code`, the remainder of the current continuation’s code. Once the instruction has been decoded and executed, it determines the next value of the current codepage. In most cases, the current codepage is left unchanged. -### 5.1.5. Improving instruction encoding +On the other hand, all primitives that switch the current continuation load the new value of `cp` from the new current continuation. In this way, all code in continuations is always interpreted exactly as it was intended to be. -Another application for codepages is to change instruction encodings, reflecting improved knowledge of -the actual frequencies of such instructions in the code base. In this case, -the new codepage will have exactly the same instructions as the old one, but -with different encodings, potentially of differing lengths. +### 5.1.3 Different versions of TVM may use different codepages +Different versions of TVM may use different codepages for their code. -For example, one -might create an experimental version of the first version of TVM, using a -(prefix) bitcode instead of the original bytecode, aiming to achieve higher -code density. +For example, the original version of TVM might use codepage zero. A newer version might use codepage one, which contains all the previously defined opcodes, along with some newly defined ones, using some of the previously unused opcode space. A subsequent version might use yet another codepage, and so on. ---- +However, a newer version of TVM will execute old code for codepage zero exactly as before. If the old code contained an opcode used for some new operations that were undefined in the original version of TVM, it will still generate an invalid opcode exception, because the new operations are absent in codepage zero. -### 5.1.6. Making instruction encoding context-dependent +### 5.1.4 Changing the behavior of old operations +New codepages can also change the effects of some operations present in the old codepages while preserving their opcodes and mnemonics. -Another way -of using codepages to improve code density is to use several codepages with -different subsets of the whole instruction set defined in each of them, or with -the whole instruction set defined, but with different length encodings for the -same instructions in different codepages. +For example, imagine a future 513-bit upgrade of TVM (replacing the current 257-bit design). It might use a 513-bit Integer type within the same arithmetic primitives as before. However, while the opcodes and instructions in the new codepage would look exactly like the old ones, they would work differently, accepting 513-bit integer arguments and results. On the other hand, during the execution of the same code in codepage zero, the new machine would generate exceptions whenever the integers used in arithmetic and other primitives do not fit into 257 bits.[26](#footnote-26) -Imagine, for instance, a “stack manipulation” codepage, where stack manipulation primitives have short encodings at the expense of all other operations, and a “data processing” codepage, where all other operations are -shorter at the expense of stack manipulation operations. If stack manipulation operations tend to come one after another, we can automatically -switch to “stack manipulation” codepage after executing any such instruction. When a data processing instruction occurs, we switch back to “data -processing” codepage. +In this way, the upgrade would not change the behavior of the old code. -If conditional probabilities of the class of the next instruction depending on the class of the previous instruction are considerably -different from corresponding unconditional probabilities, this technique— -automatically switching into stack manipulation mode to rearrange the stack -with shorter instructions, then switching back—might considerably improve -the code density. +### 5.1.5 Improving instruction encoding +Another application for codepages is to change instruction encodings, reflecting improved knowledge of the actual frequencies of such instructions in the code base. In this case, the new codepage will have exactly the same instructions as the old one, but with different encodings, potentially of differing lengths. ---- +For example, one might create an experimental version of the first version of TVM, using a (prefix) bitcode instead of the original bytecode, aiming to achieve higher code density. -### 5.1.7. Using codepages for status and control flags +### 5.1.6 Making instruction encoding context-dependent +Another way of using codepages to improve code density is to use several codepages with different subsets of the whole instruction set defined in each of them, or with the whole instruction set defined, but with different length encodings for the same instructions in different codepages. -Another potential -application of multiple codepages inside the same revision of TVM consists in -switching between several codepages depending on the result of the execution -of some instructions. +Imagine, for instance, a “stack manipulation” codepage, where stack manipulation primitives have short encodings at the expense of all other operations, and a “data processing” codepage, where all other operations are shorter at the expense of stack manipulation operations. If stack manipulation operations tend to come one after another, we can automatically switch to “stack manipulation” codepage after executing any such instruction. When a data processing instruction occurs, we switch back to “data processing” codepage. -For example, imagine a version of TVM that uses two new codepages, `2` -and `3`. Most operations do not change the current codepage. However, the -integer comparison operations will switch to codepage `2` if the condition is -false, and to codepage `3` if it is true. Furthermore, a new operation `?EXECUTE`, -similar to `EXECUTE`, will indeed be equivalent to `EXECUTE` in codepage `3`, but -will instead be a `DROP` in codepage `2`. Such a trick effectively uses bit 0 of -the current codepage as a status flag. +If conditional probabilities of the class of the next instruction depending on the class of the previous instruction are considerably different from corresponding unconditional probabilities, this technique—automatically switching into stack manipulation mode to rearrange the stack with shorter instructions, then switching back—might considerably improve the code density. -Alternatively, one might create a couple of codepages—say, `4` and `5`— -which differ only in their cell deserialisation primitives. For instance, in -codepage `4` they might work as before, while in codepage `5` they might deserialize data not from the beginning of a Slice, but from its end. Two new -instructions—say, `CLD` and `STD`—might be used for switching to codepage `4` -or codepage `5`. Clearly, we have now described a status flag, affecting the -execution of some instructions in a certain new manner. +### 5.1.7 Using codepages for status and control flags +Another potential application of multiple codepages inside the same revision of TVM consists in switching between several codepages depending on the result of the execution of some instructions. ---- - -### 5.1.8. Setting the codepage in the code itself +For example, imagine a version of TVM that uses two new codepages, 2 and 3. Most operations do not change the current codepage. However, the integer comparison operations will switch to codepage 2 if the condition is false, and to codepage 3 if it is true. Furthermore, a new operation `?EXECUTE`, similar to `EXECUTE`, will indeed be equivalent to `EXECUTE` in codepage 3, but will instead be a `DROP` in codepage 2. Such a trick effectively uses bit 0 of the current codepage as a status flag. -For convenience, we -reserve some opcode in all codepages—say, `FF n`—for the instruction `SETCP n`, -with `n` from 0 to 255 (cf. A.13). Then by inserting such an instruction -into the very beginning of (the main function of) a program (e.g., a TON -Blockchain smart contract) or a library function, we can ensure that the code -will always be executed in the intended codepage. +Alternatively, one might create a couple of codepages—say, 4 and 5—which differ only in their cell deserialisation primitives. For instance, in codepage 4 they might work as before, while in codepage 5 they might deserialize data not from the beginning of a Slice, but from its end. Two new instructions—say, `CLD` and `STD`—might be used for switching to codepage 4 or codepage 5. Clearly, we have now described a status flag, affecting the execution of some instructions in a certain new manner. ---- +### 5.1.8 Setting the codepage in the code itself +For convenience, we reserve some opcode in all codepages—say, `FF n`—for the instruction `SETCP n`, with `n` from 0 to 255 (cf. [A.13](#a-13)). Then by inserting such an instruction into the very beginning of (the main function of) a program (e.g., a TON Blockchain smart contract) or a library function, we can ensure that the code will always be executed in the intended codepage. ## 5.2 Instruction encoding -This section discusses the general principles of instruction encoding valid for -all codepages and all versions of TVM. Later, 5.3 discusses the choices made -for the experimental “codepage zero”. +This section discusses the general principles of instruction encoding valid for all codepages and all versions of TVM. Later, [5.3](#5-3-instruction-encoding-in-codepage-zero) discusses the choices made for the experimental “codepage zero”. -### 5.2.1. Instructions are encoded by a binary prefix code +### 5.2.1 Instructions are encoded by a binary prefix code +All complete instructions (i.e., instructions along with all their parameters, such as the names of stack registers `s(i)` or other embedded constants) of a TVM codepage are encoded by a binary prefix code. This means that a (finite) binary string (i.e., a bitstring) corresponds to each complete instruction, in such a way that binary strings corresponding to different complete instructions do not coincide, and no binary string among the chosen subset is a prefix of another binary string from this subset. -All complete instructions (i.e., instructions along with all their parameters, such as -the names of stack registers `s(i)` or other embedded constants) of a TVM -codepage are encoded by a **binary prefix code**. This means that a (finite) -binary string (i.e., a bitstring) corresponds to each complete instruction, in -such a way that binary strings corresponding to different complete instructions do not coincide, and no binary string among the chosen subset is a -prefix of another binary string from this subset. +### 5.2.2 Determining the first instruction from a code stream +As a consequence of this encoding method, any binary string admits at most one prefix, which is an encoding of some complete instruction. In particular, the code `cc.code` of the current continuation (which is a Slice, and thus a bitstring along with some cell references) admits at most one such prefix, which corresponds to the (uniquely determined) instruction that TVM will execute first. After execution, this prefix is removed from the code of the current continuation, and the next instruction can be decoded. ---- - -### 5.2.2. Determining the first instruction from a code stream +### 5.2.3 Invalid opcode +If no prefix of `cc.code` encodes a valid instruction in the current codepage, an invalid opcode exception is generated (cf. [4.5.7](#4-5-7-list-of-predefined-exceptions)). However, the case of an empty `cc.code` is treated separately as explained in [4.1.4](#4-1-4-normal-work-of-tvm-or-the-main-loop) (the exact behavior may depend on the current codepage). -As a consequence of this encoding method, any binary string admits at most one -prefix, which is an encoding of some complete instruction. In particular, -the code `cc.code` of the current continuation (which is a Slice, and thus a -bitstring along with some cell references) admits at most one such prefix, -which corresponds to the (uniquely determined) instruction that TVM will -execute first. After execution, this prefix is removed from the code of the -current continuation, and the next instruction can be decoded. - ---- +### 5.2.4 Special case: end-of-code padding +As an exception to the above rule, some codepages may accept some values of `cc.code` that are too short to be valid instruction encodings as additional variants of `NOP`, thus effectively using the same procedure for them as for an empty `cc.code`. Such bitstrings may be used for padding the code near its end. -### 5.2.3. Invalid opcode +For example, if binary string `00000000` (i.e., `0x00`, cf. [1.0.3](#1-0-3-hexadecimal-notation)) is used in a codepage to encode `NOP`, its proper prefixes cannot encode any instructions. So this codepage may accept `0`, `00`, `000`, …, `0000000` as variants of `NOP` if this is all that is left in `cc.code`, instead of generating an invalid opcode exception. -If no prefix of `cc.code` encodes a valid instruction -in the current codepage, an invalid opcode exception is generated (cf. 4.5.7). - -However, the case of an empty `cc.code` is treated separately as explained -in 4.1.4 (the exact behavior may depend on the current codepage). - ---- +Such a padding may be useful, for example, if the `PUSHCONT` primitive (cf. [4.2.3](#4-2-3-constant-or-literal-continuations)) creates only continuations with code consisting of an integral number of bytes, but not all instructions are encoded by an integral number of bytes. -### 5.2.4. Special case: end-of-code padding +### 5.2.5 TVM code is a bitcode, not a bytecode +Recall that TVM is a bit-oriented machine in the sense that its Cells (and Slices) are naturally considered as sequences of bits, not just of octets (bytes), cf. [3.2.5](#3-2-5-cells-and-cell-primitives-are-bit-oriented-not-byte-oriented). Because the TVM code is also kept in cells (cf. [3.1.9](#3-1-9-tvm-code-is-a-tree-of-cells) and [4.1.4](#4-1-4-normal-work-of-tvm-or-the-main-loop)), there is no reason to use only bitstrings of length divisible by eight as encodings of complete instructions. In other words, generally speaking, the TVM code is a bitcode, not a bytecode. -As an exception to the above -rule, some codepages may accept some values of `cc.code` that are too short -to be valid instruction encodings as additional variants of `NOP`, thus effectively -using the same procedure for them as for an empty `cc.code`. Such bitstrings -may be used for padding the code near its end. +That said, some codepages (such as our experimental codepage zero) may opt to use a bytecode (i.e., to use only encodings consisting of an integral number of bytes)—either for simplicity, or for the ease of debugging and of studying memory (i.e., cell) dumps.[27](#footnote-27) -For example, if binary string `00000000` (i.e., `x00`, cf. 1.0.3) is used in a -codepage to encode `NOP`, its proper prefixes cannot encode any instructions. -So this codepage may accept `0`, `00`, `000`, …, `0000000` as variants of `NOP` if -this is all that is left in `cc.code`, instead of generating an invalid opcode -exception. - -Such a padding may be useful, for example, if the `PUSHCONT` primitive -(cf. 4.2.3) creates only continuations with code consisting of an integral -number of bytes, but not all instructions are encoded by an integral number -of bytes. - ---- - -### 5.2.5. TVM code is a bitcode, not a bytecode - -Recall that TVM is -a bit-oriented machine in the sense that its Cells (and Slices) are naturally -considered as sequences of bits, not just of octets (bytes), cf. 3.2.5. Because -the TVM code is also kept in cells (cf. 3.1.9 and 4.1.4), there is no reason -to use only bitstrings of length divisible by eight as encodings of complete -instructions. In other words, generally speaking, the TVM code is a **bitcode**, -not a **bytecode**. - -That said, some codepages (such as our experimental codepage zero) may -opt to use a bytecode (i.e., to use only encodings consisting of an integral -number of bytes)—either for simplicity, or for the ease of debugging and of -studying memory (i.e., cell) dumps.27 - ---- - -### 5.2.6. Opcode space used by a complete instruction - -Recall from coding theory that the lengths of bitstrings `li` used in a binary prefix code satisfy -Kraft–McMillan inequality: +### 5.2.6 Opcode space used by a complete instruction +Recall from coding theory that the lengths of bitstrings `li` used in a binary prefix code satisfy Kraft–McMillan inequality: +```math +\sum_i 2^{-l_i} \leq 1 ``` -Σ 2^(-li) ≤ 1 -``` - -This is applicable in particular to -the (complete) instruction encoding used by a TVM codepage. We say that -a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2^(-l)` of the opcode space, if it is encoded -by an `l`-bit string. One can see that all complete instructions together utilize -at most 1 (i.e., “at most the whole opcode space”). - ---- - -### 5.2.7. Opcode space used by an instruction, or a class of instructions - -The above terminology is extended to instructions (considered with -all admissible values of their parameters), or even classes of instructions (e.g., -all arithmetic instructions). We say that an (incomplete) instruction, or a -class of instructions, occupies portion `α` of the opcode space, if `α` is the sum -of the portions of the opcode space occupied by all complete instructions -belonging to that class. - ---- - -### 5.2.8. Opcode space for bytecodes - -A useful approximation of the above -definitions is as follows: - -Consider all 256 possible values for the first byte of -an instruction encoding. Suppose that `k` of these values correspond to the -specific instruction or class of instructions we are considering. Then this -instruction or class of instructions occupies approximately the portion `k/256` -of the opcode space. - -This approximation shows why all instructions cannot occupy together -more than the portion `256/256 = 1` of the opcode space, at least without -compromising the uniqueness of instruction decoding. - ---- - -### 5.2.9. Almost optimal encodings - -Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete -instruction (`2^(-l)`, if the complete instruction is encoded in `l` bits) should be -approximately equal to the probability or frequency of its occurrence in real -programs.28 The same should hold for (incomplete) instructions, or primitives -(i.e., generic instructions without specified values of parameters), and -for classes of instructions. - ---- - -### 5.2.10. Example: stack manipulation primitives - -For instance, if stack -manipulation instructions constitute approximately half of all instructions in -a typical TVM program, one should allocate approximately half of the opcode -space for encoding stack manipulation instructions. - -One might reserve the -first bytes (“opcodes”) `0x00–0x7f` for such instructions. If a quarter of these -instructions are `XCHG`, it would make sense to reserve `0x00–0x1f` for `XCHG`s. -Similarly, if half of all `XCHG`s involve the top of stack `s0`, it would make sense -to use `0x00–0x0f` to encode `XCHG s0,s(i)`. - ---- - -### 5.2.11. Simple encodings of instructions -In most cases, simple encodings of complete instructions are used. Simple encodings begin with a fixed -bitstring called the opcode of the instruction, followed by, say, 4-bit fields -containing the indices `i` of stack registers `s(i)` specified in the instruction, followed by all other constant (literal, immediate) parameters included in the -complete instruction. +This is applicable in particular to the (complete) instruction encoding used by a TVM codepage. We say that a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2^-l` of the opcode space, if it is encoded by an `l`-bit string. One can see that all complete instructions together utilize at most 1 (i.e., “at most the whole opcode space”). -While simple encodings may not be exactly optimal, -they admit short descriptions, and their decoding and encoding can be easily -implemented. +### 5.2.7 Opcode space used by an instruction, or a class of instructions +The above terminology is extended to instructions (considered with all admissible values of their parameters), or even classes of instructions (e.g., all arithmetic instructions). We say that an (incomplete) instruction, or a class of instructions, occupies portion `α` of the opcode space, if `α` is the sum of the portions of the opcode space occupied by all complete instructions belonging to that class. -If a (generic) instruction uses a simple encoding with an `l`-bit opcode, then -the instruction will utilize `2^(-l)` portion of the opcode space. This observation -might be useful for considerations described in 5.2.9 and 5.2.10. +### 5.2.8 Opcode space for bytecodes +A useful approximation of the above definitions is as follows: Consider all 256 possible values for the first byte of an instruction encoding. Suppose that `k` of these values correspond to the specific instruction or class of instructions we are considering. Then this instruction or class of instructions occupies approximately the portion `k/256` of the opcode space. ---- +This approximation shows why all instructions cannot occupy together more than the portion `256/256 = 1` of the opcode space, at least without compromising the uniqueness of instruction decoding. -### 5.2.12. Optimizing code density further: Huffman codes +### 5.2.9 Almost optimal encodings +Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete instruction (`2^-l`, if the complete instruction is encoded in `l` bits) should be approximately equal to the probability or frequency of its occurrence in real programs.[28](#footnote-28) The same should hold for (incomplete) instructions, or primitives (i.e., generic instructions without specified values of parameters), and for classes of instructions. -One might -construct optimally dense binary code for the set of all complete instructions, -provided their probabilities or frequencies in real code are known. This is the -well-known **Huffman code** (for the given probability distribution). However, -such code would be highly unsystematic and hard to decode. +### 5.2.10 Example: stack manipulation primitives +For instance, if stack manipulation instructions constitute approximately half of all instructions in a typical TVM program, one should allocate approximately half of the opcode space for encoding stack manipulation instructions. One might reserve the first bytes (“opcodes”) `0x00–0x7f` for such instructions. If a quarter of these instructions are `XCHG`, it would make sense to reserve `0x00–0x1f` for `XCHG`s. Similarly, if half of all `XCHG`s involve the top of stack `s0`, it would make sense to use `0x00–0x0f` to encode `XCHG s0,s(i)`. ---- +### 5.2.11 Simple encodings of instructions +In most cases, simple encodings of complete instructions are used. Simple encodings begin with a fixed bitstring called the opcode of the instruction, followed by, say, 4-bit fields containing the indices `i` of stack registers `s(i)` specified in the instruction, followed by all other constant (literal, immediate) parameters included in the complete instruction. While simple encodings may not be exactly optimal, they admit short descriptions, and their decoding and encoding can be easily implemented. -### 5.2.13. Practical instruction encodings +If a (generic) instruction uses a simple encoding with an `l`-bit opcode, then the instruction will utilize `2^-l` portion of the opcode space. This observation might be useful for considerations described in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives). -In practice, instruction encodings used in TVM and other virtual machines offer a compromise between -code density and ease of encoding and decoding. Such a compromise may -be achieved by selecting simple encodings (cf. 5.2.11) for all instructions -(maybe with separate simple encodings for some often used variants, such -as `XCHG s0,s(i)` among all `XCHG s(i),s(j)`), and allocating opcode space for -such simple encodings using the heuristics outlined in 5.2.9 and 5.2.10; this -is the approach currently used in TVM. +### 5.2.12 Optimizing code density further: Huffman codes +One might construct optimally dense binary code for the set of all complete instructions, provided their probabilities or frequences in real code are known. This is the well-known Huffman code (for the given probability distribution). However, such code would be highly unsystematic and hard to decode. ---- +### 5.2.13 Practical instruction encodings +In practice, instruction encodings used in TVM and other virtual machines offer a compromise between code density and ease of encoding and decoding. Such a compromise may be achieved by selecting simple encodings (cf. [5.2.11](#5-2-11-simple-encodings-of-instructions)) for all instructions (maybe with separate simple encodings for some often used variants, such as `XCHG s0,s(i)` among all `XCHG s(i),s(j)`), and allocating opcode space for such simple encodings using the heuristics outlined in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives); this is the approach currently used in TVM. ## 5.3 Instruction encoding in codepage zero -This section provides details about the experimental instruction encoding -for codepage zero, as described elsewhere in this document (cf. Appendix A) -and used in the preliminary test version of TVM. +This section provides details about the experimental instruction encoding for codepage zero, as described elsewhere in this document (cf. [Appendix A](#appendix-a)) and used in the preliminary test version of TVM. -### 5.3.1. Upgradability +### 5.3.1 Upgradability +First of all, even if this preliminary version somehow gets into the production version of the TON Blockchain, the codepage mechanism (cf. [5.1](#51-codepages-and-interoperability-of-different-tvm-versions)) enables us to introduce better versions later without compromising backward compatibility.[29](#footnote-29) So in the meantime, we are free to experiment. -First of all, even if this preliminary version somehow gets into the production version of the TON Blockchain, the codepage -mechanism (cf. 5.1) enables us to introduce better versions later without -compromising backward compatibility.29 So in the meantime, we are free to -experiment. +### 5.3.2 Choice of instructions +We opted to include many “experimental” and not strictly necessary instructions in codepage zero just to see how they might be used in real code. For example, we have both the basic (cf. [2.2.1](#2-2-1-basic-stack-manipulation-primitives)) and the compound (cf. [2.2.3](#2-2-3-compound-stack-manipulation-primitives)) stack manipulation primitives, as well as some “unsystematic” ones such as `ROT` (mostly borrowed from Forth). If such primitives are rarely used, their inclusion just wastes some part of the opcode space and makes the encodings of other instructions slightly less effective, something we can afford at this stage of TVM’s development. ---- +### 5.3.3 Using experimental instructions +Some of these experimental instructions have been assigned quite long opcodes, just to fit more of them into the opcode space. One should not be afraid to use them just because they are long; if these instructions turn out to be useful, they will receive shorter opcodes in future revisions. Codepage zero is not meant to be fine-tuned in this respect. -### 5.3.2. Choice of instructions +### 5.3.4 Choice of bytecode +We opted to use a bytecode (i.e., to use encodings of complete instructions of lengths divisible by eight). While this may not produce optimal code density, because such a length restriction makes it more difficult to match portions of opcode space used for the encoding of instructions with estimated frequencies of these instructions in TVM code (cf. [5.2.11](#5-2-11-simple-encodings-of-instructions) and [5.2.9](#5-2-9-almost-optimal-encodings)), such an approach has its advantages: it admits a simpler instruction decoder and simplifies debugging (cf. [5.2.5](#5-2-5-tvm-code-is-a-bitcode-not-a-bytecode)). -We opted to include many “experimental” -and not strictly necessary instructions in codepage zero just to see how they -might be used in real code. For example, we have both the basic (cf. 2.2.1) -and the compound (cf. 2.2.3) stack manipulation primitives, as well as some -“unsystematic” ones such as `ROT` (mostly borrowed from Forth). If such -primitives are rarely used, their inclusion just wastes some part of the opcode -space and makes the encodings of other instructions slightly less effective, -something we can afford at this stage of TVM’s development. +After all, we do not have enough data on the relative frequencies of different instructions right now, so our code density optimizations are likely to be very approximate at this stage. The ease of debugging and experimenting and the simplicity of implementation are more important at this point. ---- - -### 5.3.3. Using experimental instructions +### 5.3.5 Simple encodings for all instructions +For similar reasons, we opted to use simple encodings for all instructions (cf. [5.2.11](#5-2-11-simple-encodings-of-instructions) and [5.2.13](#5-2-13-practical-instruction-encodings)), with separate simple encodings for some very frequently used subcases as outlined in [5.2.13](#5-2-13-practical-instruction-encodings). That said, we tried to distribute opcode space using the heuristics described in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives). -Some of these experimental -instructions have been assigned quite long opcodes, just to fit more of them -into the opcode space. One should not be afraid to use them just because -they are long; if these instructions turn out to be useful, they will receive -shorter opcodes in future revisions. Codepage zero is not meant to be fine -tuned in this respect. - ---- - -### 5.3.4. Choice of bytecode. - -We opted to use a bytecode (i.e., to use encodings of complete instructions of lengths divisible by eight). While this may not produce optimal code density, because such a length restriction makes it more difficult to match portions of opcode space used for the encoding of instructions with estimated frequencies of these instructions in TVM code -(cf. 5.2.11 and 5.2.9), such an approach has its advantages: it admits a -simpler instruction decoder and simplifies debugging (cf. 5.2.5). - -After all, we do not have enough data on the relative frequencies of different instructions right now, so our code density optimizations are likely to -be very approximate at this stage. The ease of debugging and experimenting -and the simplicity of implementation are more important at this point. - -### 5.3.5. Simple encodings for all instructions. - -For similar reasons, we -opted to use simple encodings for all instructions (cf. 5.2.11 and 5.2.13), -with separate simple encodings for some very frequently used subcases as -outlined in 5.2.13. That said, we tried to distribute opcode space using the -heuristics described in 5.2.9 and 5.2.10. - -### 5.3.6. Lack of context-dependent encodings. - -This version of TVM also -does not use context-dependent encodings (cf. 5.1.6). They may be added -at a later stage, if deemed useful. - -### 5.3.7. The list of all instructions. +### 5.3.6 Lack of context-dependent encodings +This version of TVM also does not use context-dependent encodings (cf. [5.1.6](#5-1-6-making-instruction-encoding-context-dependent)). They may be added at a later stage, if deemed useful. +### 5.3.7 The list of all instructions The list of all instructions available in codepage zero, along with their encodings and (in some cases) short descriptions, may be found in Appendix A. --- @@ -2645,6 +1485,7 @@ category (e.g., arithmetic primitives) have neighboring opcodes. So we first list a number of stack manipulation primitives, then constant primitives, arithmetic primitives, comparison primitives, cell primitives, continuation primitives, dictionary primitives, and finally application-specific primitives. + We use hexadecimal notation (cf. 1.0) for bitstrings. Stack registers `s(i)` usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, @@ -2683,6 +1524,7 @@ compound stack manipulation primitives, such as `XCPU` or `XCHG2`, turn out to have the same length as an equivalent sequence of simpler operations. We have included these primitives regardless, so that they can easily be allocated shorter opcodes in a future revision of TVM—or removed for good. + Some stack manipulation instructions have two mnemonics: one Forth- style (e.g., `-ROT`), the other conforming to the usual rules for identifiers (e.g., `ROTREV`). Whenever a stack manipulation primitive (e.g., `PICK`) accepts an @@ -2691,70 +1533,72 @@ otherwise a range check exception happens before any further checks. ### A.2.1. Basic stack manipulation primitives. -* `00` — **NOP**, does nothing. -* `01` — **XCHG s1**, also known as **SWAP**. -* `0i` — **XCHG s(i)** or **XCHG s0,s(i)**, interchanges the top of the stack with `s(i)`, `1 ≤ i ≤ 15`. -* `10ij` — **XCHG s(i),s(j)**, `1 ≤ i < j ≤ 15`, interchanges `s(i)` with `s(j)`. -* `11ii` — **XCHG s0,s(ii)**, with `0 ≤ ii ≤ 255`. -* `1i` — **XCHG s1,s(i)**, `2 ≤ i ≤ 15`. -* `2i` — **PUSH s(i)**, `0 ≤ i ≤ 15`, pushes a copy of the old `s(i)` into the stack. -* `20` — **PUSH s0**, also known as **DUP**. -* `21` — **PUSH s1**, also known as **OVER**. -* `3i` — **POP s(i)**, `0 ≤ i ≤ 15`, pops the old top-of-stack value into the old `s(i)`. -* `30` — **POP s0**, also known as **DROP**, discards the top-of-stack value. -* `31` — **POP s1**, also known as **NIP**. +* `00` — `NOP`, does nothing. +* `01` — `XCHG s1`, also known as `SWAP`. +* `0i` — `XCHG s(i)` or `XCHG s0,s(i)`, interchanges the top of the stack with `s(i)`, `1 ≤ i ≤ 15`. +* `10ij` — `XCHG s(i),s(j)`, `1 ≤ i < j ≤ 15`, interchanges `s(i)` with `s(j)`. +* `11ii` — `XCHG s0,s(ii)`, with `0 ≤ ii ≤ 255`. +* `1i` — `XCHG s1,s(i)`, `2 ≤ i ≤ 15`. +* `2i` — `PUSH s(i)`, `0 ≤ i ≤ 15`, pushes a copy of the old `s(i)` into the stack. +* `20` — `PUSH s0`, also known as `DUP`. +* `21` — `PUSH s1`, also known as `OVER`. +* `3i` — `POP s(i)`, `0 ≤ i ≤ 15`, pops the old top-of-stack value into the old `s(i)`. +* `30` — `POP s0`, also known as `DROP`, discards the top-of-stack value. +* `31` — `POP s1`, also known as `NIP`. ### A.2.2. Compound stack manipulation primitives. Parameters `i`, `j`, and `k` of the following primitives all are 4-bit integers in the range `0 . . . 15`. -* `4ijk` — **XCHG3 s(i),s(j),s(k)**, equivalent to **XCHG s2,s(i); XCHG s1,s(j); XCHG s0,s(k)**, with `0 ≤ i, j, k ≤ 15`. -* `50ij` — **XCHG2 s(i),s(j)**, equivalent to **XCHG s1,s(i); XCHG s(j)**. -* `51ij` — **XCPU s(i),s(j)**, equivalent to **XCHG s(i); PUSH s(j)**. -* `52ij` — **PUXC s(i),s(j − 1)**, equivalent to **PUSH s(i); SWAP; XCHG s(j)**. -* `53ij` — **PUSH2 s(i),s(j)**, equivalent to **PUSH s(i); PUSH s(j + 1)**. -* `540ijk` — **XCHG3 s(i),s(j),s(k)** (long form). -* `541ijk` — **XC2PU s(i),s(j),s(k)**, equivalent to **XCHG2 s(i),s(j); PUSH s(k)**. -* `542ijk` — **XCPUXC s(i),s(j),s(k−1)**, equivalent to **XCHG s1,s(i); PUXC s(j),s(k − 1)**. -* `543ijk` — **XCPU2 s(i),s(j),s(k)**, equivalent to **XCHG s(i); PUSH2 s(j),s(k)**. -* `544ijk` — **PUXC2 s(i),s(j − 1),s(k − 1)**, equivalent to **PUSH s(i); XCHG s2; XCHG2 s(j),s(k)**. -* `545ijk` — **PUXCPU s(i),s(j−1),s(k−1)**, equivalent to **PUXC s(i),s(j− 1); PUSH s(k)**. -* `546ijk` — **PU2XC s(i),s(j−1),s(k−2)**, equivalent to **PUSH s(i); SWAP; PUXC s(j),s(k − 1)**. -* `547ijk` — **PUSH3 s(i),s(j),s(k)**, equivalent to **PUSH s(i); PUSH2 s(j + 1),s(k + 1)**. -* `54C_` — **unused**. + +* `4ijk` — `XCHG3 s(i),s(j),s(k)`, equivalent to `XCHG s2,s(i); XCHG s1,s(j); XCHG s0,s(k)`, with `0 ≤ i, j, k ≤ 15`. +* `50ij` — `XCHG2 s(i),s(j)`, equivalent to `XCHG s1,s(i); XCHG s(j)`. +* `51ij` — `XCPU s(i),s(j)`, equivalent to `XCHG s(i); PUSH s(j)`. +* `52ij` — `PUXC s(i),s(j − 1)`, equivalent to `PUSH s(i); SWAP; XCHG s(j)`. +* `53ij` — `PUSH2 s(i),s(j)`, equivalent to `PUSH s(i); PUSH s(j + 1)`. +* `540ijk` — `XCHG3 s(i),s(j),s(k)` (long form). +* `541ijk` — `XC2PU s(i),s(j),s(k)`, equivalent to `XCHG2 s(i),s(j); PUSH s(k)`. +* `542ijk` — `XCPUXC s(i),s(j),s(k−1)`, equivalent to `XCHG s1,s(i); PUXC s(j),s(k − 1)`. +* `543ijk` — `XCPU2 s(i),s(j),s(k)`, equivalent to `XCHG s(i); PUSH2 s(j),s(k)`. +* `544ijk` — `PUXC2 s(i),s(j − 1),s(k − 1)`, equivalent to `PUSH s(i); XCHG s2; XCHG2 s(j),s(k)`. +* `545ijk` — `PUXCPU s(i),s(j−1),s(k−1)`, equivalent to `PUXC s(i),s(j−1); PUSH s(k)`. +* `546ijk` — `PU2XC s(i),s(j−1),s(k−2)`, equivalent to `PUSH s(i); SWAP; PUXC s(j),s(k − 1)`. +* `547ijk` — `PUSH3 s(i),s(j),s(k)`, equivalent to `PUSH s(i); PUSH2 s(j + 1),s(k + 1)`. +* `54C_` — `unused`. + ### A.2.3. Exotic stack manipulation primitives. -* `55ij` — **BLKSWAP i+1,j+1**, permutes two blocks `s(j + i + 1)…s(j + 1)` and `s(j)…s0`, for `0 ≤ i, j ≤ 15`. Equivalent to **REVERSE i+1,j+1; REVERSE j+1,0; REVERSE i+j+2,0**. -* `5513` — **ROT2** or **2ROT** (`a b c d e f – c d e f a b`), rotates the three topmost pairs of stack entries. -* `550i` — **ROLL i+1**, rotates the top `i+1` stack entries. Equivalent to **BLKSWAP 1,i+1**. -* `55i0` — **ROLLREV i+1** or **-ROLL i+1**, rotates the top `i+1` stack entries in the other direction. Equivalent to **BLKSWAP i+1,1**. -* `56ii` — **PUSH s(ii)** for `0 ≤ ii ≤ 255`. -* `57ii` — **POP s(ii)** for `0 ≤ ii ≤ 255`. -* `58` — **ROT** (`a b c – b c a`), equivalent to **BLKSWAP 1,2** or to **XCHG2 s2,s1**. -* `59` — **ROTREV** or **-ROT** (`a b c – c a b`), equivalent to **BLKSWAP 2,1** or to **XCHG2 s2,s2**. -* `5A` — **SWAP2** or **2SWAP** (`a b c d – c d a b`), equivalent to **BLKSWAP 2,2** or to **XCHG2 s3,s2**. -* `5B` — **DROP2** or **2DROP** (`a b –`), equivalent to **DROP; DROP**. -* `5C` — **DUP2** or **2DUP** (`a b – a b a b`), equivalent to **PUSH2 s1,s0**. -* `5D` — **OVER2** or **2OVER** (`a b c d – a b c d a b`), equivalent to **PUSH2 s3,s2**. -* `5Eij` — **REVERSE i+2,j**, reverses the order of `s(j+i+1)…s(j)` for `0 ≤ i, j ≤ 15`; equivalent to a sequence of `⌊i/2⌋+1` **XCHG**s. -* `5F0i` — **BLKDROP i**, equivalent to **DROP** performed `i` times. -* `5Fij` — **BLKPUSH i,j**, equivalent to **PUSH s(j)** performed `i` times, `1 ≤ i ≤ 15`, `0 ≤ j ≤ 15`. -* `60` — **PICK** or **PUSHX**, pops integer `i` from the stack, then performs **PUSH s(i)**. -* `61` — **ROLLX**, pops integer `i` from the stack, then performs **BLKSWAP 1,i**. -* `62` — **-ROLLX** or **ROLLREVX**, pops integer `i` from the stack, then performs **BLKSWAP i,1**. -* `63` — **BLKSWX**, pops integers `i,j` from the stack, then performs **BLKSWAP i,j**. -* `64` — **REVX**, pops integers `i,j` from the stack, then performs **REVERSE i,j**. -* `65` — **DROPX**, pops integer `i` from the stack, then performs **BLKDROP i**. -* `66` — **TUCK** (`a b – b a b`), equivalent to **SWAP; OVER** or to **XCPU s1,s1**. -* `67` — **XCHGX**, pops integer `i` from the stack, then performs **XCHG s(i)**. -* `68` — **DEPTH**, pushes the current depth of the stack. -* `69` — **CHKDEPTH**, pops integer `i` from the stack, then checks whether there are at least `i` elements, generating a stack underflow exception otherwise. -* `6A` — **ONLYTOPX**, pops integer `i` from the stack, then removes all but the top `i` elements. -* `6B` — **ONLYX**, pops integer `i` from the stack, then leaves only the bottom `i` elements. Approximately equivalent to **DEPTH; SWAP; SUB; DROPX**. -* `6C00–6C0F` — **reserved** for stack operations. -* `6Cij` — **BLKDROP2 i,j**, drops `i` stack elements under the top `j` elements, where `1 ≤ i ≤ 15` and `0 ≤ j ≤ 15`. Equivalent to **REVERSE i+j,0; BLKDROP i; REVERSE j,0**. +* `55ij` — `BLKSWAP i+1,j+1`, permutes two blocks `s(j+i+1)…s(j+1)` and `s(j)…s0`, for `0 ≤ i, j ≤ 15`. Equivalent to `REVERSE i+1,j+1; REVERSE j+1,0; REVERSE i+j+2,0`. +* `5513` — `ROT2` or `2ROT` (`a b c d e f – c d e f a b`), rotates the three topmost pairs of stack entries. +* `550i` — `ROLL i+1`, rotates the top `i+1` stack entries. Equivalent to `BLKSWAP 1,i+1`. +* `55i0` — `ROLLREV i+1` or `-ROLL i+1`, rotates the top `i+1` stack entries in the other direction. Equivalent to `BLKSWAP i+1,1`. +* `56ii` — `PUSH s(ii)` for `0 ≤ ii ≤ 255`. +* `57ii` — `POP s(ii)` for `0 ≤ ii ≤ 255`. +* `58` — `ROT` (`a b c – b c a`), equivalent to `BLKSWAP 1,2` or to `XCHG2 s2,s1`. +* `59` — `ROTREV` or `-ROT` (`a b c – c a b`), equivalent to `BLKSWAP 2,1` or to `XCHG2 s2,s2`. +* `5A` — `SWAP2` or `2SWAP` (`a b c d – c d a b`), equivalent to `BLKSWAP 2,2` or to `XCHG2 s3,s2`. +* `5B` — `DROP2` or `2DROP` (`a b –`), equivalent to `DROP; DROP`. +* `5C` — `DUP2` or `2DUP` (`a b – a b a b`), equivalent to `PUSH2 s1,s0`. +* `5D` — `OVER2` or `2OVER` (`a b c d – a b c d a b`), equivalent to `PUSH2 s3,s2`. +* `5Eij` — `REVERSE i+2,j`, reverses the order of `s(j+i+1)…s(j)` for `0 ≤ i, j ≤ 15`; equivalent to a sequence of `⌊i/2⌋+1` `XCHG`s. +* `5F0i` — `BLKDROP i`, equivalent to `DROP` performed `i` times. +* `5Fij` — `BLKPUSH i,j`, equivalent to `PUSH s(j)` performed `i` times, `1 ≤ i ≤ 15`, `0 ≤ j ≤ 15`. +* `60` — `PICK` or `PUSHX`, pops integer `i` from the stack, then performs `PUSH s(i)`. +* `61` — `ROLLX`, pops integer `i` from the stack, then performs `BLKSWAP 1,i`. +* `62` — `-ROLLX` or `ROLLREVX`, pops integer `i` from the stack, then performs `BLKSWAP i,1`. +* `63` — `BLKSWX`, pops integers `i,j` from the stack, then performs `BLKSWAP i,j`. +* `64` — `REVX`, pops integers `i,j` from the stack, then performs `REVERSE i,j`. +* `65` — `DROPX`, pops integer `i` from the stack, then performs `BLKDROP i`. +* `66` — `TUCK` (`a b – b a b`), equivalent to `SWAP; OVER` or to `XCPU s1,s1`. +* `67` — `XCHGX`, pops integer `i` from the stack, then performs `XCHG s(i)`. +* `68` — `DEPTH`, pushes the current depth of the stack. +* `69` — `CHKDEPTH`, pops integer `i` from the stack, then checks whether there are at least `i` elements, generating a stack underflow exception otherwise. +* `6A` — `ONLYTOPX`, pops integer `i` from the stack, then removes all but the top `i` elements. +* `6B` — `ONLYX`, pops integer `i` from the stack, then leaves only the bottom `i` elements. Approximately equivalent to `DEPTH; SWAP; SUB; DROPX`. +* `6C00–6C0F` — `reserved` for stack operations. +* `6Cij` — `BLKDROP2 i,j`, drops `i` stack elements under the top `j` elements, where `1 ≤ i ≤ 15` and `0 ≤ j ≤ 15`. Equivalent to `REVERSE i+j,0; BLKDROP i; REVERSE j,0`. ## A.3 Tuple, List, and Null primitives @@ -3368,81 +2212,104 @@ All these primitives first check whether there is enough space in the Builder, a ## A.8 Continuation and control flow primitives +### A.8.1. Unconditional control flow primitives. + +* `D8` — `EXECUTE` or `CALLX` `(c – )`, calls or executes continuation `c` (i.e., `cc ← c ◦0 cc`). +* `D9` — `JMPX` `(c – )`, jumps, or transfers control, to continuation `c` (i.e., `cc ← c ◦0 c0, or rather cc ← (c ◦0 c0) ◦1 c1`). The remainder of the previous current continuation `cc` is discarded. +* `DApr` — `CALLXARGS p,r` `(c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. +* `DB0p` — `CALLXARGS p,−1` `(c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. +* `DB1p` — `JMPXARGS p` `(c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). +* `DB2r` — `RETARGS r`, returns to `c0`, with `0 ≤ r ≤ 15` return values taken from the current stack. +* `DB30` — `RET` or `RETTRUE`, returns to the continuation at `c0` (i.e., performs `cc ← c0`). The remainder of the current continuation `cc` is discarded. Approximately equivalent to `PUSH c0; JMPX`. +* `DB31` — `RETALT` or `RETFALSE`, returns to the continuation at `c1` (i.e., `cc ← c1`). Approximately equivalent to `PUSH c1; JMPX`. +* `DB32` — `BRANCH` or `RETBOOL` `(f – )`, performs `RETTRUE` if integer `f ≠ 0`, or `RETFALSE` if `f = 0`. +* `DB34` — `CALLCC` `(c – )`, call with current continuation, transfers control to `c`, pushing the old value of `cc` into `c`’s stack (instead of discarding it or writing it into new `c0`). +* `DB35` — `JMPXDATA` `(c – )`, similar to `CALLCC`, but the remainder of the current continuation (the old value of `cc`) is converted into a Slice before pushing it into the stack of `c`. +* `DB36pr` — `CALLCCARGS p,r` `(c – )`, similar to `CALLXARGS`, but pushes the old value of `cc` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `cc.nargs` to `−1 ≤ r ≤ 14`. +* `DB38` — `CALLXVARARGS` `(c p r – )`, similar to `CALLXARGS`, but takes `−1 ≤ p, r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1 . . . 254`. +* `DB39` — `RETVARARGS` `(p r – )`, similar to `RETARGS`. +* `DB3A` — `JMPXVARARGS` `(c p r – )`, similar to `JMPXARGS`. +* `DB3B` — `CALLCCVARARGS` `(c p r – )`, similar to `CALLCCARGS`. +* `DB3C` — `CALLREF`, equivalent to `PUSHREFCONT; CALLX`. +* `DB3D` — `JMPREF`, equivalent to `PUSHREFCONT; JMPX`. +* `DB3E` — `JMPREFDATA`, equivalent to `PUSHREFCONT; JMPXDATA`. +* `DB3F` — `RETDATA`, equivalent to `PUSH c0; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. + + ### A.8.2. Conditional control flow primitives -* `DC` — **IFRET** `(f – )`, performs a **RET**, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. -* `DD` — **IFNOTRET** `(f – )`, performs a **RET**, but only if integer `f` is zero. -* `DE` — **IF** `(f c – )`, performs **EXECUTE** for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. -* `DF` — **IFNOT** `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. -* `E0` — **IFJMP** `(f c – )`, jumps to `c` (similarly to **JMPX**), but only if `f` is non-zero. -* `E1` — **IFNOTJMP** `(f c – )`, jumps to `c` (similarly to **JMPX**), but only if `f` is zero. -* `E2` — **IFELSE** `(f c c0 – )`, if integer `f` is non-zero, executes `c`, otherwise executes `c0`. Equivalent to `CONDSELCHK; EXECUTE`. -* `E300` — **IFREF** `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. -* `E301` — **IFNOTREF** `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. -* `E302` — **IFJMPREF** `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. -* `E303` — **IFNOTJMPREF** `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. -* `E304` — **CONDSEL** `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. -* `E305` — **CONDSELCHK** `(f x y – x or y)`, same as **CONDSEL**, but first checks whether `x` and `y` have the same type. -* `E308` — **IFRETALT** `(f – )`, performs **RETALT** if integer `f ≠ 0`. -* `E309` — **IFNOTRETALT** `(f – )`, performs **RETALT** if integer `f = 0`. -* `E30D` — **IFREFELSE** `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. -* `E30E` — **IFELSEREF** `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. -* `E30F` — **IFREFELSEREF** `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. +* `DC` — `IFRET` `(f – )`, performs a `RET`, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. +* `DD` — `IFNOTRET` `(f – )`, performs a `RET`, but only if integer `f` is zero. +* `DE` — `IF` `(f c – )`, performs `EXECUTE` for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. +* `DF` — `IFNOT` `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. +* `E0` — `IFJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is non-zero. +* `E1` — `IFNOTJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is zero. +* `E2` — `IFELSE` `(f c c0 – )`, if integer `f` is non-zero, executes `c`, otherwise executes `c0`. Equivalent to `CONDSELCHK; EXECUTE`. +* `E300` — `IFREF` `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. +* `E301` — `IFNOTREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. +* `E302` — `IFJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. +* `E303` — `IFNOTJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. +* `E304` — `CONDSEL` `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. +* `E305` — `CONDSELCHK` `(f x y – x or y)`, same as `CONDSEL`, but first checks whether `x` and `y` have the same type. +* `E308` — `IFRETALT` `(f – )`, performs `RETALT` if integer `f ≠ 0`. +* `E309` — `IFNOTRETALT` `(f – )`, performs `RETALT` if integer `f = 0`. +* `E30D` — `IFREFELSE` `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. +* `E30E` — `IFELSEREF` `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. +* `E30F` — `IFREFELSEREF` `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. * `E310–E31F` — reserved for loops with break operators (cf. A.8.3). -* `E39_n` — **IFBITJMP n** `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs **JMPX** to continuation `c`. Value `x` is left in the stack. -* `E3B_n` — **IFNBITJMP n** `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. -* `E3D_n` — **IFBITJMPREF n** `(x – x)`, performs a **JMPREF** if bit `0 ≤ n ≤ 31` is set in integer `x`. -* `E3F_n` — **IFNBITJMPREF n** `(x – x)`, performs a **JMPREF** if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `E39_n` — `IFBITJMP n` `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs `JMPX` to continuation `c`. Value `x` is left in the stack. +* `E3B_n` — `IFNBITJMP n` `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `E3D_n` — `IFBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is set in integer `x`. +* `E3F_n` — `IFNBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is not set in integer `x`. ---- ### A.8.3. Control flow primitives: loops -Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. 4.1.5), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have \*BRK versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for \*ENDBRK versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for \*ENDBRK versions). - -* `E4` — **REPEAT** `(n c – )`, executes continuation `c` `n` times, if integer `n` is non-negative. If `n ≥ 2^31` or `n < −2^31`, generates a range check exception. Notice that a **RET** inside the code of `c` works as a continue, not as a break. One should use either alternative (experimental) loops or alternative **RETALT** (along with a **SETEXITALT** before the loop) to break out of a loop. -* `E5` — **REPEATEND** `(n – )`, similar to **REPEAT**, but it is applied to the current continuation `cc`. -* `E6` — **UNTIL** `(c – )`, executes continuation `c`, then pops an integer `x` from the resulting stack. If `x` is zero, performs another iteration of this loop. Implemented with extraordinary continuation `ec_until`. -* `E7` — **UNTILEND** `( – )`, similar to **UNTIL**, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs a **RET**. -* `E8` — **WHILE** `(c0 c – )`, executes `c0` and pops an integer `x` from the resulting stack. If `x = 0`, exits the loop and transfers control to the original `cc`. If `x ≠ 0`, executes `c`, and then begins a new iteration. -* `E9` — **WHILEEND** `(c0 – )`, similar to **WHILE**, but uses the current continuation `cc` as the loop body. -* `EA` — **AGAIN** `(c – )`, similar to **REPEAT**, but executes `c` infinitely many times. A **RET** only begins a new iteration of the infinite loop, which can be exited only by an exception, or a **RETALT** (or an explicit **JMPX**). -* `EB` — **AGAINEND** `( – )`, similar to **AGAIN**, but performed with respect to the current continuation `cc`. -* `E314` — **REPEATBRK** `(n c – )`, similar to **REPEAT**, but also sets `c1` to the original `cc` after saving the old value of `c1` into the savelist of the original `cc`. In this way **RETALT** could be used to break out of the loop body. -* `E315` — **REPEATENDBRK** `(n – )`, similar to **REPEATEND**, but also sets `c1` to the original `c0` after saving the old value of `c1` into the savelist of the original `c0`. Equivalent to `SAMEALTSAVE; REPEATEND`. -* `E316` — **UNTILBRK** `(c – )`, similar to **UNTIL**, but also modifies `c1` in the same way as **REPEATBRK**. -* `E317` — **UNTILENDBRK** `( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. -* `E318` — **WHILEBRK** `(c0 c – )`, similar to **WHILE**, but also modifies `c1` in the same way as **REPEATBRK**. -* `E319` — **WHILEENDBRK** `(c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. -* `E31A` — **AGAINBRK** `(c – )`, similar to **AGAIN**, but also modifies `c1` in the same way as **REPEATBRK**. -* `E31B` — **AGAINENDBRK** `( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. +Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. 4.1.5), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have `*BRK` versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for `*ENDBRK` versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for `*ENDBRK` versions). + +* `E4` — `REPEAT` `(n c – )`, executes continuation `c` `n` times, if integer `n` is non-negative. If `n ≥ 2^31` or `n < −2^31`, generates a range check exception. Notice that a `RET` inside the code of `c` works as a continue, not as a break. One should use either alternative (experimental) loops or alternative `RETALT` (along with a `SETEXITALT` before the loop) to break out of a loop. +* `E5` — `REPEATEND` `(n – )`, similar to `REPEAT`, but it is applied to the current continuation `cc`. +* `E6` — `UNTIL` `(c – )`, executes continuation `c`, then pops an integer `x` from the resulting stack. If `x` is zero, performs another iteration of this loop. Implemented with extraordinary continuation `ec_until`. +* `E7` — `UNTILEND` `( – )`, similar to `UNTIL`, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs a `RET`. +* `E8` — `WHILE` `(c0 c – )`, executes `c0` and pops an integer `x` from the resulting stack. If `x = 0`, exits the loop and transfers control to the original `cc`. If `x ≠ 0`, executes `c`, and then begins a new iteration. +* `E9` — `WHILEEND` `(c0 – )`, similar to `WHILE`, but uses the current continuation `cc` as the loop body. +* `EA` — `AGAIN` `(c – )`, similar to `REPEAT`, but executes `c` infinitely many times. A `RET` only begins a new iteration of the infinite loop, which can be exited only by an exception, or a `RETALT` (or an explicit `JMPX`). +* `EB` — `AGAINEND` `( – )`, similar to `AGAIN`, but performed with respect to the current continuation `cc`. +* `E314` — `REPEATBRK` `(n c – )`, similar to `REPEAT`, but also sets `c1` to the original `cc` after saving the old value of `c1` into the savelist of the original `cc`. In this way `RETALT` could be used to break out of the loop body. +* `E315` — `REPEATENDBRK` `(n – )`, similar to `REPEATEND`, but also sets `c1` to the original `c0` after saving the old value of `c1` into the savelist of the original `c0`. Equivalent to `SAMEALTSAVE; REPEATEND`. +* `E316` — `UNTILBRK` `(c – )`, similar to `UNTIL`, but also modifies `c1` in the same way as `REPEATBRK`. +* `E317` — `UNTILENDBRK` `( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. +* `E318` — `WHILEBRK` `(c0 c – )`, similar to `WHILE`, but also modifies `c1` in the same way as `REPEATBRK`. +* `E319` — `WHILEENDBRK` `(c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. +* `E31A` — `AGAINBRK` `(c – )`, similar to `AGAIN`, but also modifies `c1` in the same way as `REPEATBRK`. +* `E31B` — `AGAINENDBRK` `( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. ---- -### A.9 Exception generating and handling primitives +--- +## A.9 Exception generating and handling primitives -#### A.9.1. Throwing exceptions +### A.9.1. Throwing exceptions -* `F22_nn` — **THROW nn** `( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. -* `F26_nn` — **THROWIF nn** `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. -* `F2A_nn` — **THROWIFNOT nn** `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. -* `F2C4_nn` — **THROW nn** for `0 ≤ nn < 2^11`, an encoding of **THROW nn** for larger values. -* `F2CC_nn` — **THROWARG nn** `(x – x nn)`, throws exception `0 ≤ nn < 2^11` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. -* `F2D4_nn` — **THROWIF nn** `(f – )` for `0 ≤ nn < 2^11`. -* `F2DC_nn` — **THROWARGIF nn** `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f ≠ 0`. -* `F2E4_nn` — **THROWIFNOT nn** `(f – )` for `0 ≤ nn < 2^11`. -* `F2EC_nn` — **THROWARGIFNOT nn** `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f = 0`. -* `F2F0` — **THROWANY** `(n – 0 n)`, throws exception `0 ≤ n < 2^16` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. -* `F2F1` — **THROWARGANY** `(x n – x n)`, throws exception `0 ≤ n < 2^16` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. -* `F2F2` — **THROWANYIF** `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f ≠ 0`. -* `F2F3` — **THROWARGANYIF** `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f ≠ 0`. -* `F2F4` — **THROWANYIFNOT** `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f = 0`. -* `F2F5` — **THROWARGANYIFNOT** `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f = 0`. +* `F22_nn` — `THROW nn` `( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. +* `F26_nn` — `THROWIF nn` `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. +* `F2A_nn` — `THROWIFNOT nn` `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. +* `F2C4_nn` — `THROW nn` for `0 ≤ nn < 2^11`, an encoding of `THROW nn` for larger values. +* `F2CC_nn` — `THROWARG nn` `(x – x nn)`, throws exception `0 ≤ nn < 2^11` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. +* `F2D4_nn` — `THROWIF nn` `(f – )` for `0 ≤ nn < 2^11`. +* `F2DC_nn` — `THROWARGIF nn` `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f ≠ 0`. +* `F2E4_nn` — `THROWIFNOT nn` `(f – )` for `0 ≤ nn < 2^11`. +* `F2EC_nn` — `THROWARGIFNOT nn` `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f = 0`. +* `F2F0` — `THROWANY` `(n – 0 n)`, throws exception `0 ≤ n < 2^16` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. +* `F2F1` — `THROWARGANY` `(x n – x n)`, throws exception `0 ≤ n < 2^16` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. +* `F2F2` — `THROWANYIF` `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f ≠ 0`. +* `F2F3` — `THROWARGANYIF` `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f ≠ 0`. +* `F2F4` — `THROWANYIFNOT` `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f = 0`. +* `F2F5` — `THROWARGANYIFNOT` `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f = 0`. -#### A.9.2. Catching and handling exceptions +### A.9.2. Catching and handling exceptions -* `F2FF` — **TRY** `(c c0 – )`, sets `c2` to `c0`, saving the old value of `c2` both into the savelist of `c0` and into the savelist of the current continuation. Then runs `c`. If `c` does not throw any exceptions, the original value of `c2` is restored. If an exception occurs, execution is transferred to `c0`. -* `F3pr` — **TRYARGS p,r** `(c c0 – )`, similar to **TRY**, but with **CALLARGS p,r** internally used instead of **EXECUTE**. +* `F2FF` — `TRY` `(c c0 – )`, sets `c2` to `c0`, saving the old value of `c2` both into the savelist of `c0` and into the savelist of the current continuation. Then runs `c`. If `c` does not throw any exceptions, the original value of `c2` is restored. If an exception occurs, execution is transferred to `c0`. +* `F3pr` — `TRYARGS p,r` `(c c0 – )`, similar to `TRY`, but with `CALLARGS p,r` internally used instead of `EXECUTE`. --- @@ -3462,319 +2329,310 @@ Most of the dictionary primitives listed below accept and return dictionaries in Opcodes starting with `F4` and `F5` are reserved for dictionary operations. -## A.10.1. Dictionary creation. +### A.10.1. Dictionary creation. -* `6D` — **NEWDICT** `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for **PUSHNULL**, cf. A.3.1. -* `6E` — **DICTEMPTY** `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for **ISNULL**, cf. A.3.1. +* `6D` — `NEWDICT` `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for `PUSHNULL`, cf. A.3.1. +* `6E` — `DICTEMPTY` `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for `ISNULL`, cf. A.3.1. -## A.10.2. Dictionary serialization and deserialization. +--- + +### A.10.2. Dictionary serialization and deserialization. + +* `CE` — `STDICTS` `(s b – b 0)`, stores a `Slice`-represented dictionary `s` into `Builder` `b`. It is actually a synonym for `STSLICE`. +* `F400` — `STDICT` or `STOPTREF` `(D b – b 0)`, stores dictionary `D` into `Builder` `b`, returing the resulting `Builder` `b 0`. In other words, if `D` is a cell, performs `STONE` and `STREF`; if `D` is `Null`, performs `NIP` and `STZERO`; otherwise throws a type checking exception. +* `F401` — `SKIPDICT` or `SKIPOPTREF` `(s – s 0)`, equivalent to `LDDICT`; `NIP` +* `F402` — `LDDICTS` `(s – s 0 s 00)`, loads (parses) a (`Slice`-represented) dictionary `s 0` from `Slice` `s`, and returns the remainder of `s` as `s 00`. This is a “split function” for all `HashmapE(n, X)` dictionary types. +* `F403` — `PLDDICTS` `(s – s 0)`, preloads a (`Slice`-represented) dictionary `s 0` from `Slice` `s`. Approximately equivalent to `LDDICTS`; `DROP`. +* `F404` — `LDDICT` or `LDOPTREF` `(s – D s0)`, loads (parses) a dictionary `D` from `Slice` `s`, and returns the remainder of `s` as `s 0`. May be applied to dictionaries or to values of arbitrary `(ˆY ) ?` types. +* `F405` — `PLDDICT` or `PLDOPTREF` `(s – D)`, preloads a dictionary `D` from `Slice` `s`. Approximately equivalent to `LDDICT`; `DROP`. +* `F406` — `LDDICTQ` `(s – D s0 −1 or s 0)`, a quiet version of `LDDICT`. +* `F407` — `PLDDICTQ` `(s – D −1 or 0)`, a quiet version of `PLDDICT`. -* `CE` — **STDICTS** `(s b – b 0)`, stores a `Slice`-represented dictionary `s` into `Builder` `b`. It is actually a synonym for **STSLICE**. -* `F400` — **STDICT** or **STOPTREF** `(D b – b 0)`, stores dictionary `D` into `Builder` `b`, returing the resulting `Builder` `b 0`. In other words, if `D` is a cell, performs **STONE** and **STREF**; if `D` is `Null`, performs **NIP** and **STZERO**; otherwise throws a type checking exception. -* `F401` — **SKIPDICT** or **SKIPOPTREF** `(s – s 0)`, equivalent to **LDDICT**; **NIP** -* `F402` — **LDDICTS** `(s – s 0 s 00)`, loads (parses) a (`Slice`-represented) dictionary `s 0` from `Slice` `s`, and returns the remainder of `s` as `s 00`. This is a “split function” for all `HashmapE(n, X)` dictionary types. -* `F403` — **PLDDICTS** `(s – s 0)`, preloads a (`Slice`-represented) dictionary `s 0` from `Slice` `s`. Approximately equivalent to **LDDICTS**; **DROP**. -* `F404` — **LDDICT** or **LDOPTREF** `(s – D s0)`, loads (parses) a dictionary `D` from `Slice` `s`, and returns the remainder of `s` as `s 0`. May be applied to dictionaries or to values of arbitrary `(ˆY ) ?` types. -* `F405` — **PLDDICT** or **PLDOPTREF** `(s – D)`, preloads a dictionary `D` from `Slice` `s`. Approximately equivalent to **LDDICT**; **DROP**. -* `F406` — **LDDICTQ** `(s – D s0 −1 or s 0)`, a quiet version of **LDDICT**. -* `F407` — **PLDDICTQ** `(s – D −1 or 0)`, a quiet version of **PLDDICT**. -## A.10.3. Get dictionary operations. +### A.10.3. Get dictionary operations. + +* `F40A` — `DICTGET` `(k D n – x −1 or 0)`, looks up key `k` (represented by a `Slice`, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the value found as a `Slice` `x`. +* `F40B` — `DICTGETREF` `(k D n – c −1 or 0)`, similar to `DICTGET`, but with a `LDREF`; `ENDS` applied to `x` on success. This operation is useful for dictionaries of type `HashmapE(n, ˆY )`. +* `F40C` — `DICTIGET` `(i D n – x −1 or 0)`, similar to `DICTGET`, but with a signed (big-endian) n-bit `Integer` `i` as a key. If `i` does not fit into n bits, returns `0`. If `i` is a `NaN`, throws an integer overflow exception. +* `F40D` — `DICTIGETREF` `(i D n – c −1 or 0)`, combines `DICTIGET` with `DICTGETREF`: it uses signed n-bit `Integer` `i` as a key and returns a `Cell` instead of a `Slice` on success. +* `F40E` — `DICTUGET` `(i D n – x −1 or 0)`, similar to `DICTIGET`, but with unsigned (big-endian) n-bit `Integer` `i` used as a key. +* `F40F` — `DICTUGETREF` `(i D n – c −1 or 0)`, similar to `DICTIGETREF`, but with an unsigned n-bit `Integer` key `i`. -* `F40A` — **DICTGET** `(k D n – x −1 or 0)`, looks up key `k` (represented by a `Slice`, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the value found as a `Slice` `x`. -* `F40B` — **DICTGETREF** `(k D n – c −1 or 0)`, similar to **DICTGET**, but with a **LDREF**; **ENDS** applied to `x` on success. This operation is useful for dictionaries of type `HashmapE(n, ˆY )`. -* `F40C` — **DICTIGET** `(i D n – x −1 or 0)`, similar to **DICTGET**, but with a signed (big-endian) n-bit `Integer` `i` as a key. If `i` does not fit into n bits, returns `0`. If `i` is a `NaN`, throws an integer overflow exception. -* `F40D` — **DICTIGETREF** `(i D n – c −1 or 0)`, combines **DICTIGET** with **DICTGETREF**: it uses signed n-bit `Integer` `i` as a key and returns a `Cell` instead of a `Slice` on success. -* `F40E` — **DICTUGET** `(i D n – x −1 or 0)`, similar to **DICTIGET**, but with unsigned (big-endian) n-bit `Integer` `i` used as a key. -* `F40F` — **DICTUGETREF** `(i D n – c −1 or 0)`, similar to **DICTIGETREF**, but with an unsigned n-bit `Integer` key `i`. - 117 - A.10. Dictionary manipulation primitives ## A.10.4. Set/Replace/Add dictionary operations. The mnemonics of the following dictionary primitives are constructed in a systematic fashion according to the regular expression `DICT[, I, U](SET, REPLACE, ADD)[GET][REF]` depending on the type of the key used (a `Slice` or a signed or unsigned `Integer`), the dictionary operation to be performed, and the way the values are accepted and returned (as `Cells` or as `Slices`). Therefore, we provide a detailed description only for some primitives, assuming that this information is sufficient for the reader to understand the precise action of the remaining primitives. -* `F412` — **DICTSET** `(x k D n – D0)`, sets the value associated with n-bit key `k` (represented by a `Slice` as in **DICTGET**) in dictionary `D` (also represented by a `Slice`) to value `x` (again a `Slice`), and returns the resulting dictionary as `D0`. -* `F413` — **DICTSETREF** `(c k D n – D0)`, similar to **DICTSET**, but with the value set to a reference to `Cell` `c`. -* `F414` — **DICTISET** `(x i D n – D0)`, similar to **DICTSET**, but with the key represented by a (big-endian) signed n-bit integer `i`. If `i` does not fit into n bits, a range check exception is generated. -* `F415` — **DICTISETREF** `(c i D n – D0)`, similar to **DICTSETREF**, but with the key a signed n-bit integer as in **DICTISET**. -* `F416` — **DICTUSET** `(x i D n – D0)`, similar to **DICTISET**, but with `i` an unsigned n-bit integer. -* `F417` — **DICTUSETREF** `(c i D n – D0)`, similar to **DICTISETREF**, but with `i` unsigned. -* `F41A` — **DICTSETGET** `(x k D n – D0 y −1 or D0 0)`, combines **DICTSET** with **DICTGET**: it sets the value corresponding to key `k` to `x`, but also returns the old value `y` associated with the key in question, if present. -* `F41B` — **DICTSETGETREF** `(c k D n – D0 c 0 −1 or D0 0)`, combines **DICTSETREF** with **DICTGETREF** similarly to **DICTSETGET**. -* `F41C` — **DICTISETGET** `(x i D n – D0 y −1 or D0 0)`, similar to **DICTSETGET**, but with the key represented by a big-endian signed n-bit `Integer` `i` -* `F41D` — **DICTISETGETREF** `(c i D n – D0 c 0 −1 or D0 0)`, a version of **DICTSETGETREF** with signed `Integer` `i` as a key. -* `F41E` — **DICTUSETGET** `(x i D n – D0 y −1 or D0 0)`, similar to **DICTISETGET**, but with `i` an unsigned n-bit integer. -* `F41F` — **DICTUSETGETREF** `(c i D n – D0 c 0 −1 or D0 0)`. -* `F422` — **DICTREPLACE** `(x k D n – D0 −1 or D 0)`, a Replace operation, which is similar to **DICTSET**, but sets the value of key `k` in dictionary `D` to `x` only if the key `k` was already present in `D`. -* `F423` — **DICTREPLACEREF** `(c k D n – D0 −1 or D 0)`, a Replace counterpart of **DICTSETREF**. -* `F424` — **DICTIREPLACE** `(x i D n – D0 −1 or D 0)`, a version of **DICTREPLACE** with signed n-bit `Integer` `i` used as a key. -* `F425` — **DICTIREPLACEREF** `(c i D n – D0 −1 or D 0)`. -* `F426` — **DICTUREPLACE** `(x i D n – D0 −1 or D 0)`. -* `F427` — **DICTUREPLACEREF** `(c i D n – D0 −1 or D 0)`. -* `F42A` — **DICTREPLACEGET** `(x k D n – D0 y −1 or D 0)`, a Replace counterpart of **DICTSETGET**: on success, also returns the old value associated with the key in question. -* `F42B` — **DICTREPLACEGETREF** `(c k D n – D0 c 0 −1 or D 0)`. -* `F42C` — **DICTIREPLACEGET** `(x i D n – D0 y −1 or D 0)`. -* `F42D` — **DICTIREPLACEGETREF** `(c i D n – D0 c 0 −1 or D 0)`. -* `F42E` — **DICTUREPLACEGET** `(x i D n – D0 y −1 or D 0)`. -* `F42F` — **DICTUREPLACEGETREF** `(c i D n – D0 c 0 −1 or D 0)`. -* `F432` — **DICTADD** `(x k D n – D0 −1 or D 0)`, an Add counterpart of **DICTSET**: sets the value associated with key `k` in dictionary `D` to `x`, but only if it is not already present in `D`. -* `F433` — **DICTADDREF** `(c k D n – D0 −1 or D 0)`. - 119 - A.10. Dictionary manipulation primitives -* `F434` — **DICTIADD** `(x i D n – D0 −1 or D 0)`. -* `F435` — **DICTIADDREF** `(c i D n – D0 −1 or D 0)`. -* `F436` — **DICTUADD** `(x i D n – D0 −1 or D 0)`. -* `F437` — **DICTUADDREF** `(c i D n – D0 −1 or D 0)`. -* `F43A` — **DICTADDGET** `(x k D n – D0 −1 or D y 0)`, an Add counterpart of **DICTSETGET**: sets the value associated with key `k` in dictionary `D` to `x`, but only if key `k` is not already present in `D`. Otherwise, just returns the old value `y` without changing the dictionary. -* `F43B` — **DICTADDGETREF** `(c k D n – D0 −1 or D c0 0)`, an Add counterpart of **DICTSETGETREF**. -* `F43C` — **DICTIADDGET** `(x i D n – D0 −1 or D y 0)`. -* `F43D` — **DICTIADDGETREF** `(c i D n – D0 −1 or D c0 0)`. -* `F43E` — **DICTUADDGET** `(x i D n – D0 −1 or D y 0)`. -* `F43F` — **DICTUADDGETREF** `(c i D n – D0 −1 or D c0 0)`. - -## A.10.5. Builder-accepting variants of Set dictionary operations. - -The following primitives accept the new value as a `Builder` `b` instead of a `Slice` `x`, which often is more convenient if the value needs to be serialized from several components computed in the stack. (This is reflected by appending a `B` to the mnemonics of the corresponding Set primitives that work with `Slices`.) The net effect is roughly equivalent to converting `b` into a `Slice` by **ENDC**; **CTOS** and executing the corresponding primitive listed in A.10.4. - -* `F441` — **DICTSETB** `(b k D n – D0)`. -* `F442` — **DICTISETB** `(b i D n – D0)`. -* `F443` — **DICTUSETB** `(b i D n – D0)`. -* `F445` — **DICTSETGETB** `(b k D n – D0 y −1 or D0 0)`. -* `F446` — **DICTISETGETB** `(b i D n – D0 y −1 or D0 0)`. -* `F447` — **DICTUSETGETB** `(b i D n – D0 y −1 or D0 0)`. -* `F449` — **DICTREPLACEB** `(b k D n – D0 −1 or D 0)`. -* `F44A` — **DICTIREPLACEB** `(b i D n – D0 −1 or D 0)`. -* `F44B` — **DICTUREPLACEB** `(b i D n – D0 −1 or D 0)`. -* `F44D` — **DICTREPLACEGETB** `(b k D n – D0 y −1 or D 0)`. -* `F44E` — **DICTIREPLACEGETB** `(b i D n – D0 y −1 or D 0)`. -* `F44F` — **DICTUREPLACEGETB** `(b i D n – D0 y −1 or D 0)`. -* `F451` — **DICTADDB** `(b k D n – D0 −1 or D 0)`. -* `F452` — **DICTIADDB** `(b i D n – D0 −1 or D 0)`. -* `F453` — **DICTUADDB** `(b i D n – D0 −1 or D 0)`. -* `F455` — **DICTADDGETB** `(b k D n – D0 −1 or D y 0)`. -* `F456` — **DICTIADDGETB** `(b i D n – D0 −1 or D y 0)`. -* `F457` — **DICTUADDGETB** `(b i D n – D0 −1 or D y 0)`. - -## A.10.6. Delete dictionary operations. - -* `F459` — **DICTDEL** `(k D n – D0 −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0` and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. -* `F45A` — **DICTIDEL** `(i D n – D0 ?)`, a version of **DICTDEL** with the key represented by a signed n-bit `Integer` `i`. If `i` does not fit into n bits, simply returns `D 0` (“key not found, dictionary unmodified”). -* `F45B` — **DICTUDEL** `(i D n – D0 ?)`, similar to **DICTIDEL**, but with `i` an unsigned n-bit integer. -* `F462` — **DICTDELGET** `(k D n – D0 x −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0`, the original value `x` associated with the key `k` (represented by a `Slice`), and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. - 121 - A.10. Dictionary manipulation primitives -* `F463` — **DICTDELGETREF** `(k D n – D0 c −1 or D 0)`, similar to **DICTDELGET**, but with **LDREF**; **ENDS** applied to `x` on success, so that the value returned `c` is a `Cell`. -* `F464` — **DICTIDELGET** `(i D n – D0 x −1 or D 0)`, a variant of primitive **DICTDELGET** with signed n-bit integer `i` as a key. -* `F465` — **DICTIDELGETREF** `(i D n – D0 c −1 or D 0)`, a variant of primitive **DICTIDELGET** returning a `Cell` instead of a `Slice`. -* `F466` — **DICTUDELGET** `(i D n – D0 x −1 or D 0)`, a variant of primitive **DICTDELGET** with unsigned n-bit integer `i` as a key. -* `F467` — **DICTUDELGETREF** `(i D n – D0 c −1 or D 0)`, a variant of primitive **DICTUDELGET** returning a `Cell` instead of a `Slice`. - -## A.10.7. “Maybe reference” dictionary operations. +* `F412` — `DICTSET` `(x k D n – D0)`, sets the value associated with n-bit key `k` (represented by a `Slice` as in `DICTGET`) in dictionary `D` (also represented by a `Slice`) to value `x` (again a `Slice`), and returns the resulting dictionary as `D0`. +* `F413` — `DICTSETREF` `(c k D n – D0)`, similar to `DICTSET`, but with the value set to a reference to `Cell` `c`. +* `F414` — `DICTISET` `(x i D n – D0)`, similar to `DICTSET`, but with the key represented by a (big-endian) signed n-bit integer `i`. If `i` does not fit into n bits, a range check exception is generated. +* `F415` — `DICTISETREF` `(c i D n – D0)`, similar to `DICTSETREF`, but with the key a signed n-bit integer as in `DICTISET`. +* `F416` — `DICTUSET` `(x i D n – D0)`, similar to `DICTISET`, but with `i` an unsigned n-bit integer. +* `F417` — `DICTUSETREF` `(c i D n – D0)`, similar to `DICTISETREF`, but with `i` unsigned. +* `F41A` — `DICTSETGET` `(x k D n – D0 y −1 or D0 0)`, combines `DICTSET` with `DICTGET`: it sets the value corresponding to key `k` to `x`, but also returns the old value `y` associated with the key in question, if present. +* `F41B` — `DICTSETGETREF` `(c k D n – D0 c 0 −1 or D0 0)`, combines `DICTSETREF` with `DICTGETREF` similarly to `DICTSETGET`. +* `F41C` — `DICTISETGET` `(x i D n – D0 y −1 or D0 0)`, similar to `DICTSETGET`, but with the key represented by a big-endian signed n-bit `Integer` `i` +* `F41D` — `DICTISETGETREF` `(c i D n – D0 c 0 −1 or D0 0)`, a version of `DICTSETGETREF` with signed `Integer` `i` as a key. +* `F41E` — `DICTUSETGET` `(x i D n – D0 y −1 or D0 0)`, similar to `DICTISETGET`, but with `i` an unsigned n-bit integer. +* `F41F` — `DICTUSETGETREF` `(c i D n – D0 c 0 −1 or D0 0)`. +* `F422` — `DICTREPLACE` `(x k D n – D0 −1 or D 0)`, a Replace operation, which is similar to `DICTSET`, but sets the value of key `k` in dictionary `D` to `x` only if the key `k` was already present in `D`. +* `F423` — `DICTREPLACEREF` `(c k D n – D0 −1 or D 0)`, a Replace counterpart of `DICTSETREF`. +* `F424` — `DICTIREPLACE` `(x i D n – D0 −1 or D 0)`, a version of `DICTREPLACE` with signed n-bit `Integer` `i` used as a key. +* `F425` — `DICTIREPLACEREF` `(c i D n – D0 −1 or D 0)`. +* `F426` — `DICTUREPLACE` `(x i D n – D0 −1 or D 0)`. +* `F427` — `DICTUREPLACEREF` `(c i D n – D0 −1 or D 0)`. +* `F42A` — `DICTREPLACEGET` `(x k D n – D0 y −1 or D 0)`, a Replace counterpart of `DICTSETGET`: on success, also returns the old value associated with the key in question. +* `F42B` — `DICTREPLACEGETREF` `(c k D n – D0 c 0 −1 or D 0)`. +* `F42C` — `DICTIREPLACEGET` `(x i D n – D0 y −1 or D 0)`. +* `F42D` — `DICTIREPLACEGETREF` `(c i D n – D0 c 0 −1 or D 0)`. +* `F42E` — `DICTUREPLACEGET` `(x i D n – D0 y −1 or D 0)`. +* `F42F` — `DICTUREPLACEGETREF` `(c i D n – D0 c 0 −1 or D 0)`. +* `F432` — `DICTADD` `(x k D n – D0 −1 or D 0)`, an Add counterpart of `DICTSET`: sets the value associated with key `k` in dictionary `D` to `x`, but only if it is not already present in `D`. +* `F433` — `DICTADDREF` `(c k D n – D0 −1 or D 0)`. +* `F434` — `DICTIADD` `(x i D n – D0 −1 or D 0)`. +* `F435` — `DICTIADDREF` `(c i D n – D0 −1 or D 0)`. +* `F436` — `DICTUADD` `(x i D n – D0 −1 or D 0)`. +* `F437` — `DICTUADDREF` `(c i D n – D0 −1 or D 0)`. +* `F43A` — `DICTADDGET` `(x k D n – D0 −1 or D y 0)`, an Add counterpart of `DICTSETGET`: sets the value associated with key `k` in dictionary `D` to `x`, but only if key `k` is not already present in `D`. Otherwise, just returns the old value `y` without changing the dictionary. +* `F43B` — `DICTADDGETREF` `(c k D n – D0 −1 or D c0 0)`, an Add counterpart of `DICTSETGETREF`. +* `F43C` — `DICTIADDGET` `(x i D n – D0 −1 or D y 0)`. +* `F43D` — `DICTIADDGETREF` `(c i D n – D0 −1 or D c0 0)`. +* `F43E` — `DICTUADDGET` `(x i D n – D0 −1 or D y 0)`. +* `F43F` — `DICTUADDGETREF` `(c i D n – D0 −1 or D c0 0)`. + + +### A.10.5. Builder-accepting variants of Set dictionary operations. + +The following primitives accept the new value as a `Builder` `b` instead of a `Slice` `x`, which often is more convenient if the value needs to be serialized from several components computed in the stack. (This is reflected by appending a `B` to the mnemonics of the corresponding Set primitives that work with `Slices`.) The net effect is roughly equivalent to converting `b` into a `Slice` by `ENDC`; `CTOS` and executing the corresponding primitive listed in A.10.4. + +* `F441` — `DICTSETB` `(b k D n – D0)`. +* `F442` — `DICTISETB` `(b i D n – D0)`. +* `F443` — `DICTUSETB` `(b i D n – D0)`. +* `F445` — `DICTSETGETB` `(b k D n – D0 y −1 or D0 0)`. +* `F446` — `DICTISETGETB` `(b i D n – D0 y −1 or D0 0)`. +* `F447` — `DICTUSETGETB` `(b i D n – D0 y −1 or D0 0)`. +* `F449` — `DICTREPLACEB` `(b k D n – D0 −1 or D 0)`. +* `F44A` — `DICTIREPLACEB` `(b i D n – D0 −1 or D 0)`. +* `F44B` — `DICTUREPLACEB` `(b i D n – D0 −1 or D 0)`. +* `F44D` — `DICTREPLACEGETB` `(b k D n – D0 y −1 or D 0)`. +* `F44E` — `DICTIREPLACEGETB` `(b i D n – D0 y −1 or D 0)`. +* `F44F` — `DICTUREPLACEGETB` `(b i D n – D0 y −1 or D 0)`. +* `F451` — `DICTADDB` `(b k D n – D0 −1 or D 0)`. +* `F452` — `DICTIADDB` `(b i D n – D0 −1 or D 0)`. +* `F453` — `DICTUADDB` `(b i D n – D0 −1 or D 0)`. +* `F455` — `DICTADDGETB` `(b k D n – D0 −1 or D y 0)`. +* `F456` — `DICTIADDGETB` `(b i D n – D0 −1 or D y 0)`. +* `F457` — `DICTUADDGETB` `(b i D n – D0 −1 or D y 0)`. + +--- + +### A.10.6. Delete dictionary operations. + +* `F459` — `DICTDEL` `(k D n – D0 −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0` and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. +* `F45A` — `DICTIDEL` `(i D n – D0 ?)`, a version of `DICTDEL` with the key represented by a signed n-bit `Integer` `i`. If `i` does not fit into n bits, simply returns `D 0` (“key not found, dictionary unmodified”). +* `F45B` — `DICTUDEL` `(i D n – D0 ?)`, similar to `DICTIDEL`, but with `i` an unsigned n-bit integer. +* `F462` — `DICTDELGET` `(k D n – D0 x −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0`, the original value `x` associated with the key `k` (represented by a `Slice`), and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. +* `F463` — `DICTDELGETREF` `(k D n – D0 c −1 or D 0)`, similar to `DICTDELGET`, but with `LDREF`; `ENDS` applied to `x` on success, so that the value returned `c` is a `Cell`. +* `F464` — `DICTIDELGET` `(i D n – D0 x −1 or D 0)`, a variant of primitive `DICTDELGET` with signed n-bit integer `i` as a key. +* `F465` — `DICTIDELGETREF` `(i D n – D0 c −1 or D 0)`, a variant of primitive `DICTIDELGET` returning a `Cell` instead of a `Slice`. +* `F466` — `DICTUDELGET` `(i D n – D0 x −1 or D 0)`, a variant of primitive `DICTDELGET` with unsigned n-bit integer `i` as a key. +* `F467` — `DICTUDELGETREF` `(i D n – D0 c −1 or D 0)`, a variant of primitive `DICTUDELGET` returning a `Cell` instead of a `Slice`. + + +### A.10.7. “Maybe reference” dictionary operations. The following operations assume that a dictionary is used to store values `c ?` of type `Cell ?` (“Maybe `Cell`”), which can be used in particular to store dictionaries as values in other dictionaries. The representation is as follows: if `c ?` is a `Cell`, it is stored as a value with no data bits and exactly one reference to this `Cell`. If `c ?` is `Null`, then the corresponding key must be absent from the dictionary altogether. -* `F469` — **DICTGETOPTREF** `(k D n – c ? )`, a variant of **DICTGETREF** that returns `Null` instead of the value `c ?` if the key `k` is absent from dictionary `D`. -* `F46A` — **DICTIGETOPTREF** `(i D n – c ? )`, similar to **DICTGETOPTREF**, but with the key given by signed n-bit `Integer` `i`. If the key `i` is out of range, also returns `Null`. -* `F46B` — **DICTUGETOPTREF** `(i D n – c ? )`, similar to **DICTGETOPTREF**, but with the key given by unsigned n-bit `Integer` `i`. -* `F46D` — **DICTSETGETOPTREF** `(c ? k D n – D0 c˜ ? )`, a variant of both **DICTGETOPTREF** and **DICTSETGETREF** that sets the value corresponding to key `k` in dictionary `D` to `c ?` (if `c ?` is `Null`, then the key is deleted instead), and returns the old value `c˜ ?` (if the key `k` was absent before, returns `Null` instead). -* `F46E` — **DICTISETGETOPTREF** `(c ? i D n – D0 c˜ ? )`, similar to primitive **DICTSETGETOPTREF**, but using signed n-bit `Integer` `i` as a key. If `i` does not fit into n bits, throws a range checking exception. -* `F46F` — **DICTUSETGETOPTREF** `(c ? i D n – D0 c˜ ? )`, similar to primitive **DICTSETGETOPTREF**, but using unsigned n-bit `Integer` `i` as a key. +* `F469` — `DICTGETOPTREF` `(k D n – c ? )`, a variant of `DICTGETREF` that returns `Null` instead of the value `c ?` if the key `k` is absent from dictionary `D`. +* `F46A` — `DICTIGETOPTREF` `(i D n – c ? )`, similar to `DICTGETOPTREF`, but with the key given by signed n-bit `Integer` `i`. If the key `i` is out of range, also returns `Null`. +* `F46B` — `DICTUGETOPTREF` `(i D n – c ? )`, similar to `DICTGETOPTREF`, but with the key given by unsigned n-bit `Integer` `i`. +* `F46D` — `DICTSETGETOPTREF` `(c ? k D n – D0 c˜ ? )`, a variant of both `DICTGETOPTREF` and `DICTSETGETREF` that sets the value corresponding to key `k` in dictionary `D` to `c ?` (if `c ?` is `Null`, then the key is deleted instead), and returns the old value `c˜ ?` (if the key `k` was absent before, returns `Null` instead). +* `F46E` — `DICTISETGETOPTREF` `(c ? i D n – D0 c˜ ? )`, similar to primitive `DICTSETGETOPTREF`, but using signed n-bit `Integer` `i` as a key. If `i` does not fit into n bits, throws a range checking exception. +* `F46F` — `DICTUSETGETOPTREF` `(c ? i D n – D0 c˜ ? )`, similar to primitive `DICTSETGETOPTREF`, but using unsigned n-bit `Integer` `i` as a key. + -## A.10.8. Prefix code dictionary operations. +### A.10.8. Prefix code dictionary operations. These are some basic operations for constructing prefix code dictionaries (cf. 3.4.2). The primary application for prefix code dictionaries is deserializing TL-B serialized data structures, or, more generally, parsing prefix codes. Therefore, most prefix code dictionaries will be constant and created at compile time, not by the following primitives. Some Get operations for prefix code dictionaries may be found in A.10.11. Other prefix code dictionary operations include: -* `F470` — **PFXDICTSET** `(x k D n – D0 −1 or D 0)`. -* `F471` — **PFXDICTREPLACE** `(x k D n – D0 −1 or D 0)`. -* `F472` — **PFXDICTADD** `(x k D n – D0 −1 or D 0)`. -* `F473` — **PFXDICTDEL** `(k D n – D0 −1 or D 0)`. - -These primitives are completely similar to their non-prefix code counterparts **DICTSET** etc (cf. A.10.4), with the obvious difference that even a Set may fail in a prefix code dictionary, so a success flag must be returned by **PFXDICTSET** as well. - -## A.10.9. Variants of GetNext and GetPrev operations. - -* `F474` — **DICTGETNEXT** `(k D n – x 0 k 0 −1 or 0)`, computes the minimal key `k 0` in dictionary `D` that is lexicographically greater than `k`, and returns `k 0` (represented by a `Slice`) along with associated value `x 0` (also represented by a `Slice`). -* `F475` — **DICTGETNEXTEQ** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETNEXT**, but computes the minimal key `k 0` that is lexicographically greater than or equal to `k`. -* `F476` — **DICTGETPREV** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETNEXT**, but computes the maximal key `k 0` lexicographically smaller than `k`. - 123 - A.10. Dictionary manipulation primitives -* `F477` — **DICTGETPREVEQ** `(k D n – x 0 k 0 −1 or 0)`, similar to **DICTGETPREV**, but computes the maximal key `k 0` lexicographically smaller than or equal to `k`. -* `F478` — **DICTIGETNEXT** `(i D n – x 0 i 0 −1 or 0)`, similar to **DICTGETNEXT**, but interprets all keys in dictionary `D` as big-endian signed n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits). -* `F479` — **DICTIGETNEXTEQ** `(i D n – x 0 i 0 −1 or 0)`. -* `F47A` — **DICTIGETPREV** `(i D n – x 0 i 0 −1 or 0)`. -* `F47B` — **DICTIGETPREVEQ** `(i D n – x 0 i 0 −1 or 0)`. -* `F47C` — **DICTUGETNEXT** `(i D n – x 0 i 0 −1 or 0)`, similar to **DICTGETNEXT**, but interprets all keys in dictionary `D` as big-endian unsigned n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits, and is not necessarily nonnegative). -* `F47D` — **DICTUGETNEXTEQ** `(i D n – x 0 i 0 −1 or 0)`. -* `F47E` — **DICTUGETPREV** `(i D n – x 0 i 0 −1 or 0)`. -* `F47F` — **DICTUGETPREVEQ** `(i D n – x 0 i 0 −1 or 0)`. - -## A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. - -* `F482` — **DICTMIN** `(D n – x k −1 or 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. -* `F483` — **DICTMINREF** `(D n – c k −1 or 0)`, similar to **DICTMIN**, but returns the only reference in the value as a `Cell` `c`. -* `F484` — **DICTIMIN** `(D n – x i −1 or 0)`, somewhat similar to **DICTMIN**, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by **DICTMIN** and **DICTUMIN** -* `F485` — **DICTIMINREF** `(D n – c i −1 or 0)`. -* `F486` — **DICTUMIN** `(D n – x i −1 or 0)`, similar to **DICTMIN**, but returns the key as an unsigned n-bit `Integer` `i`. -* `F487` — **DICTUMINREF** `(D n – c i −1 or 0)`. -* `F48A` — **DICTMAX** `(D n – x k −1 or 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. -* `F48B` — **DICTMAXREF** `(D n – c k −1 or 0)`. -* `F48C` — **DICTIMAX** `(D n – x i −1 or 0)`. -* `F48D` — **DICTIMAXREF** `(D n – c i −1 or 0)`. -* `F48E` — **DICTUMAX** `(D n – x i −1 or 0)`. -* `F48F` — **DICTUMAXREF** `(D n – c i −1 or 0)`. -* `F492` — **DICTREMMIN** `(D n – D0 x k −1 or D 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. -* `F493` — **DICTREMMINREF** `(D n – D0 c k −1 or D 0)`, similar to **DICTREMMIN**, but returns the only reference in the value as a `Cell` `c`. -* `F494` — **DICTIREMMIN** `(D n – D0 x i −1 or D 0)`, somewhat similar to **DICTREMMIN**, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by **DICTREMMIN** and **DICTUREMMIN**. -* `F495` — **DICTIREMMINREF** `(D n – D0 c i −1 or D 0)`. -* `F496` — **DICTUREMMIN** `(D n – D0 x i −1 or D 0)`, similar to **DICTREMMIN**, but returns the key as an unsigned n-bit `Integer` `i`. -* `F497` — **DICTUREMMINREF** `(D n – D0 c i −1 or D 0)`. - 125 - A.10. Dictionary manipulation primitives -* `F49A` — **DICTREMMAX** `(D n – D0 x k −1 or D 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. -* `F49B` — **DICTREMMAXREF** `(D n – D0 c k −1 or D 0)`. -* `F49C` — **DICTIREMMAX** `(D n – D0 x i −1 or D 0)`. -* `F49D` — **DICTIREMMAXREF** `(D n – D0 c i −1 or D 0)`. -* `F49E` — **DICTUREMMAX** `(D n – D0 x i −1 or D 0)`. -* `F49F` — **DICTUREMMAXREF** `(D n – D0 c i −1 or D 0)`. - -## A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. - -* `F4A0` — **DICTIGETJMP** `(i D n – )`, similar to **DICTIGET** (cf. A.10.12), but with `x` **BLESS**ed into a continuation with a subsequent **JMPX** to it on success. On failure, does nothing. This is useful for implementing switch/case constructions. -* `F4A1` — **DICTUGETJMP** `(i D n – )`, similar to **DICTIGETJMP**, but performs **DICTUGET** instead of **DICTIGET**. -* `F4A2` — **DICTIGETEXEC** `(i D n – )`, similar to **DICTIGETJMP**, but with **EXECUTE** instead of **JMPX**. -* `F4A3` — **DICTUGETEXEC** `(i D n – )`, similar to **DICTUGETJMP**, but with **EXECUTE** instead of **JMPX**. -* `F4A6_n` — **DICTPUSHCONST n** `( – D n)`, pushes a non-empty constant dictionary `D` (as a `Cell ?`) along with its key length `0 ≤ n ≤ 1023`, stored as a part of the instruction. The dictionary itself is created from the first of remaining references of the current continuation. In this way, the complete **DICTPUSHCONST** instruction can be obtained by first serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and a cell reference), and then the unsigned 10-bit integer `n` (as if by a **STU 10** instruction). An empty dictionary can be pushed by a **NEWDICT** primitive (cf. A.10.1) instead. -* `F4A8` — **PFXDICTGETQ** `(s D n – s 0 x s00 −1 or s 0)`, looks up the unique prefix of `Slice` `s` present in the prefix code dictionary (cf. 3.4.2) represented by `Cell ?` `D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is returned as `s 0`, and the corresponding value (also a `Slice`) as `x`. The remainder of `s` is returned as a `Slice` `s 00`. If no prefix of `s` is a key in prefix code dictionary `D`, returns the unchanged `s` and a zero flag to indicate failure. -* `F4A9` — **PFXDICTGET** `(s D n – s 0 x s00)`, similar to **PFXDICTGET**, but throws a cell deserialization failure exception on failure. -* `F4AA` — **PFXDICTGETJMP** `(s D n – s 0 s 00 or s)`, similar to **PFXDICTGETQ**, but on success **BLESS**es the value `x` into a `Continuation` and transfers control to it as if by a **JMPX**. On failure, returns `s` unchanged and continues execution. -* `F4AB` — **PFXDICTGETEXEC** `(s D n – s 0 s 00)`, similar to **PFXDICTGETJMP**, but **EXEC**utes the continuation found instead of jumping to it. On failure, throws a cell deserialization exception. -* `F4AE_n` — **PFXDICTCONSTGETJMP n** or **PFXDICTSWITCH n** `(s – s 0 s 00 or s)`, combines **DICTPUSHCONST n** for `0 ≤ n ≤ 1023` with **PFXDICTGETJMP**. -* `F4BC` — **DICTIGETJMPZ** `(i D n – i or nothing)`, a variant of **DICTIGETJMP** that returns index `i` on failure. -* `F4BD` — **DICTUGETJMPZ** `(i D n – i or nothing)`, a variant of **DICTUGETJMP** that returns index `i` on failure. -* `F4BE` — **DICTIGETEXECZ** `(i D n – i or nothing)`, a variant of **DICTIGETEXEC** that returns index `i` on failure. -* `F4BF` — **DICTUGETEXECZ** `(i D n – i or nothing)`, a variant of **DICTUGETEXEC** that returns index `i` on failure. - -## A.10.12. SubDict dictionary operations. - -* `F4B1` — **SUBDICTGET** `(k l D n – D0)`, constructs a subdictionary consisting of all keys beginning with prefix `k` (represented by a `Slice`, the first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, - 127 - A.11. Application-specific primitives - returns the new subdictionary of the same type `HashmapE(n, X)` as a `Slice` `D0`. -* `F4B2` — **SUBDICTIGET** `(x l D n – D0)`, variant of **SUBDICTGET** with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. -* `F4B3` — **SUBDICTUGET** `(x l D n – D0)`, variant of **SUBDICTGET** with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. -* `F4B5` — **SUBDICTRPGET** `(k l D n – D0)`, similar to **SUBDICTGET**, but removes the common prefix `k` from all keys of the new dictionary `D0`, which becomes of type `HashmapE(n − l, X)`. -* `F4B6` — **SUBDICTIRPGET** `(x l D n – D0)`, variant of **SUBDICTRPGET** with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. -* `F4B7` — **SUBDICTURPGET** `(x l D n – D0)`, variant of **SUBDICTRPGET** with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. -* `F4BC–F4BF` — used by **DICT...Z** primitives in A.10.11. +* `F470` — `PFXDICTSET` `(x k D n – D0 −1 or D 0)`. +* `F471` — `PFXDICTREPLACE` `(x k D n – D0 −1 or D 0)`. +* `F472` — `PFXDICTADD` `(x k D n – D0 −1 or D 0)`. +* `F473` — `PFXDICTDEL` `(k D n – D0 −1 or D 0)`. + +These primitives are completely similar to their non-prefix code counterparts `DICTSET` etc (cf. A.10.4), with the obvious difference that even a Set may fail in a prefix code dictionary, so a success flag must be returned by `PFXDICTSET` as well. + +### A.10.9. Variants of GetNext and GetPrev operations. + +* `F474` — `DICTGETNEXT` `(k D n – x 0 k 0 −1 or 0)`, computes the minimal key `k 0` in dictionary `D` that is lexicographically greater than `k`, and returns `k 0` (represented by a `Slice`) along with associated value `x 0` (also represented by a `Slice`). +* `F475` — `DICTGETNEXTEQ` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETNEXT`, but computes the minimal key `k 0` that is lexicographically greater than or equal to `k`. +* `F476` — `DICTGETPREV` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETNEXT`, but computes the maximal key `k 0` lexicographically smaller than `k`. +* `F477` — `DICTGETPREVEQ` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETPREV`, but computes the maximal key `k 0` lexicographically smaller than or equal to `k`. +* `F478` — `DICTIGETNEXT` `(i D n – x 0 i 0 −1 or 0)`, similar to `DICTGETNEXT`, but interprets all keys in dictionary `D` as big-endian signed n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits). +* `F479` — `DICTIGETNEXTEQ` `(i D n – x 0 i 0 −1 or 0)`. +* `F47A` — `DICTIGETPREV` `(i D n – x 0 i 0 −1 or 0)`. +* `F47B` — `DICTIGETPREVEQ` `(i D n – x 0 i 0 −1 or 0)`. +* `F47C` — `DICTUGETNEXT` `(i D n – x 0 i 0 −1 or 0)`, similar to `DICTGETNEXT`, but interprets all keys in dictionary `D` as big-endian unsigned n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits, and is not necessarily nonnegative). +* `F47D` — `DICTUGETNEXTEQ` `(i D n – x 0 i 0 −1 or 0)`. +* `F47E` — `DICTUGETPREV` `(i D n – x 0 i 0 −1 or 0)`. +* `F47F` — `DICTUGETPREVEQ` `(i D n – x 0 i 0 −1 or 0)`. + +### A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. + +* `F482` — `DICTMIN` `(D n – x k −1 or 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. +* `F483` — `DICTMINREF` `(D n – c k −1 or 0)`, similar to `DICTMIN`, but returns the only reference in the value as a `Cell` `c`. +* `F484` — `DICTIMIN` `(D n – x i −1 or 0)`, somewhat similar to `DICTMIN`, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by `DICTMIN` and `DICTUMIN` +* `F485` — `DICTIMINREF` `(D n – c i −1 or 0)`. +* `F486` — `DICTUMIN` `(D n – x i −1 or 0)`, similar to `DICTMIN`, but returns the key as an unsigned n-bit `Integer` `i`. +* `F487` — `DICTUMINREF` `(D n – c i −1 or 0)`. +* `F48A` — `DICTMAX` `(D n – x k −1 or 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. +* `F48B` — `DICTMAXREF` `(D n – c k −1 or 0)`. +* `F48C` — `DICTIMAX` `(D n – x i −1 or 0)`. +* `F48D` — `DICTIMAXREF` `(D n – c i −1 or 0)`. +* `F48E` — `DICTUMAX` `(D n – x i −1 or 0)`. +* `F48F` — `DICTUMAXREF` `(D n – c i −1 or 0)`. +* `F492` — `DICTREMMIN` `(D n – D0 x k −1 or D 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. +* `F493` — `DICTREMMINREF` `(D n – D0 c k −1 or D 0)`, similar to `DICTREMMIN`, but returns the only reference in the value as a `Cell` `c`. +* `F494` — `DICTIREMMIN` `(D n – D0 x i −1 or D 0)`, somewhat similar to `DICTREMMIN`, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by `DICTREMMIN` and `DICTUREMMIN`. +* `F495` — `DICTIREMMINREF` `(D n – D0 c i −1 or D 0)`. +* `F496` — `DICTUREMMIN` `(D n – D0 x i −1 or D 0)`, similar to `DICTREMMIN`, but returns the key as an unsigned n-bit `Integer` `i`. +* `F497` — `DICTUREMMINREF` `(D n – D0 c i −1 or D 0)`. +* `F49A` — `DICTREMMAX` `(D n – D0 x k −1 or D 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. +* `F49B` — `DICTREMMAXREF` `(D n – D0 c k −1 or D 0)`. +* `F49C` — `DICTIREMMAX` `(D n – D0 x i −1 or D 0)`. +* `F49D` — `DICTIREMMAXREF` `(D n – D0 c i −1 or D 0)`. +* `F49E` — `DICTUREMMAX` `(D n – D0 x i −1 or D 0)`. +* `F49F` — `DICTUREMMAXREF` `(D n – D0 c i −1 or D 0)`. + +### A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. + +* `F4A0` — `DICTIGETJMP` `(i D n – )`, similar to `DICTIGET` (cf. A.10.12), but with `x` `BLESS`ed into a continuation with a subsequent `JMPX` to it on success. On failure, does nothing. This is useful for implementing switch/case constructions. +* `F4A1` — `DICTUGETJMP` `(i D n – )`, similar to `DICTIGETJMP`, but performs `DICTUGET` instead of `DICTIGET`. +* `F4A2` — `DICTIGETEXEC` `(i D n – )`, similar to `DICTIGETJMP`, but with `EXECUTE` instead of `JMPX`. +* `F4A3` — `DICTUGETEXEC` `(i D n – )`, similar to `DICTUGETJMP`, but with `EXECUTE` instead of `JMPX`. +* `F4A6_n` — `DICTPUSHCONST n` `( – D n)`, pushes a non-empty constant dictionary `D` (as a `Cell ?`) along with its key length `0 ≤ n ≤ 1023`, stored as a part of the instruction. The dictionary itself is created from the first of remaining references of the current continuation. In this way, the complete `DICTPUSHCONST` instruction can be obtained by first serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and a cell reference), and then the unsigned 10-bit integer `n` (as if by a `STU 10` instruction). An empty dictionary can be pushed by a `NEWDICT` primitive (cf. A.10.1) instead. +* `F4A8` — `PFXDICTGETQ` `(s D n – s 0 x s00 −1 or s 0)`, looks up the unique prefix of `Slice` `s` present in the prefix code dictionary (cf. 3.4.2) represented by `Cell ?` `D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is returned as `s 0`, and the corresponding value (also a `Slice`) as `x`. The remainder of `s` is returned as a `Slice` `s 00`. If no prefix of `s` is a key in prefix code dictionary `D`, returns the unchanged `s` and a zero flag to indicate failure. +* `F4A9` — `PFXDICTGET` `(s D n – s 0 x s00)`, similar to `PFXDICTGET`, but throws a cell deserialization failure exception on failure. +* `F4AA` — `PFXDICTGETJMP` `(s D n – s 0 s 00 or s)`, similar to `PFXDICTGETQ`, but on success `BLESS`es the value `x` into a `Continuation` and transfers control to it as if by a `JMPX`. On failure, returns `s` unchanged and continues execution. +* `F4AB` — `PFXDICTGETEXEC` `(s D n – s 0 s 00)`, similar to `PFXDICTGETJMP`, but `EXEC`utes the continuation found instead of jumping to it. On failure, throws a cell deserialization exception. +* `F4AE_n` — `PFXDICTCONSTGETJMP n` or `PFXDICTSWITCH n` `(s – s 0 s 00 or s)`, combines `DICTPUSHCONST n` for `0 ≤ n ≤ 1023` with `PFXDICTGETJMP`. +* `F4BC` — `DICTIGETJMPZ` `(i D n – i or nothing)`, a variant of `DICTIGETJMP` that returns index `i` on failure. +* `F4BD` — `DICTUGETJMPZ` `(i D n – i or nothing)`, a variant of `DICTUGETJMP` that returns index `i` on failure. +* `F4BE` — `DICTIGETEXECZ` `(i D n – i or nothing)`, a variant of `DICTIGETEXEC` that returns index `i` on failure. +* `F4BF` — `DICTUGETEXECZ` `(i D n – i or nothing)`, a variant of `DICTUGETEXEC` that returns index `i` on failure. + +### A.10.12. SubDict dictionary operations. + +* `F4B1` — `SUBDICTGET` `(k l D n – D0)`, constructs a subdictionary consisting of all keys beginning with prefix `k` (represented by a `Slice`, the first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the new subdictionary of the same type `HashmapE(n, X)` as a `Slice` `D0`. +* `F4B2` — `SUBDICTIGET` `(x l D n – D0)`, variant of `SUBDICTGET` with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. +* `F4B3` — `SUBDICTUGET` `(x l D n – D0)`, variant of `SUBDICTGET` with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. +* `F4B5` — `SUBDICTRPGET` `(k l D n – D0)`, similar to `SUBDICTGET`, but removes the common prefix `k` from all keys of the new dictionary `D0`, which becomes of type `HashmapE(n − l, X)`. +* `F4B6` — `SUBDICTIRPGET` `(x l D n – D0)`, variant of `SUBDICTRPGET` with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. +* `F4B7` — `SUBDICTURPGET` `(x l D n – D0)`, variant of `SUBDICTRPGET` with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. +* `F4BC–F4BF` — used by `DICT...Z` primitives in A.10.11. --- + # A.11 Application-specific primitives Opcode range `F8...FB` is reserved for the application-specific primitives. When TVM is used to execute TON Blockchain smart contracts, these application-specific primitives are in fact TON Blockchain-specific. -## A.11.1. External actions and access to blockchain configuration data. +### A.11.1. External actions and access to blockchain configuration data. Some of the primitives listed below pretend to produce some externally visible actions, such as sending a message to another smart contract. In fact, the execution of a smart contract in TVM never has any effect apart from a modification of the TVM state. All external actions are collected into a linked list stored in special register `c5` (“output actions”). Additionally, some primitives use the data kept in the first component of the Tuple stored in `c7` (“root of temporary data”, cf. 1.3.2). Smart contracts are free to modify any other data kept in the cell `c7`, provided the first reference remains intact (otherwise some application-specific primitives would be likely to throw exceptions when invoked). Most of the primitives listed below use 16-bit opcodes. -A.11. Application-specific primitives - -## A.11.2. Gas-related primitives. +### A.11.2. Gas-related primitives. Of the following primitives, only the first two are “pure” in the sense that they do not use `c5` or `c7`. -* `F800` — **ACCEPT**, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. 1.4), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence no gas) with themselves. -* `F801` — **SETGASLIMIT** `(g – )`, sets current gas limit `gl` to the minimum of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed so far (including the present instruction) exceeds the resulting value of `gl`, an (unhandled) out of gas exception is thrown before setting new gas limits. Notice that **SETGASLIMIT** with an argument `g ≥ 2^63 − 1` is equivalent to **ACCEPT**. -* `F802` — **BUYGAS** `(x – )`, computes the amount of gas that can be bought for `x` nanograms, and sets `gl` accordingly in the same way as **SETGASLIMIT**. -* `F804` — **GRAMTOGAS** `(x – g)`, computes the amount of gas that can be bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `2^63−1`, it is replaced with this value. -* `F805` — **GASTOGRAM** `(g – x)`, computes the price of `g` gas in nanograms. +* `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. 1.4), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence no gas) with themselves. +* `F801` — `SETGASLIMIT` `(g – )`, sets current gas limit `gl` to the minimum of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed so far (including the present instruction) exceeds the resulting value of `gl`, an (unhandled) out of gas exception is thrown before setting new gas limits. Notice that `SETGASLIMIT` with an argument `g ≥ 2^63 − 1` is equivalent to `ACCEPT`. +* `F802` — `BUYGAS` `(x – )`, computes the amount of gas that can be bought for `x` nanograms, and sets `gl` accordingly in the same way as `SETGASLIMIT`. +* `F804` — `GRAMTOGAS` `(x – g)`, computes the amount of gas that can be bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `2^63−1`, it is replaced with this value. +* `F805` — `GASTOGRAM` `(g – x)`, computes the price of `g` gas in nanograms. * `F806–F80E` — Reserved for gas-related primitives. -* `F80F` — **COMMIT** `( – )`, commits the current state of registers `c4` (“persistent data”) and `c5` (“actions”) so that the current execution is considered “successful” with the saved values even if an exception is thrown later. +* `F80F` — `COMMIT` `( – )`, commits the current state of registers `c4` (“persistent data”) and `c5` (“actions”) so that the current execution is considered “successful” with the saved values even if an exception is thrown later. + +--- -## A.11.3. Pseudo-random number generator primitives. +### A.11.3. Pseudo-random number generator primitives. The pseudo-random number generator uses the random seed (parameter `#6`, cf. A.11.4), an unsigned 256-bit `Integer`, and (sometimes) other data kept in `c7`. -The initial value of the random seed before a smart contract is executed in TON Blockchain is a hash of the smart contract address and the global block random seed. If there are several runs of the same smart contract inside a block, then all of these runs will have the same random seed. This can be fixed, for example, by running **LTIME**; **ADDRAND** before using the pseudo-random number generator for the first time. +The initial value of the random seed before a smart contract is executed in TON Blockchain is a hash of the smart contract address and the global block random seed. If there are several runs of the same smart contract inside a block, then all of these runs will have the same random seed. This can be fixed, for example, by running `LTIME`; `ADDRAND` before using the pseudo-random number generator for the first time. -* `F810` — **RANDU256** `( – x)`, generates a new pseudo-random unsigned 256-bit `Integer` `x`. The algorithm is as follows: if `r` is the old value of the random seed, considered as a 32-byte array (by constructing the big-endian representation of an unsigned 256-bit integer), then its `sha512(r)` is computed; the first 32 bytes of this hash are stored as the new value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`. -* `F811` — **RAND** `(y – z)`, generates a new pseudo-random integer `z` in the range `0 ... y − 1` (or `y ... − 1`, if `y < 0`). More precisely, an unsigned random value `x` is generated as in **RAND256U**; then `z := ⌊x·y/2^256⌋` is computed. Equivalent to **RANDU256**; **MULRSHIFT** `256`. -* `F814` — **SETRAND** `(x – )`, sets the random seed to unsigned 256-bit `Integer` `x`. -* `F815` — **ADDRAND** `(x – )`, mixes unsigned 256-bit `Integer` `x` into the random seed `r` by setting the random seed to `sha256` of the concatenation of two 32-byte strings: the first with the big-endian representation of the old seed `r`, and the second with the big-endian representation of `x`. +* `F810` — `RANDU256` `( – x)`, generates a new pseudo-random unsigned 256-bit `Integer` `x`. The algorithm is as follows: if `r` is the old value of the random seed, considered as a 32-byte array (by constructing the big-endian representation of an unsigned 256-bit integer), then its `sha512(r)` is computed; the first 32 bytes of this hash are stored as the new value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`. +* `F811` — `RAND` `(y – z)`, generates a new pseudo-random integer `z` in the range `0 ... y − 1` (or `y ... − 1`, if `y < 0`). More precisely, an unsigned random value `x` is generated as in `RAND256U`; then `z := ⌊x·y/2^256⌋` is computed. Equivalent to `RANDU256`; `MULRSHIFT` `256`. +* `F814` — `SETRAND` `(x – )`, sets the random seed to unsigned 256-bit `Integer` `x`. +* `F815` — `ADDRAND` `(x – )`, mixes unsigned 256-bit `Integer` `x` into the random seed `r` by setting the random seed to `sha256` of the concatenation of two 32-byte strings: the first with the big-endian representation of the old seed `r`, and the second with the big-endian representation of `x`. * `F810–F81F` — Reserved for pseudo-random number generator primitives. - `129` - A.11. Application-specific primitives -## A.11.4. Configuration primitives. +--- + +### A.11.4. Configuration primitives. The following primitives read configuration data provided in the Tuple stored in the first component of the Tuple at `c7`. Whenever TVM is invoked for executing TON Blockchain smart contracts, this Tuple is initialized by a `SmartContractInfo` structure; configuration primitives assume that it has remained intact. -* `F82i` — **GETPARAM** `i` `( – x)`, returns the `i`-th parameter from the Tuple provided at `c7` for `0 ≤ i < 16`. Equivalent to **PUSH** `c7`; **FIRST**; **INDEX** `i`. If one of these internal operations fails, throws an appropriate type checking or range checking exception -* `F823` — **NOW** `( – x)`, returns the current Unix time as an `Integer`. If it is impossible to recover the requested value starting from `c7`, throws a type checking or range checking exception as appropriate. Equivalent to **GETPARAM** `3`. -* `F824` — **BLOCKLT** `( – x)`, returns the starting logical time of the current block. Equivalent to **GETPARAM** `4`. -* `F825` — **LTIME** `( – x)`, returns the logical time of the current transaction. Equivalent to **GETPARAM** `5`. -* `F826` — **RANDSEED** `( – x)`, returns the current random seed as an unsigned 256-bit `Integer`. Equivalent to **GETPARAM** `6`. -* `F827` — **BALANCE** `( – t)`, returns the remaining balance of the smart contract as a `Tuple` consisting of an `Integer` (the remaining Gram balance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys representing the balance of “extra currencies”). Equivalent to **GETPARAM** `7`. Note that RAW primitives such as **SENDRAWMSG** do not update this field. -* `F828` — **MYADDR** `( – s)`, returns the internal address of the current smart contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed further using primitives such as **PARSESTDADDR** or **REWRITESTDADDR**. Equivalent to **GETPARAM** `8`. -* `F829` — **CONFIGROOT** `( – D)`, returns the `Maybe Cell` `D` with the current global configuration dictionary. Equivalent to **GETPARAM** `9`. -* `F830` — **CONFIGDICT** `( – D 32)`, returns the global configuration dictionary along with its key length (`32`). Equivalent to **CONFIGROOT**; **PUSHINT** `32`. -* `F832` — **CONFIGPARAM** `(i – c −1 or 0)`, returns the value of the global configuration parameter with integer index `i` as a `Cell` `c`, and a flag to indicate success. Equivalent to **CONFIGDICT**; **DICTIGETREF**. -* `F833` — **CONFIGOPTPARAM** `(i – c ? )`, returns the value of the global configuration parameter with integer index `i` as a `Maybe Cell` `c ?`. Equivalent to **CONFIGDICT**; **DICTIGETOPTREF**. +* `F82i` — `GETPARAM` `i` `( – x)`, returns the `i`-th parameter from the Tuple provided at `c7` for `0 ≤ i < 16`. Equivalent to `PUSH` `c7`; `FIRST`; `INDEX` `i`. If one of these internal operations fails, throws an appropriate type checking or range checking exception +* `F823` — `NOW` `( – x)`, returns the current Unix time as an `Integer`. If it is impossible to recover the requested value starting from `c7`, throws a type checking or range checking exception as appropriate. Equivalent to `GETPARAM` `3`. +* `F824` — `BLOCKLT` `( – x)`, returns the starting logical time of the current block. Equivalent to `GETPARAM` `4`. +* `F825` — `LTIME` `( – x)`, returns the logical time of the current transaction. Equivalent to `GETPARAM` `5`. +* `F826` — `RANDSEED` `( – x)`, returns the current random seed as an unsigned 256-bit `Integer`. Equivalent to `GETPARAM` `6`. +* `F827` — `BALANCE` `( – t)`, returns the remaining balance of the smart contract as a `Tuple` consisting of an `Integer` (the remaining Gram balance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys representing the balance of “extra currencies”). Equivalent to `GETPARAM` `7`. Note that RAW primitives such as `SENDRAWMSG` do not update this field. +* `F828` — `MYADDR` `( – s)`, returns the internal address of the current smart contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed further using primitives such as `PARSESTDADDR` or `REWRITESTDADDR`. Equivalent to `GETPARAM` `8`. +* `F829` — `CONFIGROOT` `( – D)`, returns the `Maybe Cell` `D` with the current global configuration dictionary. Equivalent to `GETPARAM` `9`. +* `F830` — `CONFIGDICT` `( – D 32)`, returns the global configuration dictionary along with its key length (`32`). Equivalent to `CONFIGROOT`; `PUSHINT` `32`. +* `F832` — `CONFIGPARAM` `(i – c −1 or 0)`, returns the value of the global configuration parameter with integer index `i` as a `Cell` `c`, and a flag to indicate success. Equivalent to `CONFIGDICT`; `DICTIGETREF`. +* `F833` — `CONFIGOPTPARAM` `(i – c ? )`, returns the value of the global configuration parameter with integer index `i` as a `Maybe Cell` `c ?`. Equivalent to `CONFIGDICT`; `DICTIGETOPTREF`. * `F820–F83F` — Reserved for configuration primitives. - `131` - A.11. Application-specific primitives - -## A.11.5. Global variable primitives. -The “global variables” may be helpful in implementing some high-level smart-contract languages. They are in fact stored as components of the Tuple at `c7`: the `k`-th global variable simply is the `k`-th component of this Tuple, for `1 ≤ k ≤ 254`. By convention, the `0`-th component is used for the “configuration parameters” of A.11.4, so it is not available as a global variable. - -* `F840` — **GETGLOBVAR** `(k – x)`, returns the `k`-th global variable for `0 ≤ k < 255`. Equivalent to **PUSH** `c7`; **SWAP**; **INDEXVARQ** (cf. A.3.2). -* `F85_k` — **GETGLOB** `k` `( – x)`, returns the `k`-th global variable for `1 ≤ k ≤ 31`. Equivalent to **PUSH** `c7`; **INDEXQ** `k`. -* `F860` — **SETGLOBVAR** `(x k – )`, assigns `x` to the `k`-th global variable for `0 ≤ k < 255`. Equivalent to **PUSH** `c7`; **ROTREV**; **SETINDEXVARQ**; **POP** `c7`. -* `F87_k` — **SETGLOB** `k` `(x – )`, assigns `x` to the `k`-th global variable for `1 ≤ k ≤ 31`. Equivalent to **PUSH** `c7`; **SWAP**; **SETINDEXQ** `k`; **POP** `c7`. +--- -## A.11.6. Hashing and cryptography primitives. +### A.11.6. Hashing and cryptography primitives. -* `F900` — **HASHCU** `(c – x)`, computes the representation hash (cf. 3.1.5) of a `Cell` `c` and returns it as a 256-bit unsigned integer `x`. Useful for signing and checking signatures of arbitrary entities represented by a tree of cells. -* `F901` — **HASHSU** `(s – x)`, computes the hash of a `Slice` `s` and returns it as a 256-bit unsigned integer `x`. The result is the same as if an ordinary cell containing only data and references from `s` had been created and its hash computed by **HASHCU**. -* `F902` — **SHA256U** `(s – x)`, computes `sha256` of the data bits of `Slice` `s`. If the bit length of `s` is not divisible by eight, throws a cell underflow exception. The hash value is returned as a 256-bit unsigned integer `x`. -* `F910` — **CHKSIGNU** `(h s k – ? )`, checks the Ed25519-signature `s` of a hash `h` (a 256-bit unsigned integer, usually computed as the hash of some data) using public key `k` (also represented by a 256-bit unsigned integer). The signature `s` must be a `Slice` containing at least 512 databits; only the first 512 bits are used. The result is `−1` if the signature is valid, `0` otherwise. Notice that **CHKSIGNU** is equivalent to **ROT**; **NEWB**; **STU** `256`; **ENDB**; **NEWC**; **ROTREV**; **CHKSIGNS**, i.e., to **CHKSIGNS** with the first argument `d` set to 256-bit `Slice` containing `h`. Therefore, if `h` is computed as the hash of some data, these data are hashed twice, the second hashing occurring inside **CHKSIGNS**. -* `F911` — **CHKSIGNS** `(d s k – ? )`, checks whether `s` is a valid Ed25519-signature of the data portion of `Slice` `d` using public key `k`, similarly to **CHKSIGNU**. If the bit length of `Slice` `d` is not divisible by eight, throws a cell underflow exception. The verification of Ed25519 signatures is the standard one, with `sha256` used to reduce `d` to the 256-bit number that is actually signed. +* `F900` — `HASHCU` `(c – x)`, computes the representation hash (cf. 3.1.5) of a `Cell` `c` and returns it as a 256-bit unsigned integer `x`. Useful for signing and checking signatures of arbitrary entities represented by a tree of cells. +* `F901` — `HASHSU` `(s – x)`, computes the hash of a `Slice` `s` and returns it as a 256-bit unsigned integer `x`. The result is the same as if an ordinary cell containing only data and references from `s` had been created and its hash computed by `HASHCU`. +* `F902` — `SHA256U` `(s – x)`, computes `sha256` of the data bits of `Slice` `s`. If the bit length of `s` is not divisible by eight, throws a cell underflow exception. The hash value is returned as a 256-bit unsigned integer `x`. +* `F910` — `CHKSIGNU` `(h s k – ? )`, checks the Ed25519-signature `s` of a hash `h` (a 256-bit unsigned integer, usually computed as the hash of some data) using public key `k` (also represented by a 256-bit unsigned integer). The signature `s` must be a `Slice` containing at least 512 databits; only the first 512 bits are used. The result is `−1` if the signature is valid, `0` otherwise. Notice that `CHKSIGNU` is equivalent to `ROT`; `NEWB`; `STU` `256`; `ENDB`; `NEWC`; `ROTREV`; `CHKSIGNS`, i.e., to `CHKSIGNS` with the first argument `d` set to 256-bit `Slice` containing `h`. Therefore, if `h` is computed as the hash of some data, these data are hashed twice, the second hashing occurring inside `CHKSIGNS`. +* `F911` — `CHKSIGNS` `(d s k – ? )`, checks whether `s` is a valid Ed25519-signature of the data portion of `Slice` `d` using public key `k`, similarly to `CHKSIGNU`. If the bit length of `Slice` `d` is not divisible by eight, throws a cell underflow exception. The verification of Ed25519 signatures is the standard one, with `sha256` used to reduce `d` to the 256-bit number that is actually signed. * `F912–F93F` — Reserved for hashing and cryptography primitives. -## A.11.7. Miscellaneous primitives. +--- + +### A.11.7. Miscellaneous primitives. -* `F940` — **CDATASIZEQ** `(c n – x y z −1 or 0)`, recursively computes the count of distinct cells `x`, data bits `y`, and cell references `z` in the dag rooted at `Cell` `c`, effectively returning the total storage used by this dag taking into account the identification of equal cells. The values of `x`, `y`, and `z` are computed by a depth-first traversal of this dag, with a hash table of visited cell hashes used to prevent visits of already-visited cells. The total count of visited cells `x` cannot exceed non-negative `Integer` `n`; otherwise the computation is aborted before visiting the `(n + 1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, returns `x = y = z = 0`. -* `F941` — **CDATASIZE** `(c n – x y z)`, a non-quiet version of **CDATASIZEQ** that throws a cell overflow exception (8) on failure. -* `F942` — **SDATASIZEQ** `(s n – x y z −1 or 0)`, similar to **CDATASIZEQ**, but accepting a `Slice` `s` instead of a `Cell`. The returned value of `x` does not take into account the cell that contains the slice `s` itself; however, the data bits and the cell references of `s` are accounted for in `y` and `z`. -* `F943` — **SDATASIZE** `(s n – x y z)`, a non-quiet version of **SDATASIZEQ** that throws a cell overflow exception (8) on failure. +* `F940` — `CDATASIZEQ` `(c n – x y z −1 or 0)`, recursively computes the count of distinct cells `x`, data bits `y`, and cell references `z` in the dag rooted at `Cell` `c`, effectively returning the total storage used by this dag taking into account the identification of equal cells. The values of `x`, `y`, and `z` are computed by a depth-first traversal of this dag, with a hash table of visited cell hashes used to prevent visits of already-visited cells. The total count of visited cells `x` cannot exceed non-negative `Integer` `n`; otherwise the computation is aborted before visiting the `(n + 1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, returns `x = y = z = 0`. +* `F941` — `CDATASIZE` `(c n – x y z)`, a non-quiet version of `CDATASIZEQ` that throws a cell overflow exception (8) on failure. +* `F942` — `SDATASIZEQ` `(s n – x y z −1 or 0)`, similar to `CDATASIZEQ`, but accepting a `Slice` `s` instead of a `Cell`. The returned value of `x` does not take into account the cell that contains the slice `s` itself; however, the data bits and the cell references of `s` are accounted for in `y` and `z`. +* `F943` — `SDATASIZE` `(s n – x y z)`, a non-quiet version of `SDATASIZEQ` that throws a cell overflow exception (8) on failure. * `F944–F97F` — Reserved for miscellaneous TON-specific primitives that do not fall into any other specific category. - `133` - A.11. Application-specific primitives -## A.11.8. Currency manipulation primitives. +--- + +### A.11.8. Currency manipulation primitives. -* `FA00` — **LDGRAMS** or **LDVARUINT16** `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to **LDU** `4`; **SWAP**; **LSHIFT** `3`; **LDUX**. -* `FA01` — **LDVARINT16** `(s – x s0)`, similar to **LDVARUINT16**, but loads a signed `Integer` `x`. Approximately equivalent to **LDU** `4`; **SWAP**; **LSHIFT** `3`; **LDIX**. -* `FA02` — **STGRAMS** or **STVARUINT16** `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2^120−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2^(8l)`, followed by an `8l`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. -* `FA03` — **STVARINT16** `(b x – b 0)`, similar to **STVARUINT16**, but serializes a signed `Integer` `x` in the range `−2^119 ... 2^119 − 1`. -* `FA04` — **LDVARUINT32** `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2^248`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to **LDU** `5`; **SWAP**; **SHIFT** `3`; **LDUX**. -* `FA05` — **LDVARINT32** `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2^247 ≤ x < 2^247`. -* `FA06` — **STVARUINT32** `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2^248` as a `VarUInteger 32`. -* `FA07` — **STVARINT32** `(b x – b 0)`, serializes an `Integer` `−2^247 ≤ x < 2^247` as a `VarInteger 32`. +* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU` `4`; `SWAP`; `LSHIFT` `3`; `LDUX`. +* `FA01` — `LDVARINT16` `(s – x s0)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU` `4`; `SWAP`; `LSHIFT` `3`; `LDIX`. +* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2^120−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2^(8l)`, followed by an `8l`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. +* `FA03` — `STVARINT16` `(b x – b 0)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2^119 ... 2^119 − 1`. +* `FA04` — `LDVARUINT32` `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2^248`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU` `5`; `SWAP`; `SHIFT` `3`; `LDUX`. +* `FA05` — `LDVARINT32` `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2^247 ≤ x < 2^247`. +* `FA06` — `STVARUINT32` `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2^248` as a `VarUInteger 32`. +* `FA07` — `STVARINT32` `(b x – b 0)`, serializes an `Integer` `−2^247 ≤ x < 2^247` as a `VarInteger 32`. * `FA08–FA1F` — Reserved for currency manipulation primitives. -## A.11.9. Message and address manipulation primitives. + +### A.11.9. Message and address manipulation primitives. The message and address manipulation primitives listed below serialize and deserialize values according to the following TL-B scheme (cf. 3.3.4): ``` addr_none$00 = MsgAddressExt; addr_extern$01 len:(## 8) external_address:(bits len) = MsgAddressExt; -anycast_info$_ depth:(#<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; +anycast_info$_ depth:(<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt; addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) workchain_id:int32 address:(bits addr_len) = MsgAddressInt; _ _:MsgAddressInt = MsgAddress; @@ -3800,74 +2658,71 @@ A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: The following primitives, which use the above conventions, are defined: -* `FA40` — **LDMSGADDR** `(s – s 0 s 00)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s 0` and the remainder `s 00` of `s` as `CellSlices`. -* `FA41` — **LDMSGADDRQ** `(s – s 0 s 00 −1 or s 0)`, a quiet version of **LDMSGADDR**: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. -* `FA42` — **PARSEMSGADDR** `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. -* `FA43` — **PARSEMSGADDRQ** `(s – t −1 or 0)`, a quiet version of **PARSEMSGADDR**: returns a zero on error instead of throwing an exception. -* `FA44` — **REWRITESTDADDR** `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. -* `FA45` — **REWRITESTDADDRQ** `(s – x y −1 or 0)`, a quiet version of primitive **REWRITESTDADDR**. -* `FA46` — **REWRITEVARADDR** `(s – x s0)`, a variant of **REWRITESTDADDR** that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). -* `FA47` — **REWRITEVARADDRQ** `(s – x s0 −1 or 0)`, a quiet version of primitive **REWRITEVARADDR**. +### A.11.9. Message and address manipulation primitives. + +* `FA40` — `LDMSGADDR` `(s – s 0 s 00)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s 0` and the remainder `s 00` of `s` as `CellSlices`. +* `FA41` — `LDMSGADDRQ` `(s – s 0 s 00 −1 or s 0)`, a quiet version of `LDMSGADDR`: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. +* `FA42` — `PARSEMSGADDR` `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. +* `FA43` — `PARSEMSGADDRQ` `(s – t −1 or 0)`, a quiet version of `PARSEMSGADDR`: returns a zero on error instead of throwing an exception. +* `FA44` — `REWRITESTDADDR` `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. +* `FA45` — `REWRITESTDADDRQ` `(s – x y −1 or 0)`, a quiet version of primitive `REWRITESTDADDR`. +* `FA46` — `REWRITEVARADDR` `(s – x s0)`, a variant of `REWRITESTDADDR` that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). +* `FA47` — `REWRITEVARADDRQ` `(s – x s0 −1 or 0)`, a quiet version of primitive `REWRITEVARADDR`. * `FA48–FA5F` — Reserved for message and address manipulation primitives. -## A.11.10. Outbound message and output action primitives. +### A.11.10. Outbound message and output action primitives. -* `FB00` — **SENDRAWMSG** `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. -* `FB02` — **RAWRESERVE** `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. -* `FB03` — **RAWRESERVEX** `(x D y – )`, similar to **RAWRESERVE**, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. - `137` - A.12. Debug primitives -* `FB04` — **SETCODE** `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. -* `FB06` — **SETLIBCODE** `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. -* `FB07` — **CHANGELIB** `(h x – )`, creates an output action similarly to **SETLIBCODE**, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. +* `FB00` — `SENDRAWMSG` `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. +* `FB02` — `RAWRESERVE` `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. +* `FB03` — `RAWRESERVEX` `(x D y – )`, similar to `RAWRESERVE`, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. +* `FB04` — `SETCODE` `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. +* `FB06` — `SETLIBCODE` `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. +* `FB07` — `CHANGELIB` `(h x – )`, creates an output action similarly to `SETLIBCODE`, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. * `FB08–FB3F` — Reserved for output action primitives. --- -# A.12 Debug primitives -Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) **NOP** operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. +## A.12 Debug primitives -## A.12.1. Debug primitives as multibyte NOPs. +Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) `NOP` operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. -`138` -A.12. Debug primitives +### A.12.1. Debug primitives as multibyte NOPs. -* `FEnn` — **DEBUG** `nn`, for `0 ≤ nn < 240`, is a two-byte **NOP**. -* `FEFnssss` — **DEBUGSTR** `ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte **NOP**, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. +* `FEnn` — `DEBUG nn`, for `0 ≤ nn < 240`, is a two-byte `NOP`. +* `FEFnssss` — `DEBUGSTR ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte `NOP`, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. -## A.12.2. Debug primitives as operations without side-effect. +### A.12.2. Debug primitives as operations without side-effect. -Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte **NOP**s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as **NOP**s, but they cannot throw exceptions. +Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte `NOP`s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as `NOP`s, but they cannot throw exceptions. -* `FE00` — **DUMPSTK**, dumps the stack (at most the top 255 values) and shows the total stack depth. -* `FE0n` — **DUMPSTKTOP** `n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. -* `FE10` — **HEXDUMP**, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. -* `FE11` — **HEXPRINT**, similar to **HEXDUMP**, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. -* `FE12` — **BINDUMP**, dumps `s0` in binary form, similarly to **HEXDUMP**. -* `FE13` — **BINPRINT**, outputs the binary representation of `s0` to a text buffer. -* `FE14` — **STRDUMP**, dumps the `Slice` at `s0` as an UTF-8 string. -* `FE15` — **STRPRINT**, similar to **STRDUMP**, but outputs the string into a text buffer (without carriage return). -* `FE1E` — **DEBUGOFF**, disables all debug output until it is re-enabled by a **DEBUGON**. More precisely, this primitive increases an internal counter, which disables all debug operations (except **DEBUGOFF** and **DEBUGON**) when strictly positive. - `139` - A.13. Codepage primitives -* `FE1F` — **DEBUGON**, enables debug output (in a debug version of TVM). -* `FE2n` — **DUMP s(n)**, `0 ≤ n < 15`, dumps `s(n)`. -* `FE3n` — **PRINT s(n)**, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. +* `FE00` — `DUMPSTK`, dumps the stack (at most the top 255 values) and shows the total stack depth. +* `FE0n` — `DUMPSTKTOP n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. +* `FE10` — `HEXDUMP`, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. +* `FE11` — `HEXPRINT`, similar to `HEXDUMP`, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. +* `FE12` — `BINDUMP`, dumps `s0` in binary form, similarly to `HEXDUMP`. +* `FE13` — `BINPRINT`, outputs the binary representation of `s0` to a text buffer. +* `FE14` — `STRDUMP`, dumps the `Slice` at `s0` as an UTF-8 string. +* `FE15` — `STRPRINT`, similar to `STRDUMP`, but outputs the string into a text buffer (without carriage return). +* `FE1E` — `DEBUGOFF`, disables all debug output until it is re-enabled by a `DEBUGON`. More precisely, this primitive increases an internal counter, which disables all debug operations (except `DEBUGOFF` and `DEBUGON`) when strictly positive. +* `FE1F` — `DEBUGON`, enables debug output (in a debug version of TVM). +* `FE2n` — `DUMP s(n)`, `0 ≤ n < 15`, dumps `s(n)`. +* `FE3n` — `PRINT s(n)`, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. * `FEC0–FEEF` — Use these opcodes for custom/experimental debug operations. -* `FEFnssss` — **DUMPTOSFMT** `ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). -* `FEFn00ssss` — **LOGSTR** `ssss`, string `ssss` is `n` bytes long. -* `FEF000` — **LOGFLUSH**, flushes all pending debug output from the buffer into the debug log. -* `FEFn01ssss` — **PRINTSTR** `ssss`, string `ssss` is `n` bytes long. +* `FEFnssss` — `DUMPTOSFMT ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). +* `FEFn00ssss` — `LOGSTR ssss`, string `ssss` is `n` bytes long. +* `FEF000` — `LOGFLUSH`, flushes all pending debug output from the buffer into the debug log. +* `FEFn01ssss` — `PRINTSTR ssss`, string `ssss` is `n` bytes long. -# A.13 Codepage primitives +--- -The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. 5.1.8). +## A.13 Codepage primitives -* `FFnn` — **SETCP** `nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. -* `FF00` — **SETCP0**, selects TVM (test) codepage zero as described in this document -* `FFFz` — **SETCP** `z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 . . . − 1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in B.2.6. Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. -* `FFF0` — **SETCPX** `(c – )`, selects codepage `c` with `−2^15 ≤ c < 2^15` passed in the top of the stack. +The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. 5.1.8). +* `FFnn` — `SETCP nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. +* `FF00` — `SETCP0`, selects TVM (test) codepage zero as described in this document. +* `FFFz` — `SETCP z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 ... −1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in B.2.6. Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. +* `FFF0` — `SETCPX` `(c – )`, selects codepage `c` with `−2^15 ≤ c < 2^15` passed in the top of the stack. --- # B Formal properties and specifications of TVM @@ -4013,7 +2868,7 @@ Codepage `−1` of TVM is reserved for the stripped-down version of TVM. Its mai ### B.2.7. Codepage −2. -This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage `−2`”. All 64-bit arithmetic used in codepage `−1` would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage `−1`. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer. +This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage −2”. All 64-bit arithmetic used in codepage −1 would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage −1. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer.[30](#footnote-30) --- @@ -4031,7 +2886,7 @@ We start with a comparison of machine code generated by an (imaginary) optimizin The source file we consider contains one function f that takes six (integer) arguments, a, b, c, d, e, f, and returns two (integer) values, x and y, which are the solutions of the system of two linear equations -``` +```math ( ax + by = e cx + dy = f @@ -4040,17 +2895,16 @@ cx + dy = f The source code of the function, in a programming language similar to C, might look as follows: -```c -(int, int) f(int a, int b, int c, int d, int e, int f) { -int D = a*d - b*c; -int Dx = e*d - b*f; -int Dy = a*f - e*c; -147 -C.1. Sample leaf function -return (Dx / D, Dy / D); + +```math +(int, int) f(int a, int b, int c, int d, int e, int f) \\ +{ \\ + int D = a*d - b*c; \\ + int Dx = e*d - b*f; \\ + int Dy = a*f - e*c; \\ + return (Dx / D, Dy / D); \\ } ``` - We assume (cf. 2.1) that the register machines we consider accept the six parameters a. . . f in registers r0. . . r5, and return the two values x and y in r0 and r1. We also assume that the register machines have 16 registers, and that the stack machine can directly access s0 to s15 by its stack manipulation primitives; the stack machine will accept the parameters in s5 to s0, and return the two values in s0 and s1, somewhat similarly to the register machine. Finally, we assume at first that the register machine is allowed to destroy values in all registers (which is slightly unfair towards the stack machine); this assumption will be revisited later. ### C.1.2. Three-address register machine. @@ -4097,7 +2951,7 @@ IDIV r1,r6 // r1 := Dy/D RET ``` -We have used 16 operations; optimistically assuming each of them (with the exception of RET) can be encoded by two bytes, this code would require 31 bytes.31 +We have used 16 operations; optimistically assuming each of them (with the exception of RET) can be encoded by two bytes, this code would require 31 bytes.[31](#footnote-31) ### C.1.4. One-address register machine. @@ -4382,7 +3236,7 @@ Table 4: A summary of machine code properties for hypothetical 3-address, 2-addr This section compares the machine code for different register machines for a sample non-leaf function. Again, we assume that either m = 0, m = 8, or m = 16 registers are preserved by called functions, with m = 8 representing the compromise made by most modern compilers and operating systems. -## C.3.1. Sample source code for a non-leaf function. +### C.3.1. Sample source code for a non-leaf function. A sample source file may be obtained by replacing the built-in integer type with a custom Rational type, represented by a pointer to an object in memory, in our function for solving systems of two linear equations (cf. C.1.1): @@ -4407,11 +3261,11 @@ Rational numbers will now be represented by pointers, addresses, or references, We assume that subroutines (or functions) are called by a special CALL instruction, which is encoded by three bytes, including the specification of the function to be called (e.g., the index in a “global function table”). -## C.3.2. Three-address and two-address register machines, m = 0 preserved registers. +### C.3.2. Three-address and two-address register machines, m = 0 preserved registers. Because our sample function does not use built-in arithmetic instructions at all, compilers for our hypothetical three-address and two-address register machines will produce the same machine code. Apart from the previously introduced PUSH r(i) and POP r(i) one-byte instructions, we assume that our two- and three-address machines support the following two-byte instructions: MOV r(i),s(j), MOV s(j),r(i), and XCHG r(i),s(j), for 0 ≤ i, j ≤ 15. Such instructions occupy only 3/256 of the opcode space, so their addition seems quite natural. -We first assume that m = 0 (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for r\_f does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. A size-optimizing compiler might produce the following code: +We first assume that m = 0 (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for `r_f` does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. A size-optimizing compiler might produce the following code: ``` PUSH r4 // STACK: e @@ -4459,9 +3313,9 @@ POP r0 // x ; .. RET ``` -We have used 41 instructions: 17 one-byte (eight PUSH/POP pairs and one RET), 13 two-byte (MOV and XCHG; out of them 11 “new” ones, involving the stack),and 11 three-byte (CALL), for a total of 17 · 1 + 13 · 2 + 11 · 3 = 76 bytes. +We have used 41 instructions: 17 one-byte (eight PUSH/POP pairs and one RET), 13 two-byte (MOV and XCHG; out of them 11 “new” ones, involving the stack),and 11 three-byte (CALL), for a total of 17 · 1 + 13 · 2 + 11 · 3 = 76 bytes.[32](#footnote-32) -## C.3.3. Three-address and two-address register machines, m = 8 preserved registers. +### C.3.3. Three-address and two-address register machines, m = 8 preserved registers. Now we have eight registers, r8 to r15, that are preserved by subroutine calls. We might keep some intermediate values there instead of pushing them into the stack. However, the penalty for doing so consists in a PUSH/POP pair for every such register that we choose to use, because our function is also required to preserve its original value. It seems that using these registers under such a penalty does not improve the density of the code, so the optimal code for three- and two-address machines for m = 8 preserved registers is the same as that provided in C.3.2, with a total of 42 instructions and 74 code bytes. @@ -4517,7 +3371,7 @@ RET We have used 39 instructions: 11 one-byte, 17 two-byte (among them 5 “new” instructions), and 11 three-byte, for a total of 11 · 1 + 17 · 2 + 11 · 3 = 78 bytes. Somewhat paradoxically, the code size in bytes is slightly longer than in the previous case (cf. C.3.2), contrary to what one might have expected. This is partially due to the fact that we have assumed two-byte encodings for “new” MOV and XCHG instructions involving the stack, similarly to the “old” instructions. Most existing architectures (such as x86-64) use longer encodings (maybe even twice as long) for their counterparts of our “new” move and exchange instructions compared to the “usual” register-register ones. Taking this into account, we see that we would have obtained here 83 bytes (versus 87 for the code in C.3.2) assuming three-byte encodings of new operations, and 88 bytes (versus 98) assuming four-byte encodings. This shows that, for two-address architectures without optimized encodings for register-stackmove and exchange operations, m = 16 preserved registers might result in slightly shorter code for some non-leaf functions, at the expense of leaf functions (cf. C.2.3 and C.2.4), which would become considerably longer. -## C.3.5. One-address register machine, m = 0 preserved registers. +### C.3.5. One-address register machine, m = 0 preserved registers. For our one-address register machine, we assume that new register-stack instructions work through the accumulator only. Therefore, we have three new instructions, LD s(j) (equivalent to MOV r0,s(j) of two-address machines), ST s(j) (equivalent to MOV s(j),r0), and XCHG s(j) (equivalent to XCHG r0,s(j)). To make the comparison with two-address machines more interesting, we assume one-byte encodings for these new instructions, even though this would consume 48/256 = 3/16 of the opcode space. @@ -4575,11 +3429,11 @@ RET We have used 45 instructions: 34 one-byte and 11 three-byte, for a total of 67 bytes. Compared to the 76 bytes used by two- and three-address machines in C.3.2, we see that, again, the one-address register machine code may be denser than that of two-register machines, at the expense of utilizing more opcode space (just as shown in C.2). However, this time the extra 3/16 of the opcode space was used for data manipulation instructions, which do not depend on specific arithmetic operations or user functions invoked. -## C.3.6. One-address register machine, m = 8 preserved registers. +### C.3.6. One-address register machine, m = 8 preserved registers. As explained in C.3.3, the preservation of r8–r15 between subroutine calls does not improve the size of our previously written code, so the one-address machine will use for m = 8 the same code provided in C.3.5. -## C.3.7. One-address register machine, m = 16 preserved registers. +### C.3.7. One-address register machine, m = 16 preserved registers. We simply adapt the code provided in C.3.4 to the one-address register machine: @@ -4629,7 +3483,7 @@ RET We have used 40 instructions: 18 one-byte, 11 two-byte, and 11 three-byte, for a total of 18 · 1 + 11 · 2 + 11 · 3 = 73 bytes. -## C.3.8. Stack machine with basic stack primitives. +### C.3.8. Stack machine with basic stack primitives. We reuse the code provided in C.1.5, simply replacing arithmetic primitives (VM instructions) with subroutine calls. The only substantive modification is the insertion of the previously optional XCHG s1 before the third multiplication, because even an optimizing compiler cannot now know whether CALL r\_mul is a commutative operation. We have also used the “tail recursion optimization” by replacing the final CALL r\_div followed by RET with JMP r\_div. @@ -4667,7 +3521,7 @@ JMP r_div // x y We have used 29 instructions; assuming one-byte encodings for all stack operations, and three-byte encodings for CALL and JMP instructions, we end up with 51 bytes. -## C.3.9. Stack machine with compound stack primitives. +### C.3.9. Stack machine with compound stack primitives. We again reuse the code provided in C.1.7, replacing arithmetic primitives with subroutine calls and making the tail recursion optimization: @@ -4760,7 +3614,9 @@ For example, the very popular two-address register architecture x86-64 produces An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in 2.2.2 and 2.2.5. The only exception is the unimportant “manual” XCHG3 optimization described in C.1.7, which enabled us to shorten the code by one more byte. By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. +## References + [1] N. Durov, *Telegram Open Network*, 2017. ## Footnotes @@ -4768,4 +3624,62 @@ By contrast, the heavily optimized (with respect to size) code for register mach **2.** The production version will likely require some tweaks and modifications prior to launch, which will become apparent only after using the experimental version in the test environment for some time. [Back ↑](#1-introduction) - **3.** A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. [Back ↑](#11-tvm-is-a-stack-machine) + **3.** A high-level smart-contract language might create a visibility of variables for the ease of programming; however, the high-level source code working with variables will be translated into TVM machine code keeping all the values of these variables in the TVM stack. [Back ↑](#1-1-tvm-is-a-stack-machine) + + **4.** In the TON Blockchain context, `c7` is initialized with a singleton `Tuple`, the only component of which is a `Tuple` containing blockchain-specific data. The smart contract is free to modify `c7` to store its temporary data provided the first component of this `Tuple` remains intact. [Back ↑](#1-3-2-list-of-control-registers) + + **5.** Strictly speaking, there is also the current library context, which consists of a dictionary with 256-bit keys and cell values, used to load library reference cells of 3.1.7. [Back ↑](#1-4-total-state-of-tvm-scccg) + + **6.** Our inclusion of `r0` here creates a minor conflict with our assumption that the accumulator register, if present, is also `r0`; for simplicity, we will resolve this problem by assuming that the first argument to a function is passed in the accumulator. [Back ↑](#2-1-5-register-calling-conventions) + + **7.** For instance, if one writes a function for extracting square roots, this function will always accept its argument and return its result in the same registers, in contrast with a hypothetical built-in square root instruction, which could allow the programmer to arbitrarily choose the source and destination registers. Therefore, a user-defined function is tremendously less flexible than a built-in instruction on a register machine. [Back ↑](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines) + + **8.** Of course, if the second option is used, this will destroy the original arrangement of `x` in the top of the stack. In this case, one should either issue a `SWAP` before `XCHG s(j₀)`, or replace the previous operation `XCHG s(i)` with `XCHG s1, s(i)`, so that `x` is exchanged with `s1` from the beginning. [Back ↑](#2-2-2-basic-stack-manipulation-primitives-suffice) + + **9.** Notice that the most common `XCHG s(i)` operation is not really required here if we do not insist on keeping the same temporary value or variable always in the same stack location, but rather keep track of its subsequent locations. We will move it to some other location while preparing the arguments to the next primitive or function call. [Back ↑](#2-2-2-basic-stack-manipulation-primitives-suffice) + + **10.** An alternative, arguably better, translation of `PU O₀ s(i₁), …, s(iγ)` consists of the translation of `O₀ s(i₂), …, s(iγ)`, followed by `PUSH s(i₁ + α − 1); XCHG s(γ − 1)`. [Back ↑](#2-2-5-semantics-of-compound-stack-operations) + + **11.** From the perspective of low-level cell operations, these data bits and cell references are not intermixed. In other words, an (ordinary) cell essentially is a couple consisting of a list of up to 1023 bits and of a list of up to four cell references, without prescribing an order in which the references and the data bits should be deserialized, even though TL-B schemes appear to suggest such an order. [Back ↑](#3-1-1-tvm-memory-and-persistent-storage-consist-of-cells) + + **12.** From a theoretical perspective, we might say that a cell `c` has an infinite sequence of hashes `Hashᵢ(c)` (`i ≥ 1`), which eventually stabilizes: `Hashᵢ(c) → Hash∞(c)`. Then the level `l` is simply the largest index `i`, such that `Hashᵢ(c) ≠ Hash∞(c)`. [Back ↑](#3-1-7-types-of-exotic-cells) + + **13.** A pruned branch cell `c₀` of level `l` is bound by a Merkle (proof or update) cell `c` if there are exactly `l` Merkle cells on the path from `c` to its descendant `c₀`, including `c`. [Back ↑](#3-1-7-types-of-exotic-cells) + + **14.** Negative numbers are represented using two’s complement. For instance, integer `−17` is serialized by instruction `STI 8` into bitstring `xEF`. [Back ↑](#3-2-8-integers-in-cells-are-big-endian-by-default) + + **15.** A description of an older version of TL may be found at https://core.telegram.org/mtproto/TL. [Back ↑](#3-3-3-serialization-of-hashmaps) + + **16.** The field’s name is useful for representing values of the type being defined in human-readable form, but it does not affect the binary serialization. [Back ↑](#3-3-4-brief-explanation-of-tl-b-schemes) + + **17.** This is the “linear negation” operation `(-)^⊥` of linear logic, hence the notation `~`. [Back ↑](#3-3-4-brief-explanation-of-tl-b-schemes) + + **18.** In fact, `f` may receive `m` extra arguments and return `m` modified values, which are passed to the next invocation of `f`. This may be used to implement “map” and “reduce” operations with dictionaries. [Back ↑](#3-3-10-basic-dictionary-operations) + + **19.** Versions of this operation may be introduced where `f` and `g` receive an additional bitstring argument, equal to the key (for leaves) or to the common prefix of all keys (for forks) in the corresponding subtree. [Back ↑](#3-3-10-basic-dictionary-operations) + + **20.** If there are no bits of data left in `code`, but there is still exactly one reference, an implicit `JMP` to the cell at that reference is performed instead of an implicit `RET`. [Back ↑](#414-normal-work-of-tvm-or-the-main-loop) + + **21.** Technically, TVM may simply invoke a virtual method `run()` of the continuation currently in `cc`. [Back ↑](#415-extraordinary-continuations) + + **22.** The already used savelist `cc.save` of the new `cc` is emptied before the execution starts. [Back ↑](#418-restoring-control-registers-from-the-new-continuation-c) + + **23.** The implementation of REPEAT involves an extraordinary continuation that remembers the remaining number of iterations, the body of the loop c, and the return continuation c'. (The latter term represents the remainder of the body of the function that invoked REPEAT, which would be normally stored in c0 of the new cc.) [Back ↑](#422-iterated-execution-and-loops) + + **24.** An important point here is that the tree of cells representing a TVM program cannot have cyclic references, so using `CALLREF` along with a reference to a cell higher up the tree would not work. [Back ↑](#4-6-1-the-problem-of-recursion) + + **25.** This is not exactly true. A more precise statement is that usually the codepage of the newly-created continuation is a known function of the current codepage. [Back ↑](#5-1-1-codepages-in-continuations) + + **26.** This is another important mechanism of backward compatibility. All values of newly-added types, as well as values belonging to extended original types that do not belong to the original types (e.g., 513-bit integers that do not fit into 257 bits in the example above), are treated by all instructions (except stack manipulation instructions, which are naturally polymorphic, cf. [2.2.6](#2-2-6-stack-manipulation-instructions-are-polymorphic)) in the old codepages as “values of incorrect type”, and generate type-checking exceptions accordingly. [Back ↑](#5-1-4-changing-the-behavior-of-old-operations) + + **27.** If the cell dumps are hexadecimal, encodings consisting of an integral number of hexadecimal digits (i.e., having length divisible by four bits) might be equally convenient. [Back ↑](#5-2-5-tvm-code-is-a-bitcode-not-a-bytecode) + + **28.** Notice that it is the probability of occurrence in the code that counts, not the probability of being executed. An instruction occurring in the body of a loop executed a million times is still counted only once. [Back ↑](#5-2-9-almost-optimal-encodings) + + **29.** Notice that any modifications after launch cannot be done unilaterally; rather they would require the support of at least two-thirds of validators. [Back ↑](#5-3-1-upgradability) + + **30.** The preliminary version of TVM does not use codepage −2 for this purpose. This may change in the future. [Back ↑](#b27-codepage-2) + + **31.** It is interesting to compare this code with that generated by optimizing C compilers for the x86-64 architecture. First of all, the integer division operation for x86-64 uses the one-address form, with the (double-length) dividend to be supplied in accumulator pair `r2:r0`. The quotient is also returned in `r0`. As a consequence, two single-to-double extension operations (**CDQ** or **CQO**) and at least one move operation need to be added. Secondly, the encoding used for arithmetic and move operations is less optimistic than in our example above, requiring about three bytes per operation on average. As a result, we obtain a total of 43 bytes for 32-bit integers, and 68 bytes for 64-bit integers. [Back ↑](#c13-two-address-register-machine) + + **32.** Code produced for this function by an optimizing compiler for x86-64 architecture. [Back ↑](#c32-three-address-and-two-address-register-machines-m--0-preserved-registers) \ No newline at end of file From 8c6a4a0bc524d124b2dd17bc9a9c1720ffe97781 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Tue, 9 Sep 2025 03:18:51 +0100 Subject: [PATCH 11/18] more markdown updates --- ton/tvm.mdx | 3018 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 1965 insertions(+), 1053 deletions(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 75fedb0c..aa704237 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -104,7 +104,7 @@ All type tags attached to values processed by TVM will always have expected valu A preliminary list of value types supported by TVM is as follows: -- **Integer** — Signed 257-bit integers, representing integer numbers in the range `−2^256 … 2^256 − 1`, as well as a special “not-a-number” value `NaN`. +- **Integer** — Signed 257-bit integers, representing integer numbers in the range `−2²⁵⁶ … 2²⁵⁶ − 1`, as well as a special “not-a-number” value `NaN`. - **Cell** — A TVM cell consists of at most 1023 bits of data, and of at most four references to other cells. All persistent data (including TVM code) in the TON Blockchain is represented as a collection of TVM cells (cf. [1](#reference-1) 2.5.14]). - **Tuple** — An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent nonpersistent values of arbitrary algebraic data types. - **Null** — A type with exactly one value `⊥`, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on. @@ -179,7 +179,7 @@ Also notice that there are no general-purpose registers, because TVM is a stack ## 1.5 Integer arithmetic -All arithmetic primitives of TVM operate on several arguments of type `Integer`, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that `Integer` represents all integer values in the range `−2^256 ≤ x < 2^256`, and additionally contains a special value `NaN` (“not-a-number”). +All arithmetic primitives of TVM operate on several arguments of type `Integer`, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that `Integer` represents all integer values in the range `−2²⁵⁶ ≤ x < 2²⁵⁶`, and additionally contains a special value `NaN` (“not-a-number”). If one of the results does not fit into the supported range of integers—or if one of the arguments is a `NaN`—then this result or all of the results are replaced by a `NaN`, and (by default) an integer overflow exception is generated. However, special “quiet” versions of arithmetic operations will simply produce `NaN`s and keep going. If these `NaN`s end up being used in a “non-quiet” arithmetic operation, or in a non-arithmetic operation, an integer overflow exception will occur. @@ -191,11 +191,11 @@ Notice that TVM `Integer`s are “mathematical” integers, and not 257-bit stri Notice that all TVM arithmetic primitives perform overflow checks of the results. If a result does not fit into the `Integer` type, it is replaced by a `NaN`, and (usually) an exception occurs. -In particular, the result is not automatically reduced modulo `2^256` or `2^257`, as is common for most hardware machine code architectures. +In particular, the result is not automatically reduced modulo `−2²⁵⁶` or `2²⁵⁷`, as is common for most hardware machine code architectures. ### 1.5.3 Custom overflow checks -In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. These primitives check whether the value on (the top of) the stack is an integer `x` in the range `−2^(n−1) ≤ x < 2^(n−1)` or `0 ≤ x < 2^n`, respectively, and replace the value with a `NaN` and (optionally) generate an integer overflow exception if this is not the case. +In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives `FITS n` and `UFITS n`, where `1 ≤ n ≤ 256`. These primitives check whether the value on (the top of) the stack is an integer `x` in the range `−2ⁿ⁻¹ ≤ x < 2ⁿ⁻¹` or `0 ≤ x < 2ⁿ`, respectively, and replace the value with a `NaN` and (optionally) generate an integer overflow exception if this is not the case. This greatly simplifies the implementation of arbitrary n-bit integer types, signed or unsigned: the programmer or the compiler must insert appropriate `FITS` or `UFITS` primitives either after each arithmetic operation (which is more reasonable, but requires more checks) or before storing computed values and returning them from functions. @@ -203,7 +203,7 @@ This is important for smart contracts, where unexpected integer overflows happen ### 1.5.4 Reduction modulo 2ⁿ -TVM also has a primitive `MODPOW2 n`, which reduces the integer at the top of the stack modulo `2^n`, with the result ranging from `0` to `2^n − 1`. +TVM also has a primitive MODPOW2 n, which reduces the integer at the top of the stack modulo `2ⁿ`, with the result ranging from `0` to `2ⁿ − 1`. ### 1.5.5 Integer is 257-bit, not 256-bit @@ -233,7 +233,7 @@ If `c` is zero or if the quotient does not fit into `Integer`, either two `NaN`s # 2 The stack -This chapter contains a general discussion and comparison of register and stack machines, expanded further in [Appendix C](#appendix-c), and describes the two main classes of stack manipulation primitives employed by TVM: the basic and the compound stack manipulation primitives. An informal explanation of their sufficiency for all stack reordering required for correctly invoking other primitives and user-defined functions is also provided. Finally, the problem of efficiently implementing TVM stack manipulation primitives is discussed in [2.3](#2-3-...). +This chapter contains a general discussion and comparison of register and stack machines, expanded further in [Appendix C](#c-code-density-of-stack-and-register-machines), and describes the two main classes of stack manipulation primitives employed by TVM: the basic and the compound stack manipulation primitives. An informal explanation of their sufficiency for all stack reordering required for correctly invoking other primitives and user-defined functions is also provided. Finally, the problem of efficiently implementing TVM stack manipulation primitives is discussed in [2.3](#2-3-...). ## 2.1 Stack calling conventions @@ -271,7 +271,7 @@ For simplicity, we will assume that up to `m ≤ n` function arguments are passe ### 2.1.6 Order of function arguments -If a function or primitive requires `m` arguments `x1, …, xm`, they are pushed by the caller into the stack in the same order, starting from `x1`. Therefore, when the function or primitive is invoked, its first argument `x1` is in `s(m − 1)`, its second argument `x2` is in `s(m − 2)`, and so on. The last argument `xm` is in `s0` (i.e., at the top of the stack). It is the called function or primitive’s responsibility to remove its arguments from the stack. +If a function or primitive requires `m` arguments `x₁, …, xₘ`, they are pushed by the caller into the stack in the same order, starting from `x1`. Therefore, when the function or primitive is invoked, its first argument `x₁` is in `s(m − 1)`, its second argument `x₂` is in `s(m − 2)`, and so on. The last argument `xₘ` is in `s0` (i.e., at the top of the stack). It is the called function or primitive’s responsibility to remove its arguments from the stack. In this respect the TVM stack calling conventions—obeyed, at least, by TMV primitives—match those of Pascal and Forth, and are the opposite of those of C (in which the arguments are pushed into the stack in the reverse order, and are removed by the caller after it regains control, not the callee). @@ -307,13 +307,13 @@ In this respect TVM, again, faithfully observes Forth calling conventions. ### 2.1.10 Stack notation -When a stack of depth `n` contains values `z1, …, zn`, in that order, with `z1` the deepest element and `zn` the top of the stack, the contents of the stack are often represented by a list `z1 z2 … zn`, in that order. When a primitive transforms the original stack state `S₀` into a new state `S₀₀`, this is often written as `S₀ – S₀₀`; this is the so-called **stack notation**. +When a stack of depth n contains values `z₁, …, zₙ`, in that order, with z₁ the deepest element and `zₙ` the top of the stack, the contents of the stack are often represented by a list `z₁ z₂ … zₙ`, in that order.. When a primitive transforms the original stack state `S′` into a new state `S′′`, this is often written as `S′ – S′′`; this is the so-called **stack notation**. For example, the action of the division primitive `DIV` can be described by `S x y – S ⌊x/y⌋`, where `S` is any list of values. This is usually abbreviated as `x y – ⌊x/y⌋`, tacitly assuming that all other values deeper in the stack remain intact. -Alternatively, one can describe `DIV` as a primitive that runs on a stack `S₀` of depth `n ≥ 2`, divides `s1` by `s0`, and returns the floor-rounded quotient as `s0` of the new stack `S₀₀` of depth `n − 1`. The new value of `s(i)` equals the old value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `… x y` into `… ⌊x/y⌋`, is more concise. +Alternatively, one can describe `DIV` as a primitive that runs on a stack `S′′` of depth `n ≥ 2`, divides `s1` by `S0`, and returns the floor-rounded quotient as `s0` of the new stack `S′′` of depth `n − 1`. The new value of `s(i)` equals the old value of `s(i + 1)` for `1 ≤ i < n − 1`. These descriptions are equivalent, but saying that `DIV` transforms `x y` into `⌊x/y⌋`, or `… x y` into `… ⌊x/y⌋`, is more concise. -The stack notation is extensively used throughout [Appendix A](#appendix-a), where all currently defined TVM primitives are listed. +The stack notation is extensively used throughout [Appendix A](#a-instructions-and-opcodes), where all currently defined TVM primitives are listed. ### 2.1.11 Explicitly defining the number of arguments to a function @@ -325,7 +325,7 @@ Such argument-checking mechanisms might be useful, for example, for a library fu ## 2.2 Stack manipulation primitives -A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, so that they become located near the top of the stack in correct order. This section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some examples of code using these primitives can be found in [Appendix C](#appendix-c). +A stack machine, such as TVM, employs a lot of stack manipulation primitives to rearrange arguments to other primitives and user-defined functions, so that they become located near the top of the stack in correct order. This section discusses which stack manipulation primitives are necessary and sufficient for achieving this goal, and which of them are used by TVM. Some examples of code using these primitives can be found in [Appendix C](#c-code-density-of-stack-and-register-machines). ### 2.2.1 Basic stack manipulation primitives @@ -340,9 +340,9 @@ Some other “unsystematic” stack manipulation operations might be also define ### 2.2.2 Basic stack manipulation primitives suffice -A compiler or a human TVM-code programmer might use the basic stack primitives as follows. Suppose that the function or primitive to be invoked is to be passed, say, three arguments `x, y, z`, currently located in stack registers `s(i)`, `s(j)`, and `s(k)`. In this circumstance, the compiler (or programmer) might issue operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) or `XCHG s(i)` (if it will not be needed thereafter) to put the first argument `x` into the top of the stack. Then, the compiler (or programmer) could use either `PUSH s(j₀)` or `XCHG s(j₀)`, where `j₀ = j` or `j + 1`, to put `y` into the new top of the stack.[8](#footnote-8) +A compiler or a human TVM-code programmer might use the basic stack primitives as follows. Suppose that the function or primitive to be invoked is to be passed, say, three arguments `x, y, z`, currently located in stack registers `s(i)`, `s(j)`, and `s(k)`. In this circumstance, the compiler (or programmer) might issue operation `PUSH s(i)` (if a copy of `x` is needed after the call to this primitive) or `XCHG s(i)` (if it will not be needed thereafter) to put the first argument `x` into the top of the stack. Then, the compiler (or programmer) could use either `PUSH s(j′)` or `XCHG s(j′)`, where `j′ = j` or `j + 1`, to put `y` into the new top of the stack.[8](#footnote-8) -Proceeding in this manner, we see that we can put the original values of `x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using a sequence of push and exchange operations (cf. [2.2.4](#2-2-4-mnemonics-of-compound-stack-operations) and [2.2.5](#2-2-5-... ) for a more detailed explanation). In order to generate this sequence, the compiler will need to know only the three values `i, j, k`, describing the old locations of variables or temporary values in question, and some flags describing whether each value will be needed thereafter or is needed only for this primitive or function call. The locations of other variables and temporary values will be affected in the process, but a compiler (or a human programmer) can easily track their new locations. +Proceeding in this manner, we see that we can put the original values of `x`, `y`, and `z`—or their copies, if needed—into locations `s2`, `s1`, and `s0`, using a sequence of push and exchange operations (cf. [2.2.4](#2-2-4-mnemonics-of-compound-stack-operations) and [2.2.5](#2-2-5-semantics-of-compound-stack-operations) for a more detailed explanation). In order to generate this sequence, the compiler will need to know only the three values `i, j, k`, describing the old locations of variables or temporary values in question, and some flags describing whether each value will be needed thereafter or is needed only for this primitive or function call. The locations of other variables and temporary values will be affected in the process, but a compiler (or a human programmer) can easily track their new locations. Similarly, if the results returned from a function need to be discarded or moved to other stack registers, a suitable sequence of exchange and pop operations will do the job. In the typical case of one return value in `s0`, this is achieved either by an `XCHG s(i)` or a `POP s(i)` (in most cases, a `DROP`) operation.[9](#footnote-9) @@ -361,15 +361,15 @@ In order to improve the density of the TVM code and simplify development of comp Of course, such operations make sense only if they admit a more compact encoding than the equivalent sequence of basic operations. For example, if all top-of-stack exchanges, `XCHG s1,s(i)` exchanges, and push and pop operations admit one-byte encodings, the only compound stack operations suggested above that might merit inclusion in the set of stack manipulation primitives are `PUXC`, `XCHG3`, and `PUSH3`. -These compound stack operations essentially augment other primitives (instructions) in the code with the “true” locations of their operands, somewhat similarly to what happens with two-address or three-address register machine code. However, instead of encoding these locations inside the opcode of the arithmetic or another instruction, as is customary for register machines, we indicate these locations in a preceding compound stack manipulation operation. As already described in [2.1.7](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines), the advantage of such an approach is that user-defined functions (or rarely used specific primitives added in a future version of TVM) can benefit from it as well (cf. [C.3](#c-3-...) for a more detailed discussion with examples). +These compound stack operations essentially augment other primitives (instructions) in the code with the “true” locations of their operands, somewhat similarly to what happens with two-address or three-address register machine code. However, instead of encoding these locations inside the opcode of the arithmetic or another instruction, as is customary for register machines, we indicate these locations in a preceding compound stack manipulation operation. As already described in [2.1.7](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines), the advantage of such an approach is that user-defined functions (or rarely used specific primitives added in a future version of TVM) can benefit from it as well (cf. [C.3](#c-3-sample-non-leaf-function) for a more detailed discussion with examples). ### 2.2.4 Mnemonics of compound stack operations The mnemonics of compound stack operations, some examples of which have been provided in [2.2.3](#2-2-3-compound-stack-manipulation-primitives), are created as follows. -The `γ ≥ 2` formal arguments `s(i₁), …, s(i_γ)` to such an operation `O` represent the values in the original stack that will end up in `s(γ − 1), …, s0` after the execution of this compound operation, at least if all `iν`, `1 ≤ ν ≤ γ`, are distinct and at least `γ`. The mnemonic itself of the operation `O` is a sequence of `γ` two-letter strings `PU` and `XC`, with `PU` meaning that the corresponding argument is to be **PU**shed (i.e., a copy is to be created), and `XC` meaning that the value is to be **eX**Changed (i.e., no other copy of the original value is created). Sequences of several `PU` or `XC` strings may be abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, we write `PUXC2PU` instead of `PUXCXCPU`.) +The `γ ≥ 2` formal arguments `s(i₁), …, s(iγ)` to such an operation `O` represent the values in the original stack that will end up in `s(γ − 1), …, s₀` after the execution of this compound operation, at least if all `iᵥ, 1 ≤ ν ≤ γ`, are distinct and at least `γ`. The mnemonic itself of the operation `O` is a sequence of `γ` two-letter strings `PU` and `XC`, with `PU` meaning that the corresponding argument is to be PUshed (i.e., a copy is to be created), and `XC` meaning that the value is to be eXChanged (i.e., no other copy of the original value is created). Sequences of several `PU` or `XC` strings may be abbreviated to one `PU` or `XC` followed by the number of copies. (For instance, we write `PUXC2PU` instead of `PUXCXCPU`.) -As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, so that the compound operation is equivalent to a sequence of `m` `PUSH`es or `eXCHanGe`s, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. +As an exception, if a mnemonic would consist of only `PU` or only `XC` strings, so that the compound operation is equivalent to a sequence of `m` `PUSH`es or eXCHanGEs, the notation `PUSHm` or `XCHGm` is used instead of `PUm` or `XCm`. ### 2.2.5 Semantics of compound stack operations @@ -379,11 +379,11 @@ Each compound γ-ary operation `O s(i₁), …, s(iγ)` is translated into an eq - Equivalently, we might begin the induction from γ = 1. Then `PU s(i)` corresponds to the sequence consisting of one basic operation `PUSH s(i)`, and `XC s(i)` corresponds to the one-element sequence consisting of `XCHG s(i)`. - For γ ≥ 1 (or for γ ≥ 2, if we use γ = 1 as induction base), there are two subcases: - 1. `O s(i₁), …, s(iγ)`, with `O = XC O₀`, where `O₀` is a compound operation of arity γ − 1 (i.e., the mnemonic of `O₀` consists of γ − 1 strings `XC` and `PU`). - Let α be the total quantity of **PU**shes in `O`, and β be that of eXChanges, so that α + β = γ. Then the original operation is translated into `XCHG s(β − 1), s(i₁)`, followed by the translation of `O₀ s(i₂), …, s(iγ)`, defined by the induction hypothesis. + 1. `O s(i₁), …, s(iγ)`, with `O = XC O′`, where `O′` is a compound operation of arity γ − 1 (i.e., the mnemonic of `O′` consists of γ − 1 strings `XC` and `PU`). + Let α be the total quantity of **PU**shes in `O`, and β be that of eXChanges, so that α + β = γ. Then the original operation is translated into `XCHG s(β − 1), s(i₁)`, followed by the translation of `O′ s(i₂), …, s(iγ)`, defined by the induction hypothesis. - 2. `O s(i₁), …, s(iγ)`, with `O = PU O₀`, where `O₀` is a compound operation of arity γ − 1. - Then the original operation is translated into `PUSH s(i₁); XCHG s(β)`, followed by the translation of `O₀ s(i₂ + 1), …, s(iγ + 1)`, defined by the induction hypothesis.[10](#footnote-10) + 2. `O s(i₁), …, s(iγ)`, with `O = PU O′`, where `O′` is a compound operation of arity γ − 1. + Then the original operation is translated into `PUSH s(i₁); XCHG s(β)`, followed by the translation of `O′s(i₂ + 1), …, s(iγ + 1)`, defined by the induction hypothesis.[10](#footnote-10) --- @@ -429,7 +429,7 @@ In other words, the programmer should always act as if the objects themselves we One might attempt to create a circular reference between two cells, `A` and `B`, as follows: first create `A` and write some data into it; then create `B` and write some data into it, along with a reference to previously constructed cell `A`; finally, add a reference to `B` into `A`. -While it may seem that after this sequence of operations we obtain a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. In fact, we obtain a new cell `A₀`, which contains a copy of the data originally stored into cell `A` along with a reference to cell `B`, which contains a reference to (the original) cell `A`. +While it may seem that after this sequence of operations we obtain a cell `A`, which refers to `B`, which in turn refers to `A`, this is not the case. In fact, we obtain a new cell `A′`, which contains a copy of the data originally stored into cell `A` along with a reference to cell `B`, which contains a reference to (the original) cell `A`. In this way the transparent copy-on-write mechanism and the “everything is a value” paradigm enable us to create new cells using only previously constructed cells, thus forbidding the appearance of circular references. @@ -461,33 +461,33 @@ The type of an exotic cell is stored as the first eight bits of its data. If an ### 3.1.3 The level of a cell -Every cell `c` has another attribute `Lvl(c)` called its (de Brujn) **level**, which currently takes integer values in the range 0…3. +Every cell `c` has another attribute `Lvl(c)` called its (_de Brujn_) **level**, which currently takes integer values in the range 0…3. The level of an ordinary cell is always equal to the maximum of the levels of all its children `ci`: ```math Lvl(c) = max_{1 ≤ i ≤ r} Lvl(ci) -```` +``` -for an ordinary cell `c` containing `r` references to cells `c1, …, cr`. +For an ordinary cell `c` containing `r` references to cells `c₁, …, cᵣ`. If `r = 0`, then `Lvl(c) = 0`. Exotic cells may have different rules for setting their level. -A cell’s level affects the number of higher hashes it has. More precisely, a level `l` cell has `l` higher hashes `Hash₁(c), …, Hash_l(c)` in addition to its representation hash `Hash(c) = Hash∞(c)`. +A cell’s level affects the number of higher hashes it has. More precisely, a level `ℓ` cell has `ℓ` higher hashes `Hash₁(c), …, Hashℓ(c)` in addition to its representation hash `Hash(c) = Hash∞(c)`. Cells of non-zero level appear inside Merkle proofs and Merkle updates, after some branches of the tree of cells representing a value of an abstract data type are pruned. + ### 3.1.4 Standard cell representation When a cell needs to be transferred by a network protocol or stored in a disk file, it must be serialized. The standard representation `CellRepr(c) = CellRepr∞(c)` of a cell `c` as an octet (byte) sequence is constructed as follows: -1. Two descriptor bytes `d1` and `d2` are serialized first. - - * `d1 = r + 8s + 32l`, where `0 ≤ r ≤ 4` is the number of cell references contained in the cell, `0 ≤ l ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is 1 for exotic cells and 0 for ordinary cells. - * `d2 = ⌊b/8⌋ + ⌈b/8⌉`, where `0 ≤ b ≤ 1023` is the number of data bits in `c`. +1. Two descriptor bytes `d₁` and `d₂` are serialized first. + * Byte `d₁` equals `r + 8s + 32ℓ`, where `0 ≤ r ≤ 4` is the quantity of cell references contained in the cell, `0 ≤ ℓ ≤ 3` is the level of the cell, and `0 ≤ s ≤ 1` is `1` for exotic cells and `0` for ordinary cells. + * Byte `d₂` equals `⌊b / 8⌋ + ⌈b / 8⌉`, where `0 ≤ b ≤ 1023` is the quantity of data bits in `c`. 2. Then the data bits are serialized as `⌈b/8⌉` 8-bit octets (bytes). If `b` is not a multiple of eight, a binary `1` and up to six binary `0`s are appended to the data bits. After that, the data is split into `⌈b/8⌉` eight-bit groups, and each group is interpreted as an unsigned big-endian integer 0…255 and stored into an octet. -3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(ci)` (explained in [3.1.5](#3-1-5-the-representation-hash-of-a-cell)) of the cell `ci` referred to. +3. Finally, each of the `r` cell references is represented by 32 bytes containing the 256-bit representation hash `Hash(cᵢ)` (explained in [3.1.5](#3-1-5-the-representation-hash-of-a-cell)) of the cell `cᵢ` referred to. In this way, `2 + ⌈b/8⌉ + 32r` bytes of `CellRepr(c)` are obtained. @@ -503,14 +503,9 @@ Notice that cyclic cell references are not allowed and cannot be created by mean ### 3.1.6 The higher hashes of a cell -Recall that a cell `c` of level `l` has `l` higher hashes `Hashᵢ(c), 1 ≤ i ≤ l`, as well. Exotic cells have their own rules for computing their higher hashes. +Recall that a cell `c` of level `ℓ` has `ℓ` higher hashes `Hashᵢ(c)`, `1 ≤ i ≤ ℓ`, as well. Exotic cells have their own rules for computing their higher hashes. Higher hashes `Hashᵢ(c)` of an ordinary cell `c` are computed similarly to its representation hash, but using the higher hashes `Hashᵢ(cⱼ)` of its children `cⱼ` instead of their representation hashes `Hash(cⱼ)`. -Higher hashes `Hashᵢ(c)` of an ordinary cell `c` are computed similarly to its representation hash, but using the higher hashes `Hashᵢ(cj)` of its children `cj` instead of their representation hashes `Hash(cj)`. - -By convention: - -* `Hash∞(c) := Hash(c)` -* `Hashᵢ(c) := Hash∞(c) = Hash(c)` for all `i > l`. +By convention, we set `Hash∞(c) := Hash(c)`, and `Hashᵢ(c) := Hash∞(c) = Hash(c)` for all `i > ℓ`.[12](#footnote-13) ### 3.1.7 Types of exotic cells @@ -518,15 +513,15 @@ TVM currently supports the following cell types: * **Type −1: Ordinary cell** — Contains up to 1023 bits of data and up to four cell references. -* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ l ≤ 3`. - Contains exactly `8 + 256l` data bits: first an 8-bit integer equal to `1` (the cell’s type), then its `l` higher hashes `Hash₁(c), …, Hash_l(c)`. - The level `l` may be called its **de Brujn index**, because it determines the outer Merkle proof or Merkle update during which the branch has been pruned. +* **Type 1: Pruned branch cell `c`** — May have any level `1 ≤ ℓ ≤ 3`. + Contains exactly `8 + 256ℓ` data bits: first an 8-bit integer equal to `1` (the cell’s type), then its `ℓ` higher hashes `Hash₁(c), …, Hashℓ(c)`. + The level `ℓ` may be called its **de Brujn index**, because it determines the outer Merkle proof or Merkle update during which the branch has been pruned. An attempt to load a pruned branch cell usually leads to an exception. * **Type 2: Library reference cell** — Always has level 0, and contains `8 + 256` data bits, including its 8-bit type integer `2` and the representation hash `Hash(c₀)` of the library cell being referred to. When loaded, a library reference cell may be transparently replaced by the cell it refers to, if found in the current library context. -* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c₁` and level `0 ≤ l ≤ 3`, which must be one less than the level of its only child `c₁`: +* **Type 3: Merkle proof cell `c`** — Has exactly one reference `c₁` and level `0 ≤ ℓ ≤ 3`, which must be one less than the level of its only child `c₁`: ```math Lvl(c) = max(Lvl(c₁) − 1, 0) @@ -537,7 +532,7 @@ TVM currently supports the following cell types: The higher hashes `Hashᵢ(c)` of `c` are computed similarly to the higher hashes of an ordinary cell, but with `Hashᵢ₊₁(c₁)` used instead of `Hashᵢ(c₁)`. When loaded, a Merkle proof cell is replaced by `c₁`. -* **Type 4: Merkle update cell `c`** — Has two children `c₁` and `c₂`. Its level `0 ≤ l ≤ 3` is given by: +* **Type 4: Merkle update cell `c`** — Has two children `c₁` and `c₂`. Its level `0 ≤ ℓ ≤ 3` is given by: ```math Lvl(c) = max(Lvl(c₁) − 1, Lvl(c₂) − 1, 0) @@ -621,7 +616,7 @@ The mnemonics of cell serialization primitives usually begin with `ST`. Subseque - The source of the field width in bits to be used (e.g., `X` for integer serialization instructions means that the bit width `n` is supplied in the stack; otherwise it has to be embedded into the instruction as an immediate value). - The action to be performed if the operation cannot be completed (by default, an exception is generated; “quiet” versions of serialization instructions are marked by a `Q` letter in their mnemonics). -This classification scheme is used to create a more complete taxonomy of cell serialization primitives, which can be found in [A.7.1](#a-7-1). +This classification scheme is used to create a more complete taxonomy of cell serialization primitives, which can be found in [A.7.1](#a-7-1-cell-serialization-primitives). ### 3.2.7 Integer serialization primitives @@ -629,10 +624,10 @@ Integer serialization primitives can be classified according to the above taxono - There are signed and unsigned (big-endian) integer serialization primitives. - The size `n` of the bit field to be used (`1 ≤ n ≤ 257` for signed integers, `0 ≤ n ≤ 256` for unsigned integers) can either come from the top of stack or be embedded into the instruction itself. -- If the integer `x` to be serialized is not in the range `−2^(n−1) ≤ x < 2^(n−1)` (for signed integer serialization) or `0 ≤ x < 2^n` (for unsigned integer serialization), a range check exception is usually generated, and if `n` bits cannot be stored into the provided Builder, a cell overflow exception is generated. +- If the integer x to be serialized is not in the range `−2ⁿ⁻¹ ≤ x < 2ⁿ⁻¹` (for signed integer serialization) or `0 ≤ x < 2ⁿ` (for unsigned integer serialization), a range check exception is usually generated, and if n bits cannot be stored into the provided Builder, a cell overflow exception is generated. - Quiet versions of serialization instructions do not throw exceptions; instead, they push `-1` on top of the resulting Builder upon success, or return the original Builder with `0` on top of it to indicate failure. -Integer serialization instructions have mnemonics like `STU 20` (“store an unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of variable length provided in the stack”). The full list of these instructions—including their mnemonics, descriptions, and opcodes—is provided in [A.7.1](#a-7-1). +Integer serialization instructions have mnemonics like `STU 20` (“store an unsigned 20-bit integer value”) or `STIXQ` (“quietly store an integer value of variable length provided in the stack”). The full list of these instructions—including their mnemonics, descriptions, and opcodes—is provided in [A.7.1](#a-7-1-cell-serialization-primitives). ### 3.2.8 Integers in cells are big-endian by default @@ -657,7 +652,7 @@ Cell parsing, or deserialization, primitives can be classified as described in [ For example, an unsigned big-endian 20-bit integer previously serialized into a cell by a `STU 20` instruction is likely to be deserialized later by a matching `LDU 20` instruction. -Again, more detailed information about these instructions is provided in [A.7.2](#a-7-2). +Again, more detailed information about these instructions is provided in [A.7.2](#a-7-2-cell-deserialization-primitives). ### 3.2.12 Other cell slice primitives @@ -687,7 +682,7 @@ Hashmaps, or dictionaries, are a specific data structure represented by a tree o The two most basic hashmap types predefined in TVM are `HashmapE n X` or `HashmapE(n, X)`, which represents a partially defined map from `n`-bit strings (called keys) for some fixed `0 ≤ n ≤ 1023` into values of some type `X`, and `Hashmap(n, X)`, which is similar to `HashmapE(n, X)` but is not allowed to be empty (i.e., it must contain at least one key-value pair). -Other hashmap types are also available—for example, one with keys of arbitrary length up to some predefined bound (up to 1023 bits). +Other hashmap types are also available — for example, one with keys of arbitrary length up to some predefined bound (up to `1023` bits). ### 3.3.2 Hashmaps as Patricia trees @@ -695,11 +690,11 @@ The abstract representation of a hashmap in TVM is a Patricia tree, or a compact It is easy to see that any collection of key-value pairs (with distinct keys) is represented by a unique Patricia tree. -### 3.3.3 Serialization of hashmaps +### 3.3.3 Serialization of hashmaps The serialization of a hashmap into a tree of cells (or, more generally, into a `Slice`) is defined by the following TL-B scheme:[15](#footnote-15) -```tlb +```c bit#_ _:(## 1) = Bit; hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(HashmapNode m X) = Hashmap n X; @@ -728,7 +723,7 @@ The left-hand side of each equation describes a way to define, or even to serial The constructor and its optional tag are followed by field definitions. Each field definition is of the form `ident : type-expr`, where ident is an identifier with the name of the field[16](#footnote-16) (replaced by an underscore for anonymous fields), and `type-expr` is the field’s type. The type provided here is a type expression, which may include simple types or parametrized types with suitable parameters. Variables—i.e., the (identifiers of the) previously defined fields of types `#` (natural numbers) or `Type` (type of types)—may be used as parameters for the parametrized types. The serialization process recursively serializes each field according to its type, and the serialization of a value ultimately consists of the concatenation of bitstrings representing the constructor (i.e., the constructor tag) and the field values. -Some fields may be implicit. Their definitions are surrounded by curly braces, which indicate that the field is not actually present in the serialization, but that its value must be deduced from other data (usually the parameters of the type being serialized). +Some fields may be _implicit_. Their definitions are surrounded by curly braces, which indicate that the field is not actually present in the serialization, but that its value must be deduced from other data (usually the parameters of the type being serialized). Some occurrences of “variables” (i.e., already-defined fields) are prefixed by a tilde. This indicates that the variable’s occurrence is used in the opposite way of the default behavior: in the left-hand side of the equation, it means that the variable will be deduced (computed) based on this occurrence, instead of substituting its previously computed value; in the right-hand side, conversely, it means that the variable will not be deduced from the type being serialized, but rather that it will be computed during the deserialization process. In other words, a tilde transforms an “input argument” into an “output argument”, and vice versa.[17](#footnote-17) @@ -740,15 +735,16 @@ Parametrized type `#<= p` with `p : #` (this notation means “p of type #”, i ### 3.3.5 Application to the serialization of hashmaps -Let us explain the net result of applying the general rules described in [3.3.4](#3-3-4-brief-explanation-of-tl-b-schemes) to the TL-B scheme presented in [3.3.3](#3-3-3-serialization-of-hashmaps). +Let us explain the net result of applying the general rules described in `3.3.4` to the TL-B scheme presented in [3.3.3](#3-3-3-serialization-of-hashmaps). -Suppose we wish to serialize a value of type `HashmapE n X` for some integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with `n`-bit keys and values of type `X`, admitting an abstract representation as a Patricia tree (cf. [3.3.2](#3-3-2-hashmaps-as-patricia-trees))). +Suppose we wish to serialize a value of type `HashmapE n X` for some integer `0 ≤ n ≤ 1023` and some type `X` (i.e., a dictionary with `n`-bit keys and values of type `X`, admitting an abstract representation as a Patricia tree, (cf. [3.3.2](#3-3-2-hashmaps-as-patricia-trees))). First of all, if our dictionary is empty, it is serialized into a single binary `0`, which is the tag of nullary constructor `hme_empty`. Otherwise, its serialization consists of a binary `1` (the tag of `hme_root`), along with a reference to a cell containing the serialization of a value of type `Hashmap n X` (i.e., a necessarily non-empty dictionary). -The only way to serialize a value of type `Hashmap n X` is given by the `hm_edge` constructor, which instructs us to serialize first the label `label` of the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel ~l n`, which means that it is a bitstring of length at most `n`, serialized in such a way that the true length `l` of the label, `0 ≤ l ≤ n`, becomes known from the serialization of the label. (This special serialization method is described separately in [3.3.6](#3-3-6-serialization-of-labels).) +The only way to serialize a value of type `Hashmap n X` is given by the `hm_edge` constructor, which instructs us to serialize first the label `label` of the edge leading to the root of the subtree under consideration (i.e., the common prefix of all keys in our (sub)dictionary). This label is of type `HmLabel_ℓ^n`, which means that it is a bitstring of length at most `n`, serialized in such a way that the true length `ℓ` of the label, `0 ≤ ℓ ≤ n`, becomes known from its serialization. + -The label must be followed by the serialization of a node of type `HashmapNode m X`, where `m = n − l`. It corresponds to a vertex of the Patricia tree, representing a non-empty subdictionary of the original dictionary with `m`-bit keys, obtained by removing from all the keys of the original subdictionary their common prefix of length `l`. +The label must be followed by the serialization of a node of type `HashmapNode m X`, where `m = n − ℓ`. It corresponds to a vertex of the Patricia tree, representing a non-empty subdictionary of the original dictionary with `m`-bit keys, obtained by removing from all the keys of the original subdictionary their common prefix of length `l`. If `m = 0`, a value of type `HashmapNode 0 X` is given by the `hmn_leaf` constructor, which describes a leaf of the Patricia tree—or, equivalently, a subdictionary with `0`-bit keys. A leaf simply consists of the corresponding value of type `X` and is serialized accordingly. @@ -756,11 +752,11 @@ On the other hand, if `m > 0`, a value of type `HashmapNode m X` corresponds to ### 3.3.6 Serialization of labels -There are several ways to serialize a label of length at most `n`, if its exact length is `l ≤ n` (recall that the exact length must be deducible from the serialization of the label itself, while the upper bound `n` is known before the label is serialized or deserialized). These ways are described by the three constructors `hml_short`, `hml_long`, and `hml_same` of type `HmLabel ~l n`: +There are several ways to serialize a label of length at most `n`, if its exact length is `ℓ ≤ n` (recall that the exact length must be deducible from the serialization of the label itself, while the upper bound `n` is known before the label is serialized or deserialized). These ways are described by the three constructors `hml_short`, `hml_long`, and `hml_same` of type `HmLabel ~l n`: -* **`hml_short`** — Describes a way to serialize “short” labels, of small length `l ≤ n`. Such a serialization consists of a binary `0` (the constructor tag of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary representation of the length `l`), followed by `l` bits comprising the label itself. -* **`hml_long`** — Describes a way to serialize “long” labels, of arbitrary length `l ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by `l` bits comprising the label itself. -* **`hml_same`** — Describes a way to serialize “long” labels, consisting of `l` repetitions of the same bit `v`. Such a serialization consists of `11` (the constructor tag of `hml_same`), followed by the bit `v`, followed by the length `l` stored in `⌈log2(n + 1)⌉` bits as before. +* **`hml_short`** — Describes a way to serialize “short” labels, of small length `ℓ ≤ n`. Such a serialization consists of a binary `0` (the constructor tag of `hml_short`), followed by `l` binary `1`s and one binary `0` (the unary representation of the length `l`), followed by `l` bits comprising the label itself. +* **`hml_long`** — Describes a way to serialize “long” labels, of arbitrary length `ℓ ≤ n`. Such a serialization consists of a binary `10` (the constructor tag of `hml_long`), followed by the big-endian binary representation of the length `0 ≤ l ≤ n` in `⌈log2(n + 1)⌉` bits, followed by `l` bits comprising the label itself. +* **`hml_same`** — Describes a way to serialize “long” labels, consisting of `ℓ` repetitions of the same bit `v`. Such a serialization consists of `11` (the constructor tag of `hml_same`), followed by the bit `v`, followed by the length `l` stored in `⌈log2(n + 1)⌉` bits as before. Each label can always be serialized in at least two different fashions, using `hml_short` or `hml_long` constructors. Usually the shortest serialization (and in the case of a tie—the lexicographically smallest among the shortest) is preferred and is generated by TVM hashmap primitives, while the other variants are still considered valid. @@ -772,7 +768,7 @@ Consider a dictionary with three 16-bit keys `13`, `17`, and `239` (considered a In binary form: -``` +```asm 0000000000001101 => 0000000010101001 0000000000010001 => 0000000100100001 0000000011101111 => 1101111100100001 @@ -782,7 +778,7 @@ The corresponding Patricia tree consists of a root `A`, two intermediate nodes ` The corresponding value of type `HashmapE 16 (## 16)` may be written in human-readable form as: -``` +```c (hme_root$1 root:^(hm_edge label:(hml_same$11 v:0 n:8) node:(hm_fork left:^(hm_edge label:(hml_short$0 len:$110 s:$00) node:(hm_fork @@ -796,7 +792,7 @@ The corresponding value of type `HashmapE 16 (## 16)` may be written in human-re The serialization of this data structure into a tree of cells consists of six cells with the following binary data contained in them: -``` +```asm A := 1 A.0 := 11 0 01000 A.0.0 := 0 110 00 @@ -807,7 +803,7 @@ A.0.1 := 10 111 1101111 1101111100100001 Here `A` is the root cell, `A.0` is the cell at the first reference of `A`, `A.1` is the cell at the second reference of `A`, and so on. This tree of cells can be represented more compactly using the hexadecimal notation described in [1.0](#1-0-notation-for-bitstrings), using indentation to reflect the tree-of-cells structure: -``` +```asm C_ C8 62_ @@ -824,9 +820,10 @@ Notice that the built-in TVM primitives for dictionary manipulation need to know * The simplest case is when `X = ^Y` for some other type `Y`. In this case the serialization of `X` itself always consists of one reference to a cell, which in fact must contain a value of type `Y`, something that is not relevant for dictionary manipulation primitives. * Another simple case is when the serialization of any value of type `X` always consists of `0 ≤ b ≤ 1023` data bits and `0 ≤ r ≤ 4` references. Integers `b` and `r` can then be passed to a dictionary manipulation primitive as a simple description of `X`. (Notice that the previous case corresponds to `b = 0, r = 1`.) -* A more sophisticated case can be described by four integers `1 ≤ b0, b1 ≤ 1023`, `0 ≤ r0, r1 ≤ 4`, with `b_i` and `r_i` used when the first bit of the serialization equals `i`. When `b0 = b1` and `r0 = r1`, this case reduces to the previous one. +* A more sophisticated case can be described by four integers `1 ≤ b₀, b₁ ≤ 1023`, `0 ≤ r₀, r₁ ≤ 4`, with `bᵢ` and `rᵢ` used when the first bit of the serialization equals `i`. When `b₀ = b₁` and `r₀ = r₁`, this case reduces to the previous one. * Finally, the most general description of the serialization of a type `X` is given by a splitting function `split_X` for `X`, which accepts one `Slice` parameter `s`, and returns two `Slice`s, `s'` and `s''`, where `s'` is the only prefix of `s` that is the serialization of a value of type `X`, and `s''` is the remainder of `s`. If no such prefix exists, the splitting function is expected to throw an exception. Notice that a compiler for a high-level language, which supports some or all algebraic TL-B types, is likely to automatically generate splitting functions for all types defined in the program. + ### 3.3.9 A simplifying assumption on the serialization of X One may notice that values of type `X` always occupy the remaining part of an `hm_edge/hmn_leaf` cell inside the serialization of a `HashmapE n X`. Therefore, if we do not insist on strict validation of all dictionaries accessed, we may assume that everything left unparsed in an `hm_edge/hmn_leaf` cell after deserializing its label is a value of type `X`. This greatly simplifies the creation of dictionary manipulation primitives, because in most cases they turn out not to need any information about `X` at all. @@ -835,7 +832,7 @@ One may notice that values of type `X` always occupy the remaining part of an `h Let us present a classification of basic operations with dictionaries (i.e., values D of type `HashmapE n X`): -- `GET(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns the corresponding value `D[k] : X?` kept in `D`. +- `GET(D, k)` — Given `D : HashmapE(n, X)` and a key `k : n·bit`, returns the corresponding value `D[k] : Xˀ` kept in `D`. - `SET(D, k, x)` — Given `D : HashmapE(n, X)`, a key `k : n·bit`, and a value `x : X`, sets `D′[k]` to `x` in a copy `D′` of `D`, and returns the resulting dictionary `D′` (cf. [2.3.4](#234-transparency-of-the-implementation-stack-values-are-values-not-references)). - `ADD(D, k, x)` — Similar to `SET`, but adds the key-value pair `(k, x)` to `D` only if key `k` is absent in `D`. - `REPLACE(D, k, x)` — Similar to `SET`, but changes `D′[k]` to `x` only if key `k` is already present in `D`. @@ -847,15 +844,16 @@ Let us present a classification of basic operations with dictionaries (i.e., val - `GETPREV(D, k)` — Computes the maximal key `k′ < k` (or `k′ ≤ k` in a variant) and returns it along with the corresponding value `x′ : X`. - `EMPTY(n)` — Creates an empty dictionary `D : HashmapE(n, X)`. - `ISEMPTY(D)` — Checks whether a dictionary is empty. -- `CREATE(n, {(ki, xi)})` — Given `n`, creates a dictionary from a list `(ki, xi)` of key-value pairs passed in stack. -- `GETSUBDICT(D, l, k0)` — Given `D : HashmapE(n, X)` and some `l`-bit string `k0 : l·bit` for `0 ≤ l ≤ n`, returns subdictionary `D′ = D/k0` of `D`, consisting of keys beginning with `k0`. The result `D′` may be of either type `HashmapE(n, X)` or type `HashmapE(n − l, X)`. -- `REPLACESUBDICT(D, l, k0, D0)` — Given `D : HashmapE(n, X)`, `0 ≤ l ≤ n`, `k0 : l · bit`, and `D0 : HashmapE(n − l, X)`, replaces with `D0` the subdictionary `D/k0` of `D` consisting of keys beginning with `k0`, and returns the resulting dictionary `D′′ : HashmapE(n, X)`. Some variants of `REPLACESUBDICT` may also return the old value of the subdictionary `D/k0` in question. -- `DELETESUBDICT(D, l, k0)` — Equivalent to `REPLACESUBDICT` with `D0` being an empty dictionary. -- `SPLIT(D)` — Given `D : HashmapE(n, X)`, returns `D0 := D/0` and `D1 := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with `0` and `1`, respectively. -- `MERGE(D0, D1)` — Given `D0` and `D1 : HashmapE(n − 1, X)`, computes `D : HashmapE(n, X)`, such that `D/0 = D0` and `D/1 = D1`. -- `FOREACH(D, f)` — Executes a function `f` with two arguments `k` and `x`, with `(k, x)` running over all key-value pairs of a dictionary `D` in lexicographical order.[18](#footnote-18) -- `FOREACHREV(D, f)` — Similar to `FOREACH`, but processes all key-value pairs in reverse order. -- `TREEREDUCE(D, o, f, g)` — Given `D : HashmapE(n, X)`, a value `o : X`, and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree reduction” of `D` by first applying `f` to all the leaves, and then using `g` to compute the value corresponding to a fork starting from the values assigned to its children.[19](#footnote-19) +- `CREATE(n, {(kᵢ, xᵢ)})` — Given `n`, creates a dictionary from a list `(kᵢ, xᵢ)` of key–value pairs passed in stack. +* **`GETSUBDICT(D, ℓ, k₀)`** — Given `D : HashmapE(n, X)` and some `ℓ`-bit string `k₀ : ℓ·bit` for `0 ≤ ℓ ≤ n`, returns subdictionary `D′ = D/k₀` of `D`, consisting of keys beginning with `k₀`. The result `D′` may be of either type `HashmapE(n, X)` or type `HashmapE(n − ℓ, X)`. +* **`REPLACESUBDICT(D, ℓ, k₀, D₀)`** — Given `D : HashmapE(n, X)`, `0 ≤ ℓ ≤ n`, `k₀ : ℓ·bit`, and `D₀ : HashmapE(n − ℓ, X)`, replaces with `D₀` the subdictionary `D/k₀` of `D` consisting of keys beginning with `k₀`, and returns the resulting dictionary `D′′ : HashmapE(n, X)`. Some variants of `REPLACESUBDICT` may also return the old value of the subdictionary `D/k₀` in question. +* **`DELETESUBDICT(D, ℓ, k₀)`** — Equivalent to `REPLACESUBDICT` with `D₀` being an empty dictionary. +* **`SPLIT(D)`** — Given `D : HashmapE(n, X)`, returns `D₀ := D/0` and `D₁ := D/1 : HashmapE(n − 1, X)`, the two subdictionaries of `D` consisting of all keys beginning with `0` and `1`, respectively. +* **`MERGE(D₀, D₁)`** — Given `D₀` and `D₁ : HashmapE(n − 1, X)`, computes `D : HashmapE(n, X)` such that `D/0 = D₀` and `D/1 = D₁`. +* **`FOREACH(D, f)`** — Executes a function `f` with two arguments `k` and `x`, with `(k, x)` running over all key–value pairs of a dictionary `D` in lexicographical order. +* **`FOREACHREV(D, f)`** — Similar to `FOREACH`, but processes all key–value pairs in reverse order. +* **`TREEREDUCE(D, o, f, g)`** — Given `D : HashmapE(n, X)`, a value `o : X`, and two functions `f : X → Y` and `g : Y × Y → Y`, performs a “tree reduction” of `D` by first applying `f` to all the leaves, and then using `g` to compute the value corresponding to a fork starting from the values assigned to its children. + ### 3.3.11 Taxonomy of dictionary primitives @@ -873,13 +871,13 @@ In addition, TVM includes special serialization/deserialization primitives, such ## 3.4 Hashmaps with variable-length keys -TVM provides some support for dictionaries, or hashmaps, with variable-length keys, in addition to its support for dictionaries with fixed-length keys (as described in [3.3](#33-hashmaps-or-dictionaries)). +TVM provides some support for dictionaries, or hashmaps, with variable-length keys, in addition to its support for dictionaries with fixed-length keys (as described in [3.3](#3-3-hashmaps%2C-or-dictionaries)). ### 3.4.1. Serialization of dictionaries with variable-length keys -The serialization of a `VarHashmap` into a tree of cells (or, more generally, into a `Slice`) is defined by a TL-B scheme, similar to that described in [3.3.3](#333-serialization-of-hashmaps): +The serialization of a `VarHashmap` into a tree of cells (or, more generally, into a `Slice`) is defined by a TL-B scheme, similar to that described in [3.3.3](#3-3-3-serialization-of-hashmaps): -```tl-b +```c vhm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(VarHashmapNode m X) = VarHashmap n X; @@ -910,7 +908,7 @@ One special case of a dictionary with variable-length keys is that of a **prefix The serialization of a prefix code is defined by the following TL-B scheme: -```tl-b +```c phm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) {n = (~m) + l} node:(PfxHashmapNode m X) = PfxHashmap n X; @@ -937,15 +935,15 @@ We conclude this chapter with a discussion of the problem of recursion and of fa ## 4.1 Continuations and subroutines -Recall (cf. [1.1.3](#113-preliminary-list-of-value-types)) that Continuation values represent “execution tokens” that can be executed later—for example, by `EXECUTE` = `CALLX` (“execute” or “call indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations are responsible for the execution of the program, and are heavily used by control flow primitives, enabling subroutine calls, conditional expressions, loops, and so on. +Recall (cf. [1.1.3](#1-1-3-preliminary-list-of-value-types)) that Continuation values represent “execution tokens” that can be executed later—for example, by `EXECUTE` = `CALLX` (“execute” or “call indirect”) or `JMPX` (“jump indirect”) primitives. As such, the continuations are responsible for the execution of the program, and are heavily used by control flow primitives, enabling subroutine calls, conditional expressions, loops, and so on. ### 4.1.1 Ordinary continuations The most common kind of continuations are the ordinary continuations, containing the following data: -* A Slice `code` (cf. [1.1.3](#113-preliminary-list-of-value-types) and [3.2.2](#322-builder-and-slice-values)), containing (the remainder of) the TVM code to be executed. +* A Slice `code` (cf. [1.1.3](#1-1-3-preliminary-list-of-value-types) and [3.2.2](#3-2-2-builder-and-slice-values)), containing (the remainder of) the TVM code to be executed. * A (possibly empty) Stack `stack`, containing the original contents of the stack for the code to be executed. -* A (possibly empty) list `save` of pairs `(c(i), vi)` (also called “savelist”), containing the values of control registers to be restored before the execution of the code. +* A (possibly empty) list `save` of pairs `(c(i), vᵢ)` (also called “savelist”), containing the values of control registers to be restored before the execution of the code. * A 16-bit integer value `cp`, selecting the TVM codepage used to interpret the TVM code from `code`. * An optional non-negative integer `nargs`, indicating the number of arguments expected by the continuation. @@ -963,7 +961,7 @@ TVM usually performs the following operations: If the current continuation `cc` is an ordinary one, it decodes the first instruction from the Slice `code`, similarly to the way other cells are deserialized by TVM `LD*` primitives (cf. [3.2](#3-2-data-manipulation-instructions-and-cells) and [3.2.11](#3-2-11-taxonomy-of-cell-deserialisation-primitives)): it decodes the opcode first, and then the parameters of the instruction (e.g., 4-bit fields indicating “stack registers” involved for stack manipulation primitives, or constant values for “push constant” or “literal” primitives). The remainder of the Slice is then put into the code of the new `cc`, and the decoded operation is executed on the current stack. This entire process is repeated until there are no operations left in `cc.code`. -If the code is empty (i.e., contains no bits of data and no references), or if a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, the current continuation is discarded, and the “return continuation” from control register `c0` is loaded into `cc` instead (this process is discussed in more detail starting in [4.1.6](#416-switching-to-another-continuation-jmp-and-ret)).[20](#footnote-20) Then the execution continues by parsing operations from the new current continuation. +If the code is empty (i.e., contains no bits of data and no references), or if a (rarely needed) explicit subroutine return (`RET`) instruction is encountered, the current continuation is discarded, and the “return continuation” from control register `c0` is loaded into `cc` instead (this process is discussed in more detail starting in [4.1.6](#4-1-6-switching-to-another-continuation%3A-jmp-and-ret)).[20](#footnote-20) Then the execution continues by parsing operations from the new current continuation. ### 4.1.5 Extraordinary continuations @@ -1049,8 +1047,6 @@ Because constant continuations are very often used as arguments to conditional o --- -# 4 Control flow, continuations, and exceptions - ## 4.3 Operations with continuations ### 4.3.1 Continuations are opaque @@ -1114,14 +1110,8 @@ Some “experimental” primitives also involve `c1` and `◦1`. For example: * Conditional versions of `RET` and `RETALT` may also be useful: `RETBOOL` takes an integer `x` from the stack, and performs `RETTRUE` if `x ≠ 0`, `RETFALSE` otherwise. * `INVERT` does `c0 ↔ c1`; if the two continuations in `c0` and `c1` represent the two branches we should select depending on some boolean expression, `INVERT` negates this expression on the outer level. * `INVERTCONT` does `c.c0 ↔ c.c1` to a continuation `c` taken from the stack. -* Variants of `ATEXIT` include `ATEXITALT (c1 ← c ◦1 c1)` and `SETEXITALT (c1 ← (c ◦0 c0) ◦1 c1)`. -* `BOOLEVAL` takes a continuation `c` from the stack and does: - - ``` - cc ← (c ◦0 (PUSH −1)) ◦1 (PUSH0) ◦0 cc - ``` - - If `c` represents a boolean circuit, the net effect is to evaluate it and push either `−1` or `0` into the stack before continuing. +* Variants of `ATEXIT` include `ATEXITALT (c1 ← c◦₁ c1)` and `SETEXITALT (c1 ← (c◦₀ c0) ◦₁ c1)`. +* `BOOLEVAL` takes a continuation `c` from the stack and does `cc ← (c◦₀ (PUSH−1))◦₁ (PUSH0)◦₀ cc`. If `c` represents a boolean circuit, the net effect is to evaluate it and push either `−1` or `0` into the stack before continuing. --- @@ -1131,7 +1121,7 @@ Some “experimental” primitives also involve `c1` and `◦1`. For example: Object-oriented programming in Smalltalk (or Objective C) style may be implemented with the aid of continuations. For this, an object is represented by a special continuation `o`. If it has any data fields, they can be kept in the stack of `o`, making `o` a partial application (i.e., a continuation with a non-empty stack). -When somebody wants to invoke a method `m` of `o` with arguments `x1, x2, …, xn`, she pushes the arguments into the stack, then pushes a magic number corresponding to the method `m`, and then executes `o` passing `n+1` arguments (cf. [4.1.10](#4-1-10-determining-the-number-of-arguments-passed-to-andor-return-values-accepted-from-a-subroutine)). Then `o` uses the top-of-stack integer `m` to select the branch with the required method, and executes it. +When somebody wants to invoke a method `m` of `o` with arguments `x₁, x₂, …, xₙ`, she pushes the arguments into the stack, then pushes a magic number corresponding to the method `m`, and then executes `o` passing `n+1` arguments (cf. [4.1.10](#4-1-10-determining-the-number-of-arguments-passed-to-andor-return-values-accepted-from-a-subroutine)). Then `o` uses the top-of-stack integer `m` to select the branch with the required method, and executes it. If `o` needs to modify its state, it simply computes a new continuation `o'` of the same sort (perhaps with the same code as `o`, but with a different initial stack). The new continuation `o'` is returned to the caller along with whatever other return values need to be returned. @@ -1151,39 +1141,45 @@ For example, imagine a continuation that represents the output stream to a print --- -# 4.5 Exception handling +## 4.5 Exception handling TVM’s exception handling is quite simple and consists in a transfer of control to the continuation kept in control register c2. -## 4.5.1. Two arguments of the exception handler: exception parameter and exception number +### 4.5.1. Two arguments of the exception handler: exception parameter and exception number + +Every exception is characterized by two arguments: the **exception number** (an `Integer`) and the **exception parameter** (any value, most often a zero `Integer`). Exception numbers `0–31` are reserved for TVM, while all other exception numbers are available for user-defined exceptions. -Every exception is characterized by two arguments: the exception number (an Integer) and the exception parameter (any value, most often a zero Integer). Exception numbers 0–31 are reserved for TVM, while all other exception numbers are available for user-defined exceptions. +### 4.5.2. Primitives for throwing an exception -## 4.5.2. Primitives for throwing an exception +There are several special primitives used for throwing an exception. The most general of them, `THROWANY`, takes two arguments, `v` and `0 ≤ n < 2¹⁶` from the stack, and throws the exception with number `n` and value `v`. -There are several special primitives used for throwing an exception. The most general of them, THROWANY, takes two arguments, v and 0 ≤ n < 2^16, from the stack, and throws the exception with number n and value v. There are variants of this primitive that assume v to be a zero integer, store n as a literal value, and/or are conditional on an integer value taken from the stack. User-defined exceptions may use arbitrary values as v (e.g., trees of cells) if needed. +There are variants of this primitive that assume `v` to be a zero integer, store `n` as a literal value, and/or are conditional on an integer value taken from the stack. User-defined exceptions may use arbitrary values as `v` (e.g., trees of cells) if needed. -## 4.5.3. Exceptions generated by TVM +### 4.5.3. Exceptions generated by TVM -Of course, some exceptions are generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit into a signed 257-bit integer. In such cases, the arguments of the exception, v and n, are determined by TVM itself. +Some exceptions are generated by normal primitives. For example, an arithmetic overflow exception is generated whenever the result of an arithmetic operation does not fit into a signed 257-bit integer. In such cases, the arguments of the exception, `v` and `n`, are determined by TVM itself. -## 4.5.4. Exception handling +### 4.5.4. Exception handling -The exception handling itself consists in a control transfer to the exception handler—i.e., the continuation specified in control register c2, with v and n supplied as the two arguments to this continuation, as if a JMP to c2 had been requested with n00 = 2 arguments (cf. [4.1.7](#4-1-7-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c) and [4.1.6](#4-1-6-switching-to-another-continuation-jmp-and-ret)). As a consequence, v and n end up in the top of the stack of the exception handler. The remainder of the old stack is discarded. +Exception handling consists in a control transfer to the exception handler — i.e., the continuation specified in control register `c₂`, with `v` and `n` supplied as the two arguments to this continuation, as if a `JMP` to `c2` had been requested with `n′′ = 2` arguments (cf. [4.1.7](#4-1-7-determining-the-number-n-of-arguments-passed-to-the-next-continuation-c) and [4.1.6](#4-1-6-switching-to-another-continuation-jmp-and-ret)). -Notice that if the continuation in c2 has a value for c2 in its savelist, it will be used to set up the new value of c2 before executing the exception handler. In particular, if the exception handler invokes THROWANY, it will rethrow the original exception with the restored value of c2. This trick enables the exception handler to handle only some exceptions, and pass the rest to an outer exception handler. +As a consequence, `v` and `n` end up on top of the stack of the exception handler. The remainder of the old stack is discarded. -## 4.5.5. Default exception handler +Notice that if the continuation in `c2` has a value for `c2` in its savelist, it will be used to set up the new value of `c2` before executing the exception handler. In particular, if the exception handler invokes `THROWANY`, it will rethrow the original exception with the restored value of `c2`. This trick enables the exception handler to handle only some exceptions, and pass the rest to an outer exception handler. -When an instance of TVM is created, c2 contains a reference to the “default exception handler continuation”, which is an ec_fatal extraordinary continuation (cf. [4.1.5](#4-1-5-extraordinary-continuations)). Its execution leads to the termination of the execution of TVM, with the arguments v and n of the exception returned to the outside caller. In the context of the TON Blockchain, n will be stored as a part of the transaction’s result. +### 4.5.5. Default exception handler -## 4.5.6. TRY primitive +When an instance of TVM is created, `c2` contains a reference to the “default exception handler continuation”, which is an **`ec_fatal`** extraordinary continuation (cf. [4.1.5](#4-1-5-extraordinary-continuations)). -A TRY primitive can be used to implement C++-like exception handling. This primitive accepts two continuations, c and c0. It stores the old value of c2 into the savelist of c0, sets c2 to c0, and executes c just as EXECUTE would, but additionally saving the old value of c2 into the savelist of the new c0 as well. Usually a version of the TRY primitive with an explicit number of arguments n00 passed to the continuation c is used. +Its execution leads to the termination of the execution of TVM, with the arguments `v` and `n` of the exception returned to the outside caller. In the context of the TON Blockchain, `n` will be stored as a part of the transaction’s result. -The net result is roughly equivalent to C++’s `try { c } catch(...) { c0 }` operator. +### 4.5.6. `TRY` primitive -## 4.5.7. List of predefined exceptions +A **`TRY`** primitive can be used to implement C++-like exception handling. This primitive accepts two continuations, `c` and `c′`. It stores the old value of `c2` into the savelist of `c′`, sets `c₂` to `c′`, and executes `c` just as `EXECUTE` would, but additionally saving the old value of `C2` into the savelist of the new `c′` as well. Usually, a version of the `TRY` primitive with an explicit number of arguments `n′′` passed to the continuation `c` is used. + +The net result is roughly equivalent to C++’s `try { c } catch(...) { c′ }` operator. + +### 4.5.7. List of predefined exceptions Predefined exceptions of TVM correspond to exception numbers n in the range 0–31. They include: @@ -1191,7 +1187,7 @@ Predefined exceptions of TVM correspond to exception numbers n in the range 0– - **Alternative termination (n = 1)** — Again, should never be generated. - **Stack underflow (n = 2)** — Not enough arguments in the stack for a primitive. - **Stack overflow (n = 3)** — More values have been stored on a stack than allowed by this version of TVM. -- **Integer overflow (n = 4)** — Integer does not fit into −2^256 ≤ x < 2^256, or a division by zero has occurred. +- **Integer overflow (n = 4)** — Integer does not fit into `−2²⁵⁶ ≤ x < 2²⁵⁶`, or a division by zero has occurred. - **Range check error (n = 5)** — Integer out of expected range. - **Invalid opcode (n = 6)** — Instruction or its immediate arguments cannot be decoded. - **Type check error (n = 7)** — An argument to a primitive is of incorrect value type. @@ -1204,7 +1200,7 @@ Predefined exceptions of TVM correspond to exception numbers n in the range 0– Most of these exceptions have no parameter (i.e., use a zero integer instead). The order in which these exceptions are checked is outlined below in 4.5.8. -## 4.5.8. Order of stack underflow, type check, and range check exceptions +### 4.5.8. Order of stack underflow, type check, and range check exceptions All TVM primitives first check whether the stack contains the required number of arguments, generating a stack underflow exception if this is not the case. Only then are the type tags of the arguments and their ranges (e.g., if a primitive expects an argument not only to be an Integer, but also to be in the range from 0 to 256) checked, starting from the value in the top of the stack (the last argument) and proceeding deeper into the stack. If an argument’s type is incorrect, a type-checking exception is generated; if the type is correct, but the value does not fall into the expected range, a range check exception is generated. @@ -1212,15 +1208,15 @@ Some primitives accept a variable number of arguments, depending on the values o --- -# 4.6 Functions, recursion, and dictionaries +## 4.6 Functions, recursion, and dictionaries -## 4.6.1 The problem of recursion +### 4.6.1 The problem of recursion The conditional and iterated execution primitives described in [4.2](#4-2-control-flow-primitives-conditional-and-iterated-execution)—along with the unconditional branch, call, and return primitives described in [4.1](#4-1-continuations-and-subroutines)—enable one to implement more or less arbitrary code with nested loops and conditional expressions, with one notable exception: one can only create new constant continuations from parts of the current continuation. (In particular, one cannot invoke a subroutine from itself in this way.) Therefore, the code being executed—i.e., the current continuation—gradually becomes smaller and smaller.[24](#footnote-24) -## 4.6.2 Y-combinator solution: pass a continuation as an argument to itself +### 4.6.2 Y-combinator solution: pass a continuation as an argument to itself One way of dealing with the problem of recursion is by passing a copy of the continuation representing the body of a recursive function as an extra argument to itself. Consider, for example, the following code for a factorial function: -``` +```asm 71 PUSHINT 1 9C PUSHCONT { 22 PUSH s2 @@ -1242,9 +1238,9 @@ D8 EXECUTE 31 NIP ``` -This roughly corresponds to defining an auxiliary function `body` with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, n·x, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. +This roughly corresponds to defining an auxiliary function `body` with three arguments `n`, `x`, and `f`, such that `body(n, x, f)` equals `x` if `n < 2` and `f(n − 1, nx, f)` otherwise, then invoking `body(n, 1, body)` to compute the factorial of `n`. The recursion is then implemented with the aid of the `DUP; EXECUTE` construction, or `DUP; JMPX` in the case of tail recursion. This trick is equivalent to applying Y-combinator to a function body. -## 4.6.3 A variant of Y-combinator solution +### 4.6.3 A variant of Y-combinator solution Another way of recursively computing the factorial, more closely following the classical recursive definition: ```math @@ -1257,7 +1253,7 @@ n \cdot \text{fact}(n - 1) & \text{otherwise} is as follows: -``` +```asm 9D PUSHCONT { 21 OVER C102 LESSINT 2 @@ -1279,11 +1275,11 @@ D9 JMPX This definition of the factorial function is two bytes shorter than the previous one, but it uses general recursion instead of tail recursion, so it cannot be easily transformed into a loop. -## 4.6.4 Comparison: non-recursive definition of the factorial function +### 4.6.4 Comparison: non-recursive definition of the factorial function Incidentally, a non-recursive definition of the factorial with the aid of a `REPEAT` loop is also possible, and it is much shorter than both recursive definitions: -``` +```asm 71 PUSHINT 1 01 SWAP 20 DUP @@ -1297,39 +1293,39 @@ E4 REPEAT 30 DROP ``` -## 4.6.5 Several mutually recursive functions +### 4.6.5 Several mutually recursive functions -If one has a collection `f1, …, fn` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fi}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. +If one has a collection `f₁, …, fₙ` of mutually recursive functions, one can use the same trick by passing the whole collection of continuations `{fᵢ}` in the stack as an extra `n` arguments to each of these functions. However, as `n` grows, this becomes more and more cumbersome, since one has to reorder these extra arguments in the stack to work with the “true” arguments, and then push their copies into the top of the stack before any recursive call. -## 4.6.6 Combining several functions into one tuple +### 4.6.6 Combining several functions into one tuple -One might also combine a collection of continuations representing functions `f1, …, fn` into a “tuple” `f := (f1, …, fn)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fi`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. +One might also combine a collection of continuations representing functions `f₁, …, fₙ` into a “tuple” `f := (f₁, …, fₙ)`, and pass this tuple as one stack element `f`. For instance, when `n ≤ 4`, each function can be represented by a cell `˜fi` (along with the tree of cells rooted in this cell), and the tuple may be represented by a cell `˜f`, which has references to its component cells `˜fᵢ`. However, this would lead to the necessity of “unpacking” the needed component from this tuple before each recursive call. -## 4.6.7 Combining several functions into a selector function +### 4.6.7 Combining several functions into a selector function -Another approach is to combine several functions `f1, …, fn` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fi` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. +Another approach is to combine several functions `f₁, …, fₙ` into one “selector function” `f`, which takes an extra argument `i`, `1 ≤ i ≤ n`, from the top of the stack, and invokes the appropriate function `fi`. Stack machines such as TVM are well-suited to this approach, because they do not require the functions `fᵢ` to have the same number and types of arguments. Using this approach, one would need to pass only one extra argument, `f`, to each of these functions, and push into the stack an extra argument `i` before each recursive call to `f` to select the correct function to be called. -## 4.6.8 Using a dedicated register to keep the selector function +### 4.6.8 Using a dedicated register to keep the selector function However, even if we use one of the two previous approaches to combine all functions into one extra argument, passing this argument to all mutually recursive functions is still quite cumbersome and requires a lot of additional stack manipulation operations. Because this argument changes very rarely, one might use a dedicated register to keep it and transparently pass it to all functions called. This is the approach used by TVM by default. -## 4.6.9 Special register c3 for the selector function +### 4.6.9 Special register c3 for the selector function -In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. [A.8.7](#a-8-7)) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). +In fact, TVM uses a dedicated register `c3` to keep the continuation representing the current or global “selector function”, which can be used to invoke any of a family of mutually recursive functions. Special primitives `CALL nn` or `CALLDICT nn` (cf. [A.8.7](#a-8-7-dictionary-subroutine-calls-and-jumps)) are equivalent to `PUSHINT nn; PUSH c3; EXECUTE`, and similarly `JMP nn` or `JMPDICT nn` are equivalent to `PUSHINT nn; PUSH c3; JMPX`. In this way a TVM program, which ultimately is a large collection of mutually recursive functions, may initialize `c3` with the correct selector function representing the family of all the functions in the program, and then use `CALL nn` to invoke any of these functions by its index (sometimes also called the selector of a function). -## 4.6.10 Initialization of c3 +### 4.6.10 Initialization of c3 A TVM program might initialize `c3` by means of a `POP c3` instruction. However, because this usually is the very first action undertaken by a program (e.g., a smart contract), TVM makes some provisions for the automatic initialization of `c3`. Namely, `c3` is initialized by the code (the initial value of `cc`) of the program itself, and an extra zero (or, in some cases, some other predefined number `s`) is pushed into the stack before the program’s execution. This is approximately equivalent to invoking `JMPDICT 0` (or `JMPDICT s`) at the very beginning of a program—i.e., the function with index zero is effectively the `main()` function for the program. -## 4.6.11 Creating selector functions and switch statements +### 4.6.11 Creating selector functions and switch statements -TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. [A.8.2](#a-8-2)). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. +TVM makes special provisions for simple and concise implementation of selector functions (which usually constitute the top level of a TVM program) or, more generally, arbitrary switch or case statements (which are also useful in TVM programs). The most important primitives included for this purpose are `IFBITJMP`, `IFNBITJMP`, `IFBITJMPREF`, and `IFNBITJMPREF` (cf. [A.8.2](#a-8-2-conditional-control-flow-primitives)). They effectively enable one to combine subroutines, kept either in separate cells or as subslices of certain cells, into a binary decision tree with decisions made according to the indicated bits of the integer passed in the top of the stack. -Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. [A.7.2](#a-7-2)). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. +Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. [A.7.2](#a-7-2-cell-deserialization-primitives)). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. ## 4.6.12 Alternative: using a hashmap to select the correct function -Yet another alternative is to use a Hashmap (cf. [3.3](#3-3-hashmaps-or-dictionaries)) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. [A.10](#a-10-dictionary-manipulation-primitives)) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. [A.8.5](#a-8-5)) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. [A.10.11](#a-10-11)). +Yet another alternative is to use a Hashmap (cf. [3.3](#3-3-hashmaps%2C-or-dictionaries)) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. [A.10](#a-10-dictionary-manipulation-primitives)) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. [A.8.5](#a-8-5-creating-simple-continuations-and-closures)) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. [A.10.11](#a-10-10-getmin%2C-getmax%2C-removemin%2C-removemax-operations)). This approach may be more efficient for larger programs and switch statements. --- @@ -1413,13 +1409,13 @@ Recall that TVM is a bit-oriented machine in the sense that its Cells (and Slice That said, some codepages (such as our experimental codepage zero) may opt to use a bytecode (i.e., to use only encodings consisting of an integral number of bytes)—either for simplicity, or for the ease of debugging and of studying memory (i.e., cell) dumps.[27](#footnote-27) ### 5.2.6 Opcode space used by a complete instruction -Recall from coding theory that the lengths of bitstrings `li` used in a binary prefix code satisfy Kraft–McMillan inequality: +Recall from coding theory that the lengths of bitstrings `ℓᵢ` used in a binary prefix code satisfy Kraft–McMillan inequality: ```math \sum_i 2^{-l_i} \leq 1 ``` -This is applicable in particular to the (complete) instruction encoding used by a TVM codepage. We say that a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2^-l` of the opcode space, if it is encoded by an `l`-bit string. One can see that all complete instructions together utilize at most 1 (i.e., “at most the whole opcode space”). +This is applicable in particular to the (complete) instruction encoding used by a TVM codepage. We say that a particular complete instruction (or, more precisely, the encoding of a complete instruction) utilizes the portion `2⁻ˡ` of the opcode space, if it is encoded by an `ℓ`-bit string. One can see that all complete instructions together utilize at most `1` (i.e., “at most the whole opcode space”). ### 5.2.7 Opcode space used by an instruction, or a class of instructions The above terminology is extended to instructions (considered with all admissible values of their parameters), or even classes of instructions (e.g., all arithmetic instructions). We say that an (incomplete) instruction, or a class of instructions, occupies portion `α` of the opcode space, if `α` is the sum of the portions of the opcode space occupied by all complete instructions belonging to that class. @@ -1430,7 +1426,7 @@ A useful approximation of the above definitions is as follows: Consider all 256 This approximation shows why all instructions cannot occupy together more than the portion `256/256 = 1` of the opcode space, at least without compromising the uniqueness of instruction decoding. ### 5.2.9 Almost optimal encodings -Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete instruction (`2^-l`, if the complete instruction is encoded in `l` bits) should be approximately equal to the probability or frequency of its occurrence in real programs.[28](#footnote-28) The same should hold for (incomplete) instructions, or primitives (i.e., generic instructions without specified values of parameters), and for classes of instructions. +Coding theory tells us that in an optimally dense encoding, the portion of the opcode space used by a complete instruction (`2⁻ℓ`, if the complete instruction is encoded in `ℓ` bits) should be approximately equal to the probability or frequency of its occurrence in real programs.[28](#footnote-28) The same should hold for (incomplete) instructions, or primitives (i.e., generic instructions without specified values of parameters), and for classes of instructions. ### 5.2.10 Example: stack manipulation primitives For instance, if stack manipulation instructions constitute approximately half of all instructions in a typical TVM program, one should allocate approximately half of the opcode space for encoding stack manipulation instructions. One might reserve the first bytes (“opcodes”) `0x00–0x7f` for such instructions. If a quarter of these instructions are `XCHG`, it would make sense to reserve `0x00–0x1f` for `XCHG`s. Similarly, if half of all `XCHG`s involve the top of stack `s0`, it would make sense to use `0x00–0x0f` to encode `XCHG s0,s(i)`. @@ -1438,7 +1434,7 @@ For instance, if stack manipulation instructions constitute approximately half o ### 5.2.11 Simple encodings of instructions In most cases, simple encodings of complete instructions are used. Simple encodings begin with a fixed bitstring called the opcode of the instruction, followed by, say, 4-bit fields containing the indices `i` of stack registers `s(i)` specified in the instruction, followed by all other constant (literal, immediate) parameters included in the complete instruction. While simple encodings may not be exactly optimal, they admit short descriptions, and their decoding and encoding can be easily implemented. -If a (generic) instruction uses a simple encoding with an `l`-bit opcode, then the instruction will utilize `2^-l` portion of the opcode space. This observation might be useful for considerations described in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives). +If a (generic) instruction uses a simple encoding with an `ℓ`-bit opcode, then the instruction will utilize `2⁻ℓ` portion of the opcode space. This observation might be useful for considerations described in [5.2.9](#5-2-9-almost-optimal-encodings) and [5.2.10](#5-2-10-example-stack-manipulation-primitives). ### 5.2.12 Optimizing code density further: Huffman codes One might construct optimally dense binary code for the set of all complete instructions, provided their probabilities or frequences in real code are known. This is the well-known Huffman code (for the given probability distribution). However, such code would be highly unsystematic and hard to decode. @@ -1476,27 +1472,22 @@ The list of all instructions available in codepage zero, along with their encodi --- # A Instructions and opcodes +This appendix lists all instructions available in the (experimental) codepage zero of TVM, as explained in [5.3](#5-3-instruction-encoding-in-codepage-zero). +We list the instructions in lexicographical opcode order. However, the opcode space is distributed in such way as to make all instructions in each category (e.g., arithmetic primitives) have neighboring opcodes. So we first list a number of stack manipulation primitives, then constant primitives, arithmetic primitives, comparison primitives, cell primitives, continuation primitives, dictionary primitives, and finally application-specific primitives. + +We use hexadecimal notation (cf. [1.0](#1-0-notation-for-bitstrings)) for bitstrings. Stack registers `s(i)` usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, 8-bit, or variable length. + +The stack notation described in [2.1.10](#2-1-10-stack-notation) is extensively used throughout this appendix. -This appendix lists all instructions available in the (experimental) codepage -zero of TVM, as explained in 5.3. -We list the instructions in lexicographical opcode order. However, the -opcode space is distributed in such way as to make all instructions in each -category (e.g., arithmetic primitives) have neighboring opcodes. So we first -list a number of stack manipulation primitives, then constant primitives, -arithmetic primitives, comparison primitives, cell primitives, continuation -primitives, dictionary primitives, and finally application-specific primitives. - -We use hexadecimal notation (cf. 1.0) for bitstrings. Stack registers `s(i)` -usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare -occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, -8-bit, or variable length. -The stack notation described in 2.1.10 is extensively used throughout -this appendix. ## A.1 Gas prices The gas price for most primitives equals the basic gas price, computed as -`Pb := 10 + b + 5r`, where `b` is the instruction length in bits and `r` is the + +```math +P_{b} := 10 + b + 5r +``` +where `b` is the instruction length in bits and `r` is the number of cell references included in the instruction. When the gas price of an instruction differs from this basic price, it is indicated in parentheses after its mnemonics, either as `(x)`, meaning that the total gas price equals @@ -1514,11 +1505,15 @@ expressions may appear: * `Cw` — The total price of creating new `Cell`s from `Builder`s. Currently equal to 500 gas units per cell. -By default, the gas price of an instruction equals `P := Pb + Cr + L + Bw + Cw`. +By default, the gas price of an instruction equals + +```math +P := P_{b} + C_{r} + L + B_{w} + C_{w} +``` ## A.2 Stack manipulation primitives -This section includes both the basic (cf. 2.2.1) and the compound (cf. 2.2.3) +This section includes both the basic (cf. [2.2.1](#2-2-1-basic-stack-manipulation-primitives)) and the compound (cf. [2.2.3](#2-2-3-compound-stack-manipulation-primitives)) stack manipulation primitives, as well as some “unsystematic” ones. Some compound stack manipulation primitives, such as `XCPU` or `XCHG2`, turn out to have the same length as an equivalent sequence of simpler operations. We @@ -1531,6 +1526,7 @@ style (e.g., `-ROT`), the other conforming to the usual rules for identifiers (e integer parameter `n` from the stack, it must be within the range `0 . . . 255`; otherwise a range check exception happens before any further checks. + ### A.2.1. Basic stack manipulation primitives. * `00` — `NOP`, does nothing. @@ -1608,10 +1604,12 @@ arbitrary types (not necessarily the same). Tuple primitives create, modify, and unpack Tuples; they manipulate values of arbitrary types in the process, similarly to the stack primitives. We do not recommend using Tuples of more than 15 elements. -When a Tuple `t` contains elements `x1, . . . , xn` (in that order), we write -`t = (x1, . . . , xn)`; number `n ≥ 0` is the length of Tuple `t`. It is also denoted + +When a Tuple `t` contains elements `x₁, ..., xₙ` (in that order), we write +`t = (x₁, ..., xₙ)`; number `n ≥ 0` is the length of Tuple `t`. It is also denoted by `|t|`. Tuples of length two are called pairs, and Tuples of length three are triples. + Lisp-style lists are represented with the aid of pairs, i.e., tuples consisting of exactly two elements. An empty list is represented by a `Null` value, and a non-empty list is represented by pair `(h, t)`, where `h` is the first element of @@ -1631,7 +1629,7 @@ more efficient and costs less gas. ### A.3.2. Tuple primitives. -* `6F0n` — `TUPLE n` `(x1 . . . xn – t)`, creates a new Tuple `t = (x1, . . . , xn)` +* `6F0n` — `TUPLE n` `(x₁, ..., xₙ – t)`, creates a new Tuple `t = (x₁, ..., xₙ)` containing `n` values `x1, . . . , xn`, where `0 ≤ n ≤ 15`. * `6F00` — `NIL` `( – t)`, pushes the only Tuple `t = ()` of length zero. * `6F01` — `SINGLE` `(x – t)`, creates a singleton `t := (x)`, i.e., a Tuple of @@ -1639,12 +1637,12 @@ more efficient and costs less gas. * `6F02` — `PAIR` or `CONS` `(x y – t)`, creates pair `t := (x, y)`. * `6F03` — `TRIPLE` `(x y z – t)`, creates triple `t := (x, y, z)`. * `6F1k` — `INDEX k` `(t – x)`, returns the `k`-th element of a Tuple `t`, where - `0 ≤ k ≤ 15`. In other words, returns `xk+1` if `t = (x1, . . . , xn)`. If `k ≥ n`, + `0 ≤ k ≤ 15`. In other words, returns `xk+1` if `t = (x₁, ..., xₙ)`. If `k ≥ n`, throws a range check exception. * `6F10` — `FIRST` or `CAR` `(t – x)`, returns the first element of a Tuple. * `6F11` — `SECOND` or `CDR` `(t – y)`, returns the second element of a Tuple. * `6F12` — `THIRD` `(t – z)`, returns the third element of a Tuple -* `6F2n` — `UNTUPLE n` `(t – x1 . . . xn)`, unpacks a Tuple `t = (x1, . . . , xn)` of +* `6F2n` — `UNTUPLE n` `(t – x1 . . . xn)`, unpacks a Tuple `t = (x₁, ..., xₙ)` of length equal to `0 ≤ n ≤ 15`. If `t` is not a Tuple, of if `|t| 6= n`, a type check exception is thrown. * `6F21` — `UNSINGLE` `(t – x)`, unpacks a singleton `t = (x)`. @@ -1676,13 +1674,13 @@ more efficient and costs less gas. If `t` is not `Null` or `Tuple`, throws an exception. If `x` is `Null` and either `|t| ≤ k` or `t` is `Null`, then always returns `t' = t` (and does not consume tuple creation gas). -* `6F80` — `TUPLEVAR` `(x1 . . . xn n – t)`, creates a new Tuple `t` of length `n` +* `6F80` — `TUPLEVAR` `(x₁, ..., xₙ n – t)`, creates a new Tuple `t` of length `n` similarly to `TUPLE`, but with `0 ≤ n ≤ 255` taken from the stack. * `6F81` — `INDEXVAR` `(t k – x)`, similar to `INDEX k`, but with `0 ≤ k ≤ 254` taken from the stack. -* `6F82` — `UNTUPLEVAR` `(t n – x1 . . . xn)`, similar to `UNTUPLE n`, but with +* `6F82` — `UNTUPLEVAR` `(t n – x₁, ..., xₙ)`, similar to `UNTUPLE n`, but with `0 ≤ n ≤ 255` taken from the stack. -* `6F83` — `UNPACKFIRSTVAR` `(t n – x1 . . . xn)`, similar to `UNPACKFIRST n`, +* `6F83` — `UNPACKFIRSTVAR` `(t n – x₁, ..., xₙ)`, similar to `UNPACKFIRST n`, but with `0 ≤ n ≤ 255` taken from the stack. * `6F84` — `EXPLODEVAR` `(t n – x1 . . . xm m)`, similar to `EXPLODE n`, but with `0 ≤ n ≤ 255` taken from the stack. @@ -1728,14 +1726,15 @@ more efficient and costs less gas. * `6FA7` — `NULLROTRIFNOT2` `(x y – x y or ⊥ ⊥ x y)`, pushes two `Null`s under the second stack entry from the top, but only if the topmost Integer `y` is zero. Equivalent to `NULLROTRIFNOT; NULLROTRIFNOT`. -* `6FBij` — `INDEX2 i,j` `(t – x)`, recovers `x = (ti+1)j+1` for `0 ≤ i, j ≤ 3`. +* `6FBij` — `INDEX2 i,j` `(t – x)`, recovers `x = (tᵢ₊₁)ⱼ₊₁` for `0 ≤ i, j ≤ 3`. Equivalent to `INDEX i; INDEX j`. -* `6FB4` — `CADR` `(t – x)`, recovers `x = (t2)1`. -* `6FB5` — `CDDR` `(t – x)`, recovers `x = (t2)2`. -* `6FE_ijk` — `INDEX3 i,j,k` `(t – x)`, recovers `x = ((ti+1)j+1)k+1` for `0 ≤ +* `6FB4` — `CADR` `(t – x)`, recovers `x = (t₂)₁`. +* `6FB5` — `CDDR` `(t – x)`, recovers `x = (t₂)₂`. +* `6FE_ijk` — `INDEX3 i,j,k` `(t – x)`, recovers `x = (tᵢ₊₁)ⱼ₊₁ₖ₊₁` for `0 ≤ i, j, k ≤ 3`. Equivalent to `INDEX2 i,j; INDEX k`. -* `6FD4` — `CADDR` `(t – x)`, recovers `x = ((t2)2)1`. -* `6FD5` — `CDDDR` `(t – x)`, recovers `x = ((t2)2)2`. +* `6FD4` — `CADDR` `(t – x)`, recovers `x = (t₂)₂₁`. +* `6FD5` — `CDDDR` `(t – x)`, recovers `x = (t₂)₂₂`. + ## A.4 Constant, or literal primitives @@ -1746,31 +1745,44 @@ instruction. Therefore, if the immediate argument is absent or too short, an ### A.4.1. Integer and boolean constants. -* `7i` — `PUSHINT x` with `−5 ≤ x ≤ 10`, pushes integer `x` into the stack; - here `i` equals four lower-order bits of `x` (i.e., `i = x mod 16`). -* `70` — `ZERO`, `FALSE`, or `PUSHINT 0`, pushes a zero. -* `71` — `ONE` or `PUSHINT 1`. -* `72` — `TWO` or `PUSHINT 2`. -* `7A` — `TEN` or `PUSHINT 10`. -* `7F` — `TRUE` or `PUSHINT -1`. -* `80xx` — `PUSHINT xx` with `−128 ≤ xx ≤ 127`. -* `81xxxx` — `PUSHINT xxxx` with `−2^15 ≤ xxxx < 2^15` a signed 16-bit - big-endian integer. -* `81FC18` — `PUSHINT −1000`. -* `82lxxx` — `PUSHINT xxx`, where 5-bit `0 ≤ l ≤ 30` determines the length - `n = 8l + 19` of signed big-endian integer `xxx`. The total length of this - instruction is `l + 4` bytes or `n + 13 = 8l + 32` bits. -* `821005F5E100` — `PUSHINT 1088`. -* `83xx` — `PUSHPOW2 xx + 1`, (quietly) pushes `2^(xx+1)` for `0 ≤ xx ≤ 255`. -* `83FF` — `PUSHNAN`, pushes a `NaN`. -* `84xx` — `PUSHPOW2DEC xx + 1`, pushes `2^(xx+1) − 1` for `0 ≤ xx ≤ 255`. -* `85xx` — `PUSHNEGPOW2 xx + 1`, pushes `−2^(xx+1)` for `0 ≤ xx ≤ 255`. -* `86, 87` — reserved for integer constants. +* `7i` — `PUSHINT x` with `−5 ≤ x ≤ 10`, pushes integer `x` into the stack; + here `i` equals four lower-order bits of `x` (i.e., `i = x mod 16`). + +* `70` — `ZERO`, `FALSE`, or `PUSHINT 0`, pushes a zero. + +* `71` — `ONE` or `PUSHINT 1`. + +* `72` — `TWO` or `PUSHINT 2`. + +* `7A` — `TEN` or `PUSHINT 10`. + +* `7F` — `TRUE` or `PUSHINT −1`. + +* `80xx` — `PUSHINT xx` with `−128 ≤ xx ≤ 127`. + +* `81xxxx` — `PUSHINT xxxx` with `−2¹⁵ ≤ xxxx < 2¹⁵`, a signed 16-bit big-endian integer. + +* `81FC18` — `PUSHINT −1000`. + +* `82lxxx` — `PUSHINT xxx`, where 5-bit `0 ≤ ℓ ≤ 30` determines the length + `n = 8ℓ + 19` of signed big-endian integer `xxx`. + The total length of this instruction is `ℓ + 4` bytes or `n + 13 = 8ℓ + 32` bits. + +* `821005F5E100` — `PUSHINT 10⁸`. + +* `83xx` — `PUSHPOW2 xx + 1`, (quietly) pushes `2ˣˣ⁺¹` for `0 ≤ xx ≤ 255`. + +* `83FF` — `PUSHNAN`, pushes a `NaN`. + +* `84xx` — `PUSHPOW2DEC xx + 1`, pushes `2ˣˣ⁺¹ − 1` for `0 ≤ xx ≤ 255`. + +* `85xx` — `PUSHNEGPOW2 xx + 1`, pushes `−2ˣˣ⁺¹` for `0 ≤ xx ≤ 255`. + +* `86, 87` — reserved for integer constants. ### A.4.2. Constant slices, continuations, cells, and references. -Most -of the instructions listed below push literal slices, continuations, cells, and +Most of the instructions listed below push literal slices, continuations, cells, and cell references, stored as immediate arguments to the instruction. Therefore, if the immediate argument is absent or too short, an “invalid or too short opcode” exception (code `6`) is thrown. @@ -1808,7 +1820,7 @@ opcode” exception (code `6`) is thrown. * `A1` — `SUB` `(x y – x − y)`. * `A2` — `SUBR` `(x y – y − x)`, equivalent to `SWAP; SUB`. * `A3` — `NEGATE` `(x – −x)`, equivalent to `MULCONST −1` or to `ZERO; SUBR`. - Notice that it triggers an integer overflow exception if `x = −2^256`. + Notice that it triggers an integer overflow exception if `x = −2²⁵⁶`. * `A4` — `INC` `(x – x + 1)`, equivalent to `ADDCONST 1`. * `A5` — `DEC` `(x – x − 1)`, equivalent to `ADDCONST −1`. * `A6cc` — `ADDCONST cc` `(x – x + cc)`, `−128 ≤ cc ≤ 127`. @@ -1835,31 +1847,31 @@ operation and its variants), possibly replaced by a left shift. * `1 ≤ d ≤ 3` — Indicates which results of division are required: `1`—only the quotient, `2`—only the remainder, `3`—both. * `0 ≤ f ≤ 2` — Rounding mode: `0`—floor, `1`—nearest integer, `2`—ceiling - (cf. 1.5.6). + (cf. [1.5.6](#1-5-2-automatic-overflow-checks)). Examples: -* `A904` — `DIV` `(x y – q := ⌊x/y⌋)`. -* `A905` — `DIVR` `(x y – q' := ⌊x/y + 1/2⌋)`. -* `A906` — `DIVC` `(x y – q'' := ⌈x/y⌉)`. -* `A908` — `MOD` `(x y – r)`, where `q := ⌊x/y⌋`, `r := x mod y := x − yq`. -* `A90C` — `DIVMOD` `(x y – q r)`, where `q := ⌊x/y⌋`, `r := x − yq`. -* `A90D` — `DIVMODR` `(x y – q' r')`, where `q' := ⌊x/y + 1/2⌋`, `r' := x − yq'`. -* `A90E` — `DIVMODC` `(x y – q'' r'')`, where `q'' := ⌈x/y⌉`, `r'' := x − yq''`. -* `A924` — same as `RSHIFT`: `(x y – ⌊x · 2^(−y)⌋)` for `0 ≤ y ≤ 256`. -* `A934tt` — same as `RSHIFT tt + 1`: `(x – ⌊x · 2^(−tt−1)⌋)`. -* `A938tt` — `MODPOW2 tt + 1`: `(x – x mod 2^(tt+1))`. -* `A985` — `MULDIVR` `(x y z – q')`, where `q' = ⌊xy/z + 1/2⌋`. -* `A98C` — `MULDIVMOD` `(x y z – q r)`, where `q := ⌊x · y/z⌋`, `r := x · y mod z` - (same as `*/MOD` in Forth). -* `A9A4` — `MULRSHIFT` `(x y z – ⌊xy · 2^(−z)⌋)` for `0 ≤ z ≤ 256`. -* `A9A5` — `MULRSHIFTR` `(x y z – ⌊xy · 2^(−z) + 1/2⌋)` for `0 ≤ z ≤ 256`. -* `A9B4tt` — `MULRSHIFT tt + 1` `(x y – ⌊xy · 2^(−tt−1)⌋)`. -* `A9B5tt` — `MULRSHIFTR tt + 1` `(x y – ⌊xy · 2^(−tt−1) + 1/2⌋)`. -* `A9C4` — `LSHIFTDIV` `(x y z – ⌊2^z x/y⌋)` for `0 ≤ z ≤ 256`. -* `A9C5` — `LSHIFTDIVR` `(x y z – ⌊2^z x/y + 1/2⌋)` for `0 ≤ z ≤ 256`. -* `A9D4tt` — `LSHIFTDIV tt + 1` `(x y – ⌊2^(tt+1) x/y⌋)`. -* `A9D5tt` — `LSHIFTDIVR tt + 1` `(x y – ⌊2^(tt+1) x/y + 1/2⌋)`. +* `A904` — `DIV (x y – q := ⌊x/y⌋)`. +* `A905` — `DIVR (x y – q′ := ⌊x/y + 1/2⌋)`. +* `A906` — `DIVC (x y – q″ := ⌈x/y⌉)`. +* `A908` — `MOD (x y – r)`, where `q := ⌊x/y⌋`, `r := x mod y := x − yq`. +* `A90C` — `DIVMOD (x y – q r)`, where `q := ⌊x/y⌋`, `r := x − yq`. +* `A90D` — `DIVMODR (x y – q′ r′)`, where `q′ := ⌊x/y + 1/2⌋`, `r′ := x − yq′`. +* `A90E` — `DIVMODC (x y – q″ r″)`, where `q″ := ⌈x/y⌉`, `r″ := x − yq″`. +* `A924` — same as `RSHIFT`: `(x y – ⌊x · 2⁻ʸ⌋)` for `0 ≤ y ≤ 256`. +* `A934tt` — same as `RSHIFT tt + 1`: `(x – ⌊x · 2⁻ᵗᵗ⁻¹⌋)`. +* `A938tt` — `MODPOW2 tt + 1`: `(x – x mod 2ᵗᵗ⁺¹)`. +* `A985` — `MULDIVR (x y z – q′)`, where `q′ = ⌊xy/z + 1/2⌋`. +* `A98C` — `MULDIVMOD (x y z – q r)`, where `q := ⌊x · y/z⌋`, `r := x · y mod z` (same as `*/MOD` in Forth). +* `A9A4` — `MULRSHIFT (x y z – ⌊xy · 2⁻ᶻ⌋)` for `0 ≤ z ≤ 256`. +* `A9A5` — `MULRSHIFTR (x y z – ⌊xy · 2⁻ᶻ + 1/2⌋)` for `0 ≤ z ≤ 256`. +* `A9B4tt` — `MULRSHIFT tt + 1 (x y – ⌊xy · 2⁻ᵗᵗ⁻¹⌋)`. +* `A9B5tt` — `MULRSHIFTR tt + 1 (x y – ⌊xy · 2⁻ᵗᵗ⁻¹ + 1/2⌋)`. +* `A9C4` — `LSHIFTDIV (x y z – ⌊2ᶻx/y⌋)` for `0 ≤ z ≤ 256`. +* `A9C5` — `LSHIFTDIVR (x y z – ⌊2ᶻx/y + 1/2⌋)` for `0 ≤ z ≤ 256`. +* `A9D4tt` — `LSHIFTDIV tt + 1 (x y – ⌊2ᵗᵗ⁺¹x/y⌋)`. +* `A9D5tt` — `LSHIFTDIVR tt + 1 (x y – ⌊2ᵗᵗ⁺¹x/y + 1/2⌋)`. + The most useful of these operations are `DIV`, `DIVMOD`, `MOD`, `DIVR`, `DIVC`, `MODPOW2 t`, and `RSHIFTR t` (for integer arithmetic); and `MULDIVMOD`, `MULDIV`, @@ -1867,50 +1879,50 @@ The most useful of these operations are `DIV`, `DIVMOD`, `MOD`, `DIVR`, `DIVC`, ### A.5.3. Shifts, logical operations. -* `AAcc` — `LSHIFT cc + 1` `(x – x · 2^(cc+1))`, `0 ≤ cc ≤ 255`. +* `AAcc` — `LSHIFT cc + 1 (x – x · 2ᶜᶜ⁺¹)`, `0 ≤ cc ≤ 255`. * `AA00` — `LSHIFT 1`, equivalent to `MULCONST 2` or to Forth’s `2*`. -* `ABcc` — `RSHIFT cc + 1` `(x – ⌊x · 2^(−cc−1)⌋)`, `0 ≤ cc ≤ 255`. -* `AC` — `LSHIFT` `(x y – x · 2^y)`, `0 ≤ y ≤ 1023`. -* `AD` — `RSHIFT` `(x y – ⌊x · 2^(−y)⌋)`, `0 ≤ y ≤ 1023`. -* `AE` — `POW2` `(y – 2^y)`, `0 ≤ y ≤ 1023`, equivalent to `ONE; SWAP; LSHIFT`. +* `ABcc` — `RSHIFT cc + 1 (x – ⌊x · 2⁻ᶜᶜ⁻¹⌋)`, `0 ≤ cc ≤ 255`. +* `AC` — `LSHIFT (x y – x · 2ʸ)`, `0 ≤ y ≤ 1023`. +* `AD` — `RSHIFT (x y – ⌊x · 2⁻ʸ⌋)`, `0 ≤ y ≤ 1023`. +* `AE` — `POW2 (y – 2ʸ)`, `0 ≤ y ≤ 1023`, equivalent to `ONE; SWAP; LSHIFT`. * `AF` — reserved. -* `B0` — `AND` `(x y – x&y)`, bitwise “and” of two signed integers `x` and `y`, +* `B0` — `AND (x y – x&y)`, bitwise “and” of two signed integers `x` and `y`, sign-extended to infinity. -* `B1` — `OR` `(x y – x ∨ y)`, bitwise “or” of two integers. -* `B2` — `XOR` `(x y – x ⊕ y)`, bitwise “xor” of two integers. -* `B3` — `NOT` `(x – x ⊕ −1 = −1 − x)`, bitwise “not” of an integer. -* `B4cc` — `FITS cc + 1` `(x – x)`, checks whether `x` is a `cc + 1`-bit signed - integer for `0 ≤ cc ≤ 255` (i.e., whether `−2^cc ≤ x < 2^cc`). If not, either +* `B1` — `OR (x y – x ∨ y)`, bitwise “or” of two integers. +* `B2` — `XOR (x y – x ⊕ y)`, bitwise “xor” of two integers. +* `B3` — `NOT (x – x ⊕ −1 = −1 − x)`, bitwise “not” of an integer. +* `B4cc` — `FITS cc + 1 (x – x)`, checks whether `x` is a `cc + 1`-bit signed + integer for `0 ≤ cc ≤ 255` (i.e., whether `−2ᶜᶜ ≤ x < 2ᶜᶜ`). If not, either triggers an integer overflow exception, or replaces `x` with a `NaN` (quiet version). -* `B400` — `FITS 1` or `CHKBOOL` `(x – x)`, checks whether `x` is a “boolean +* `B400` — `FITS 1` or `CHKBOOL (x – x)`, checks whether `x` is a “boolean value” (i.e., either `0` or `-1`). -* `B5cc` — `UFITS cc + 1` `(x – x)`, checks whether `x` is a `cc + 1`-bit unsigned - integer for `0 ≤ cc ≤ 255` (i.e., whether `0 ≤ x < 2^(cc+1)`). +* `B5cc` — `UFITS cc + 1 (x – x)`, checks whether `x` is a `cc + 1`-bit unsigned + integer for `0 ≤ cc ≤ 255` (i.e., whether `0 ≤ x < 2ᶜᶜ⁺¹`). * `B500` — `UFITS 1` or `CHKBIT`, checks whether `x` is a binary digit (i.e., zero or one). -* `B600` — `FITSX` `(x c – x)`, checks whether `x` is a `c`-bit signed integer for +* `B600` — `FITSX (x c – x)`, checks whether `x` is a `c`-bit signed integer for `0 ≤ c ≤ 1023`. -* `B601` — `UFITSX` `(x c – x)`, checks whether `x` is a `c`-bit unsigned integer +* `B601` — `UFITSX (x c – x)`, checks whether `x` is a `c`-bit unsigned integer for `0 ≤ c ≤ 1023`. -* `B602` — `BITSIZE` `(x – c)`, computes smallest `c ≥ 0` such that `x` fits into - a `c`-bit signed integer (`−2^(c−1) ≤ c < 2^(c−1)`). -* `B603` — `UBITSIZE` `(x – c)`, computes smallest `c ≥ 0` such that `x` fits - into a `c`-bit unsigned integer (`0 ≤ x < 2^c`), or throws a range check +* `B602` — `BITSIZE (x – c)`, computes smallest `c ≥ 0` such that `x` fits into + a `c`-bit signed integer (`−2ᶜ⁻¹ ≤ x < 2ᶜ⁻¹`). +* `B603` — `UBITSIZE (x – c)`, computes smallest `c ≥ 0` such that `x` fits + into a `c`-bit unsigned integer (`0 ≤ x < 2ᶜ`), or throws a range check exception. -* `B608` — `MIN` `(x y – x or y)`, computes the minimum of two integers `x` +* `B608` — `MIN (x y – x or y)`, computes the minimum of two integers `x` and `y`. -* `B609` — `MAX` `(x y – x or y)`, computes the maximum of two integers `x` +* `B609` — `MAX (x y – x or y)`, computes the maximum of two integers `x` and `y`. -* `B60A` — `MINMAX` or `INTSORT2` `(x y – x y or y x)`, sorts two integers. Quiet +* `B60A` — `MINMAX` or `INTSORT2 (x y – x y or y x)`, sorts two integers. Quiet version of this operation returns two `NaN`s if any of the arguments are `NaN`s. -* `B60B` — `ABS` `(x – |x|)`, computes the absolute value of an integer `x`. +* `B60B` — `ABS (x – |x|)`, computes the absolute value of an integer `x`. + ### A.5.4. Quiet arithmetic primitives. -We opted to make all arithmetic -operations “non-quiet” (signaling) by default, and create their quiet counterparts by means of a prefix. Such an encoding is definitely sub-optimal. It is +We opted to make all arithmetic operations “non-quiet” (signaling) by default, and create their quiet counterparts by means of a prefix. Such an encoding is definitely sub-optimal. It is not yet clear whether it should be done in this way, or in the opposite way by making all arithmetic operations quiet by default, or whether quiet and non-quiet operations should be given opcodes of equal length; this can only @@ -1922,18 +1934,23 @@ be settled by practice. Notice that this does not extend to shift amounts and other parameters that must be within a small range (e.g., `0–1023`). Also notice that this does not disable type-checking exceptions if a value of a type other than `Integer` is supplied. -* `B7A0` — `QADD` `(x y – x + y)`, always works if `x` and `y` are `Integer`s, but + +* `B7A0` — `QADD (x y – x + y)`, always works if `x` and `y` are `Integer`s, but returns a `NaN` if the addition cannot be performed. -* `B7A904` — `QDIV` `(x y – ⌊x/y⌋)`, returns a `NaN` if `y = 0`, or if `y = −1` and - `x = −2^256`, or if either of `x` or `y` is a `NaN`. -* `B7B0` — `QAND` `(x y – x&y)`, bitwise “and” (similar to `AND`), but returns + +* `B7A904` — `QDIV (x y – ⌊x/y⌋)`, returns a `NaN` if `y = 0`, or if `y = −1` and + `x = −2²⁵⁶`, or if either of `x` or `y` is a `NaN`. + +* `B7B0` — `QAND (x y – x&y)`, bitwise “and” (similar to `AND`), but returns a `NaN` if either `x` or `y` is a `NaN` instead of throwing an integer overflow exception. However, if one of the arguments is zero, and the other is a `NaN`, the result is zero. -* `B7B1` — `QOR` `(x y – x∨y)`, bitwise “or”. If `x = −1` or `y = −1`, the result + +* `B7B1` — `QOR (x y – x ∨ y)`, bitwise “or”. If `x = −1` or `y = −1`, the result is always `−1`, even if the other argument is a `NaN`. -* `B7B507` — `QUFITS 8` `(x – x' )`, checks whether `x` is an unsigned byte - (i.e., whether `0 ≤ x < 2^8`), and replaces `x` with a `NaN` if this is not the + +* `B7B507` — `QUFITS 8 (x – x′)`, checks whether `x` is an unsigned byte + (i.e., whether `0 ≤ x < 2⁸`), and replaces `x` with a `NaN` if this is not the case; leaves `x` intact otherwise (i.e., if `x` is an unsigned byte). ## A.6 Comparison primitives @@ -1948,66 +1965,104 @@ with the aid of the `QUIET` prefix (`B7`). If any of the integers being compared are `NaN`s, the result of a quiet comparison will also be a `NaN` (“undefined”), instead of a `−1` (“yes”) or `0` (“no”), thus effectively supporting ternary logic. -* `B8` — `SGN` `(x – sgn(x))`, computes the sign of an integer `x`: `−1` if `x < 0`, +* `B8` — `SGN (x – sgn(x))`, computes the sign of an integer `x`: `−1` if `x < 0`, `0` if `x = 0`, `1` if `x > 0`. -* `B9` — `LESS` `(x y – x < y)`, returns `−1` if `x < y`, `0` otherwise. -* `BA` — `EQUAL` `(x y – x = y)`, returns `−1` if `x = y`, `0` otherwise. -* `BB` — `LEQ` `(x y – x ≤ y)`. -* `BC` — `GREATER` `(x y – x > y)`. -* `BD` — `NEQ` `(x y – x 6= y)`, equivalent to `EQUAL; NOT`. -* `BE` — `GEQ` `(x y – x ≥ y)`, equivalent to `LESS; NOT`. -* `BF` — `CMP` `(x y – sgn(x − y))`, computes the sign of `x − y`: `−1` if `x < y`, + +* `B9` — `LESS (x y – x < y)`, returns `−1` if `x < y`, `0` otherwise. + +* `BA` — `EQUAL (x y – x = y)`, returns `−1` if `x = y`, `0` otherwise. + +* `BB` — `LEQ (x y – x ≤ y)`. + +* `BC` — `GREATER (x y – x > y)`. + +* `BD` — `NEQ (x y – x ≠ y)`, equivalent to `EQUAL; NOT`. + +* `BE` — `GEQ (x y – x ≥ y)`, equivalent to `LESS; NOT`. + +* `BF` — `CMP (x y – sgn(x − y))`, computes the sign of `x − y`: `−1` if `x < y`, `0` if `x = y`, `1` if `x > y`. No integer overflow can occur here unless `x` or `y` is a `NaN`. -* `C0yy` — `EQINT yy` `(x – x = yy)` for `−2^7 ≤ yy < 2^7`. + +* `C0yy` — `EQINT yy (x – x = yy)` for `−2⁷ ≤ yy < 2⁷`. + * `C000` — `ISZERO`, checks whether an integer is zero. Corresponds to Forth’s `0=`. -* `C1yy` — `LESSINT yy` `(x – x < yy)` for `−2^7 ≤ yy < 2^7`. + +* `C1yy` — `LESSINT yy (x – x < yy)` for `−2⁷ ≤ yy < 2⁷`. + * `C100` — `ISNEG`, checks whether an integer is negative. Corresponds to Forth’s `0<`. + * `C101` — `ISNPOS`, checks whether an integer is non-positive. -* `C2yy` — `GTINT yy` `(x – x > yy)` for `−2^7 ≤ yy < 2^7`. + +* `C2yy` — `GTINT yy (x – x > yy)` for `−2⁷ ≤ yy < 2⁷`. + * `C200` — `ISPOS`, checks whether an integer is positive. Corresponds to Forth’s `0>`. + * `C2FF` — `ISNNEG`, checks whether an integer is non-negative. -* `C3yy` — `NEQINT yy` `(x – x 6= yy)` for `−2^7 ≤ yy < 2^7`. -* `C4` — `ISNAN` `(x – x = NaN)`, checks whether `x` is a `NaN`. -* `C5` — `CHKNAN` `(x – x)`, throws an arithmetic overflow exception if `x` is a + +* `C3yy` — `NEQINT yy (x – x ≠ yy)` for `−2⁷ ≤ yy < 2⁷`. + +* `C4` — `ISNAN (x – x = NaN)`, checks whether `x` is a `NaN`. + +* `C5` — `CHKNAN (x – x)`, throws an arithmetic overflow exception if `x` is a `NaN`. + * `C6` — reserved for integer comparison. + ### A.6.2. Other comparison. Most of these “other comparison” primitives actually compare the data portions of `Slice`s as bitstrings. -* `C700` — `SEMPTY` `(s – s = ∅)`, checks whether a `Slice s` is empty (i.e., +* `C700` — `SEMPTY (s – s = ∅)`, checks whether a Slice `s` is empty (i.e., contains no bits of data and no cell references). -* `C701` — `SDEMPTY` `(s – s ≈ ∅)`, checks whether `Slice s` has no bits of + +* `C701` — `SDEMPTY (s – s ≈ ∅)`, checks whether Slice `s` has no bits of data. -* `C702` — `SREMPTY` `(s – r(s) = 0)`, checks whether `Slice s` has no references. -* `C703` — `SDFIRST` `(s – s0 = 1)`, checks whether the first bit of `Slice s` is + +* `C702` — `SREMPTY (s – r(s) = 0)`, checks whether Slice `s` has no + references. + +* `C703` — `SDFIRST (s – s₀ = 1)`, checks whether the first bit of Slice `s` is a one. -* `C704` — `SDLEXCMP` `(s s0 – c)`, compares the data of `s` lexicographically - with the data of `s0`, returning `−1`, `0`, or `1` depending on the result. -* `C705` — `SDEQ` `(s s0 – s ≈ s0)`, checks whether the data parts of `s` and `s0` + +* `C704` — `SDLEXCMP (s s′ – c)`, compares the data of `s` lexicographically + with the data of `s′`, returning `−1`, `0`, or `1` depending on the result. + +* `C705` — `SDEQ (s s′ – s ≈ s′)`, checks whether the data parts of `s` and `s′` coincide, equivalent to `SDLEXCMP; ISZERO`. -* `C708` — `SDPFX` `(s s0 – ? )`, checks whether `s` is a prefix of `s0`. -* `C709` — `SDPFXREV` `(s s0 – ? )`, checks whether `s0` is a prefix of `s`, equivalent - to `SWAP; SDPFX`. -* `C70A` — `SDPPFX` `(s s0 – ? )`, checks whether `s` is a proper prefix of `s0` (i.e., - a prefix distinct from `s0`). -* `C70B` — `SDPPFXREV` `(s s0 – ? )`, checks whether `s0` is a proper prefix of `s`. -* `C70C` — `SDSFX` `(s s0 – ? )`, checks whether `s` is a suffix of `s0`. -* `C70D` — `SDSFXREV` `(s s0 – ? )`, checks whether `s0` is a suffix of `s`. -* `C70E` — `SDPSFX` `(s s0 – ? )`, checks whether `s` is a proper suffix of `s0`. -* `C70F` — `SDPSFXREV` `(s s0 – ? )`, checks whether `s0` is a proper suffix of `s`. -* `C710` — `SDCNTLEAD0` `(s – n)`, returns the number of leading zeroes in - `s`. -* `C711` — `SDCNTLEAD1` `(s – n)`, returns the number of leading ones in `s`. -* `C712` — `SDCNTTRAIL0` `(s – n)`, returns the number of trailing zeroes in + +* `C708` — `SDPFX (s s′ – ? )`, checks whether `s` is a prefix of `s′`. + +* `C709` — `SDPFXREV (s s′ – ? )`, checks whether `s′` is a prefix of `s`, + equivalent to `SWAP; SDPFX`. + +* `C70A` — `SDPPFX (s s′ – ? )`, checks whether `s` is a proper prefix of `s′` + (i.e., a prefix distinct from `s′`). + +* `C70B` — `SDPPFXREV (s s′ – ? )`, checks whether `s′` is a proper prefix of `s`. + +* `C70C` — `SDSFX (s s′ – ? )`, checks whether `s` is a suffix of `s′`. + +* `C70D` — `SDSFXREV (s s′ – ? )`, checks whether `s′` is a suffix of `s`. + +* `C70E` — `SDPSFX (s s′ – ? )`, checks whether `s` is a proper suffix of `s′`. + +* `C70F` — `SDPSFXREV (s s′ – ? )`, checks whether `s′` is a proper suffix of `s`. + +* `C710` — `SDCNTLEAD0 (s – n)`, returns the number of leading zeroes in `s`. -* `C713` — `SDCNTTRAIL1` `(s – n)`, returns the number of trailing ones in `s`. + +* `C711` — `SDCNTLEAD1 (s – n)`, returns the number of leading ones in `s`. + +* `C712` — `SDCNTTRAIL0 (s – n)`, returns the number of trailing zeroes in `s`. + +* `C713` — `SDCNTTRAIL1 (s – n)`, returns the number of trailing ones in `s`. + ## A.7 Cell primitives @@ -2018,738 +2073,1495 @@ with `Builder`s, or cell deserialization primitives, which work with `Slice`s. All these primitives first check whether there is enough space in the Builder, and only then check the range of the value being serialized. -* `C8` — `NEWC` ( – b), creates a new empty Builder. -* `C9` — `ENDC` (b – c), converts a Builder into an ordinary Cell. -* `CAcc` — `STI cc + 1` (x b – b0), stores a signed cc + 1-bit integer x into Builder b for 0 ≤ cc ≤ 255, throws a range check exception if x does not fit into cc + 1 bits. -* `CBcc` — `STU cc + 1` (x b – b0), stores an unsigned cc + 1-bit integer x into Builder b. In all other respects it is similar to STI. -* `CC` — `STREF` (c b – b0), stores a reference to Cell c into Builder b. -* `CD` — `STBREFR` or `ENDCST` (b b00 – b), equivalent to ENDC; SWAP; STREF. -* `CE` — `STSLICE` (s b – b0), stores Slice s into Builder b. -* `CF00` — `STIX` (x b l – b0), stores a signed l-bit integer x into b for 0 ≤ l ≤ 257. -* `CF01` — `STUX` (x b l – b0), stores an unsigned l-bit integer x into b for 0 ≤ l ≤ 256. -* `CF02` — `STIXR` (b x l – b0), similar to STIX, but with arguments in a different order. -* `CF03` — `STUXR` (b x l – b0), similar to STUX, but with arguments in a different order. -* `CF04` — `STIXQ` (x b l – x b f or b0 0), a quiet version of STIX. If there is no space in b, sets b0 = b and f = −1. If x does not fit into l bits, sets b0 = b and f = 1. If the operation succeeds, b0 is the new Builder and f = 0. However, 0 ≤ l ≤ 257, with a range check exception if this is not so. -* `CF05` — `STUXQ` (x b l – b0 f). -* `CF06` — `STIXRQ` (b x l – b x f or b0 0). -* `CF07` — `STUXRQ` (b x l – b x f or b0 0). -* `CF08cc` — a longer version of `STI cc + 1`. -* `CF09cc` — a longer version of `STU cc + 1`. -* `CF0Acc` — `STIR cc + 1` (b x – b0), equivalent to SWAP; STI cc + 1. -* `CF0Bcc` — `STUR cc + 1` (b x – b0), equivalent to SWAP; STU cc + 1. -* `CF0Ccc` — `STIQ cc + 1` (x b – x b f or b0 0). -* `CF0Dcc` — `STUQ cc + 1` (x b – x b f or b0 0). -* `CF0Ecc` — `STIRQ cc + 1` (b x – b x f or b0 0). -* `CF0Fcc` — `STURQ cc + 1` (b x – b x f or b0 0). -* `CF10` — a longer version of `STREF` (c b – b0). -* `CF11` — `STBREF` (b0 b – b00), equivalent to SWAP; STBREFREV. -* `CF12` — a longer version of `STSLICE` (s b – b0). -* `CF13` — `STB` (b0 b – b00), appends all data from Builder b0 to Builder b. -* `CF14` — `STREFR` (b c – b0). -* `CF15` — `STBREFR` (b b0 – b00), a longer encoding of STBREFR. -* `CF16` — `STSLICER` (b s – b0). -* `CF17` — `STBR` (b b0 – b00), concatenates two Builder s, equivalent to SWAP; STB. -* `CF18` — `STREFQ` (c b – c b −1 or b0 0). -* `CF19` — `STBREFQ` (b0 b – b0 b −1 or b00 0). -* `CF1A` — `STSLICEQ` (s b – s b −1 or b0 0). -* `CF1B` — `STBQ` (b0 b – b0 b −1 or b00 0). -* `CF1C` — `STREFRQ` (b c – b c −1 or b0 0). -* `CF1D` — `STBREFRQ` (b b0 – b b0 −1 or b00 0). -* `CF1E` — `STSLICERQ` (b s – b s −1 or b00 0). -* `CF1F` — `STBRQ` (b b0 – b b0 −1 or b00 0). -* `CF20` — `STREFCONST`, equivalent to PUSHREF; STREFR. -* `CF21` — `STREF2CONST`, equivalent to STREFCONST; STREFCONST. -* `CF23` — `ENDXC` (b x – c), if x 6= 0, creates a special or exotic cell (cf. 3.1.2) from Builder b. The type of the exotic cell must be stored in the first 8 bits of b. If x = 0, it is equivalent to ENDC. Otherwise some validity checks on the data and references of b are performed before creating the exotic cell. -* `CF28` — `STILE4` (x b – b0), stores a little-endian signed 32-bit integer. -* `CF29` — `STULE4` (x b – b0), stores a little-endian unsigned 32-bit integer. -* `CF2A` — `STILE8` (x b – b0), stores a little-endian signed 64-bit integer. -* `CF2B` — `STULE8` (x b – b0), stores a little-endian unsigned 64-bit integer. -* `CF30` — `BDEPTH` (b – x), returns the depth of Builder b. If no cell references are stored in b, then x = 0; otherwise x is one plus the maximum of depths of cells referred to from b. -* `CF31` — `BBITS` (b – x), returns the number of data bits already stored in Builder b. -* `CF32` — `BREFS` (b – y), returns the number of cell references already stored in b. -* `CF33` — `BBITREFS` (b – x y), returns the numbers of both data bits and cell references in b. -* `CF35` — `BREMBITS` (b – x0), returns the number of data bits that can still be stored in b. -* `CF36` — `BREMREFS` (b – y0). -* `CF37` — `BREMBITREFS` (b – x0 y0). -* `CF38cc` — `BCHKBITS cc + 1` (b –), checks whether cc + 1 bits can be stored into b, where 0 ≤ cc ≤ 255. -* `CF39` — `BCHKBITS` (b x – ), checks whether x bits can be stored into b, 0 ≤ x ≤ 1023. If there is no space for x more bits in b, or if x is not within the range 0 . . . 1023, throws an exception. -* `CF3A` — `BCHKREFS` (b y – ), checks whether y references can be stored into b, 0 ≤ y ≤ 7. -* `CF3B` — `BCHKBITREFS` (b x y – ), checks whether x bits and y references can be stored into b, 0 ≤ x ≤ 1023, 0 ≤ y ≤ 7. -* `CF3Ccc` — `BCHKBITSQ cc + 1` (b – ?), checks whether cc + 1 bits can be stored into b, where 0 ≤ cc ≤ 255. -* `CF3D` — `BCHKBITSQ` (b x – ?), checks whether x bits can be stored into b, 0 ≤ x ≤ 1023. -* `CF3E` — `BCHKREFSQ` (b y – ?), checks whether y references can be stored into b, 0 ≤ y ≤ 7. -* `CF3F` — `BCHKBITREFSQ` (b x y – ?), checks whether x bits and y references can be stored into b, 0 ≤ x ≤ 1023, 0 ≤ y ≤ 7. -* `CF40` — `STZEROES` (b n – b0), stores n binary zeroes into Builder b. -* `CF41` — `STONES` (b n – b0), stores n binary ones into Builder b. -* `CF42` — `STSAME` (b n x – b0), stores n binary xes (0 ≤ x ≤ 1) into Builder b. -* `CFC0_xysss` — `STSLICECONST sss` (b – b0), stores a constant subslice sss consisting of 0 ≤ x ≤ 3 references and up to 8y + 1 data bits, with 0 ≤ y ≤ 7. Completion bit is assumed. -* `CF81` — `STSLICECONST ‘0’` or `STZERO` (b – b0), stores one binary zero. -* `CF83` — `STSLICECONST ‘1’` or `STONE` (b – b0), stores one binary one. -* `CFA2` — equivalent to `STREFCONST`. -* `CFA3` — almost equivalent to `STSLICECONST ‘1’`; `STREFCONST`. -* `CFC2` — equivalent to `STREF2CONST`. -* `CFE2` — `STREF3CONST`. +* `C8` — `NEWC ( – b)`, creates a new empty Builder. ---- +* `C9` — `ENDC (b – c)`, converts a Builder into an ordinary Cell. -### A.7.2. Cell deserialization primitives +* `CAcc` — `STI cc + 1 (x b – b′)`, stores a signed `cc + 1`-bit integer `x` into + Builder `b` for `0 ≤ cc ≤ 255`, throws a range check exception if `x` does + not fit into `cc + 1` bits. -* `D0` — `CTOS` (c – s), converts a Cell into a Slice. Notice that `c` must be either an ordinary cell, or an exotic cell (cf. 3.1.2) which is automatically loaded to yield an ordinary cell `c0`, converted into a Slice afterwards. -* `D1` — `ENDS` (s – ), removes a Slice `s` from the stack, and throws an exception if it is not empty. -* `D2cc` — `LDI cc + 1` (s – x s0), loads (i.e., parses) a signed cc + 1-bit integer `x` from Slice `s`, and returns the remainder of `s` as `s0`. -* `D3cc` — `LDU cc + 1` (s – x s0), loads an unsigned cc + 1-bit integer `x` from Slice `s`. -* `D4` — `LDREF` (s – c s0), loads a cell reference `c` from `s`. -* `D5` — `LDREFRTOS` (s – s0 s00), equivalent to `LDREF`; `SWAP`; `CTOS`. -* `D6cc` — `LDSLICE cc + 1` (s – s00 s0), cuts the next cc + 1 bits of `s` into a separate Slice `s00`. -* `D700` — `LDIX` (s l – x s0), loads a signed `l`-bit (0 ≤ l ≤ 257) integer `x` from Slice `s`, and returns the remainder of `s` as `s0`. -* `D701` — `LDUX` (s l – x s0), loads an unsigned `l`-bit integer `x` from Slice `s`, 0 ≤ l ≤ 256. -* `D702` — `PLDIX` (s l – x), preloads a signed `l`-bit integer from Slice `s`, 0 ≤ l ≤ 257. -* `D703` — `PLDUX` (s l – x), preloads an unsigned `l`-bit integer from `s`, 0 ≤ l ≤ 256. -* `D704` — `LDIXQ` (s l – x s0 −1 or s0), quiet version of `LDIX`. If `s` has fewer than `l` bits, returns a flag instead of exception. -* `D705` — `LDUXQ` (s l – x s0 −1 or s0), quiet version of `LDUX`. -* `D706` — `PLDIXQ` (s l – x −1 or 0), quiet version of `PLDIX`. -* `D707` — `PLDUXQ` (s l – x −1 or 0), quiet version of `PLDUX`. -* `D708cc` — longer encoding of `LDI cc + 1`. -* `D709cc` — longer encoding of `LDU cc + 1`. -* `D70Acc` — `PLDI cc + 1` (s – x), preloads a signed cc + 1-bit integer from Slice `s`. -* `D70Bcc` — `PLDU cc + 1` (s – x), preloads an unsigned cc + 1-bit integer from `s`. -* `D70Ccc` — `LDIQ cc + 1` (s – x s0 −1 or s0), quiet version of `LDI`. -* `D70Dcc` — `LDUQ cc + 1` (s – x s0 −1 or s0), quiet version of `LDU`. -* `D70Ecc` — `PLDIQ cc + 1` (s – x −1 or 0), quiet version of `PLDI`. -* `D70Fcc` — `PLDUQ cc + 1` (s – x −1 or 0), quiet version of `PLDU`. -* `D714_c` — `PLDUZ 32(c + 1)` (s – s x), preloads first 32(c + 1) bits of Slice `s` into an unsigned integer `x`, 0 ≤ c ≤ 7. Missing bits are assumed zero. Used with `IFBITJMP` etc. -* `D718` — `LDSLICEX` (s l – s00 s0), loads first 0 ≤ l ≤ 1023 bits of `s` into a new Slice `s00`, returns the remainder as `s0`. -* `D719` — `PLDSLICEX` (s l – s00), returns first 0 ≤ l ≤ 1023 bits of `s` as `s00`. -* `D71A` — `LDSLICEXQ` (s l – s00 s0 −1 or s0), quiet version of `LDSLICEX`. -* `D71B` — `PLDSLICEXQ` (s l – s0 −1 or 0), quiet version of `PLDSLICEX`. -* `D71Ccc` — longer encoding of `LDSLICE cc + 1`. -* `D71Dcc` — `PLDSLICE cc + 1` (s – s00), returns first 0 < cc + 1 ≤ 256 bits of `s` as `s00`. -* `D71Ecc` — `LDSLICEQ cc + 1` (s – s00 s0 −1 or s0), quiet version of `LDSLICE`. -* `D71Fcc` — `PLDSLICEQ cc + 1` (s – s00 −1 or 0), quiet version of `PLDSLICE`. -* `D720` — `SDCUTFIRST` (s l – s0), returns first 0 ≤ l ≤ 1023 bits of `s`. Equivalent to `PLDSLICEX`. -* `D721` — `SDSKIPFIRST` (s l – s0), returns all but first 0 ≤ l ≤ 1023 bits of `s`. Equivalent to `LDSLICEX`; `NIP`. -* `D722` — `SDCUTLAST` (s l – s0), returns last 0 ≤ l ≤ 1023 bits of `s`. -* `D723` — `SDSKIPLAST` (s l – s0), returns all but last 0 ≤ l ≤ 1023 bits of `s`. -* `D724` — `SDSUBSTR` (s l l0 – s0), returns substring of length 0 ≤ l0 ≤ 1023 starting at offset 0 ≤ l ≤ 1023. -* `D726` — `SDBEGINSX` (s s0 – s00), checks whether `s` begins with data bits of `s0`. Removes `s0` on success. Throws exception on failure. -* `D727` — `SDBEGINSXQ` (s s0 – s00 −1 or s0), quiet version of `SDBEGINSX`. -* `D72A_xsss` — `SDBEGINS` (s – s00), checks whether `s` begins with constant bitstring `sss` of length 8x + 3 (completion bit assumed). Removes on success. -* `D72802` — `SDBEGINS ‘0’` (s – s00), checks whether `s` begins with binary zero. -* `D72806` — `SDBEGINS ‘1’` (s – s00), checks whether `s` begins with binary one. -* `D72E_xsss` — `SDBEGINSQ` (s – s00 −1 or s0), quiet version of `SDBEGINS`. -* `D730` — `SCUTFIRST` (s l r – s0), returns first 0 ≤ l ≤ 1023 bits and 0 ≤ r ≤ 4 references of `s`. -* `D731` — `SSKIPFIRST` (s l r – s0). -* `D732` — `SCUTLAST` (s l r – s0), returns last 0 ≤ l ≤ 1023 bits and last 0 ≤ r ≤ 4 references. -* `D733` — `SSKIPLAST` (s l r – s0). -* `D734` — `SUBSLICE` (s l r l0 r0 – s0), returns 0 ≤ l0 ≤ 1023 bits and 0 ≤ r0 ≤ 4 refs after skipping first l bits and r refs. -* `D736` — `SPLIT` (s l r – s0 s00), splits off first l bits and r refs of `s` into `s0`, returns remainder as `s00`. -* `D737` — `SPLITQ` (s l r – s0 s00 −1 or s0), quiet version of `SPLIT`. -* `D739` — `XCTOS` (c – s ?), converts a Cell (ordinary or exotic) into a Slice. Returns flag if exotic. -* `D73A` — `XLOAD` (c – c0), loads exotic cell `c` to ordinary `c0`. -* `D73B` — `XLOADQ` (c – c0 −1 or c0), quiet version of `XLOAD`. -* `D741` — `SCHKBITS` (s l – ), checks there are ≥ l data bits. Throws exception if not. -* `D742` — `SCHKREFS` (s r – ), checks ≥ r references. -* `D743` — `SCHKBITREFS` (s l r – ), checks ≥ l bits and ≥ r references. -* `D745` — `SCHKBITSQ` (s l – ?), quiet version of `SCHKBITS`. -* `D746` — `SCHKREFSQ` (s r – ?). -* `D747` — `SCHKBITREFSQ` (s l r – ?). -* `D748` — `PLDREFVAR` (s n – c), returns n-th cell reference of Slice `s`, 0 ≤ n ≤ 3. -* `D749` — `SBITS` (s – l), returns number of data bits. -* `D74A` — `SREFS` (s – r), returns number of references. -* `D74B` — `SBITREFS` (s – l r), returns both bit and ref counts. -* `D74E_n` — `PLDREFIDX n` (s – c), returns n-th reference, 0 ≤ n ≤ 3. -* `D74C` — `PLDREF` (s – c), preloads first reference of `s`. -* `D750` — `LDILE4` (s – x s0), loads little-endian signed 32-bit integer. -* `D751` — `LDULE4` (s – x s0), loads little-endian unsigned 32-bit integer. -* `D752` — `LDILE8` (s – x s0), loads little-endian signed 64-bit integer. -* `D753` — `LDULE8` (s – x s0), loads little-endian unsigned 64-bit integer. -* `D754` — `PLDILE4` (s – x), preloads little-endian signed 32-bit integer. -* `D755` — `PLDULE4` (s – x), preloads little-endian unsigned 32-bit integer. -* `D756` — `PLDILE8` (s – x), preloads little-endian signed 64-bit integer. -* `D757` — `PLDULE8` (s – x), preloads little-endian unsigned 64-bit integer. -* `D758` — `LDILE4Q` (s – x s0 −1 or s0), quiet 32-bit signed LE load. -* `D759` — `LDULE4Q` (s – x s0 −1 or s0), quiet 32-bit unsigned LE load. -* `D75A` — `LDILE8Q` (s – x s0 −1 or s0), quiet 64-bit signed LE load. -* `D75B` — `LDULE8Q` (s – x s0 −1 or s0), quiet 64-bit unsigned LE load. -* `D75C` — `PLDILE4Q` (s – x −1 or 0), quiet preload 32-bit signed. -* `D75D` — `PLDULE4Q` (s – x −1 or 0), quiet preload 32-bit unsigned. -* `D75E` — `PLDILE8Q` (s – x −1 or 0), quiet preload 64-bit signed. -* `D75F` — `PLDULE8Q` (s – x −1 or 0), quiet preload 64-bit unsigned. -* `D760` — `LDZEROES` (s – n s0), returns count n of leading zero bits in `s` and removes them. -* `D761` — `LDONES` (s – n s0), returns count n of leading one bits in `s` and removes them. -* `D762` — `LDSAME` (s x – n s0), returns count n of leading bits equal to `x` (0 ≤ x ≤ 1) in `s`, removes them. -* `D764` — `SDEPTH` (s – x), returns depth of Slice `s`. If no references, x = 0; else x = 1 + max depth of cells referred. -* `D765` — `CDEPTH` (c – x), returns depth of Cell `c`. If no refs, x = 0; else 1 + max depth. If `c` = Null, returns 0. +* `CBcc` — `STU cc + 1 (x b – b′)`, stores an unsigned `cc + 1`-bit integer `x` + into Builder `b`. In all other respects it is similar to `STI`. ---- +* `CC` — `STREF (c b – b′)`, stores a reference to Cell `c` into Builder `b`. -## A.8 Continuation and control flow primitives +* `CD` — `STBREFR` or `ENDCST (b b′′ – b)`, equivalent to `ENDC; SWAP; STREF`. -### A.8.1. Unconditional control flow primitives. +* `CE` — `STSLICE (s b – b′)`, stores Slice `s` into Builder `b`. -* `D8` — **EXECUTE** or **CALLX** `(c – )`, calls or executes continuation `c` (i.e., `cc ← c ◦0 cc`). -* `D9` — **JMPX** `(c – )`, jumps, or transfers control, to continuation `c` (i.e., `cc ← c ◦0 c0, or rather cc ← (c ◦0 c0) ◦1 c1`). The remainder of the previous current continuation `cc` is discarded. -* `DApr` — **CALLXARGS p,r** `(c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. -* `DB0p` — **CALLXARGS p,−1** `(c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. -* `DB1p` — **JMPXARGS p** `(c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). -* `DB2r` — **RETARGS r**, returns to `c0`, with `0 ≤ r ≤ 15` return values taken from the current stack. -* `DB30` — **RET** or **RETTRUE**, returns to the continuation at `c0` (i.e., performs `cc ← c0`). The remainder of the current continuation `cc` is discarded. Approximately equivalent to `PUSH c0; JMPX`. -* `DB31` — **RETALT** or **RETFALSE**, returns to the continuation at `c1` (i.e., `cc ← c1`). Approximately equivalent to `PUSH c1; JMPX`. -* `DB32` — **BRANCH** or **RETBOOL** `(f – )`, performs **RETTRUE** if integer `f ≠ 0`, or **RETFALSE** if `f = 0`. -* `DB34` — **CALLCC** `(c – )`, call with current continuation, transfers control to `c`, pushing the old value of `cc` into `c`’s stack (instead of discarding it or writing it into new `c0`). -* `DB35` — **JMPXDATA** `(c – )`, similar to **CALLCC**, but the remainder of the current continuation (the old value of `cc`) is converted into a Slice before pushing it into the stack of `c`. -* `DB36pr` — **CALLCCARGS p,r** `(c – )`, similar to **CALLXARGS**, but pushes the old value of `cc` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `cc.nargs` to `−1 ≤ r ≤ 14`. -* `DB38` — **CALLXVARARGS** `(c p r – )`, similar to **CALLXARGS**, but takes `−1 ≤ p, r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1 . . . 254`. -* `DB39` — **RETVARARGS** `(p r – )`, similar to **RETARGS**. -* `DB3A` — **JMPXVARARGS** `(c p r – )`, similar to **JMPXARGS**. -* `DB3B` — **CALLCCVARARGS** `(c p r – )`, similar to **CALLCCARGS**. -* `DB3C` — **CALLREF**, equivalent to `PUSHREFCONT; CALLX`. -* `DB3D` — **JMPREF**, equivalent to `PUSHREFCONT; JMPX`. -* `DB3E` — **JMPREFDATA**, equivalent to `PUSHREFCONT; JMPXDATA`. -* `DB3F` — **RETDATA**, equivalent to `PUSH c0; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. +* `CF00` — `STIX (x b l – b′)`, stores a signed `l`-bit integer `x` into `b` for `0 ≤ l ≤ 257`. ---- +* `CF01` — `STUX (x b l – b′)`, stores an unsigned `l`-bit integer `x` into `b` for `0 ≤ l ≤ 256`. -## A.8 Continuation and control flow primitives +* `CF02` — `STIXR (b x l – b′)`, similar to `STIX`, but with arguments in a + different order. -### A.8.1. Unconditional control flow primitives. +* `CF03` — `STUXR (b x l – b′)`, similar to `STUX`, but with arguments in a + different order. -* `D8` — `EXECUTE` or `CALLX` `(c – )`, calls or executes continuation `c` (i.e., `cc ← c ◦0 cc`). -* `D9` — `JMPX` `(c – )`, jumps, or transfers control, to continuation `c` (i.e., `cc ← c ◦0 c0, or rather cc ← (c ◦0 c0) ◦1 c1`). The remainder of the previous current continuation `cc` is discarded. -* `DApr` — `CALLXARGS p,r` `(c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. -* `DB0p` — `CALLXARGS p,−1` `(c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. -* `DB1p` — `JMPXARGS p` `(c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). -* `DB2r` — `RETARGS r`, returns to `c0`, with `0 ≤ r ≤ 15` return values taken from the current stack. -* `DB30` — `RET` or `RETTRUE`, returns to the continuation at `c0` (i.e., performs `cc ← c0`). The remainder of the current continuation `cc` is discarded. Approximately equivalent to `PUSH c0; JMPX`. -* `DB31` — `RETALT` or `RETFALSE`, returns to the continuation at `c1` (i.e., `cc ← c1`). Approximately equivalent to `PUSH c1; JMPX`. -* `DB32` — `BRANCH` or `RETBOOL` `(f – )`, performs `RETTRUE` if integer `f ≠ 0`, or `RETFALSE` if `f = 0`. -* `DB34` — `CALLCC` `(c – )`, call with current continuation, transfers control to `c`, pushing the old value of `cc` into `c`’s stack (instead of discarding it or writing it into new `c0`). -* `DB35` — `JMPXDATA` `(c – )`, similar to `CALLCC`, but the remainder of the current continuation (the old value of `cc`) is converted into a Slice before pushing it into the stack of `c`. -* `DB36pr` — `CALLCCARGS p,r` `(c – )`, similar to `CALLXARGS`, but pushes the old value of `cc` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `cc.nargs` to `−1 ≤ r ≤ 14`. -* `DB38` — `CALLXVARARGS` `(c p r – )`, similar to `CALLXARGS`, but takes `−1 ≤ p, r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1 . . . 254`. -* `DB39` — `RETVARARGS` `(p r – )`, similar to `RETARGS`. -* `DB3A` — `JMPXVARARGS` `(c p r – )`, similar to `JMPXARGS`. -* `DB3B` — `CALLCCVARARGS` `(c p r – )`, similar to `CALLCCARGS`. -* `DB3C` — `CALLREF`, equivalent to `PUSHREFCONT; CALLX`. -* `DB3D` — `JMPREF`, equivalent to `PUSHREFCONT; JMPX`. -* `DB3E` — `JMPREFDATA`, equivalent to `PUSHREFCONT; JMPXDATA`. -* `DB3F` — `RETDATA`, equivalent to `PUSH c0; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. +* `CF04` — `STIXQ (x b l – x b f or b′ 0)`, a quiet version of `STIX`. + - If there is no space in `b`, sets `b′ = b` and `f = −1`. + - If `x` does not fit into `l` bits, sets `b′ = b` and `f = 1`. + - If the operation succeeds, `b′` is the new Builder and `f = 0`. + However, `0 ≤ l ≤ 257`, with a range check exception if this is not so. +* `CF05` — `STUXQ (x b l – b′ f)`. -### A.8.2. Conditional control flow primitives +* `CF06` — `STIXRQ (b x l – b x f or b′ 0)`. -* `DC` — `IFRET` `(f – )`, performs a `RET`, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. -* `DD` — `IFNOTRET` `(f – )`, performs a `RET`, but only if integer `f` is zero. -* `DE` — `IF` `(f c – )`, performs `EXECUTE` for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. -* `DF` — `IFNOT` `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. -* `E0` — `IFJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is non-zero. -* `E1` — `IFNOTJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is zero. -* `E2` — `IFELSE` `(f c c0 – )`, if integer `f` is non-zero, executes `c`, otherwise executes `c0`. Equivalent to `CONDSELCHK; EXECUTE`. -* `E300` — `IFREF` `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. -* `E301` — `IFNOTREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. -* `E302` — `IFJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. -* `E303` — `IFNOTJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. -* `E304` — `CONDSEL` `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. -* `E305` — `CONDSELCHK` `(f x y – x or y)`, same as `CONDSEL`, but first checks whether `x` and `y` have the same type. -* `E308` — `IFRETALT` `(f – )`, performs `RETALT` if integer `f ≠ 0`. -* `E309` — `IFNOTRETALT` `(f – )`, performs `RETALT` if integer `f = 0`. -* `E30D` — `IFREFELSE` `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. -* `E30E` — `IFELSEREF` `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. -* `E30F` — `IFREFELSEREF` `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. -* `E310–E31F` — reserved for loops with break operators (cf. A.8.3). -* `E39_n` — `IFBITJMP n` `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs `JMPX` to continuation `c`. Value `x` is left in the stack. -* `E3B_n` — `IFNBITJMP n` `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. -* `E3D_n` — `IFBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is set in integer `x`. -* `E3F_n` — `IFNBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `CF07` — `STUXRQ (b x l – b x f or b′ 0)`. +* `CF08cc` — a longer version of `STI cc + 1`. -### A.8.3. Control flow primitives: loops +* `CF09cc` — a longer version of `STU cc + 1`. -Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. 4.1.5), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have `*BRK` versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for `*ENDBRK` versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for `*ENDBRK` versions). - -* `E4` — `REPEAT` `(n c – )`, executes continuation `c` `n` times, if integer `n` is non-negative. If `n ≥ 2^31` or `n < −2^31`, generates a range check exception. Notice that a `RET` inside the code of `c` works as a continue, not as a break. One should use either alternative (experimental) loops or alternative `RETALT` (along with a `SETEXITALT` before the loop) to break out of a loop. -* `E5` — `REPEATEND` `(n – )`, similar to `REPEAT`, but it is applied to the current continuation `cc`. -* `E6` — `UNTIL` `(c – )`, executes continuation `c`, then pops an integer `x` from the resulting stack. If `x` is zero, performs another iteration of this loop. Implemented with extraordinary continuation `ec_until`. -* `E7` — `UNTILEND` `( – )`, similar to `UNTIL`, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs a `RET`. -* `E8` — `WHILE` `(c0 c – )`, executes `c0` and pops an integer `x` from the resulting stack. If `x = 0`, exits the loop and transfers control to the original `cc`. If `x ≠ 0`, executes `c`, and then begins a new iteration. -* `E9` — `WHILEEND` `(c0 – )`, similar to `WHILE`, but uses the current continuation `cc` as the loop body. -* `EA` — `AGAIN` `(c – )`, similar to `REPEAT`, but executes `c` infinitely many times. A `RET` only begins a new iteration of the infinite loop, which can be exited only by an exception, or a `RETALT` (or an explicit `JMPX`). -* `EB` — `AGAINEND` `( – )`, similar to `AGAIN`, but performed with respect to the current continuation `cc`. -* `E314` — `REPEATBRK` `(n c – )`, similar to `REPEAT`, but also sets `c1` to the original `cc` after saving the old value of `c1` into the savelist of the original `cc`. In this way `RETALT` could be used to break out of the loop body. -* `E315` — `REPEATENDBRK` `(n – )`, similar to `REPEATEND`, but also sets `c1` to the original `c0` after saving the old value of `c1` into the savelist of the original `c0`. Equivalent to `SAMEALTSAVE; REPEATEND`. -* `E316` — `UNTILBRK` `(c – )`, similar to `UNTIL`, but also modifies `c1` in the same way as `REPEATBRK`. -* `E317` — `UNTILENDBRK` `( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. -* `E318` — `WHILEBRK` `(c0 c – )`, similar to `WHILE`, but also modifies `c1` in the same way as `REPEATBRK`. -* `E319` — `WHILEENDBRK` `(c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. -* `E31A` — `AGAINBRK` `(c – )`, similar to `AGAIN`, but also modifies `c1` in the same way as `REPEATBRK`. -* `E31B` — `AGAINENDBRK` `( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. +* `CF0Acc` — `STIR cc + 1 (b x – b′)`, equivalent to `SWAP; STI cc + 1`. +* `CF0Bcc` — `STUR cc + 1 (b x – b′)`, equivalent to `SWAP; STU cc + 1`. ---- -## A.9 Exception generating and handling primitives +* `CF0Ccc` — `STIQ cc + 1 (x b – x b f or b′ 0)`. -### A.9.1. Throwing exceptions +* `CF0Dcc` — `STUQ cc + 1 (x b – x b f or b′ 0)`. -* `F22_nn` — `THROW nn` `( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. -* `F26_nn` — `THROWIF nn` `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. -* `F2A_nn` — `THROWIFNOT nn` `(f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. -* `F2C4_nn` — `THROW nn` for `0 ≤ nn < 2^11`, an encoding of `THROW nn` for larger values. -* `F2CC_nn` — `THROWARG nn` `(x – x nn)`, throws exception `0 ≤ nn < 2^11` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. -* `F2D4_nn` — `THROWIF nn` `(f – )` for `0 ≤ nn < 2^11`. -* `F2DC_nn` — `THROWARGIF nn` `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f ≠ 0`. -* `F2E4_nn` — `THROWIFNOT nn` `(f – )` for `0 ≤ nn < 2^11`. -* `F2EC_nn` — `THROWARGIFNOT nn` `(x f – )`, throws exception `0 ≤ nn < 2^11` with parameter `x` only if integer `f = 0`. -* `F2F0` — `THROWANY` `(n – 0 n)`, throws exception `0 ≤ n < 2^16` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. -* `F2F1` — `THROWARGANY` `(x n – x n)`, throws exception `0 ≤ n < 2^16` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. -* `F2F2` — `THROWANYIF` `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f ≠ 0`. -* `F2F3` — `THROWARGANYIF` `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f ≠ 0`. -* `F2F4` — `THROWANYIFNOT` `(n f – )`, throws exception `0 ≤ n < 2^16` with parameter zero only if `f = 0`. -* `F2F5` — `THROWARGANYIFNOT` `(x n f – )`, throws exception `0 ≤ n < 2^16` with parameter `x` only if `f = 0`. +* `CF0Ecc` — `STIRQ cc + 1 (b x – b x f or b′ 0)`. -### A.9.2. Catching and handling exceptions +* `CF0Fcc` — `STURQ cc + 1 (b x – b x f or b′ 0)`. -* `F2FF` — `TRY` `(c c0 – )`, sets `c2` to `c0`, saving the old value of `c2` both into the savelist of `c0` and into the savelist of the current continuation. Then runs `c`. If `c` does not throw any exceptions, the original value of `c2` is restored. If an exception occurs, execution is transferred to `c0`. -* `F3pr` — `TRYARGS p,r` `(c c0 – )`, similar to `TRY`, but with `CALLARGS p,r` internally used instead of `EXECUTE`. +* `CF10` — a longer version of `STREF (c b – b′)`. ---- +* `CF11` — `STBREF (b′ b – b′′)`, equivalent to `SWAP; STBREFREV`. -# A.10 Dictionary manipulation primitives +* `CF12` — a longer version of `STSLICE (s b – b′)`. -TVM’s dictionary support is discussed at length in 3.3. The basic operations with dictionaries are listed in 3.3.10, while the taxonomy of dictionary -115 -A.10. Dictionary manipulation primitives -manipulation primitives is provided in 3.3.11. Here we use the concepts and notation introduced in those sections. +* `CF13` — `STB (b′ b – b′′)`, appends all data from Builder `b′` to Builder `b`. -Dictionaries admit two different representations as TVM stack values: +* `CF14` — `STREFR (b c – b′)`. -* A `Slice` `s` with a serialization of a TL-B value of type `HashmapE(n, X)`. In other words, `s` consists either of one bit equal to zero (if the dictionary is empty), or of one bit equal to one and a reference to a `Cell` containing the root of the binary tree, i.e., a serialized value of type `Hashmap(n, X)`. -* A “maybe `Cell`” `c ?`, i.e., a value that is either a `Cell` (containing a serialized value of type `Hashmap(n, X)` as before) or a `Null` (corresponding to an empty dictionary). When a “maybe `Cell`” `c ?` is used to represent a dictionary, we usually denote it by `D` in the stack notation. +* `CF15` — `STBREFR (b b′ – b′′)`, a longer encoding of `STBREFR`. -Most of the dictionary primitives listed below accept and return dictionaries in the second form, which is more convenient for stack manipulation. However, serialized dictionaries inside larger TL-B objects use the first representation. +* `CF16` — `STSLICER (b s – b′)`. -Opcodes starting with `F4` and `F5` are reserved for dictionary operations. +* `CF17` — `STBR (b b′ – b′′)`, concatenates two Builders, equivalent to `SWAP; STB`. -### A.10.1. Dictionary creation. +* `CF18` — `STREFQ (c b – c b−1 or b′ 0)`. -* `6D` — `NEWDICT` `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for `PUSHNULL`, cf. A.3.1. -* `6E` — `DICTEMPTY` `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for `ISNULL`, cf. A.3.1. +* `CF19` — `STBREFQ (b′ b – b′ b−1 or b′′ 0)`. ---- +* `CF1A` — `STSLICEQ (s b – s b−1 or b′ 0)`. -### A.10.2. Dictionary serialization and deserialization. +* `CF1B` — `STBQ (b′ b – b′ b−1 or b′′ 0)`. -* `CE` — `STDICTS` `(s b – b 0)`, stores a `Slice`-represented dictionary `s` into `Builder` `b`. It is actually a synonym for `STSLICE`. -* `F400` — `STDICT` or `STOPTREF` `(D b – b 0)`, stores dictionary `D` into `Builder` `b`, returing the resulting `Builder` `b 0`. In other words, if `D` is a cell, performs `STONE` and `STREF`; if `D` is `Null`, performs `NIP` and `STZERO`; otherwise throws a type checking exception. -* `F401` — `SKIPDICT` or `SKIPOPTREF` `(s – s 0)`, equivalent to `LDDICT`; `NIP` -* `F402` — `LDDICTS` `(s – s 0 s 00)`, loads (parses) a (`Slice`-represented) dictionary `s 0` from `Slice` `s`, and returns the remainder of `s` as `s 00`. This is a “split function” for all `HashmapE(n, X)` dictionary types. -* `F403` — `PLDDICTS` `(s – s 0)`, preloads a (`Slice`-represented) dictionary `s 0` from `Slice` `s`. Approximately equivalent to `LDDICTS`; `DROP`. -* `F404` — `LDDICT` or `LDOPTREF` `(s – D s0)`, loads (parses) a dictionary `D` from `Slice` `s`, and returns the remainder of `s` as `s 0`. May be applied to dictionaries or to values of arbitrary `(ˆY ) ?` types. -* `F405` — `PLDDICT` or `PLDOPTREF` `(s – D)`, preloads a dictionary `D` from `Slice` `s`. Approximately equivalent to `LDDICT`; `DROP`. -* `F406` — `LDDICTQ` `(s – D s0 −1 or s 0)`, a quiet version of `LDDICT`. -* `F407` — `PLDDICTQ` `(s – D −1 or 0)`, a quiet version of `PLDDICT`. +* `CF1C` — `STREFRQ (b c – b c−1 or b′ 0)`. +* `CF1D` — `STBREFRQ (b b′ – b b′−1 or b′′ 0)`. -### A.10.3. Get dictionary operations. +* `CF1E` — `STSLICERQ (b s – b s−1 or b′′ 0)`. -* `F40A` — `DICTGET` `(k D n – x −1 or 0)`, looks up key `k` (represented by a `Slice`, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the value found as a `Slice` `x`. -* `F40B` — `DICTGETREF` `(k D n – c −1 or 0)`, similar to `DICTGET`, but with a `LDREF`; `ENDS` applied to `x` on success. This operation is useful for dictionaries of type `HashmapE(n, ˆY )`. -* `F40C` — `DICTIGET` `(i D n – x −1 or 0)`, similar to `DICTGET`, but with a signed (big-endian) n-bit `Integer` `i` as a key. If `i` does not fit into n bits, returns `0`. If `i` is a `NaN`, throws an integer overflow exception. -* `F40D` — `DICTIGETREF` `(i D n – c −1 or 0)`, combines `DICTIGET` with `DICTGETREF`: it uses signed n-bit `Integer` `i` as a key and returns a `Cell` instead of a `Slice` on success. -* `F40E` — `DICTUGET` `(i D n – x −1 or 0)`, similar to `DICTIGET`, but with unsigned (big-endian) n-bit `Integer` `i` used as a key. -* `F40F` — `DICTUGETREF` `(i D n – c −1 or 0)`, similar to `DICTIGETREF`, but with an unsigned n-bit `Integer` key `i`. +* `CF1F` — `STBRQ (b b′ – b b′−1 or b′′ 0)`. +* `CF20` — `STREFCONST`, equivalent to `PUSHREF; STREFR`. -## A.10.4. Set/Replace/Add dictionary operations. +* `CF21` — `STREF2CONST`, equivalent to `STREFCONST; STREFCONST`. -The mnemonics of the following dictionary primitives are constructed in a systematic fashion according to the regular expression `DICT[, I, U](SET, REPLACE, ADD)[GET][REF]` depending on the type of the key used (a `Slice` or a signed or unsigned `Integer`), the dictionary operation to be performed, and the way the values are accepted and returned (as `Cells` or as `Slices`). Therefore, we provide a detailed description only for some primitives, assuming that this information is sufficient for the reader to understand the precise action of the remaining primitives. +* `CF23` — `ENDXC (b x – c)`, if `x ≠ 0`, creates a special or exotic cell + (cf. [3.1.2](#3-1-2-ordinary-and-exotic-cells)) from Builder `b`. + - The type of the exotic cell must be stored in the first 8 bits of `b`. + - If `x = 0`, it is equivalent to `ENDC`. + - Otherwise some validity checks on the data and references of `b` are + performed before creating the exotic cell. -* `F412` — `DICTSET` `(x k D n – D0)`, sets the value associated with n-bit key `k` (represented by a `Slice` as in `DICTGET`) in dictionary `D` (also represented by a `Slice`) to value `x` (again a `Slice`), and returns the resulting dictionary as `D0`. -* `F413` — `DICTSETREF` `(c k D n – D0)`, similar to `DICTSET`, but with the value set to a reference to `Cell` `c`. -* `F414` — `DICTISET` `(x i D n – D0)`, similar to `DICTSET`, but with the key represented by a (big-endian) signed n-bit integer `i`. If `i` does not fit into n bits, a range check exception is generated. -* `F415` — `DICTISETREF` `(c i D n – D0)`, similar to `DICTSETREF`, but with the key a signed n-bit integer as in `DICTISET`. -* `F416` — `DICTUSET` `(x i D n – D0)`, similar to `DICTISET`, but with `i` an unsigned n-bit integer. -* `F417` — `DICTUSETREF` `(c i D n – D0)`, similar to `DICTISETREF`, but with `i` unsigned. -* `F41A` — `DICTSETGET` `(x k D n – D0 y −1 or D0 0)`, combines `DICTSET` with `DICTGET`: it sets the value corresponding to key `k` to `x`, but also returns the old value `y` associated with the key in question, if present. -* `F41B` — `DICTSETGETREF` `(c k D n – D0 c 0 −1 or D0 0)`, combines `DICTSETREF` with `DICTGETREF` similarly to `DICTSETGET`. -* `F41C` — `DICTISETGET` `(x i D n – D0 y −1 or D0 0)`, similar to `DICTSETGET`, but with the key represented by a big-endian signed n-bit `Integer` `i` -* `F41D` — `DICTISETGETREF` `(c i D n – D0 c 0 −1 or D0 0)`, a version of `DICTSETGETREF` with signed `Integer` `i` as a key. -* `F41E` — `DICTUSETGET` `(x i D n – D0 y −1 or D0 0)`, similar to `DICTISETGET`, but with `i` an unsigned n-bit integer. -* `F41F` — `DICTUSETGETREF` `(c i D n – D0 c 0 −1 or D0 0)`. -* `F422` — `DICTREPLACE` `(x k D n – D0 −1 or D 0)`, a Replace operation, which is similar to `DICTSET`, but sets the value of key `k` in dictionary `D` to `x` only if the key `k` was already present in `D`. -* `F423` — `DICTREPLACEREF` `(c k D n – D0 −1 or D 0)`, a Replace counterpart of `DICTSETREF`. -* `F424` — `DICTIREPLACE` `(x i D n – D0 −1 or D 0)`, a version of `DICTREPLACE` with signed n-bit `Integer` `i` used as a key. -* `F425` — `DICTIREPLACEREF` `(c i D n – D0 −1 or D 0)`. -* `F426` — `DICTUREPLACE` `(x i D n – D0 −1 or D 0)`. -* `F427` — `DICTUREPLACEREF` `(c i D n – D0 −1 or D 0)`. -* `F42A` — `DICTREPLACEGET` `(x k D n – D0 y −1 or D 0)`, a Replace counterpart of `DICTSETGET`: on success, also returns the old value associated with the key in question. -* `F42B` — `DICTREPLACEGETREF` `(c k D n – D0 c 0 −1 or D 0)`. -* `F42C` — `DICTIREPLACEGET` `(x i D n – D0 y −1 or D 0)`. -* `F42D` — `DICTIREPLACEGETREF` `(c i D n – D0 c 0 −1 or D 0)`. -* `F42E` — `DICTUREPLACEGET` `(x i D n – D0 y −1 or D 0)`. -* `F42F` — `DICTUREPLACEGETREF` `(c i D n – D0 c 0 −1 or D 0)`. -* `F432` — `DICTADD` `(x k D n – D0 −1 or D 0)`, an Add counterpart of `DICTSET`: sets the value associated with key `k` in dictionary `D` to `x`, but only if it is not already present in `D`. -* `F433` — `DICTADDREF` `(c k D n – D0 −1 or D 0)`. -* `F434` — `DICTIADD` `(x i D n – D0 −1 or D 0)`. -* `F435` — `DICTIADDREF` `(c i D n – D0 −1 or D 0)`. -* `F436` — `DICTUADD` `(x i D n – D0 −1 or D 0)`. -* `F437` — `DICTUADDREF` `(c i D n – D0 −1 or D 0)`. -* `F43A` — `DICTADDGET` `(x k D n – D0 −1 or D y 0)`, an Add counterpart of `DICTSETGET`: sets the value associated with key `k` in dictionary `D` to `x`, but only if key `k` is not already present in `D`. Otherwise, just returns the old value `y` without changing the dictionary. -* `F43B` — `DICTADDGETREF` `(c k D n – D0 −1 or D c0 0)`, an Add counterpart of `DICTSETGETREF`. -* `F43C` — `DICTIADDGET` `(x i D n – D0 −1 or D y 0)`. -* `F43D` — `DICTIADDGETREF` `(c i D n – D0 −1 or D c0 0)`. -* `F43E` — `DICTUADDGET` `(x i D n – D0 −1 or D y 0)`. -* `F43F` — `DICTUADDGETREF` `(c i D n – D0 −1 or D c0 0)`. +* `CF28` — `STILE4 (x b – b′)`, stores a little-endian signed 32-bit integer. +* `CF29` — `STULE4 (x b – b′)`, stores a little-endian unsigned 32-bit integer. -### A.10.5. Builder-accepting variants of Set dictionary operations. +* `CF2A` — `STILE8 (x b – b′)`, stores a little-endian signed 64-bit integer. -The following primitives accept the new value as a `Builder` `b` instead of a `Slice` `x`, which often is more convenient if the value needs to be serialized from several components computed in the stack. (This is reflected by appending a `B` to the mnemonics of the corresponding Set primitives that work with `Slices`.) The net effect is roughly equivalent to converting `b` into a `Slice` by `ENDC`; `CTOS` and executing the corresponding primitive listed in A.10.4. - -* `F441` — `DICTSETB` `(b k D n – D0)`. -* `F442` — `DICTISETB` `(b i D n – D0)`. -* `F443` — `DICTUSETB` `(b i D n – D0)`. -* `F445` — `DICTSETGETB` `(b k D n – D0 y −1 or D0 0)`. -* `F446` — `DICTISETGETB` `(b i D n – D0 y −1 or D0 0)`. -* `F447` — `DICTUSETGETB` `(b i D n – D0 y −1 or D0 0)`. -* `F449` — `DICTREPLACEB` `(b k D n – D0 −1 or D 0)`. -* `F44A` — `DICTIREPLACEB` `(b i D n – D0 −1 or D 0)`. -* `F44B` — `DICTUREPLACEB` `(b i D n – D0 −1 or D 0)`. -* `F44D` — `DICTREPLACEGETB` `(b k D n – D0 y −1 or D 0)`. -* `F44E` — `DICTIREPLACEGETB` `(b i D n – D0 y −1 or D 0)`. -* `F44F` — `DICTUREPLACEGETB` `(b i D n – D0 y −1 or D 0)`. -* `F451` — `DICTADDB` `(b k D n – D0 −1 or D 0)`. -* `F452` — `DICTIADDB` `(b i D n – D0 −1 or D 0)`. -* `F453` — `DICTUADDB` `(b i D n – D0 −1 or D 0)`. -* `F455` — `DICTADDGETB` `(b k D n – D0 −1 or D y 0)`. -* `F456` — `DICTIADDGETB` `(b i D n – D0 −1 or D y 0)`. -* `F457` — `DICTUADDGETB` `(b i D n – D0 −1 or D y 0)`. +* `CF2B` — `STULE8 (x b – b′)`, stores a little-endian unsigned 64-bit integer. ---- +* `CF30` — `BDEPTH (b – x)`, returns the depth of Builder `b`. If no cell + references are stored in `b`, then `x = 0`; otherwise `x` is one plus the + maximum of depths of cells referred to from `b`. -### A.10.6. Delete dictionary operations. +* `CF31` — `BBITS (b – x)`, returns the number of data bits already stored + in Builder `b`. -* `F459` — `DICTDEL` `(k D n – D0 −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0` and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. -* `F45A` — `DICTIDEL` `(i D n – D0 ?)`, a version of `DICTDEL` with the key represented by a signed n-bit `Integer` `i`. If `i` does not fit into n bits, simply returns `D 0` (“key not found, dictionary unmodified”). -* `F45B` — `DICTUDEL` `(i D n – D0 ?)`, similar to `DICTIDEL`, but with `i` an unsigned n-bit integer. -* `F462` — `DICTDELGET` `(k D n – D0 x −1 or D 0)`, deletes n-bit key, represented by a `Slice` `k`, from dictionary `D`. If the key is present, returns the modified dictionary `D0`, the original value `x` associated with the key `k` (represented by a `Slice`), and the success flag `−1`. Otherwise, returns the original dictionary `D` and `0`. -* `F463` — `DICTDELGETREF` `(k D n – D0 c −1 or D 0)`, similar to `DICTDELGET`, but with `LDREF`; `ENDS` applied to `x` on success, so that the value returned `c` is a `Cell`. -* `F464` — `DICTIDELGET` `(i D n – D0 x −1 or D 0)`, a variant of primitive `DICTDELGET` with signed n-bit integer `i` as a key. -* `F465` — `DICTIDELGETREF` `(i D n – D0 c −1 or D 0)`, a variant of primitive `DICTIDELGET` returning a `Cell` instead of a `Slice`. -* `F466` — `DICTUDELGET` `(i D n – D0 x −1 or D 0)`, a variant of primitive `DICTDELGET` with unsigned n-bit integer `i` as a key. -* `F467` — `DICTUDELGETREF` `(i D n – D0 c −1 or D 0)`, a variant of primitive `DICTUDELGET` returning a `Cell` instead of a `Slice`. +* `CF32` — `BREFS (b – y)`, returns the number of cell references already + stored in `b`. +* `CF33` — `BBITREFS (b – x y)`, returns the numbers of both data bits and + cell references in `b`. -### A.10.7. “Maybe reference” dictionary operations. +* `CF35` — `BREMBITS (b – x′)`, returns the number of data bits that can + still be stored in `b`. -The following operations assume that a dictionary is used to store values `c ?` of type `Cell ?` (“Maybe `Cell`”), which can be used in particular to store dictionaries as values in other dictionaries. The representation is as follows: if `c ?` is a `Cell`, it is stored as a value with no data bits and exactly one reference to this `Cell`. If `c ?` is `Null`, then the corresponding key must be absent from the dictionary altogether. +* `CF36` — `BREMREFS (b – y′)`. -* `F469` — `DICTGETOPTREF` `(k D n – c ? )`, a variant of `DICTGETREF` that returns `Null` instead of the value `c ?` if the key `k` is absent from dictionary `D`. -* `F46A` — `DICTIGETOPTREF` `(i D n – c ? )`, similar to `DICTGETOPTREF`, but with the key given by signed n-bit `Integer` `i`. If the key `i` is out of range, also returns `Null`. -* `F46B` — `DICTUGETOPTREF` `(i D n – c ? )`, similar to `DICTGETOPTREF`, but with the key given by unsigned n-bit `Integer` `i`. -* `F46D` — `DICTSETGETOPTREF` `(c ? k D n – D0 c˜ ? )`, a variant of both `DICTGETOPTREF` and `DICTSETGETREF` that sets the value corresponding to key `k` in dictionary `D` to `c ?` (if `c ?` is `Null`, then the key is deleted instead), and returns the old value `c˜ ?` (if the key `k` was absent before, returns `Null` instead). -* `F46E` — `DICTISETGETOPTREF` `(c ? i D n – D0 c˜ ? )`, similar to primitive `DICTSETGETOPTREF`, but using signed n-bit `Integer` `i` as a key. If `i` does not fit into n bits, throws a range checking exception. -* `F46F` — `DICTUSETGETOPTREF` `(c ? i D n – D0 c˜ ? )`, similar to primitive `DICTSETGETOPTREF`, but using unsigned n-bit `Integer` `i` as a key. +* `CF37` — `BREMBITREFS (b – x′ y′)`. +* `CF38cc` — `BCHKBITS cc + 1 (b – )`, checks whether `cc + 1` bits can be + stored into `b`, where `0 ≤ cc ≤ 255`. -### A.10.8. Prefix code dictionary operations. +* `CF39` — `BCHKBITS (b x – )`, checks whether `x` bits can be stored into `b`, + `0 ≤ x ≤ 1023`. If there is no space for `x` more bits in `b`, or if `x` is not + within the range, throws an exception. -These are some basic operations for constructing prefix code dictionaries (cf. 3.4.2). The primary application for prefix code dictionaries is deserializing TL-B serialized data structures, or, more generally, parsing prefix codes. Therefore, most prefix code dictionaries will be constant and created at compile time, not by the following primitives. -Some Get operations for prefix code dictionaries may be found in A.10.11. -Other prefix code dictionary operations include: +* `CF3A` — `BCHKREFS (b y – )`, checks whether `y` references can be stored + into `b`, `0 ≤ y ≤ 7`. -* `F470` — `PFXDICTSET` `(x k D n – D0 −1 or D 0)`. -* `F471` — `PFXDICTREPLACE` `(x k D n – D0 −1 or D 0)`. -* `F472` — `PFXDICTADD` `(x k D n – D0 −1 or D 0)`. -* `F473` — `PFXDICTDEL` `(k D n – D0 −1 or D 0)`. +* `CF3B` — `BCHKBITREFS (b x y – )`, checks whether `x` bits and `y` + references can be stored into `b`, `0 ≤ x ≤ 1023`, `0 ≤ y ≤ 7`. -These primitives are completely similar to their non-prefix code counterparts `DICTSET` etc (cf. A.10.4), with the obvious difference that even a Set may fail in a prefix code dictionary, so a success flag must be returned by `PFXDICTSET` as well. +* `CF3Ccc` — `BCHKBITSQ cc + 1 (b – ? )`, checks whether `cc + 1` bits can + be stored into `b`, where `0 ≤ cc ≤ 255`. -### A.10.9. Variants of GetNext and GetPrev operations. +* `CF3D` — `BCHKBITSQ (b x – ? )`, checks whether `x` bits can be stored into + `b`, `0 ≤ x ≤ 1023`. -* `F474` — `DICTGETNEXT` `(k D n – x 0 k 0 −1 or 0)`, computes the minimal key `k 0` in dictionary `D` that is lexicographically greater than `k`, and returns `k 0` (represented by a `Slice`) along with associated value `x 0` (also represented by a `Slice`). -* `F475` — `DICTGETNEXTEQ` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETNEXT`, but computes the minimal key `k 0` that is lexicographically greater than or equal to `k`. -* `F476` — `DICTGETPREV` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETNEXT`, but computes the maximal key `k 0` lexicographically smaller than `k`. -* `F477` — `DICTGETPREVEQ` `(k D n – x 0 k 0 −1 or 0)`, similar to `DICTGETPREV`, but computes the maximal key `k 0` lexicographically smaller than or equal to `k`. -* `F478` — `DICTIGETNEXT` `(i D n – x 0 i 0 −1 or 0)`, similar to `DICTGETNEXT`, but interprets all keys in dictionary `D` as big-endian signed n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits). -* `F479` — `DICTIGETNEXTEQ` `(i D n – x 0 i 0 −1 or 0)`. -* `F47A` — `DICTIGETPREV` `(i D n – x 0 i 0 −1 or 0)`. -* `F47B` — `DICTIGETPREVEQ` `(i D n – x 0 i 0 −1 or 0)`. -* `F47C` — `DICTUGETNEXT` `(i D n – x 0 i 0 −1 or 0)`, similar to `DICTGETNEXT`, but interprets all keys in dictionary `D` as big-endian unsigned n-bit integers, and computes the minimal key `i 0` that is larger than `Integer` `i` (which does not necessarily fit into n bits, and is not necessarily nonnegative). -* `F47D` — `DICTUGETNEXTEQ` `(i D n – x 0 i 0 −1 or 0)`. -* `F47E` — `DICTUGETPREV` `(i D n – x 0 i 0 −1 or 0)`. -* `F47F` — `DICTUGETPREVEQ` `(i D n – x 0 i 0 −1 or 0)`. +* `CF3E` — `BCHKREFSQ (b y – ? )`, checks whether `y` references can be stored + into `b`, `0 ≤ y ≤ 7`. -### A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. +* `CF3F` — `BCHKBITREFSQ (b x y – ? )`, checks whether `x` bits and `y` + references can be stored into `b`, `0 ≤ x ≤ 1023`, `0 ≤ y ≤ 7`. -* `F482` — `DICTMIN` `(D n – x k −1 or 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. -* `F483` — `DICTMINREF` `(D n – c k −1 or 0)`, similar to `DICTMIN`, but returns the only reference in the value as a `Cell` `c`. -* `F484` — `DICTIMIN` `(D n – x i −1 or 0)`, somewhat similar to `DICTMIN`, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by `DICTMIN` and `DICTUMIN` -* `F485` — `DICTIMINREF` `(D n – c i −1 or 0)`. -* `F486` — `DICTUMIN` `(D n – x i −1 or 0)`, similar to `DICTMIN`, but returns the key as an unsigned n-bit `Integer` `i`. -* `F487` — `DICTUMINREF` `(D n – c i −1 or 0)`. -* `F48A` — `DICTMAX` `(D n – x k −1 or 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, and returns `k` along with the associated value `x`. -* `F48B` — `DICTMAXREF` `(D n – c k −1 or 0)`. -* `F48C` — `DICTIMAX` `(D n – x i −1 or 0)`. -* `F48D` — `DICTIMAXREF` `(D n – c i −1 or 0)`. -* `F48E` — `DICTUMAX` `(D n – x i −1 or 0)`. -* `F48F` — `DICTUMAXREF` `(D n – c i −1 or 0)`. -* `F492` — `DICTREMMIN` `(D n – D0 x k −1 or D 0)`, computes the minimal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. -* `F493` — `DICTREMMINREF` `(D n – D0 c k −1 or D 0)`, similar to `DICTREMMIN`, but returns the only reference in the value as a `Cell` `c`. -* `F494` — `DICTIREMMIN` `(D n – D0 x i −1 or D 0)`, somewhat similar to `DICTREMMIN`, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by `DICTREMMIN` and `DICTUREMMIN`. -* `F495` — `DICTIREMMINREF` `(D n – D0 c i −1 or D 0)`. -* `F496` — `DICTUREMMIN` `(D n – D0 x i −1 or D 0)`, similar to `DICTREMMIN`, but returns the key as an unsigned n-bit `Integer` `i`. -* `F497` — `DICTUREMMINREF` `(D n – D0 c i −1 or D 0)`. -* `F49A` — `DICTREMMAX` `(D n – D0 x k −1 or D 0)`, computes the maximal key `k` (represented by a `Slice` with `n` data bits) in dictionary `D`, removes `k` from the dictionary, and returns `k` along with the associated value `x` and the modified dictionary `D0`. -* `F49B` — `DICTREMMAXREF` `(D n – D0 c k −1 or D 0)`. -* `F49C` — `DICTIREMMAX` `(D n – D0 x i −1 or D 0)`. -* `F49D` — `DICTIREMMAXREF` `(D n – D0 c i −1 or D 0)`. -* `F49E` — `DICTUREMMAX` `(D n – D0 x i −1 or D 0)`. -* `F49F` — `DICTUREMMAXREF` `(D n – D0 c i −1 or D 0)`. +* `CF40` — `STZEROES (b n – b′)`, stores `n` binary zeroes into Builder `b`. -### A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. +* `CF41` — `STONES (b n – b′)`, stores `n` binary ones into Builder `b`. -* `F4A0` — `DICTIGETJMP` `(i D n – )`, similar to `DICTIGET` (cf. A.10.12), but with `x` `BLESS`ed into a continuation with a subsequent `JMPX` to it on success. On failure, does nothing. This is useful for implementing switch/case constructions. -* `F4A1` — `DICTUGETJMP` `(i D n – )`, similar to `DICTIGETJMP`, but performs `DICTUGET` instead of `DICTIGET`. -* `F4A2` — `DICTIGETEXEC` `(i D n – )`, similar to `DICTIGETJMP`, but with `EXECUTE` instead of `JMPX`. -* `F4A3` — `DICTUGETEXEC` `(i D n – )`, similar to `DICTUGETJMP`, but with `EXECUTE` instead of `JMPX`. -* `F4A6_n` — `DICTPUSHCONST n` `( – D n)`, pushes a non-empty constant dictionary `D` (as a `Cell ?`) along with its key length `0 ≤ n ≤ 1023`, stored as a part of the instruction. The dictionary itself is created from the first of remaining references of the current continuation. In this way, the complete `DICTPUSHCONST` instruction can be obtained by first serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and a cell reference), and then the unsigned 10-bit integer `n` (as if by a `STU 10` instruction). An empty dictionary can be pushed by a `NEWDICT` primitive (cf. A.10.1) instead. -* `F4A8` — `PFXDICTGETQ` `(s D n – s 0 x s00 −1 or s 0)`, looks up the unique prefix of `Slice` `s` present in the prefix code dictionary (cf. 3.4.2) represented by `Cell ?` `D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is returned as `s 0`, and the corresponding value (also a `Slice`) as `x`. The remainder of `s` is returned as a `Slice` `s 00`. If no prefix of `s` is a key in prefix code dictionary `D`, returns the unchanged `s` and a zero flag to indicate failure. -* `F4A9` — `PFXDICTGET` `(s D n – s 0 x s00)`, similar to `PFXDICTGET`, but throws a cell deserialization failure exception on failure. -* `F4AA` — `PFXDICTGETJMP` `(s D n – s 0 s 00 or s)`, similar to `PFXDICTGETQ`, but on success `BLESS`es the value `x` into a `Continuation` and transfers control to it as if by a `JMPX`. On failure, returns `s` unchanged and continues execution. -* `F4AB` — `PFXDICTGETEXEC` `(s D n – s 0 s 00)`, similar to `PFXDICTGETJMP`, but `EXEC`utes the continuation found instead of jumping to it. On failure, throws a cell deserialization exception. -* `F4AE_n` — `PFXDICTCONSTGETJMP n` or `PFXDICTSWITCH n` `(s – s 0 s 00 or s)`, combines `DICTPUSHCONST n` for `0 ≤ n ≤ 1023` with `PFXDICTGETJMP`. -* `F4BC` — `DICTIGETJMPZ` `(i D n – i or nothing)`, a variant of `DICTIGETJMP` that returns index `i` on failure. -* `F4BD` — `DICTUGETJMPZ` `(i D n – i or nothing)`, a variant of `DICTUGETJMP` that returns index `i` on failure. -* `F4BE` — `DICTIGETEXECZ` `(i D n – i or nothing)`, a variant of `DICTIGETEXEC` that returns index `i` on failure. -* `F4BF` — `DICTUGETEXECZ` `(i D n – i or nothing)`, a variant of `DICTUGETEXEC` that returns index `i` on failure. - -### A.10.12. SubDict dictionary operations. - -* `F4B1` — `SUBDICTGET` `(k l D n – D0)`, constructs a subdictionary consisting of all keys beginning with prefix `k` (represented by a `Slice`, the first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` in dictionary `D` of type `HashmapE(n, X)` with n-bit keys. On success, returns the new subdictionary of the same type `HashmapE(n, X)` as a `Slice` `D0`. -* `F4B2` — `SUBDICTIGET` `(x l D n – D0)`, variant of `SUBDICTGET` with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. -* `F4B3` — `SUBDICTUGET` `(x l D n – D0)`, variant of `SUBDICTGET` with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. -* `F4B5` — `SUBDICTRPGET` `(k l D n – D0)`, similar to `SUBDICTGET`, but removes the common prefix `k` from all keys of the new dictionary `D0`, which becomes of type `HashmapE(n − l, X)`. -* `F4B6` — `SUBDICTIRPGET` `(x l D n – D0)`, variant of `SUBDICTRPGET` with the prefix represented by a signed big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 257`. -* `F4B7` — `SUBDICTURPGET` `(x l D n – D0)`, variant of `SUBDICTRPGET` with the prefix represented by an unsigned big-endian `l`-bit `Integer` `x`, where necessarily `l ≤ 256`. -* `F4BC–F4BF` — used by `DICT...Z` primitives in A.10.11. +* `CF42` — `STSAME (b n x – b′)`, stores `n` binary `x`s (`0 ≤ x ≤ 1`) into + Builder `b`. ---- +* `CF81` — `STSLICECONST '0'` or `STZERO (b – b′)`, stores one binary zero. -# A.11 Application-specific primitives +* `CF83` — `STSLICECONST '1'` or `STONE (b – b′)`, stores one binary one. -Opcode range `F8...FB` is reserved for the application-specific primitives. When TVM is used to execute TON Blockchain smart contracts, these application-specific primitives are in fact TON Blockchain-specific. +* `CFA2` — equivalent to `STREFCONST`. -### A.11.1. External actions and access to blockchain configuration data. +* `CFA3` — almost equivalent to `STSLICECONST '1'; STREFCONST`. -Some of the primitives listed below pretend to produce some externally visible actions, such as sending a message to another smart contract. In fact, the execution of a smart contract in TVM never has any effect apart from a modification of the TVM state. All external actions are collected into a linked list stored in special register `c5` (“output actions”). Additionally, some primitives use the data kept in the first component of the Tuple stored in `c7` (“root of temporary data”, cf. 1.3.2). Smart contracts are free to modify any other data kept in the cell `c7`, provided the first reference remains intact (otherwise some application-specific primitives would be likely to throw exceptions when invoked). +* `CFC0_xysss` — `STSLICECONST sss (b – b′)`, stores a constant subslice + `sss` consisting of `0 ≤ x ≤ 3` references and up to `8y + 1` data bits, with + `0 ≤ y ≤ 7`. Completion bit is assumed. -Most of the primitives listed below use 16-bit opcodes. +* `CFC2` — equivalent to `STREF2CONST`. -### A.11.2. Gas-related primitives. +* `CFE2` — `STREF3CONST`. -Of the following primitives, only the first two are “pure” in the sense that they do not use `c5` or `c7`. +### A.7.2. Cell deserialization primitives -* `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. 1.4), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence no gas) with themselves. -* `F801` — `SETGASLIMIT` `(g – )`, sets current gas limit `gl` to the minimum of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed so far (including the present instruction) exceeds the resulting value of `gl`, an (unhandled) out of gas exception is thrown before setting new gas limits. Notice that `SETGASLIMIT` with an argument `g ≥ 2^63 − 1` is equivalent to `ACCEPT`. -* `F802` — `BUYGAS` `(x – )`, computes the amount of gas that can be bought for `x` nanograms, and sets `gl` accordingly in the same way as `SETGASLIMIT`. -* `F804` — `GRAMTOGAS` `(x – g)`, computes the amount of gas that can be bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `2^63−1`, it is replaced with this value. -* `F805` — `GASTOGRAM` `(g – x)`, computes the price of `g` gas in nanograms. -* `F806–F80E` — Reserved for gas-related primitives. -* `F80F` — `COMMIT` `( – )`, commits the current state of registers `c4` (“persistent data”) and `c5` (“actions”) so that the current execution is considered “successful” with the saved values even if an exception is thrown later. +* `D0` — `CTOS (c– s)`, converts a Cell into a Slice. Notice that c must + be either an ordinary cell, or an exotic cell (cf. [3.1.2](#3-1-2-ordinary-and-exotic-cells)) which is au- + tomatically loaded to yield an ordinary cell c′, converted into a Slice + afterwards. ---- +* `D1` — `ENDS (s – )`, removes a Slice s from the stack, and throws an + exception if it is not empty. -### A.11.3. Pseudo-random number generator primitives. +* `D2cc` — `LDI cc+ 1 (s– x s′)`, loads (i.e., parses) a signed cc+ 1-bit + integer x from Slice s, and returns the remainder of s as s′. -The pseudo-random number generator uses the random seed (parameter `#6`, cf. A.11.4), an unsigned 256-bit `Integer`, and (sometimes) other data kept in `c7`. -The initial value of the random seed before a smart contract is executed in TON Blockchain is a hash of the smart contract address and the global block random seed. If there are several runs of the same smart contract inside a block, then all of these runs will have the same random seed. This can be fixed, for example, by running `LTIME`; `ADDRAND` before using the pseudo-random number generator for the first time. +* `D3cc` — `LDU cc+ 1 (s– x s′)`, loads an unsigned cc+ 1-bit integer x + from Slice s. -* `F810` — `RANDU256` `( – x)`, generates a new pseudo-random unsigned 256-bit `Integer` `x`. The algorithm is as follows: if `r` is the old value of the random seed, considered as a 32-byte array (by constructing the big-endian representation of an unsigned 256-bit integer), then its `sha512(r)` is computed; the first 32 bytes of this hash are stored as the new value `r'` of the random seed, and the remaining 32 bytes are returned as the next random value `x`. -* `F811` — `RAND` `(y – z)`, generates a new pseudo-random integer `z` in the range `0 ... y − 1` (or `y ... − 1`, if `y < 0`). More precisely, an unsigned random value `x` is generated as in `RAND256U`; then `z := ⌊x·y/2^256⌋` is computed. Equivalent to `RANDU256`; `MULRSHIFT` `256`. -* `F814` — `SETRAND` `(x – )`, sets the random seed to unsigned 256-bit `Integer` `x`. -* `F815` — `ADDRAND` `(x – )`, mixes unsigned 256-bit `Integer` `x` into the random seed `r` by setting the random seed to `sha256` of the concatenation of two 32-byte strings: the first with the big-endian representation of the old seed `r`, and the second with the big-endian representation of `x`. -* `F810–F81F` — Reserved for pseudo-random number generator primitives. +* `D4` — `LDREF (s– c s′)`, loads a cell reference c from s. ---- +* `D5` — `LDREFRTOS (s– s′ s′′)`, equivalent to LDREF; SWAP; CTOS. -### A.11.4. Configuration primitives. +* `D6cc` — `LDSLICE cc+ 1 (s– s′′s′)`, cuts the next cc+ 1 bits of s into a + separate Slice s′′. -The following primitives read configuration data provided in the Tuple stored in the first component of the Tuple at `c7`. Whenever TVM is invoked for executing TON Blockchain smart contracts, this Tuple is initialized by a `SmartContractInfo` structure; configuration primitives assume that it has remained intact. - -* `F82i` — `GETPARAM` `i` `( – x)`, returns the `i`-th parameter from the Tuple provided at `c7` for `0 ≤ i < 16`. Equivalent to `PUSH` `c7`; `FIRST`; `INDEX` `i`. If one of these internal operations fails, throws an appropriate type checking or range checking exception -* `F823` — `NOW` `( – x)`, returns the current Unix time as an `Integer`. If it is impossible to recover the requested value starting from `c7`, throws a type checking or range checking exception as appropriate. Equivalent to `GETPARAM` `3`. -* `F824` — `BLOCKLT` `( – x)`, returns the starting logical time of the current block. Equivalent to `GETPARAM` `4`. -* `F825` — `LTIME` `( – x)`, returns the logical time of the current transaction. Equivalent to `GETPARAM` `5`. -* `F826` — `RANDSEED` `( – x)`, returns the current random seed as an unsigned 256-bit `Integer`. Equivalent to `GETPARAM` `6`. -* `F827` — `BALANCE` `( – t)`, returns the remaining balance of the smart contract as a `Tuple` consisting of an `Integer` (the remaining Gram balance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys representing the balance of “extra currencies”). Equivalent to `GETPARAM` `7`. Note that RAW primitives such as `SENDRAWMSG` do not update this field. -* `F828` — `MYADDR` `( – s)`, returns the internal address of the current smart contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed further using primitives such as `PARSESTDADDR` or `REWRITESTDADDR`. Equivalent to `GETPARAM` `8`. -* `F829` — `CONFIGROOT` `( – D)`, returns the `Maybe Cell` `D` with the current global configuration dictionary. Equivalent to `GETPARAM` `9`. -* `F830` — `CONFIGDICT` `( – D 32)`, returns the global configuration dictionary along with its key length (`32`). Equivalent to `CONFIGROOT`; `PUSHINT` `32`. -* `F832` — `CONFIGPARAM` `(i – c −1 or 0)`, returns the value of the global configuration parameter with integer index `i` as a `Cell` `c`, and a flag to indicate success. Equivalent to `CONFIGDICT`; `DICTIGETREF`. -* `F833` — `CONFIGOPTPARAM` `(i – c ? )`, returns the value of the global configuration parameter with integer index `i` as a `Maybe Cell` `c ?`. Equivalent to `CONFIGDICT`; `DICTIGETOPTREF`. -* `F820–F83F` — Reserved for configuration primitives. +* `D700` — `LDIX (s l– x s′)`, loads a signed l-bit (0 ≤l ≤257) integer x + from Slice s, and returns the remainder of s as s′. ---- +* `D701` — `LDUX (s l– x s′)`, loads an unsigned l-bit integer x from (the + first l bits of) s, with 0 ≤l≤256. -### A.11.6. Hashing and cryptography primitives. +* `D702` — `PLDIX (s l– x)`, preloads a signed l-bit integer from Slice s, + for 0 ≤l≤257. -* `F900` — `HASHCU` `(c – x)`, computes the representation hash (cf. 3.1.5) of a `Cell` `c` and returns it as a 256-bit unsigned integer `x`. Useful for signing and checking signatures of arbitrary entities represented by a tree of cells. -* `F901` — `HASHSU` `(s – x)`, computes the hash of a `Slice` `s` and returns it as a 256-bit unsigned integer `x`. The result is the same as if an ordinary cell containing only data and references from `s` had been created and its hash computed by `HASHCU`. -* `F902` — `SHA256U` `(s – x)`, computes `sha256` of the data bits of `Slice` `s`. If the bit length of `s` is not divisible by eight, throws a cell underflow exception. The hash value is returned as a 256-bit unsigned integer `x`. -* `F910` — `CHKSIGNU` `(h s k – ? )`, checks the Ed25519-signature `s` of a hash `h` (a 256-bit unsigned integer, usually computed as the hash of some data) using public key `k` (also represented by a 256-bit unsigned integer). The signature `s` must be a `Slice` containing at least 512 databits; only the first 512 bits are used. The result is `−1` if the signature is valid, `0` otherwise. Notice that `CHKSIGNU` is equivalent to `ROT`; `NEWB`; `STU` `256`; `ENDB`; `NEWC`; `ROTREV`; `CHKSIGNS`, i.e., to `CHKSIGNS` with the first argument `d` set to 256-bit `Slice` containing `h`. Therefore, if `h` is computed as the hash of some data, these data are hashed twice, the second hashing occurring inside `CHKSIGNS`. -* `F911` — `CHKSIGNS` `(d s k – ? )`, checks whether `s` is a valid Ed25519-signature of the data portion of `Slice` `d` using public key `k`, similarly to `CHKSIGNU`. If the bit length of `Slice` `d` is not divisible by eight, throws a cell underflow exception. The verification of Ed25519 signatures is the standard one, with `sha256` used to reduce `d` to the 256-bit number that is actually signed. -* `F912–F93F` — Reserved for hashing and cryptography primitives. +* `D703` — `PLDUX (s l– x)`, preloads an unsigned l-bit integer from s, for + 0 ≤l≤256. ---- +* `D704` — `LDIXQ (s l– x s′ −1 or s 0)`, quiet version of LDIX: loads a + signed l-bit integer from ssimilarly to LDIX, but returns a success flag, + equal to−1 on success or to 0 on failure (if s does not have l bits), + instead of throwing a cell underflow exception. -### A.11.7. Miscellaneous primitives. +* `D705` — `LDUXQ (s l– x s′ −1 or s 0)`, quiet version of LDUX. -* `F940` — `CDATASIZEQ` `(c n – x y z −1 or 0)`, recursively computes the count of distinct cells `x`, data bits `y`, and cell references `z` in the dag rooted at `Cell` `c`, effectively returning the total storage used by this dag taking into account the identification of equal cells. The values of `x`, `y`, and `z` are computed by a depth-first traversal of this dag, with a hash table of visited cell hashes used to prevent visits of already-visited cells. The total count of visited cells `x` cannot exceed non-negative `Integer` `n`; otherwise the computation is aborted before visiting the `(n + 1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, returns `x = y = z = 0`. -* `F941` — `CDATASIZE` `(c n – x y z)`, a non-quiet version of `CDATASIZEQ` that throws a cell overflow exception (8) on failure. -* `F942` — `SDATASIZEQ` `(s n – x y z −1 or 0)`, similar to `CDATASIZEQ`, but accepting a `Slice` `s` instead of a `Cell`. The returned value of `x` does not take into account the cell that contains the slice `s` itself; however, the data bits and the cell references of `s` are accounted for in `y` and `z`. -* `F943` — `SDATASIZE` `(s n – x y z)`, a non-quiet version of `SDATASIZEQ` that throws a cell overflow exception (8) on failure. -* `F944–F97F` — Reserved for miscellaneous TON-specific primitives that do not fall into any other specific category. +* `D706` — `PLDIXQ (s l– x−1 or 0)`, quiet version of PLDIX. ---- +* `D707` — `PLDUXQ (s l– x−1 or 0)`, quiet version of PLDUX. -### A.11.8. Currency manipulation primitives. +* `D708cc` — `LDI cc+ 1 (s– x s′)`, a longer encoding for LDI. -* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU` `4`; `SWAP`; `LSHIFT` `3`; `LDUX`. -* `FA01` — `LDVARINT16` `(s – x s0)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU` `4`; `SWAP`; `LSHIFT` `3`; `LDIX`. -* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2^120−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2^(8l)`, followed by an `8l`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. -* `FA03` — `STVARINT16` `(b x – b 0)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2^119 ... 2^119 − 1`. -* `FA04` — `LDVARUINT32` `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2^248`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8l`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU` `5`; `SWAP`; `SHIFT` `3`; `LDUX`. -* `FA05` — `LDVARINT32` `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2^247 ≤ x < 2^247`. -* `FA06` — `STVARUINT32` `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2^248` as a `VarUInteger 32`. -* `FA07` — `STVARINT32` `(b x – b 0)`, serializes an `Integer` `−2^247 ≤ x < 2^247` as a `VarInteger 32`. -* `FA08–FA1F` — Reserved for currency manipulation primitives. +* `D709cc` — `LDU cc+ 1 (s– x s′)`, a longer encoding for LDU. +* `D70Acc` — `PLDI cc+ 1 (s– x)`, preloads a signed cc+ 1-bit integer from + Slice s. -### A.11.9. Message and address manipulation primitives. +* `D70Bcc` — `PLDU cc+ 1 (s– x)`, preloads an unsigned cc+ 1-bit integer + from s. -The message and address manipulation primitives listed below serialize and deserialize values according to the following TL-B scheme (cf. 3.3.4): +* `D70Ccc` — `LDIQ cc+ 1 (s– x s′ −1 or s 0)`, a quiet version of LDI. -``` -addr_none$00 = MsgAddressExt; -addr_extern$01 len:(## 8) external_address:(bits len) = MsgAddressExt; -anycast_info$_ depth:(<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; -addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt; -addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) workchain_id:int32 address:(bits addr_len) = MsgAddressInt; -_ _:MsgAddressInt = MsgAddress; -_ _:MsgAddressExt = MsgAddress; +* `D70Dcc` — `LDUQ cc+ 1 (s– x s′ −1 or s 0)`, a quiet version of LDU. -int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool - src:MsgAddress dest:MsgAddressInt - value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams - created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; +* `D70Ecc` — `PLDIQ cc+ 1 (s– x−1 or 0)`, a quiet version of PLDI. -ext_out_msg_info$11 src:MsgAddress dest:MsgAddressExt - created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; -``` +* `D70Fcc` — `PLDUQ cc+ 1 (s– x−1 or 0)`, a quiet version of PLDU. -A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: +* `D714_c` — `PLDUZ 32(c+ 1) (s– s x)`, preloads the first 32(c+ 1) bits + of Slice s into an unsigned integer x, for 0 ≤c ≤7. If s is shorter + than necessary, missing bits are assumed to be zero. This operation is + intended to be used along with IFBITJMP and similar instructions. -* `addr_none` is represented by `t = (0)`, i.e., a `Tuple` containing exactly one `Integer` equal to zero. -* `addr_extern` is represented by `t = (1, s)`, where `Slice` `s` contains the field `external_address`. In other words, `t` is a pair (a `Tuple` consisting of two entries), containing an `Integer` equal to one and `Slice` `s`. -* `addr_std` is represented by `t = (2, u, x, s)`, where `u` is either a `Null` (if `anycast` is absent) or a `Slice` `s0` containing `rewrite_pfx` (if `anycast` is present). Next, `Integer` `x` is the `workchain_id`, and `Slice` `s` contains the address. - `135` - A.11. Application-specific primitives -* `addr_var` is represented by `t = (3, u, x, s)`, where `u`, `x`, and `s` have the same meaning as for `addr_std`. +* `D718` — `LDSLICEX (s l– s′′ s′)`, loads the first 0 ≤l ≤1023 bits from + Slice s into a separate Slice s′′, returning the remainder of s as s′. -The following primitives, which use the above conventions, are defined: +* `D719` — `PLDSLICEX (s l– s′′)`, returns the first 0 ≤l ≤1023 bits of s + as s′′. -### A.11.9. Message and address manipulation primitives. +* `D71A` — `LDSLICEXQ (sl– s′′s′ −1 or s0)`, a quiet version of LDSLICEX. -* `FA40` — `LDMSGADDR` `(s – s 0 s 00)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s 0` and the remainder `s 00` of `s` as `CellSlices`. -* `FA41` — `LDMSGADDRQ` `(s – s 0 s 00 −1 or s 0)`, a quiet version of `LDMSGADDR`: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. -* `FA42` — `PARSEMSGADDR` `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. -* `FA43` — `PARSEMSGADDRQ` `(s – t −1 or 0)`, a quiet version of `PARSEMSGADDR`: returns a zero on error instead of throwing an exception. -* `FA44` — `REWRITESTDADDR` `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. -* `FA45` — `REWRITESTDADDRQ` `(s – x y −1 or 0)`, a quiet version of primitive `REWRITESTDADDR`. -* `FA46` — `REWRITEVARADDR` `(s – x s0)`, a variant of `REWRITESTDADDR` that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). -* `FA47` — `REWRITEVARADDRQ` `(s – x s0 −1 or 0)`, a quiet version of primitive `REWRITEVARADDR`. -* `FA48–FA5F` — Reserved for message and address manipulation primitives. +* `D71B` — `PLDSLICEXQ (s l– s′ −1 or 0)`, a quiet version of LDSLICEXQ. -### A.11.10. Outbound message and output action primitives. +* `D71Ccc` — `LDSLICE cc+ 1 (s– s′′ s′)`, a longer encoding for LDSLICE. -* `FB00` — `SENDRAWMSG` `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. -* `FB02` — `RAWRESERVE` `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. -* `FB03` — `RAWRESERVEX` `(x D y – )`, similar to `RAWRESERVE`, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. -* `FB04` — `SETCODE` `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. -* `FB06` — `SETLIBCODE` `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. -* `FB07` — `CHANGELIB` `(h x – )`, creates an output action similarly to `SETLIBCODE`, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. -* `FB08–FB3F` — Reserved for output action primitives. +* `D71Dcc` — `PLDSLICE cc+ 1 (s– s′′)`, returns the first 0 `cc+ 1 ≤256` + bits of s as s′′. ---- +* `D71Ecc` — `LDSLICEQ cc+ 1 (s– s′′ s′ −1 or s 0)`, a quiet version of + LDSLICE. -## A.12 Debug primitives +* `D71Fcc` — `PLDSLICEQ cc + 1 (s– s′′ −1 or 0)`, a quiet version of + PLDSLICE. -Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) `NOP` operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. +* `D720` — `SDCUTFIRST (s l– s′)`, returns the first 0 ≤l≤1023 bits of s. + It is equivalent to PLDSLICEX. -### A.12.1. Debug primitives as multibyte NOPs. +* `D721` — `SDSKIPFIRST (s l– s′)`, returns all but the first 0 ≤l ≤1023 + bits of s. It is equivalent to LDSLICEX; NIP. -* `FEnn` — `DEBUG nn`, for `0 ≤ nn < 240`, is a two-byte `NOP`. -* `FEFnssss` — `DEBUGSTR ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte `NOP`, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. +* `D722` — `SDCUTLAST (s l– s′)`, returns the last 0 ≤l≤1023 bits of s. -### A.12.2. Debug primitives as operations without side-effect. +* `D723` — `SDSKIPLAST (s l– s′)`, returns all but the last 0 ≤l ≤1023 + bits of s. -Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte `NOP`s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as `NOP`s, but they cannot throw exceptions. +* `D724` — `SDSUBSTR (s l l′ – s′)`, returns 0 ≤l′≤1023 bits of s starting + from offset 0 ≤l ≤1023, thus extracting a bit substring out of the + data of s. -* `FE00` — `DUMPSTK`, dumps the stack (at most the top 255 values) and shows the total stack depth. -* `FE0n` — `DUMPSTKTOP n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. -* `FE10` — `HEXDUMP`, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. -* `FE11` — `HEXPRINT`, similar to `HEXDUMP`, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. -* `FE12` — `BINDUMP`, dumps `s0` in binary form, similarly to `HEXDUMP`. -* `FE13` — `BINPRINT`, outputs the binary representation of `s0` to a text buffer. -* `FE14` — `STRDUMP`, dumps the `Slice` at `s0` as an UTF-8 string. -* `FE15` — `STRPRINT`, similar to `STRDUMP`, but outputs the string into a text buffer (without carriage return). -* `FE1E` — `DEBUGOFF`, disables all debug output until it is re-enabled by a `DEBUGON`. More precisely, this primitive increases an internal counter, which disables all debug operations (except `DEBUGOFF` and `DEBUGON`) when strictly positive. -* `FE1F` — `DEBUGON`, enables debug output (in a debug version of TVM). -* `FE2n` — `DUMP s(n)`, `0 ≤ n < 15`, dumps `s(n)`. -* `FE3n` — `PRINT s(n)`, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. -* `FEC0–FEEF` — Use these opcodes for custom/experimental debug operations. -* `FEFnssss` — `DUMPTOSFMT ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). -* `FEFn00ssss` — `LOGSTR ssss`, string `ssss` is `n` bytes long. -* `FEF000` — `LOGFLUSH`, flushes all pending debug output from the buffer into the debug log. -* `FEFn01ssss` — `PRINTSTR ssss`, string `ssss` is `n` bytes long. +* `D726` — `SDBEGINSX (ss′ – s′′)`, checks whether sbegins with (the data + bits of) s′, and removes s′ from s on success. On failure throws a + cell deserialization exception. Primitive SDPFXREV can be considered a + quiet version of SDBEGINSX. ---- +* `D727` — `SDBEGINSXQ (ss′ – s′′ −1 or s0)`, a quiet version of SDBEGINSX. -## A.13 Codepage primitives +* `D72A_xsss` — `SDBEGINS(s– s′′)`, checks whether sbegins with constant + bitstring sss of length 8x+ 3 (with continuation bit assumed), where + 0 ≤x≤127, and removes sss from s on success. -The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. 5.1.8). +* `D72802` — `SDBEGINS ‘0’ (s– s′′)`, checks whether s begins with a + binary zero. -* `FFnn` — `SETCP nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. -* `FF00` — `SETCP0`, selects TVM (test) codepage zero as described in this document. -* `FFFz` — `SETCP z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 ... −1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in B.2.6. Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. -* `FFF0` — `SETCPX` `(c – )`, selects codepage `c` with `−2^15 ≤ c < 2^15` passed in the top of the stack. ---- +* `D72806` — `SDBEGINS ‘1’ (s– s′′)`, checks whether s begins with a + binary one. -# B Formal properties and specifications of TVM +* `D72E_xsss` — `SDBEGINSQ(s–s′′ −1 ors0)`, a quiet version of SDBEGINS. -This appendix discusses certain formal properties of TVM that are necessary for executing smart contracts in the TON Blockchain and validating such executions afterwards. +* `D730` — `SCUTFIRST (s l r– s′)`, returns the first 0 ≤l≤1023 bits and + first 0 ≤r≤4 references of s. -## B.1 Serialization of the TVM state +* `D731` — `SSKIPFIRST (s l r– s′)`. -Recall that a virtual machine used for executing smart contracts in a blockchain must be deterministic, otherwise the validation of each execution would require the inclusion of all intermediate steps of the execution into a block, or at least of the choices made when indeterministic operations have been performed. +* `D732` — `SCUTLAST (s l r– s′)`, returns the last 0 ≤l ≤1023 data bits + and last 0 ≤r≤4 references of s. -Furthermore, the state of such a virtual machine must be (uniquely) serializable, so that even if the state itself is not usually included in a block, its hash is still well-defined and can be included into a block for verification purposes. +* `D733` — `SSKIPLAST (s l r– s′)`. -### B.1.1. TVM stack values. +* `D734` — `SUBSLICE (s l r l′ r′ – s′)`, returns 0 ≤l′ ≤1023 bits and + 0 ≤r′≤4 references from Slice s, after skipping the first 0 ≤l≤1023 + bits and first 0 ≤r≤4 references. -TVM stack values can be serialized as follows: +* `D736` — `SPLIT (slr– s′s′′)`, splits the first 0 ≤l≤1023 data bits and + first 0 ≤r ≤4 references from s into s′, returning the remainder of s + as s′′. -``` -vm_stk_tinyint#01 value:int64 = VmStackValue; -vm_stk_int#0201_ value:int257 = VmStackValue; -vm_stk_nan#02FF = VmStackValue; -vm_stk_cell#03 cell:^Cell = VmStackValue; -_ cell:^Cell st_bits:(## 10) end_bits:(## 10) - { st_bits <= end_bits } - st_ref:(#<= 4) end_ref:(#<= 4) - { st_ref <= end_ref } = VmCellSlice; -vm_stk_slice#04 _:VmCellSlice = VmStackValue; -vm_stk_builder#05 cell:^Cell = VmStackValue; +* `D737` — `SPLITQ (s l r– s′ s′′ −1 or s 0)`, a quiet version of SPLIT. + +* `D739` — `XCTOS (c– s ?),` transforms an ordinary or exotic cell into a + Slice, asifitwereanordinarycell. Aflagisreturnedindicatingwhether + c is exotic. If that be the case, its type can later be deserialized from + the first eight bits of s. + +* `D73A` — `XLOAD (c– c′)`, loads an exotic cell c and returns an ordinary + cell c′. If c is already ordinary, does nothing. If c cannot be loaded, + throws an exception. + +* `D73B` — `XLOADQ (c– c′ −1 or c 0)`, loads an exotic cell c as XLOAD, but + returns 0 on failure. + +* `D741` — `SCHKBITS (sl– )`, checks whether there are at least ldata bits + in Slice s. If this is not the case, throws a cell deserialisation (i.e., cell + underflow) exception. + +* `D742` — `SCHKREFS (sr–)`, checkswhetherthereareatleastrreferences + in Slice s. + +* `D743` — `SCHKBITREFS (s l r – )`, checks whether there are at least l + data bits and r references in Slice s. + +* `D745` — `SCHKBITSQ (s l– ?),` checks whether there are at least l data + bits in Slice s. + +* `D746` — `SCHKREFSQ (sr– ?),` checks whether there are at least r refer- + ences in Slice s. + +* `D747` — `SCHKBITREFSQ (s l r– ?),` checks whether there are at least l + data bits and r references in Slice s. + +* `D748` — `PLDREFVAR (s n– c)`, returns the n-th cell reference of Slice s + for 0 ≤n≤3. + +* `D749` — `SBITS (s– l)`, returns the number of data bits in Slice s. + +* `D74A` — `SREFS (s– r)`, returns the number of references in Slice s. + +* `D74B` — `SBITREFS (s– l r)`, returns both the number of data bits and + the number of references in s. + +* `D74E_n` — `PLDREFIDX n (s– c)`, returns the n-th cell reference of + Slice s, where 0 ≤n≤3. + +* `D74C` — `PLDREF (s– c)`, preloads the first cell reference of a Slice. + +* `D750` — `LDILE4 (s– x s′)`, loads a little-endian signed 32-bit integer. + +* `D751` — `LDULE4 (s– xs′)`, loads a little-endian unsigned 32-bit integer. + +* `D752` — `LDILE8 (s– x s′)`, loads a little-endian signed 64-bit integer. + +* `D753` — `LDULE8 (s– xs′)`, loads a little-endian unsigned 64-bit integer. + +* `D754` — `PLDILE4 (s– x)`, preloads a little-endian signed 32-bit integer. + +* `D755` — `PLDULE4 (s– x)`, preloads a little-endian unsigned 32-bit inte- + ger. + +* `D756` — `PLDILE8 (s– x)`, preloads a little-endian signed 64-bit integer. + +* `D757` — `PLDULE8 (s– x)`, preloads a little-endian unsigned 64-bit inte- + ger. + +* `D758` — `LDILE4Q (s– x s′ −1 or s 0)`, quietly loads a little-endian + signed 32-bit integer. + +* `D759` — `LDULE4Q (s– x s′ −1 or s 0)`, quietly loads a little-endian + unsigned 32-bit integer. + +* `D75A` — `LDILE8Q (s– x s′ −1 or s 0)`, quietly loads a little-endian + signed 64-bit integer. + +* `D75B` — `LDULE8Q (s– x s′ −1 or s 0)`, quietly loads a little-endian + unsigned 64-bit integer. + +* `D75C` — `PLDILE4Q (s– x−1 or 0)`, quietly preloads a little-endian + signed 32-bit integer. + +* `D75D` — `PLDULE4Q (s– x−1 or 0)`, quietly preloads a little-endian + unsigned 32-bit integer. + +* `D75E` — `PLDILE8Q (s– x−1 or 0)`, quietly preloads a little-endian + signed 64-bit integer. + +* `D75F` — `PLDULE8Q (s– x−1 or 0)`, quietly preloads a little-endian + unsigned 64-bit integer. + +* `D760` — `LDZEROES (s– n s′)`, returns the count n of leading zero bits + in s, and removes these bits from s. + +* `D761` — `LDONES (s– ns′)`, returns the count nof leading one bits in s, + and removes these bits from s. + +* `D762` — `LDSAME (s x– n s′)`, returns the count n of leading bits equal + to 0 ≤x≤1 in s, and removes these bits from s. + +* `D764` — `SDEPTH (s– x)`, returns the depth of Slice s. If s has no + references, then x= 0; otherwise xis one plus the maximum of depths + of cells referred to from s. + +* `D765` — `CDEPTH (c– x)`, returns the depth of Cell c. If c has no + references, then x= 0; otherwise xis one plus the maximum of depths + of cells referred to from c. If cis a Null instead of a Cell, returns zero. + +--- + +## A.8 Continuation and control flow primitives + +### A.8.1. Unconditional control flow primitives. + +• `D8` — `EXECUTE` or `CALLX (c – )`, calls or executes continuation `c` (i.e., `c꜀ ← c◦₀c꜀`). + +• `D9` — `JMPX (c – )`, jumps, or transfers control, to continuation `c` (i.e., `c꜀ ← c◦₀c₀`, or rather `c꜀ ← (c◦₀c₀)◦₁c₁`). The remainder of the previous current continuation `c꜀` is discarded. + +• `DApr` — `CALLXARGS p,r (c – )`, calls continuation `c` with `p` parameters and expecting `r` return values, `0 ≤ p ≤ 15`, `0 ≤ r ≤ 15`. + +• `DB0p` — `CALLXARGS p,−1 (c – )`, calls continuation `c` with `0 ≤ p ≤ 15` parameters, expecting an arbitrary number of return values. + +• `DB1p` — `JMPXARGS p (c – )`, jumps to continuation `c`, passing only the top `0 ≤ p ≤ 15` values from the current stack to it (the remainder of the current stack is discarded). + +• `DB2r` — `RETARGS r`, returns to `c₀`, with `0 ≤ r ≤ 15` return values taken from the current stack. + +• `DB30` — `RET` or `RETTRUE`, returns to the continuation at `c₀` (i.e., performs `c꜀ ← c₀`). The remainder of the current continuation `c꜀` is discarded. Approximately equivalent to `PUSH c₀; JMPX`. + +• `DB31` — `RETALT` or `RETFALSE`, returns to the continuation at `c₁` (i.e., `c꜀ ← c₁`). Approximately equivalent to `PUSH c₁; JMPX`. + +• `DB32` — `BRANCH` or `RETBOOL (f – )`, performs `RETTRUE` if integer `f ≠ 0`, or `RETFALSE` if `f = 0`. + +• `DB34` — `CALLCC (c – )`, call with current continuation, transfers control to `c`, pushing the old value of `c꜀` into `c`’s stack (instead of discarding it or writing it into new `c₀`). + +• `DB35` — `JMPXDATA (c – )`, similar to `CALLCC`, but the remainder of the current continuation (the old value of `c꜀`) is converted into a Slice before pushing it into the stack of `c`. + +• `DB36pr` — `CALLCCARGS p,r (c – )`, similar to `CALLXARGS`, but pushes the old value of `c꜀` (along with the top `0 ≤ p ≤ 15` values from the original stack) into the stack of newly-invoked continuation `c`, setting `c꜀.nargs` to `−1 ≤ r ≤ 14`. + +• `DB38` — `CALLXVARARGS (c p r – )`, similar to `CALLXARGS`, but takes `−1 ≤ p,r ≤ 254` from the stack. The next three operations also take `p` and `r` from the stack, both in the range `−1...254`. + +• `DB39` — `RETVARARGS (p r – )`, similar to `RETARGS`. + +• `DB3A` — `JMPXVARARGS (c p r – )`, similar to `JMPXARGS`. + +• `DB3B` — `CALLCCVARARGS (c p r – )`, similar to `CALLCCARGS`. + +• `DB3C` — `CALLREF`, equivalent to `PUSHREFCONT; CALLX`. + +• `DB3D` — `JMPREF`, equivalent to `PUSHREFCONT; JMPX`. + +• `DB3E` — `JMPREFDATA`, equivalent to `PUSHREFCONT; JMPXDATA`. + +• `DB3F` — `RETDATA`, equivalent to `PUSH c₀; JMPXDATA`. In this way, the remainder of the current continuation is converted into a Slice and returned to the caller. + +### A.8.2. Conditional control flow primitives + +* `DC` — `IFRET` `(f – )`, performs a `RET`, but only if integer `f` is non-zero. If `f` is a NaN, throws an integer overflow exception. +* `DD` — `IFNOTRET` `(f – )`, performs a `RET`, but only if integer `f` is zero. +* `DE` — `IF` `(f c – )`, performs `EXECUTE` for `c` (i.e., executes `c`), but only if integer `f` is non-zero. Otherwise simply discards both values. +* `DF` — `IFNOT` `(f c – )`, executes continuation `c`, but only if integer `f` is zero. Otherwise simply discards both values. +* `E0` — `IFJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is non-zero. +* `E1` — `IFNOTJMP` `(f c – )`, jumps to `c` (similarly to `JMPX`), but only if `f` is zero. +* `E2` — `IFELSE` `(f c c′ – )`, if integer `f` is non-zero, executes `c`, otherwise executes ` c′`. Equivalent to `CONDSELCHK; EXECUTE`. +* `E300` — `IFREF` `(f – )`, equivalent to `PUSHREFCONT; IF`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next three primitives. +* `E301` — `IFNOTREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOT`. +* `E302` — `IFJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFJMP`. +* `E303` — `IFNOTJMPREF` `(f – )`, equivalent to `PUSHREFCONT; IFNOTJMP`. +* `E304` — `CONDSEL` `(f x y – x or y)`, if integer `f` is non-zero, returns `x`, otherwise returns `y`. Notice that no type checks are performed on `x` and `y`; as such, it is more like a conditional stack operation. Roughly equivalent to `ROT; ISZERO; INC; ROLLX; NIP`. +* `E305` — `CONDSELCHK` `(f x y – x or y)`, same as `CONDSEL`, but first checks whether `x` and `y` have the same type. +* `E308` — `IFRETALT` `(f – )`, performs `RETALT` if integer `f ≠ 0`. +* `E309` — `IFNOTRETALT` `(f – )`, performs `RETALT` if integer `f = 0`. +* `E30D` — `IFREFELSE` `(f c – )`, equivalent to `PUSHREFCONT; SWAP; IFELSE`, with the optimization that the cell reference is not actually loaded into a Slice and then converted into an ordinary Continuation if `f = 0`. Similar remarks apply to the next two primitives. +* `E30E` — `IFELSEREF` `(f c – )`, equivalent to `PUSHREFCONT; IFELSE`. +* `E30F` — `IFREFELSEREF` `(f – )`, equivalent to `PUSHREFCONT; PUSHREFCONT; IFELSE`. +* `E310–E31F` — reserved for loops with break operators (cf. [A.8.3](#a-8-3-control-flow-primitives%3A-loops)). +* `E39_n` — `IFBITJMP n` `(x c – x)`, checks whether bit `0 ≤ n ≤ 31` is set in integer `x`, and if so, performs `JMPX` to continuation `c`. Value `x` is left in the stack. +* `E3B_n` — `IFNBITJMP n` `(x c – x)`, jumps to `c` if bit `0 ≤ n ≤ 31` is not set in integer `x`. +* `E3D_n` — `IFBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is set in integer `x`. +* `E3F_n` — `IFNBITJMPREF n` `(x – x)`, performs a `JMPREF` if bit `0 ≤ n ≤ 31` is not set in integer `x`. + + +### A.8.3. Control flow primitives: loops + +Most of the loop primitives listed below are implemented with the aid of extraordinary continuations, such as `ec_until` (cf. [4.1.5](#4-1-5-extraordinary-continuations)), with the loop body and the original current continuation `cc` stored as the arguments to this extraordinary continuation. Typically a suitable extraordinary continuation is constructed, and then saved into the loop body continuation savelist as `c0`; after that, the modified loop body continuation is loaded into `cc` and executed in the usual fashion. All of these loop primitives have `*BRK` versions, adapted for breaking out of a loop; they additionally set `c1` to the original current continuation (or original `c0` for `*ENDBRK` versions), and save the old `c1` into the savelist of the original current continuation (or of the original `c0` for `*ENDBRK` versions). + +* `E4` — `REPEAT (n c – )`, executes continuation `c` `n` times, if integer `n` + is non-negative. If `n ≥ 2³¹` or `n < −2³¹`, generates a range check + exception. Notice that a `RET` inside the code of `c` works as a continue, + not as a break. One should use either alternative (experimental) loops + or alternative `RETALT` (along with a `SETEXITALT` before the loop) to + break out of a loop. + +* `E5` — `REPEATEND (n – )`, similar to `REPEAT`, but it is applied to the + current continuation `cc`. + +* `E6` — `UNTIL (c – )`, executes continuation `c`, then pops an integer `x` + from the resulting stack. If `x` is zero, performs another iteration of + this loop. The actual implementation of this primitive involves an + extraordinary continuation `ec_until` (cf. 4.1.5) with its arguments + set to the body of the loop (continuation `c`) and the original current + continuation `cc`. This extraordinary continuation is then saved into + the savelist of `c` as `c.c₀` and the modified `c` is then executed. The + other loop primitives are implemented similarly with the aid of suitable + extraordinary continuations. + +* `E7` — `UNTILEND ( – )`, similar to `UNTIL`, but executes the current continuation `cc` in a loop. When the loop exit condition is satisfied, performs + a `RET`. + +* `E8` — `WHILE (c′ c – )`, executes `c′` and pops an integer `x` from the + resulting stack. If `x` is zero, exists the loop and transfers control to + the original `cc`. If `x` is non-zero, executes `c`, and then begins a new + iteration. + +* `E9` — `WHILEEND (c′ – )`, similar to `WHILE`, but uses the current continuation `cc` as the loop body. + +* `EA` — `AGAIN (c – )`, similar to `REPEAT`, but executes `c` infinitely many + times. A `RET` only begins a new iteration of the infinite loop, which can + be exited only by an exception, or a `RETALT` (or an explicit `JMPX`). + +* `EB` — `AGAINEND ( – )`, similar to `AGAIN`, but performed with respect to + the current continuation `cc`. + +* `E314` — `REPEATBRK (n c – )`, similar to `REPEAT`, but also sets `c₁` to + the original `cc` after saving the old value of `c₁` into the savelist of the + original `cc`. In this way `RETALT` could be used to break out of the loop + body. + +* `E315` — `REPEATENDBRK (n – )`, similar to `REPEATEND`, but also sets `c₁` + to the original `c₀` after saving the old value of `c₁` into the savelist of + the original `c₀`. Equivalent to `SAMEALTSAVE; REPEATEND`. + +* `E316` — `UNTILBRK (c – )`, similar to `UNTIL`, but also modifies `c₁` in the + same way as `REPEATBRK`. + +* `E317` — `UNTILENDBRK ( – )`, equivalent to `SAMEALTSAVE; UNTILEND`. + +* `E318` — `WHILEBRK (c′ c – )`, similar to `WHILE`, but also modifies `c₁` in + the same way as `REPEATBRK`. + +* `E319` — `WHILEENDBRK (c – )`, equivalent to `SAMEALTSAVE; WHILEEND`. + +* `E31A` — `AGAINBRK (c – )`, similar to `AGAIN`, but also modifies `c₁` in the + same way as `REPEATBRK`. + +* `E31B` — `AGAINENDBRK ( – )`, equivalent to `SAMEALTSAVE; AGAINEND`. + + +### A.8.4. Manipulating the stack of continuations + +* **`ECr n`** — `SETCONTARGS r,n(x₁ … xᵣ c – c′)`, similar to `SETCONTARGS r`, but sets `c.nargs` to the final size of the stack of `c′` plus `n`. In other words, transforms `c` into a closure or a partially applied function, with `0 ≤ n ≤ 14` arguments missing. + +* **`EC0n`** — `SETNUMARGS n` or `SETCONTARGS 0,n (c – c′)`, sets `c.nargs` to `n` plus the current depth of `c`’s stack, where `0 ≤ n ≤ 14`. If `c.nargs` is already set to a non-negative value, does nothing. + +* **`ECrF`** — `SETCONTARGS r` or `SETCONTARGS r,−1 (x₁ … xᵣ c – c′)`, pushes `0 ≤ r ≤ 15` values `x₁ … xᵣ` into the stack of (a copy of) the continuation `c`, starting with `x₁`. If the final depth of `c`’s stack turns out to be greater than `c.nargs`, a stack overflow exception is generated. + +* **`ED0p`** — `RETURNARGS p ( – )`, leaves only the top `0 ≤ p ≤ 15` values in the current stack (similarly to `ONLYTOPX`), with all the unused bottom values not discarded, but saved into continuation `c₀` in the same way as `SETCONTARGS` does. + +* **`ED10`** — `RETURNVARARGS(p – )`, similar to `RETURNARGS`, but with integer `0 ≤ p ≤ 255` taken from the stack. + +* **`ED11`** — `SETCONTVARARGS(x₁ … xᵣ c r n – c′)`, similar to `SETCONTARGS`, but with `0 ≤ r ≤ 255` and `−1 ≤ n ≤ 255` taken from the stack. + +* **`ED12`** — `SETNUMVARARGS (c n – c′)`, where `−1 ≤ n ≤ 255`. If `n = −1`, this operation does nothing (`c′ = c`). Otherwise, its action is similar to `SETNUMARGS n`, but with `n` taken from the stack. + +### A.8.5. Creating simple continuations and closures + +* **`ED1E`** — `BLESS (s – c)`, transforms a slice `s` into a simple ordinary continuation `c`, with `c.code = s` and an empty stack and savelist. + +* **`ED1F`** — `BLESSVARARGS (x₁ … xᵣ s r n – c)`, equivalent to `ROT; BLESS; ROTREV; SETCONTVARARGS`. + +* **`EEr n`** — `BLESSARGS r,n (x₁ … xᵣ s – c)`, where `0 ≤ r ≤ 15`, `−1 ≤ n ≤ 14`, equivalent to `BLESS; SETCONTARGS r,n`. The value of `n` is represented inside the instruction by the 4-bit integer `n mod 16`. + +* **`EE0n`** — `BLESSNUMARGS n` or `BLESSARGS 0,n (s – c)`, transforms a slice `s` into a continuation `c`, but sets `c.nargs` to `0 ≤ n ≤ 14`. + +### A.8.6. Operations with continuation savelists and control registers + +* **`ED4i`** — `PUSH cᵢ` or `PUSHCTR cᵢ ( – x)`, pushes the current value of control register `cᵢ`. If the control register is not supported in the current codepage, or if it does not have a value, an exception is triggered. + +* **`ED44`** — `PUSH c₄` or `PUSHROOT`, pushes the “global data root” cell reference, enabling access to persistent smart-contract data. + +* **`ED5i`** — `POP cᵢ` or `POPCTR cᵢ (x – )`, pops a value `x` from the stack and stores it into control register `cᵢ`, if supported in the current codepage. Type-checking exceptions may occur if the control register accepts only values of a specific type. + +* **`ED54`** — `POP c₄` or `POPROOT`, sets the “global data root” cell reference, allowing modification of persistent smart-contract data. + +* **`ED6i`** — `SETCONT cᵢ` or `SETCONTCTR cᵢ (x c – c′)`, stores `x` into the savelist of continuation `c` as `cᵢ`, and returns the resulting continuation `c′`. + +* **`ED7i`** — `SETRETCTR cᵢ (x – )`, equivalent to `PUSH c₀; SETCONTCTR cᵢ; POP c₀`. + +* **`ED8i`** — `SETALTCTR cᵢ (x – )`, equivalent to `PUSH c₁; SETCONTCTR cᵢ; POP c₀`. + +* **`ED9i`** — `POPSAVE cᵢ` or `POPCTRSAVE cᵢ (x – )`, similar to `POP cᵢ`, but also saves the old value of `cᵢ` into continuation `c₀`. Equivalent (up to exceptions) to `SAVECTR cᵢ; POP cᵢ`. + +* **`EDAi`** — `SAVE cᵢ` or `SAVECTR cᵢ ( – )`, saves the current value of `cᵢ` into the savelist of continuation `c₀`. Equivalent to `PUSH cᵢ; SETRETCTR cᵢ`. + +* **`EDBi`** — `SAVEALT cᵢ` or `SAVEALTCTR cᵢ ( – )`, similar to `SAVE cᵢ`, but saves into the savelist of `c₁`. + +* **`EDCi`** — `SAVEBOTH cᵢ` or `SAVEBOTHCTR cᵢ ( – )`, equivalent to `DUP; SAVE cᵢ; SAVEALT cᵢ`. + +* **`EDE0`** — `PUSHCTRX (i – x)`, similar to `PUSHCTR cᵢ`, but with `i`, `0 ≤ i ≤ 255`, taken from the stack. + +* **`EDE1`** — `POPCTRX (xᵢ – )`, similar to `POPCTR cᵢ`, but with `0 ≤ i ≤ 255` from the stack. + +* **`EDE2`** — `SETCONTCTRX (x cᵢ – c′)`, similar to `SETCONTCTR cᵢ`, but with `0 ≤ i ≤ 255` from the stack. + + +### A.8.7. Dictionary subroutine calls and jumps + +* **`F0n`** — `CALL n` or `CALLDICT n ( – n)`, calls the continuation in `c₃`, pushing integer `0 ≤ n ≤ 255` into its stack as an argument. Equivalent to `PUSHINT n; PUSH c₃; EXECUTE`. + +* **`F12_n`** — `CALL n` for `0 ≤ n < 2¹⁴ ( – n)`, an encoding of `CALL n` for larger values. + +* **`F16_n`** — `JMP n` or `JMPDICT n ( – n)`, jumps to the continuation in `c₃`, pushing integer `0 ≤ n < 2¹⁴` as its argument. Equivalent to `PUSHINT n; PUSH c₃; JMPX`. + +* **`F1A_n`** — `PREPARE n` or `PREPAREDICT n ( – n c)`, equivalent to `PUSHINT n; PUSH c₃`, for `0 ≤ n < 2¹⁴`. In this way, `CALL n ≈ PREPARE n; EXECUTE` and `JMP n ≈ PREPARE n; JMPX`. + + +--- + +## A.9 Exception generating and handling primitives + +### A.9.1. Throwing exceptions + +* `F22_nn` — `THROW nn ( – 0 nn)`, throws exception `0 ≤ nn ≤ 63` with parameter zero. + +* `F26_nn` — `THROWIF nn (f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f ≠ 0`. + +* `F2A_nn` — `THROWIFNOT nn (f – )`, throws exception `0 ≤ nn ≤ 63` with parameter zero only if integer `f = 0`. + +* `F2C4_nn` — `THROW nn` for `0 ≤ nn < 2¹¹`, an encoding of `THROW nn` for larger values. + +* `F2CC_nn` — `THROWARG nn (x – x nn)`, throws exception `0 ≤ nn < 2¹¹` with parameter `x`, by copying `x` and `nn` into the stack of `c2` and transferring control to `c2`. + +* `F2D4_nn` — `THROWIF nn (f – )` for `0 ≤ nn < 2¹¹`. + +* `F2DC_nn` — `THROWARGIF nn (x f – )`, throws exception `0 ≤ nn < 2¹¹` with parameter `x` only if integer `f ≠ 0`. + +* `F2E4_nn` — `THROWIFNOT nn (f – )` for `0 ≤ nn < 2¹¹`. + +* `F2EC_nn` — `THROWARGIFNOT nn (x f – )`, throws exception `0 ≤ nn < 2¹¹` with parameter `x` only if integer `f = 0`. + +* `F2F0` — `THROWANY (n – 0 n)`, throws exception `0 ≤ n < 2¹⁶` with parameter zero. Approx. `PUSHINT 0; SWAP; THROWARGANY`. + +* `F2F1` — `THROWARGANY (x n – x n)`, throws exception `0 ≤ n < 2¹⁶` with parameter `x`, transferring control to `c2`. Approx. `PUSH c2; JMPXARGS 2`. + +* `F2F2` — `THROWANYIF (n f – )`, throws exception `0 ≤ n < 2¹⁶` with parameter zero only if `f ≠ 0`. + +* `F2F3` — `THROWARGANYIF (x n f – )`, throws exception `0 ≤ n < 2¹⁶` with parameter `x` only if `f ≠ 0`. + +* `F2F4` — `THROWANYIFNOT (n f – )`, throws exception `0 ≤ n < 2¹⁶` with parameter zero only if `f = 0`. + +* `F2F5` — `THROWARGANYIFNOT (x n f – )`, throws exception `0 ≤ n < 2¹⁶` with parameter `x` only if `f = 0`. + + +### A.9.2. Catching and handling exceptions + +* `F2FF` — `TRY (c c′ – )`, sets `c2` to `c′`, first saving the old value of `c2` both + into the savelist of `c′` and into the savelist of the current continuation, + which is stored into `c.c0` and `c′.c0`. Then runs `c` similarly to `EXECUTE`. + If `c` does not throw any exceptions, the original value of `c2` is automati- + cally restored on return from `c`. If an exception occurs, the execution is + transferred to `c′`, but the original value of `c2` is restored in the process, + so that `c′` can re-throw the exception by `THROWANY` if it cannot handle + it by itself. + +* `F3pr` — `TRYARGS p,r (c c′ – )`, similar to `TRY`, but with `CALLARGS + p,r` internally used instead of `EXECUTE`. In this way, all but the top + `0 ≤ p ≤ 15` stack elements will be saved into current continuation’s + stack, and then restored upon return from either `c` or `c′`, with the top + `0 ≤ r ≤ 15` values of the resulting stack of `c` or `c′` copied as return + values. + +--- + +# A.10 Dictionary manipulation primitives + +TVM’s dictionary support is discussed at length in [3.3](#3-3-hashmaps%2C-or-dictionaries). The basic operations with dictionaries are listed in [3.3.10](#3-3-10-basic-dictionary-operations), while the taxonomy of dictionary manipulation primitives is provided in [3.3.11](#3-3-11-taxonomy-of-dictionary-primitives). Here we use the concepts and notation introduced in those sections. + +Dictionaries admit two different representations as TVM stack values: + +* A Slice `s` with a serialization of a TL-B value of type `HashmapE(n, X)`. +In other words, `s` consists either of one bit equal to zero (if the dic- +tionary is empty), or of one bit equal to one and a reference to a Cell +containing the root of the binary tree, i.e., a serialized value of type +`Hashmap(n, X)`. + +* A “maybe Cell” `cˀ`, i.e., a value that is either a Cell (containing a seri- + alized value of type `Hashmap(n, X)` as before) or a Null (corresponding + to an empty dictionary). When a “maybe Cell” `cˀ` is used to represent + a dictionary, we usually denote it by `D` in the stack notation. + +Most of the dictionary primitives listed below accept and return dictionaries in the second form, which is more convenient for stack manipulation. However, serialized dictionaries inside larger TL-B objects use the first representation. + +Opcodes starting with `F4` and `F5` are reserved for dictionary operations. + + +### A.10.1. Dictionary creation. + +* `6D` — `NEWDICT` `( – D)`, returns a new empty dictionary. It is an alternative mnemonics for `PUSHNULL`, (cf. [A.3.1](#a-3-1-null-primitives)). +* `6E` — `DICTEMPTY` `(D – ?)`, checks whether dictionary `D` is empty, and returns `−1` or `0` accordingly. It is an alternative mnemonics for `ISNULL`, (cf. [A.3.1](#a-3-1-null-primitives)). + + +### A.10.2. Dictionary serialization and deserialization + +* `CE` — `STDICTS (s b– b′)`, stores a Slice-represented dictionary `s` into + Builder `b`. It is actually a synonym for `STSLICE`. + +* `F400` — `STDICT or STOPTREF (D b– b′)`, stores dictionary `D` into Builder + `b`, returing the resulting Builder `b′`. In other words, if `D` is a cell, + performs `STONE` and `STREF`; if `D` is `Null`, performs `NIP` and `STZERO`; + otherwise throws a type checking exception. + +* `F401` — `SKIPDICT or SKIPOPTREF (s– s′)`, equivalent to `LDDICT; NIP`. + +* `F402` — `LDDICTS (s– s′ s′′)`, loads (parses) a Slice-represented dictionary + `s′` from Slice `s`, and returns the remainder of `s` as `s′′`. This is a + “split function” for all `HashmapE(n, X)` dictionary types. + +* `F403` — `PLDDICTS (s– s′)`, preloads a Slice-represented dictionary `s′` + from Slice `s`. Approximately equivalent to `LDDICTS; DROP`. + +* `F404` — `LDDICT or LDOPTREF (s– D s′)`, loads (parses) a dictionary `D` + from Slice `s`, and returns the remainder of `s` as `s′`. May be applied to + dictionaries or to values of arbitrary `(Ŷˀ)` types. + +* `F405` — `PLDDICT or PLDOPTREF (s– D)`, preloads a dictionary `D` from + Slice `s`. Approximately equivalent to `LDDICT; DROP`. + +* `F406` — `LDDICTQ (s– D s′ −1 or s 0)`, a quiet version of `LDDICT`. + +* `F407` — `PLDDICTQ (s– D −1 or 0)`, a quiet version of `PLDDICT`. + + +### A.10.3. Get dictionary operations + +* `F40A` — `DICTGET (k D n– x −1 or 0)`, looks up key `k` (represented by + a Slice, the first `0 ≤ n ≤ 1023` data bits of which are used as a key) + in dictionary `D` of type `HashmapE(n, X)` with `n`-bit keys. On success, + returns the value found as a Slice `x`. + +* `F40B` — `DICTGETREF (k D n– c −1 or 0)`, similar to `DICTGET`, but with + a `LDREF; ENDS` applied to `x` on success. This operation is useful for + dictionaries of type `HashmapE(n, Ŷ)`. + +* `F40C` — `DICTIGET (i D n– x −1 or 0)`, similar to `DICTGET`, but with + a signed (big-endian) `n`-bit Integer `i` as a key. If `i` does not fit into `n` + bits, returns 0. If `i` is a `NaN`, throws an integer overflow exception. + +* `F40D` — `DICTIGETREF (i D n– c −1 or 0)`, combines `DICTIGET` with + `DICTGETREF`: it uses signed `n`-bit Integer `i` as a key and returns a Cell + instead of a Slice on success. + +* `F40E` — `DICTUGET (i D n– x −1 or 0)`, similar to `DICTIGET`, but with + unsigned (big-endian) `n`-bit Integer `i` used as a key. + +* `F40F` — `DICTUGETREF (i D n– c −1 or 0)`, similar to `DICTIGETREF`, but + with an unsigned `n`-bit Integer key `i`. + + +### A.10.4. Set/Replace/Add dictionary operations. + +The mnemonics of the following dictionary primitives are constructed in a systematic fashion according to the regular expression `DICT[, I, U](SET, REPLACE, ADD)[GET][REF]` depending on the type of the key used (a `Slice` or a signed or unsigned `Integer`), the dictionary operation to be performed, and the way the values are accepted and returned (as `Cells` or as `Slices`). Therefore, we provide a detailed description only for some primitives, assuming that this information is sufficient for the reader to understand the precise action of the remaining primitives. + +* `F412`— `DICTSET (x k D n– D′)`, sets the value associated with n-bit + key k (represented by a Slice as in `DICTGET`) in dictionary D (also rep- + resented by a Slice) to value x(again a Slice), and returns the resulting + dictionary as D′. + +* `F413`— `DICTSETREF (c k D n– D′)`, similar to `DICTSET`, but with the + value set to a reference to Cell c. + +* `F414`— `DICTISET (x i D n– D′)`, similar to `DICTSET`, but with the + key represented by a (big-endian) signed n-bit integer i. If i does not + fit into n bits, a range check exception is generated. + +* `F415`— `DICTISETREF (ciD n– D′)`, similar to `DICTSETREF`, but with + the key a signed n-bit integer as in `DICTISET`. + +* `F416`— `DICTUSET (x i D n– D′)`, similar to `DICTISET`, but with i an + unsigned n-bit integer. + +* `F417`— `DICTUSETREF (ciDn– D′)`, similar to `DICTISETREF`, but with + i unsigned. + +* `F41A`— `DICTSETGET (x k D n– D′ y−1 or D′ 0)`, combines `DICTSET` + with DICTGET: it sets the value corresponding to key k to x, but also + returns the old value y associated with the key in question, if present. + +* `F41B`— `DICTSETGETREF (c k D n– D′ c′ −1 or D′ 0)`, combines + DICTSETREF with DICTGETREF similarly to DICTSETGET. + +* `F41C`—`DICTISETGET(xiDn–D′y−1 orD′0)`,similar to `DICTSETGET,` + but with the key represented by a big-endian signed n-bit Integer i. + +* `F41D`— `DICTISETGETREF (c i D n– D′ c′ −1 or D′ 0)`, a version of + DICTSETGETREF with signed Integer i as a key. + +* `F41E`—`DICTUSETGET(xiDn–D′y−1 orD′0)`,similar to`DICTISETGET`, + but with i an unsigned n-bit integer. + +* `F41F`— `DICTUSETGETREF (c i D n– D′ c′ −1 or D′ 0)`. + +* `F422`— `DICTREPLACE(xkDn– D′ −1 or D0)`, a Replace operation, + which is similar to `DICTSET`, but sets the value of key k in dictionary + D to x only if the key k was already present in D. + +* `F423`— `DICTREPLACEREF (c k D n– D′ −1 or D 0)`, a Replace + counterpart of DICTSETREF. + +* `F424`—`DICTIREPLACE(xiDn–D′ −1 orD0)`,a version of `DICTREPLACE` + with signed n-bit Integer `i` used as a key. + +* `F425`— `DICTIREPLACEREF (c i D n– D′ −1 or D 0)`. + +* `F426`— `DICTUREPLACE (x i D n– D′ −1 or D 0)`. + +* `F427`— `DICTUREPLACEREF (c i D n– D′ −1 or D 0)`. + +* `F42A`— `DICTREPLACEGET (x k D n– D′ y−1 or D 0)`, a Replace + counterpart of `DICTSETGET`: on success, also returns the old value asso- + ciated with the key in question. + +* `F42B`— `DICTREPLACEGETREF (c k D n– D′ c′ −1 or D 0)`. + +* `F42C`— `DICTIREPLACEGET (x i D n– D′ y−1 or D 0)`. + +* `F42D`— `DICTIREPLACEGETREF (c i D n– D′ c′ −1 or D 0)`. + +* `F42E`— `DICTUREPLACEGET (x i D n– D′ y−1 or D 0)`. + +* `F42F`— `DICTUREPLACEGETREF (c i D n– D′ c′ −1 or D 0)`. + +### A.10.5. Builder-accepting variants of Set dictionary operations. + +The following primitives accept the new value as a Builder b instead of a +Slice x, which often is more convenient if the value needs to be serialized from +several components computed in the stack. (This is reflected by appending +a B to the mnemonics of the corresponding Set primitives that work with +Slices.) The net effect is roughly equivalent to converting b into a Slice by +`ENDC`; `CTOS` and executing the corresponding primitive listed in [A.10.4](#a-10-4-set%2Freplace%2Fadd-dictionary-operations). + +* `F441`— `DICTSETB (b k D n– D′)`. +* `F442`— `DICTISETB (b i D n– D′)`. +* `F443`— `DICTUSETB (b i D n– D′)`. +* `F445`— `DICTSETGETB (b k D n– D′ y−1 or D′ 0)`. +* `F446`— `DICTISETGETB (b i D n– D′ y−1 or D′ 0)`. +* `F447`— `DICTUSETGETB (b i D n– D′ y−1 or D′ 0)`. +* `F449`— `DICTREPLACEB (b k D n– D′ −1 or D 0)`. +* `F44A`— `DICTIREPLACEB (b i D n– D′ −1 or D 0)`. +* `F44B`— `DICTUREPLACEB (b i D n– D′ −1 or D 0)`. +* `F44D`— `DICTREPLACEGETB (b k D n– D′ y−1 or D 0)`. +* `F44E`— `DICTIREPLACEGETB (b i D n– D′ y−1 or D 0)`. +* `F44F`— `DICTUREPLACEGETB (b i D n– D′ y−1 or D 0)`. +* `F451`— `DICTADDB (b k D n– D′ −1 or D 0)`. +* `F452`— `DICTIADDB (b i D n– D′ −1 or D 0)`. +* `F453`— `DICTUADDB (b i D n– D′ −1 or D 0)`. +* `F455`— `DICTADDGETB (b k D n– D′ −1 or D y 0)`. +* `F456`— `DICTIADDGETB (b i D n– D′ −1 or D y 0)`. +* `F457`— `DICTUADDGETB (b i D n– D′ −1 or D y 0)`. + +### A.10.6. Delete dictionary operations. + +* `F459`— `DICTDEL(kDn– D′ −1 or D0)`, deletes n-bit key, represented + by a Slice k, from dictionary `D`. If the key is present, returns the + modified dictionary `D′`and the success flag−1. Otherwise, returns the + original dictionary `D` and `0`. + +* `F45A`— `DICTIDEL (i D n– D′ ? )`, a version of `DICTDEL` with the key + represented by a signed n-bit Integer i. If i does not fit into n bits, + simply returns D 0 (“key not found, dictionary unmodified”). + +* `F45B`— `DICTUDEL (i D n– D′ ? )`, similar to `DICTIDEL`, but with i an + unsigned n-bit integer. + +* `F462`— `DICTDELGET (k D n– D′ x−1 or D 0)`, deletes n-bit key, + represented by a Slice k, from dictionary D. If the key is present, + returns the modified dictionary D′, the original value xassociated with + the key k (represented by a Slice), and the success flag−1. Otherwise, + returns the original dictionary D and 0. + +* `F463`—`DICTDELGETREF(kDn–D′c−1 orD0)`,similar `to `DICTDELGET`, + but with LDREF; ENDS applied to x on success, so that the value re- + turned c is a Cell. + +* `F464`— `DICTIDELGET (iD n– D′x−1 or D 0)`, a variant of primitive + DICTDELGET with signed n-bit integer i as a key. + +* `F465`— `DICTIDELGETREF (i D n– D′ c−1 or D 0)`, a variant of + primitive DICTIDELGET returning a Cell instead of a Slice. + +* `F466`— `DICTUDELGET (iD n– D′x−1 or D 0)`, a variant of primitive + DICTDELGET with unsigned n-bit integer i as a key. + +* `F467`— `DICTUDELGETREF (i D n– D′ c−1 or D 0)`, a variant of + primitive DICTUDELGET returning a Cell instead of a Slice. + +### A.10.7. “Maybe reference” dictionary operations. + +The following operations assume that a dictionary is used to store values `cˀ` of type Cellˀ +(“Maybe Cell”), which can be used in particular to store dictionaries as val- +ues in other dictionaries. The representation is as follows: if `cˀ` is a Cell, it +is stored as a value with no data bits and exactly one reference to this Cell. +If cˀ is Null, then the corresponding key must be absent from the dictionary +altogether. + +* `F469`— `DICTGETOPTREF (k D n– cˀ)`, a variant of `DICTGETREF` that + returns Null instead of the value cˀ if the key k is absent from dictio- + nary D. + +* `F46A`— `DICTIGETOPTREF (i D n– cˀ)`, similar to `DICTGETOPTREF`, but + with the key given by signed n-bit Integer i. If the key iis out of range, + also returns Null. + +* `F46B`— `DICTUGETOPTREF (i D n– cˀ)`, similar to `DICTGETOPTREF`, but + with the key given by unsigned n-bit Integer i. + +* `F46D`— `DICTSETGETOPTREF (cˀ k D n– D′ ˜cˀ)`, a variant of both + `DICTGETOPTREF` and `DICTSETGETREF` that sets the value corresponding + to key k in dictionary D to cˀ (if cˀ is Null, then the key is deleted + instead), and returns the old value ˜cˀ (if the key k was absent before, + returns Null instead). + +* `F46E`— `DICTISETGETOPTREF (cˀ i D n– D′ ˜cˀ)`, similar to primitive + `DICTSETGETOPTREF`, but using signed n-bit Integer ias a key. If idoes + not fit into n bits, throws a range checking exception. + +* `F46F`— `DICTUSETGETOPTREF (cˀ i D n– D′ ˜cˀ)`, similar to primitive + DICTSETGETOPTREF, but using unsigned n-bit Integer i as a key. + +### A.10.8. Prefix code dictionary operations. + +SomeGet operationsforprefixcodedictionariesmaybefoundinA.10.11. +Other prefix code dictionary operations include: + +* `F470`— `PFXDICTSET (x k D n– D′ −1 or D 0)`. +* `F471`— `PFXDICTREPLACE (x k D n– D′ −1 or D 0)`. +* `F472`— `PFXDICTADD (x k D n– D′ −1 or D 0)`. +* `F473`— `PFXDICTDEL (k D n– D′ −1 or D 0)`. + +These primitives are completely similar to their non-prefix code counterparts +`DICTSET` etc (cf.A.10.4),with the obvious difference that even a Set may fail +in a prefix code dictionary, so a success flag must be returned by `PFXDICTSET` +as well. + +### A.10.9. Variants of GetNext and GetPrev operations. + +* `F474`— `DICTGETNEXT (k D n– x′ k′ −1 or 0)`, computes the minimal + key `k′` in dictionary D that is lexicographically greater than `k`, and + returns `k′` (represented by a Slice) along with associated value `x′` (also + represented by a Slice). + +* `F475`—`DICTGETNEXTEQ(kDn–x′k′ −1 or0)`,similar to `DICTGETNEXT`, + but computes the minimal key k′that is lexicographically greater than + or equal to k. + +* `F476`— `DICTGETPREV (kDn– x′k′ −1 or 0)`, similar to `DICTGETNEXT`, + but computes the maximal key k′ lexicographically smaller than k. + +* `F477`—`DICTGETPREVEQ(kDn–x′k′ −1 or0)`,similar to `DICTGETPREV`, + but computes the maximal key k′ lexicographically smaller than or + equal to k. + +* `F478`— `DICTIGETNEXT (iDn– x′i′ −1 or 0)`, similar to `DICTGETNEXT`, + but interprets all keys in dictionary D as big-endian signed n-bit in- + tegers, and computes the minimal key i′ that is larger than Integer i + (which does not necessarily fit into n bits). + +* `F479`— `DICTIGETNEXTEQ (i D n– x′ i′ −1 or 0)`. + +* `F47A`— `DICTIGETPREV (i D n– x′ i′ −1 or 0)`. + +* `F47B`— `DICTIGETPREVEQ (i D n– x′ i′ −1 or 0)`. + +* `F47C`— `DICTUGETNEXT (iDn– x′i′ −1 or 0)`, similar to `DICTGETNEXT`, + but interprets all keys in dictionary D as big-endian unsigned n-bit + integers, and computes the minimal key i′ that is larger than Integer i + (which does not necessarily fit into n bits, and is not necessarily non- + negative). + +* `F47D`— `DICTUGETNEXTEQ (i D n– x′ i′ −1 or 0)`. + +* `F47E`— `DICTUGETPREV (i D n– x′ i′ −1 or 0)`. + +* `F47F`— `DICTUGETPREVEQ (i D n– x′ i′ −1 or 0)`. + +### A.10.10. GetMin, GetMax, RemoveMin, RemoveMax operations. + +* `F482`— `DICTMIN (D n– x k−1 or 0)`, computes the minimal key k + (represented by a Slice with n data bits) in dictionary D, and returns + k along with the associated value x. + +* `F483`— `DICTMINREF (D n– c k−1 or 0)`, similar to DICTMIN, but + returns the only reference in the value as a Cell c. + +* `F484`— `DICTIMIN (D n– x i−1 or 0)`, somewhat similar to DICTMIN, + but computes the minimal key i under the assumption that all keys + are big-endian signed n-bit integers. Notice that the key and value + returned may differ from those computed by `DICTMIN` and `DICTUMIN`. + +* `F485`— `DICTIMINREF (D n– c i−1 or 0)`. + +* `F486`— `DICTUMIN (Dn– xi−1 or 0)`, similar to `DICTMIN`, but returns + the key as an unsigned n-bit Integer i. + +* `F487`— `DICTUMINREF (D n– c i−1 or 0)`. + +* `F48A`— `DICTMAX (D n– x k−1 or 0)`, computes the maximal key k + (represented by a Slice with n data bits) in dictionary D, and returns + k along with the associated value x. + +* `F48B`— `DICTMAXREF (D n– c k−1 or 0)`. + +* `F48C`— `DICTIMAX (D n– x i−1 or 0)`. + +* `F48D`— `DICTIMAXREF (D n– c i−1 or 0)`. + +* `F48E`— `DICTUMAX (D n– x i−1 or 0)`. + +* `F48F`— `DICTUMAXREF (D n– c i−1 or 0)`. + +* `F492`— `DICTREMMIN (D n– D′xk−1 or D 0)`, computes the minimal + key k(represented by a Slice with ndata bits) in dictionary D, removes + k from the dictionary, and returns k along with the associated value x + and the modified dictionary D′. + +* `F493`—`DICTREMMINREF(Dn–D′ck−1 orD0)`,similar to`DICTREMMIN`, + but returns the only reference in the value as a Cell c. + +* `F494`— `DICTIREMMIN (D n– D′ x i−1 or D 0)`, somewhat similar + to DICTREMMIN, but computes the minimal key iunder the assumption + that all keys are big-endian signed n-bit integers. Notice that the key + and value returned may differ from those computed by `DICTREMMIN` and + `DICTUREMMIN`. + +* `F495`— `DICTIREMMINREF (D n– D′ c i−1 or D 0)`. + +* `F496`— `DICTUREMMIN(Dn– D′xi−1 or D0)`, similar to `DICTREMMIN`, + but returns the key as an unsigned n-bit Integer i. + +* `F497`— `DICTUREMMINREF (D n– D′ c i−1 or D 0)`. + +### A.10.11. Special Get dictionary and prefix code dictionary operations, and constant dictionaries. + +* `F4A0` — `DICTIGETJMP (i D n – )`, similar to `DICTIGET` (cf. [A.10.12](#a-10-12-subdict-dictionary-operations)), + but with `x` `BLESS`ed into a continuation with a subsequent `JMPX` to it + on success. On failure, does nothing. This is useful for implementing + switch/case constructions. + +* `F4A1` — `DICTUGETJMP (i D n – )`, similar to `DICTIGETJMP`, but performs + `DICTUGET` instead of `DICTIGET`. + +* `F4A2` — `DICTIGETEXEC (i D n – )`, similar to `DICTIGETJMP`, but with + `EXECUTE` instead of `JMPX`. + +* `F4A3` — `DICTUGETEXEC (i D n – )`, similar to `DICTUGETJMP`, but with + `EXECUTE` instead of `JMPX`. + +* `F4A6_n` — `DICTPUSHCONST n ( – D n)`, pushes a non-empty constant + dictionary `D` (as a `Cellˀ`) along with its key length `0 ≤ n ≤ 1023`, + stored as a part of the instruction. The dictionary itself is created from + the first of remaining references of the current continuation. In this + way, the complete `DICTPUSHCONST` instruction can be obtained by first + serializing `xF4A8_`, then the non-empty dictionary itself (one `1` bit and + a cell reference), and then the unsigned 10-bit integer `n` (as if by a `STU 10` + instruction). An empty dictionary can be pushed by a `NEWDICT` + primitive (cf. [A.10.1](#a-10-1-dictionary-creation)) instead. + +* `F4A8` — `PFXDICTGETQ (s D n – s′ x s′′ −1 or s 0)`, looks up the unique + prefix of `Slice s` present in the prefix code dictionary (cf. `3.4.2`) rep- + resented by `Cellˀ D` and `0 ≤ n ≤ 1023`. If found, the prefix of `s` is + returned as `s′`, and the corresponding value (also a `Slice`) as `x`. The + remainder of `s` is returned as a `Slice s′′`. If no prefix of `s` is a key in + prefix code dictionary `D`, returns the unchanged `s` and a zero flag to + indicate failure. + +* `F4A9` — `PFXDICTGET (s D n – s′ x s′′)`, similar to `PFXDICTGET`, but + throws a cell deserialization failure exception on failure. + +* `F4AA` — `PFXDICTGETJMP (s D n – s′ s′′ or s)`, similar to `PFXDICTGETQ`, + but on success `BLESS`es the value `x` into a `Continuation` and transfers + control to it as if by a `JMPX`. On failure, returns `s` unchanged and + continues execution. + +* `F4AB` — `PFXDICTGETEXEC (s D n – s′ s′′)`, similar to `PFXDICTGETJMP`, + but `EXECUTE`s the continuation found instead of jumping to it. On + failure, throws a cell deserialization exception. + +* `F4AE_n` — `PFXDICTCONSTGETJMP n` or `PFXDICTSWITCH n (s – s′ s′′ or s)`, + combines `DICTPUSHCONST n` for `0 ≤ n ≤ 1023` with `PFXDICTGETJMP`. + +* `F4BC` — `DICTIGETJMPZ (i D n – i or nothing)`, a variant of `DICTIGETJMP` + that returns index `i` on failure. + +* `F4BD` — `DICTUGETJMPZ (i D n – i or nothing)`, a variant of `DICTUGETJMP` + that returns index `i` on failure. + +* `F4BE` — `DICTIGETEXECZ (i D n – i or nothing)`, a variant of `DICTIGETEXEC` + that returns index `i` on failure. + +* `F4BF` — `DICTUGETEXECZ (i D n – i or nothing)`, a variant of `DICTUGETEXEC` + that returns index `i` on failure. + + +### A.10.12. SubDict dictionary operations + +* `F4B1` — `SUBDICTGET (k l D n – D′)`, constructs a subdictionary con- + sisting of all keys beginning with prefix `k` (represented by a `Slice`, the + first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` + in dictionary `D` of type `HashmapE(n, X)` with `n`-bit keys. On success, + returns the new subdictionary of the same type `HashmapE(n, X)` as a + `Slice D′`. + +* `F4B2` — `SUBDICTIGET (x l D n – D′)`, variant of `SUBDICTGET` with + the prefix represented by a signed big-endian `l`-bit `Integer x`, where + necessarily `l ≤ 257`. + +* `F4B3` — `SUBDICTUGET (x l D n – D′)`, variant of `SUBDICTGET` with the + prefix represented by an unsigned big-endian `l`-bit `Integer x`, where + necessarily `l ≤ 256`. + +* `F4B5` — `SUBDICTRPGET (k l D n – D′)`, similar to `SUBDICTGET`, but + removes the common prefix `k` from all keys of the new dictionary `D′`, + which becomes of type `HashmapE(n − l, X)`. + +* `F4B6` — `SUBDICTIRPGET (x l D n – D′)`, variant of `SUBDICTRPGET` with + the prefix represented by a signed big-endian `l`-bit `Integer x`, where + necessarily `l ≤ 257`. + +* `F4B7` — `SUBDICTURPGET (x l D n – D′)`, variant of `SUBDICTRPGET` with + the prefix represented by an unsigned big-endian `l`-bit `Integer x`, where + necessarily `l ≤ 256`. + +* `F4BC–F4BF` — used by `DICT...Z` primitives in [A.10.11](#a-10-11-special-get-dictionary-and-prefix-code-dictionary-operations%2C-and-constant-dictionaries). + + +## A.11 Application-specific primitives + +OpcoderangeF8...FB is reserved for the application-specific primitives. When +TVM is used to execute TON Blockchain smart contracts, these application- +specific primitives are in fact TON Blockchain-specific. + +### A.11.1. External actions and access to blockchain configuration data. + +Most of the primitives listed below use 16-bit opcodes. + +* * `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value + `gm`, and resets the gas credit `gc` to zero (cf. `1.4`), decreasing the value + of `gr` by `gc` in the process. In other words, the current smart contract + agrees to buy some gas to finish the current transaction. This action + is required to process external messages, which bring no value (hence + no gas) with themselves. + +* `F801` — `SETGASLIMIT (g – )`, sets current gas limit `gl` to the minimum + of `g` and `gm`, and resets the gas credit `gc` to zero. If the gas consumed + so far (including the present instruction) exceeds the resulting value of + `gl`, an (unhandled) out of gas exception is thrown before setting new + gas limits. Notice that `SETGASLIMIT` with an argument `g ≥263 −1` is + equivalent to `ACCEPT`. + +* `F802` — `BUYGAS (x – )`, computes the amount of gas that can be + bought for `x` nanograms, and sets `gl` accordingly in the same way as + `SETGASLIMIT`. + +* `F804` — `GRAMTOGAS (x– g)`, computes the amount of gas that can be + bought for `x` nanograms. If `x` is negative, returns `0`. If `g` exceeds `263 −1`, + it is replaced with this value. + +* `F805` — `GASTOGRAM (g– x)`, computes the price of `g` gas in nanograms. + +* `F806–F80E` — Reserved for gas-related primitives. + +* `F80F` — `COMMIT ( – )`, commits the current state of registers `c4` (“persis- + tentdata”) and `c5` (“actions”) so that the current execution is considered + “successful” with the saved values even if an exception is thrown later. + + +### A.11.3. Pseudo-random number generator primitives. + +* `F810` — `RANDU256 ( – x)`, generates a new pseudo-random unsigned + 256-bit `Integer x`. The algorithm is as follows: if `r` is the old value + of the random seed, considered as a 32-byte array (by constructing + the big-endian representation of an unsigned 256-bit integer), then its + `sha512(r)` is computed; the first 32 bytes of this hash are stored as + the new value `r′` of the random seed, and the remaining 32 bytes are + returned as the next random value `x`. + +* `F811` — `RAND (y – z)`, generates a new pseudo-random integer `z` in the + range `0 ... y − 1` (or `y ... −1`, if `y < 0`). More precisely, an unsigned + random value `x` is generated as in `RANDU256`; then + `z := ⌊x·y / 2^256⌋` is computed. + Equivalent to `RANDU256; MULRSHIFT 256`. + +* `F814` — `SETRAND (x – )`, sets the random seed to unsigned 256-bit + `Integer x`. + +* `F815` — `ADDRAND (x – )`, mixes unsigned 256-bit `Integer x` into the ran- + dom seed `r` by setting the random seed to `sha256` of the concatenation + of two 32-byte strings: the first with the big-endian representation of + the old seed `r`, and the second with the big-endian representation of `x`. + +* `F810–F81F` — Reserved for pseudo-random number generator primi- + tives. + + +### A.11.4. Configuration primitives. + +* `F82i` — `GETPARAM i ( – x)`, returns the `i`-th parameter from the `Tuple` + provided at `c7` for `0 ≤ i < 16`. Equivalent to `PUSH c7; FIRST; INDEX i`. + If one of these internal operations fails, throws an appropriate type + checking or range checking exception. + +* `F823` — `NOW ( – x)`, returns the current Unix time as an `Integer`. + If it is impossible to recover the requested value starting from `c7`, + throws a type checking or range checking exception as appropriate. + Equivalent to `GETPARAM 3`. + +* `F824` — `BLOCKLT ( – x)`, returns the starting logical time of the current + block. Equivalent to `GETPARAM 4`. + +* `F825` — `LTIME ( – x)`, returns the logical time of the current transaction. + Equivalent to `GETPARAM 5`. + +* `F826` — `RANDSEED ( – x)`, returns the current random seed as an unsigned + 256-bit `Integer`. Equivalent to `GETPARAM 6`. + +* `F827` — `BALANCE ( – t)`, returns the remaining balance of the smart + contract as a `Tuple` consisting of an `Integer` (the remaining Gram bal- + ance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys + representing the balance of “extra currencies”). Equivalent to `GETPARAM 7`. + Note that RAW primitives such as `SENDRAWMSG` do not update this field. + +* `F828` — `MYADDR ( – s)`, returns the internal address of the current smart + contract as a `Slice` with a `MsgAddressInt`. If necessary, it can be parsed + further using primitives such as `PARSESTDADDR` or `REWRITESTDADDR`. + Equivalent to `GETPARAM 8`. + +* `F829` — `CONFIGROOT ( – D)`, returns the `Maybe Cell D` with the current + global configuration dictionary. Equivalent to `GETPARAM 9`. + +* `F830` — `CONFIGDICT ( – D 32)`, returns the global configuration dic- + tionary along with its key length `(32)`. Equivalent to `CONFIGROOT; PUSHINT 32`. + +* `F832` — `CONFIGPARAM (i – c −1 or 0)`, returns the value of the global + configuration parameter with integer index `i` as a `Cell c`, and a flag to + indicate success. Equivalent to `CONFIGDICT; DICTIGETREF`. + +* `F833` — `CONFIGOPTPARAM (i – cˀ)`, returns the value of the global config- + uration parameter with integer index `i` as a `Maybe Cell cˀ`. Equivalent + to `CONFIGDICT; DICTIGETOPTREF`. + +* `F820–F83F` — Reserved for configuration primitives. + +### A.11.5. Global variable primitives. + +* `F840`— `GETGLOBVAR (k– x)`, returns the k-th global variable for `0 ≤ + k < 255`. Equivalent to PUSH c7; SWAP; INDEXVARQ (cf. A.3.2). + +* `F85_k`— `GETGLOB k ( – x)`, returns the k-th global variable for 1 ≤ + k≤31. Equivalent to PUSH c7; INDEXQ k. + +* `F860`— `SETGLOBVAR (x k – )`, assigns x to the k-th global variable for + `0 ≤ k< 255`. Equivalent to `PUSH c7`; `ROTREV`; `SETINDEXVARQ`; `POP c7`. + +* `F87_k`— `SETGLOB k (x – )`, assigns x to the k-th global variable for + `1 ≤k≤31`. Equivalent to `PUSH c7`; `SWAP`; `SETINDEXQ k`; `POP c7`. + +### A.11.6. Hashing and cryptography primitives. + +* `F900`— `HASHCU (c– x)`, computes the representation hash (cf. 3.1.5) + of a Cell c and returns it as a 256-bit unsigned integer x. Useful for + signing and checking signatures of arbitrary entities represented by a + tree of cells. + +* `F901`— `HASHSU (s– x)`, computes the hash of a Slice s and returns it + as a 256-bit unsigned integer x. The result is the same as if an ordinary + cell containing only data and references from s had been created and + its hash computed by HASHCU. + +* `F902`— `SHA256U (s– x)`, computes sha256 of the data bits of Slice s. + If the bit length of s is not divisible by eight, throws a cell underflow + exception. The hash value is returned as a 256-bit unsigned integer x. + +* `F910`— `CHKSIGNU (h s k– ? )`, checks the Ed25519-signature s of a + hash h (a 256-bit unsigned integer, usually computed as the hash of + some data) using public key k (also represented by a 256-bit unsigned + integer). The signature s must be a Slice containing at least 512 data + bits; only the first 512 bits are used. The result is−1 if the signature + is valid, 0 otherwise. Notice that CHKSIGNU is equivalent to ROT; NEWB; + STU 256; ENDB; NEWC; ROTREV; CHKSIGNS, i.e., to CHKSIGNS with the + first argument d set to 256-bit Slice containing h. Therefore, if h is + computed as the hash of some data, these data are hashed twice, the + second hashing occurring inside CHKSIGNS. + +* `F911`— `CHKSIGNS (d s k– ? )`, checks whether s is a valid Ed25519- + signature of the data portion of Slice dusing public key k, similarly to + CHKSIGNU. If the bit length of Slice d is not divisible by eight, throws + a cell underflow exception. The verification of Ed25519 signatures is + the standard one, with sha256 used to reduce dto the 256-bit number + that is actually signed. + +* `F912–F93F` — Reserved for hashing and cryptography primitives. + +### A.11.7. Miscellaneous primitives. + +* `F940` — `CDATASIZEQ (c n – x y z −1 or 0)`, recursively computes the + count of distinct cells `x`, data bits `y`, and cell references `z` in the DAG + rooted at `Cell c`, effectively returning the total storage used by this + DAG taking into account the identification of equal cells. The values of + `x`, `y`, and `z` are computed by a depth-first traversal of this DAG, with a + hash table of visited cell hashes used to prevent visits of already-visited + cells. The total count of visited cells `x` cannot exceed non-negative + `Integer n`; otherwise the computation is aborted before visiting the + `(n+1)`-st cell and a zero is returned to indicate failure. If `c` is `Null`, + returns `x = y = z = 0`. + +* `F941` — `CDATASIZE (c n – x y z)`, a non-quiet version of `CDATASIZEQ` + that throws a cell overflow exception (8) on failure. + +* `F942` — `SDATASIZEQ (s n – x y z −1 or 0)`, similar to `CDATASIZEQ`, but + accepting a `Slice s` instead of a `Cell`. The returned value of `x` does not + take into account the cell that contains the slice `s` itself; however, the + data bits and the cell references of `s` are accounted for in `y` and `z`. + +* `F943` — `SDATASIZE (s n – x y z)`, a non-quiet version of `SDATASIZEQ` + that throws a cell overflow exception (8) on failure. + +* `F944–F97F` — Reserved for miscellaneous TON-specific primitives that + do not fall into any other specific category. + + + +### A.11.8. Currency manipulation primitives. + +* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDUX`. + +* `FA01` — `LDVARINT16` `(s – x s0)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDIX`. + +* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2¹²⁰−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2⁸ˡ`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. + +* `FA03` — `STVARINT16` `(b x – b 0)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2¹¹⁹ ... 2¹¹⁹ − 1`. + +* `FA04` — `LDVARUINT32` `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2²⁴⁸`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 5`; `SWAP`; `SHIFT 3`; `LDUX`. + +* `FA05` — `LDVARINT32` `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷`. + +* `FA06` — `STVARUINT32` `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2²⁴⁸` as a `VarUInteger 32`. + +* `FA07` — `STVARINT32` `(b x – b 0)`, serializes an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷` as a `VarInteger 32`. + +* `FA08–FA1F` — Reserved for currency manipulation primitives. + + +### A.11.9. Message and address manipulation primitives. + +The message and address manipulation primitives listed below serialize and deserialize values according to the following TL-B scheme (cf. [3.3.4](#3-3-4-serialization-of-standard-types)): + +```asm +addr_none$00 = MsgAddressExt; +addr_extern$01 len:(## 8) external_address:(bits len) = MsgAddressExt; +anycast_info$_ depth:(<= 30) { depth >= 1 } rewrite_pfx:(bits depth) = Anycast; +addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt; +addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) workchain_id:int32 address:(bits addr_len) = MsgAddressInt; +_ _:MsgAddressInt = MsgAddress; +_ _:MsgAddressExt = MsgAddress; + +int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + src:MsgAddress dest:MsgAddressInt + value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams + created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; + +ext_out_msg_info$11 src:MsgAddress dest:MsgAddressExt + created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed; +``` + +A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: + +* `addr_none` is represented by `t = (0)`, i.e., a `Tuple` containing exactly one `Integer` equal to zero. +* `addr_extern` is represented by `t = (1, s)`, where `Slice` `s` contains the field `external_address`. In other words, `t` is a pair (a `Tuple` consisting of two entries), containing an `Integer` equal to one and `Slice` `s`. +* `addr_std` is represented by `t = (2, u, x, s)`, where `u` is either a `Null` (if `anycast` is absent) or a `Slice` `s′` containing `rewrite_pfx` (if `anycast` is present). Next, `Integer` `x` is the `workchain_id`, and `Slice` `s` contains the address. + `135` + A.11. Application-specific primitives +* `addr_var` is represented by `t = (3, u, x, s)`, where `u`, `x`, and `s` have the same meaning as for `addr_std`. + + +### A.11.9. Message and address manipulation primitives. + +* `FA40` — `LDMSGADDR` `(s – s′ s′′)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s′` and the remainder `s′′` of `s` as `CellSlices`. +* `FA41` — `LDMSGADDRQ` `(s – s′ s′′ −1 or s 0)`, a quiet version of `LDMSGADDR`: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. +* `FA42` — `PARSEMSGADDR` `(s – t)`, decomposes `CellSlice` `s` containing a valid `MsgAddress` into a `Tuple` `t` with separate fields of this `MsgAddress`. If `s` is not a valid `MsgAddress`, a cell deserialization exception is thrown. +* `FA43` — `PARSEMSGADDRQ` `(s – t −1 or 0)`, a quiet version of `PARSEMSGADDR`: returns a zero on error instead of throwing an exception. +* `FA44` — `REWRITESTDADDR` `(s – x y)`, parses `CellSlice` `s` containing a valid `MsgAddressInt` (usually a `msg_addr_std`), applies rewriting from the `anycast` (if present) to the same-length prefix of the address, and returns both the workchain `x` and the 256-bit address `y` as `Integer`s. If the address is not 256-bit, or if `s` is not a valid serialization of `MsgAddressInt`, throws a cell deserialization exception. +* `FA45` — `REWRITESTDADDRQ` `(s – x y −1 or 0)`, a quiet version of primitive `REWRITESTDADDR`. +* `FA46` — `REWRITEVARADDR` `(s – x s′)`, a variant of `REWRITESTDADDR` that returns the (rewritten) address as a `Slice` `s`, even if it is not exactly 256 bit long (represented by a `msg_addr_var`). +* `FA47` — `REWRITEVARADDRQ` `(s – x s′ −1 or 0)`, a quiet version of primitive `REWRITEVARADDR`. +* `FA48–FA5F` — Reserved for message and address manipulation primitives. + +### A.11.10. Outbound message and output action primitives. + +* `FB00` — `SENDRAWMSG` `(c x – )`, sends a raw message contained in `Cell` `c`, which should contain a correctly serialized object `Message X`, with the only exception that the source address is allowed to have dummy value `addr_none` (to be automatically replaced with the current smart-contract address), and `ihr_fee`, `fwd_fee`, `created_lt` and `created_at` fields can have arbitrary values (to be rewritten with correct values during the action phase of the current transaction). `Integer` parameter `x` contains the flags. Currently `x = 0` is used for ordinary messages; `x = 128` is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message); `x = 64` is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message (if bit `0` is not set, the gas fees are deducted from this amount); `x' = x + 1` means that the sender wants to pay transfer fees separately; `x' = x + 2` means that any errors arising while processing this message during the action phase should be ignored. Finally, `x' = x + 32` means that the current account must be destroyed if its resulting balance is zero. This flag is usually employed together with `+128`. +* `FB02` — `RAWRESERVE` `(x y – )`, creates an output action which would reserve exactly `x` nanograms (if `y = 0`), at most `x` nanograms (if `y = 2`), or all but `x` nanograms (if `y = 1` or `y = 3`), from the remaining balance of the account. It is roughly equivalent to creating an outbound message carrying `x` nanograms (or `b − x` nanograms, where `b` is the remaining balance) to oneself, so that the subsequent output actions would not be able to spend more money than the remainder. Bit `+2` in `y` means that the external action does not fail if the specified amount cannot be reserved; instead, all remaining balance is reserved. Bit `+8` in `y` means `x ← −x` before performing any further actions. Bit `+4` in `y` means that `x` is increased by the original balance of the current account (before the compute phase), including all extra currencies, before performing any other checks and actions. Currently `x` must be a non-negative integer, and `y` must be in the range `0 ... 15`. +* `FB03` — `RAWRESERVEX` `(x D y – )`, similar to `RAWRESERVE`, but also accepts a dictionary `D` (represented by a `Cell` or `Null`) with extra currencies. In this way currencies other than Grams can be reserved. +* `FB04` — `SETCODE` `(c – )`, creates an output action that would change this smart contract code to that given by `Cell` `c`. Notice that this change will take effect only after the successful termination of the current run of the smart contract. +* `FB06` — `SETLIBCODE` `(c x – )`, creates an output action that would modify the collection of this smart contract libraries by adding or removing library with code given in `Cell` `c`. If `x = 0`, the library is actually removed if it was previously present in the collection (if not, this action does nothing). If `x = 1`, the library is added as a private library, and if `x = 2`, the library is added as a public library (and becomes available to all smart contracts if the current smart contract resides in the masterchain); if the library was present in the collection before, its public/private status is changed according to `x`. Values of `x` other than `0 ... 2` are invalid. +* `FB07` — `CHANGELIB` `(h x – )`, creates an output action similarly to `SETLIBCODE`, but instead of the library code accepts its hash as an unsigned 256-bit integer `h`. If `x ≠ 0` and the library with hash `h` is absent from the library collection of this smart contract, this output action will fail. +* `FB08–FB3F` — Reserved for output action primitives. + +--- + +## A.12 Debug primitives + +Opcodes beginning with `FE` are reserved for the debug primitives. These primitives have known fixed operation length, and behave as (multibyte) `NOP` operations. In particular, they never change the stack contents, and never throw exceptions, unless there are not enough bits to completely decode the opcode. However, when invoked in a TVM instance with debug mode enabled, these primitives can produce specific output into the text debug log of the TVM instance, never affecting the TVM state (so that from the perspective of TVM the behavior of debug primitives in debug mode is exactly the same). For instance, a debug primitive might dump all or some of the values near the top of the stack, display the current state of TVM and so on. + +### A.12.1. Debug primitives as multibyte NOPs. + +* `FEnn` — `DEBUG nn`, for `0 ≤ nn < 240`, is a two-byte `NOP`. +* `FEFnssss` — `DEBUGSTR ssss`, for `0 ≤ n < 16`, is an `(n + 3)`-byte `NOP`, with the `(n + 1)`-byte “contents string” `ssss` skipped as well. + +### A.12.2. Debug primitives as operations without side-effect. + +Next we describe the debug primitives that might (and actually are) implemented in a version of TVM. Notice that another TVM implementation is free to use these codes for other debug purposes, or treat them as multibyte `NOP`s. Whenever these primitives need some arguments from the stack, they inspect these arguments, but leave them intact in the stack. If there are insufficient values in the stack, or they have incorrect types, debug primitives may output error messages into the debug log, or behave as `NOP`s, but they cannot throw exceptions. + +* `FE00` — `DUMPSTK`, dumps the stack (at most the top 255 values) and shows the total stack depth. +* `FE0n` — `DUMPSTKTOP n`, `1 ≤ n < 15`, dumps the top `n` values from the stack, starting from the deepest of them. If there are `d < n` values available, dumps only `d` values. +* `FE10` — `HEXDUMP`, dumps `s0` in hexadecimal form, be it a `Slice` or an `Integer`. +* `FE11` — `HEXPRINT`, similar to `HEXDUMP`, except the hexadecimal representation of `s0` is not immediately output, but rather concatenated to an output text buffer. +* `FE12` — `BINDUMP`, dumps `s0` in binary form, similarly to `HEXDUMP`. +* `FE13` — `BINPRINT`, outputs the binary representation of `s0` to a text buffer. +* `FE14` — `STRDUMP`, dumps the `Slice` at `s0` as an UTF-8 string. +* `FE15` — `STRPRINT`, similar to `STRDUMP`, but outputs the string into a text buffer (without carriage return). +* `FE1E` — `DEBUGOFF`, disables all debug output until it is re-enabled by a `DEBUGON`. More precisely, this primitive increases an internal counter, which disables all debug operations (except `DEBUGOFF` and `DEBUGON`) when strictly positive. +* `FE1F` — `DEBUGON`, enables debug output (in a debug version of TVM). +* `FE2n` — `DUMP s(n)`, `0 ≤ n < 15`, dumps `s(n)`. +* `FE3n` — `PRINT s(n)`, `0 ≤ n < 15`, concatenates the text representation of `s(n)` (without any leading or trailing spaces or carriage returns) to a text buffer which will be output before the output of any other debug operation. +* `FEC0–FEEF` — Use these opcodes for custom/experimental debug operations. +* `FEFnssss` — `DUMPTOSFMT ssss`, dumps `s0` formatted according to the `(n + 1)`-byte string `ssss`. This string might contain (a prefix of) the name of a TL-B type supported by the debugger. If the string begins with a zero byte, simply outputs it (without the first byte) into the debug log. If the string begins with a byte equal to one, concatenates it to a buffer, which will be output before the output of any other debug operation (effectively outputs a string without a carriage return). +* `FEFn00ssss` — `LOGSTR ssss`, string `ssss` is `n` bytes long. +* `FEF000` — `LOGFLUSH`, flushes all pending debug output from the buffer into the debug log. +* `FEFn01ssss` — `PRINTSTR ssss`, string `ssss` is `n` bytes long. + +--- + +## A.13 Codepage primitives + +The following primitives, which begin with byte `FF`, typically are used at the very beginning of a smart contract’s code or a library subroutine to select another TVM codepage. Notice that we expect all codepages to contain these primitives with the same codes, otherwise switching back to another codepage might be impossible (cf. [5.1.8](#5-1-8-setting-the-codepage-in-the-code-itself)). + +* `FFnn` — `SETCP nn`, selects TVM codepage `0 ≤ nn < 240`. If the codepage is not supported, throws an invalid opcode exception. +* `FF00` — `SETCP0`, selects TVM (test) codepage zero as described in this document. +* `FFFz` — `SETCP z − 16`, selects TVM codepage `z − 16` for `1 ≤ z ≤ 15`. Negative codepages `−13 ... −1` are reserved for restricted versions of TVM needed to validate runs of TVM in other codepages as explained in [B.2.6](#b-2-6-codepage-−1). Negative codepage `−14` is reserved for experimental codepages, not necessarily compatible between different TVM implementations, and should be disabled in the production versions of TVM. +* `FFF0` — `SETCPX` `(c – )`, selects codepage `c` with `−−2¹⁵ ≤ c < 2¹⁵` passed in the top of the stack. +--- + +# B Formal properties and specifications of TVM + +This appendix discusses certain formal properties of TVM that are necessary for executing smart contracts in the TON Blockchain and validating such executions afterwards. + +## B.1 Serialization of the TVM state + +Recall that a virtual machine used for executing smart contracts in a blockchain must be deterministic, otherwise the validation of each execution would require the inclusion of all intermediate steps of the execution into a block, or at least of the choices made when indeterministic operations have been performed. + +Furthermore, the state of such a virtual machine must be (uniquely) serializable, so that even if the state itself is not usually included in a block, its hash is still well-defined and can be included into a block for verification purposes. + +### B.1.1. TVM stack values. + +TVM stack values can be serialized as follows: + +```asm +vm_stk_tinyint#01 value:int64 = VmStackValue; +vm_stk_int#0201_ value:int257 = VmStackValue; +vm_stk_nan#02FF = VmStackValue; +vm_stk_cell#03 cell:^Cell = VmStackValue; +_ cell:^Cell st_bits:(## 10) end_bits:(## 10) + { st_bits <= end_bits } + st_ref:(#<= 4) end_ref:(#<= 4) + { st_ref <= end_ref } = VmCellSlice; +vm_stk_slice#04 _:VmCellSlice = VmStackValue; +vm_stk_builder#05 cell:^Cell = VmStackValue; vm_stk_cont#06 cont:VmCont = VmStackValue; ``` @@ -2759,7 +3571,7 @@ Of these, `vm_stk_tinyint` is never used by TVM in codepage zero; it is used onl The TVM stack can be serialized as follows: -``` +```asm vm_stack#_ depth:(## 24) stack:(VmStackList depth) = VmStack; vm_stk_cons#_ {n:#} head:VmStackValue tail:^(VmStackList n) = VmStackList (n + 1); @@ -2770,7 +3582,7 @@ vm_stk_nil#_ = VmStackList 0; Control registers in TVM can be serialized as follows: -``` +```asm _ cregs:(HashmapE 4 VmStackValue) = VmSaveList; ``` @@ -2778,7 +3590,7 @@ _ cregs:(HashmapE 4 VmStackValue) = VmSaveList; Gas limits in TVM can be serialized as follows: -``` +```asm gas_limits#_ remaining:int64 _:^[ max_limit:int64 cur_limit:int64 credit:int64 ] = VmGasLimits; @@ -2788,7 +3600,7 @@ gas_limits#_ remaining:int64 _:^[ The TVM library environment can be serialized as follows: -``` +```asm _ libraries:(HashmapE 256 ^Cell) = VmLibraries; ``` @@ -2796,7 +3608,7 @@ _ libraries:(HashmapE 256 ^Cell) = VmLibraries; Continuations in TVM can be serialized as follows: -``` +```asm vmc_std$00 nargs:(## 22) stack:(Maybe VmStack) save:VmSaveList cp:int16 code:VmCellSlice = VmCont; vmc_envelope$01 nargs:(## 22) stack:(Maybe VmStack) @@ -2816,7 +3628,7 @@ vmc_pushint$1111 value:int32 next:^VmCont = VmCont; The total state of TVM can be serialized as follows: -``` +```asm vms_init$00 cp:int16 step:int32 gas:GasLimits stack:(Maybe VmStack) save:VmSaveList code:VmCellSlice lib:VmLibraries = VmState; @@ -2864,54 +3676,63 @@ The TON Blockchain adopts this approach to validate the runs of TVM (e.g., those ### B.2.6. Codepage −1. -Codepage `−1` of TVM is reserved for the stripped-down version of TVM. Its main purpose is to execute the reference implementation of the step function of the full TVM. This codepage contains only special versions of arithmetic primitives working with “tiny integers” (64-bit signed integers); therefore, TVM’s 257-bit `Integer` arithmetic must be defined in terms of 64-bit arithmetic. Elliptic curve cryptography primitives are also implemented directly in codepage `−1`, without using any third-party libraries. Finally, a reference implementation of the `sha256` hash function is also provided in codepage `−1`. +Codepage `−1` of TVM is reserved for the stripped-down version of TVM. Its main purpose is to execute the reference implementation of the step function of the full TVM. This codepage contains only special versions of arithmetic primitives working with “tiny integers” (64-bit signed integers); therefore, TVM’s 257-bit `Integer` arithmetic must be defined in terms of 64-bit arithmetic. + +Elliptic curve cryptography primitives are also implemented directly in codepage `−1`, without using any third-party libraries. Finally, a reference implementation of the `sha256` hash function is also provided in codepage `−1`. ### B.2.7. Codepage −2. -This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage −2”. All 64-bit arithmetic used in codepage −1 would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage −1. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer.[30](#footnote-30) +This bootstrapping process could be iterated even further, by providing an emulator of the stripped-down version of TVM written for an even simpler version of TVM that supports only boolean values (or integers `0` and `1`)—a “codepage −2”. + +All 64-bit arithmetic used in codepage −1 would then need to be defined by means of boolean operations, thus providing a reference implementation for the stripped-down version of TVM used in codepage −1. In this way, if some of the TON Blockchain validators did not agree on the results of their 64-bit arithmetic, they could regress to this reference implementation to find the correct answer.[30](#footnote-30) --- # C Code density of stack and register machines -This appendix extends the general consideration of stack manipulation primitives provided in 2.2, explaining the choice of such primitives for TVM, with a comparison of stack machines and register machines in terms of the quantity of primitives used and the code density. We do this by comparing the machine code that might be generated by an optimizing compiler for the same source files, for different (abstract) stack and register machines. +This appendix extends the general consideration of stack manipulation primitives provided in [2.2](#2-2-stack-manipulation-primitives), explaining the choice of such primitives for TVM, with a comparison of stack machines and register machines in terms of the quantity of primitives used and the code density. We do this by comparing the machine code that might be generated by an optimizing compiler for the same source files, for different (abstract) stack and register machines. -It turns out that the stack machines (at least those equipped with the basic stack manipulation primitives described in 2.2.1) have far superior code density. Furthermore, the stack machines have excellent extendability with respect to additional arithmetic and arbitrary data processing operations, especially if one considers machine code automatically generated by optimizing compilers. +It turns out that the stack machines (at least those equipped with the basic stack manipulation primitives described in [2.2.1](#2-2-1-basic-stack-manipulation-primitives)) have far superior code density. Furthermore, the stack machines have excellent extendability with respect to additional arithmetic and arbitrary data processing operations, especially if one considers machine code automatically generated by optimizing compilers. ## C.1 Sample leaf function -We start with a comparison of machine code generated by an (imaginary) optimizing compiler for several abstract register and stack machines, corresponding to the same high-level language source code that contains the definition of a leaf function (i.e., a function that does not call any other functions). For both the register machines and stack machines, we observe the notation and conventions introduced in 2.1. +We start with a comparison of machine code generated by an (imaginary) optimizing compiler for several abstract register and stack machines, corresponding to the same high-level language source code that contains the definition of a leaf function (i.e., a function that does not call any other functions). For both the register machines and stack machines, we observe the notation and conventions introduced in [2.1](#2-1-stack-calling-conventions). ### C.1.1. Sample source file for a leaf function. - -The source file we consider contains one function f that takes six (integer) arguments, a, b, c, d, e, f, and returns two (integer) values, x and y, which are the solutions of the system of two linear equations +The source file we consider contains one function `f` that takes six (integer) arguments `a, b, c, d, e, f`, and returns two (integer) values `x` and `y`, which are the solutions of the system of two linear equations: ```math -( ax + by = e cx + dy = f (6) -``` +```` The source code of the function, in a programming language similar to C, might look as follows: - -```math -(int, int) f(int a, int b, int c, int d, int e, int f) \\ -{ \\ - int D = a*d - b*c; \\ - int Dx = e*d - b*f; \\ - int Dy = a*f - e*c; \\ - return (Dx / D, Dy / D); \\ +```c +(int, int) f(int a, int b, int c, int d, int e, int f) +{ + int D = a*d - b*c; + int Dx = e*d - b*f; + int Dy = a*f - e*c; + return (Dx / D, Dy / D); } ``` -We assume (cf. 2.1) that the register machines we consider accept the six parameters a. . . f in registers r0. . . r5, and return the two values x and y in r0 and r1. We also assume that the register machines have 16 registers, and that the stack machine can directly access s0 to s15 by its stack manipulation primitives; the stack machine will accept the parameters in s5 to s0, and return the two values in s0 and s1, somewhat similarly to the register machine. Finally, we assume at first that the register machine is allowed to destroy values in all registers (which is slightly unfair towards the stack machine); this assumption will be revisited later. + +We assume (cf. [2.1](#2-1-stack-calling-conventions)) that the register machines we consider accept the six parameters `a…f` in registers `r0…r5`, and return the two values `x` and `y` in `r0` and `r1`. + +We also assume that the register machines have 16 registers, and that the stack machine can directly access `s0` to `s15` by its stack manipulation primitives. The stack machine will accept the parameters in `s5…s0`, and return the two values in `s0` and `s1`, somewhat similarly to the register machine. + +Finally, we assume at first that the register machine is allowed to destroy values in all registers (which is slightly unfair towards the stack machine); this assumption will be revisited later. + + + ### C.1.2. Three-address register machine. -The machine code (or rather the corresponding assembly code) for a three-address register machine (cf. 2.1.7) might look as follows: +The machine code (or rather the corresponding assembly code) for a three-address register machine (cf. [2.1.7](#2-1-7-arguments-to-arithmetic-primitives-on-register-machines)) might look as follows: -``` +```asm IMUL r6,r0,r3 // r6 := r0 * r3 = ad IMUL r7,r1,r2 // r7 := bc SUB r6,r6,r7 // r6 := ad-bc = D @@ -2925,14 +3746,15 @@ IDIV r0,r3,r6 // x := Dx/D IDIV r1,r1,r6 // y := Dy/D RET ``` +We have used `12` operations and at least `23` bytes (each operation uses `3×4 = 12` bits to indicate the three registers involved, and at least `4` bits to indicate the operation performed; thus we need two or three bytes to encode each operation). -We have used 12 operations and at least 23 bytes (each operation uses 3×4 = 12 bits to indicate the three registers involved, and at least 4 bits to indicate the operation performed; thus we need two or three bytes to encode each operation). A more realistic estimate would be 34 (three bytes for each arithmetic operation) or 31 bytes (two bytes for addition and subtraction, three bytes for multiplication and division). +A more realistic estimate would be `34` (three bytes for each arithmetic operation) or `31` bytes (two bytes for addition and subtraction, three bytes for multiplication and division). ### C.1.3. Two-address register machine. The machine code for a two-address register machine might look as follows: -``` +```c MOV r6,r0 // r6 := r0 = a MOV r7,r1 // r7 := b IMUL r6,r3 // r6 := r6*r3 = ad @@ -2951,13 +3773,13 @@ IDIV r1,r6 // r1 := Dy/D RET ``` -We have used 16 operations; optimistically assuming each of them (with the exception of RET) can be encoded by two bytes, this code would require 31 bytes.[31](#footnote-31) +We have used `16` operations; optimistically assuming each of them (with the exception of `RET`) can be encoded by `2` bytes, this code would require `31` bytes.[31](#footnote-31) ### C.1.4. One-address register machine. The machine code for a one-address register machine might look as follows: -``` +```asm MOV r8,r0 // r8 := r0 = a XCHG r1 // r0 <-> r1; r0 := b, r1 := a MOV r6,r0 // r6 := b @@ -2965,16 +3787,6 @@ IMUL r2 // r0 := r0*r2; r0 := bc MOV r7,r0 // r7 := bc MOV r0,r8 // r0 := a IMUL r3 // r0 := ad -31It is interesting to compare this code with that generated by optimizing C compilers -for the x86-64 architecture. -First of all, the integer division operation for x86-64 uses the one-address form, with -the (double-length) dividend to be supplied in accumulator pair r2:r0. The quotient is -also returned in r0. As a consequence, two single-to-double extension operations (CDQ or -CQO) and at least one move operation need to be added. -Secondly, the encoding used for arithmetic and move operations is less optimistic than -in our example above, requiring about three bytes per operation on average. As a result, -we obtain a total of 43 bytes for 32-bit integers, and 68 bytes for 64-bit integers. -C.1. Sample leaf function SUB r7 // r0 := ad-bc = D XCHG r1 // r1 := D, r0 := b IMUL r5 // r0 := bf @@ -2993,13 +3805,16 @@ MOV r0,r2 // r0 := x RET ``` -We have used 23 operations; if we assume one-byte encoding for all arithmetic operations and XCHG, and two-byte encodings for MOV, the total size of the code will be 29 bytes. Notice, however, that to obtain the compact code shown above we had to choose a specific order of computation, and made heavy use of the commutativity of multiplication. (For example, we compute bc before af, and af − bc immediately after af.) It is not clear whether a compiler would be able to make all such optimizations by itself. +We have used `23` operations; if we assume one-byte encoding for all arithmetic operations and `XCHG`, and two-byte encodings for `MOV`, the total size of the code will be `29` bytes. + +Notice, however, that to obtain the compact code shown above we had to choose a specific order of computation, and made heavy use of the commutativity of multiplication. (For example, we compute `bc` before `af`, and `af − bc` immediately after `af`.) It is not clear whether a compiler would be able to make all such optimizations by itself. + ### C.1.5. Stack machine with basic stack primitives. -The machine code for a stack machine equipped with basic stack manipulation primitives described in 2.2.1 might look as follows: +The machine code for a stack machine equipped with basic stack manipulation primitives described in [2.2.1](#2-2-1-basic-stack-manipulation-primitives) might look as follows: -``` +```asm PUSH s5 // a b c d e f a PUSH s3 // a b c d e f a d IMUL // a b c d e f ad @@ -3031,20 +3846,25 @@ IDIV // x y RET ``` -We have used 29 operations; assuming one-byte encodings for all stack operations involved (including XCHG s1,s(i)), we have used 29 code bytes as well. Notice that with one-byte encoding, the “unsystematic” operation ROT (equivalent to XCHG s1; XCHG s2) would reduce the operation and byte count to 28. This shows that such “unsystematic” operations, borrowed from Forth, may indeed reduce the code size on some occasions. +We have used `29` operations; assuming one-byte encodings for all stack operations involved (including `XCHG s1,s(i)`), we have used `29` code bytes as well. + +Notice that with one-byte encoding, the “unsystematic” operation `ROT` (equivalent to `XCHG s1; XCHG s2`) would reduce the operation and byte count to `28`. This shows that such “unsystematic” operations, borrowed from Forth, may indeed reduce the code size on some occasions. + +Notice as well that we have implicitly used the commutativity of multiplication in this code, computing `de − bf` instead of `ed − bf` as specified in high-level language source code. If we were not allowed to do so, an extra `XCHG s1` would need to be inserted before the third `IMUL`, increasing the total size of the code by one operation and one byte. -Notice as well that we have implicitly used the commutativity of multiplication in this code, computing de − bf instead of ed − bf as specified in high-level language source code. If we were not allowed to do so, an extra XCHG s1 would need to be inserted before the third IMUL, increasing the total size of the code by one operation and one byte. +The code presented above might have been produced by a rather unsophisticated compiler that simply computed all expressions and subexpressions in the order they appear, then rearranged the arguments near the top of the stack before each operation as outlined in [2.2.2](#2-2-2-basic-stack-manipulation-primitives-suffice). -The code presented above might have been produced by a rather unsophisticated compiler that simply computed all expressions and subexpressions in the order they appear, then rearranged the arguments near the top of the stack before each operation as outlined in 2.2.2. The only “manual” optimization done here involves computing ec before af; one can check that the other order would lead to slightly shorter code of 28 operations and bytes (or 29, if we are not allowed to use the commutativity of multiplication), but -151 -C.1. Sample leaf function -the ROT optimization would not be applicable. +The only “manual” optimization done here involves computing `ec` before `af`; one can check that the other order would lead to slightly shorter code of `28` operations and bytes (or `29`, if we are not allowed to use the commutativity of multiplication), but the `ROT` optimization would not be applicable. ### C.1.6. Stack machine with compound stack primitives. -A stack machine with compound stack primitives (cf. 2.2.3) would not significantly improve code density of the code presented above, at least in terms of bytes used. The only difference is that, if we were not allowed to use commutativity of multiplication, the extra XCHG s1 inserted before the third IMUL might be combined with two previous operations XCHG s3, PUSH s2 into one compound operation PUXC s2,s3; we provide the resulting code below. To make this less redundant, we show a version of the code that computes subexpression af before ec as specified in the original source file. We see that this replaces six operations (starting from line 15) with five other operations, and disables the ROT optimization: +A stack machine with compound stack primitives (cf. [2.2.3](#2-2-3-compound-stack-manipulation-primitives)) would not significantly improve code density of the code presented above, at least in terms of bytes used. -``` +The only difference is that, if we were not allowed to use commutativity of multiplication, the extra `XCHG s1` inserted before the third `IMUL` might be combined with two previous operations `XCHG s3`, `PUSH s2` into one compound operation `PUXC s2,s3`; we provide the resulting code below. + +To make this less redundant, we show a version of the code that computes subexpression `af` before `ec` as specified in the original source file. We see that this replaces six operations (starting from line `15`) with five other operations, and disables the `ROT` optimization: + +```asm PUSH s5 // a b c d e f a PUSH s3 // a b c d e f a d IMUL // a b c d e f ad @@ -3074,17 +3894,21 @@ IDIV // x y RET ``` -We have used a total of 27 operations and 28 bytes, the same as the previous version (with the ROT optimization). However, we did not use the commutativity of multiplication here, so we can say that compound stack manipulation primitives enable us to reduce the code size from 29 to 28 bytes. +We have used a total of `27` operations and `28` bytes, the same as the previous version (with the `ROT` optimization). However, we did not use the commutativity of multiplication here, so we can say that compound stack manipulation primitives enable us to reduce the code size from `29` to `28` bytes. -Yet again, notice that the above code might have been generated by an unsophisticated compiler. Manual optimizations might lead to more compact code; for instance, we could use compound operations such as XCHG3 to prepare in advance not only the correct values of s0 and s1 for the next arithmetic operation, but also the value of s2 for the arithmetic operation after that. The next section provides an example of such an optimization. +Yet again, notice that the above code might have been generated by an unsophisticated compiler. Manual optimizations might lead to more compact code; for instance, we could use compound operations such as `XCHG3` to prepare in advance not only the correct values of `s0` and `s1` for the next arithmetic operation, but also the value of `s2` for the arithmetic operation after that. -### C.1.7. Stack machine with compound stack primitives and manually optimized code. +The next section provides an example of such an optimization. -The previous version of code for a stack machine with compound stack primitives can be manually optimized as follows. +### C.1.7. Stack machine with compound stack primitives and manually optimized code -By interchanging XCHG operations with preceding XCHG, PUSH, and arithmetic operations whenever possible, we obtain code fragment XCHG s2,s6; XCHG s1,s0; XCHG s0,s5, which can then be replaced by compound operation XCHG3 s6,s0,s5. This compound operation would admit a two-byte encoding, thus leading to 27-byte code using only 21 operations: +The previous version of code for a stack machine with compound stack primitives can be manually optimized as follows. -``` +By interchanging `XCHG` operations with preceding `XCHG`, `PUSH`, and arithmetic operations whenever possible, we obtain code fragment `XCHG s2,s6; XCHG s1,s0; XCHG s0,s5`, which can then be replaced by compound operation `XCHG3 s6,s0,s5`. + +This compound operation would admit a two-byte encoding, thus leading to `27`-byte code using only `21` operations: + +```asm PUSH2 s5,s2 // a b c d e f a d IMUL // a b c d e f ad PUSH2 s5,s4 // a b c d e f ad b c @@ -3101,8 +3925,6 @@ XCHG s4 // e Dx c D a f IMUL // e Dx c D af XCHG2 s4,s2 // D Dx af e c IMUL // D Dx af ec -153 -C.2. Comparison of machine code for sample leaf function SUB // D Dx Dy XCPU s1,s2 // D Dy Dx D IDIV // D Dy x @@ -3117,30 +3939,33 @@ It is interesting to note that this version of stack machine code contains only # C.2 Comparison of machine code for sample leaf function -Table 1 summarizes the properties of machine code corresponding to the same source file described in C.1.1, generated for a hypothetical three-address register machine (cf. C.1.2), with both “optimistic” and “realistic” instruction encodings; a two-address machine (cf. C.1.3); a one-address machine (cf. C.1.4); and a stack machine, similar to TVM, using either only the basic stack manipulation primitives (cf. C.1.5) or both the basic and the composite stack primitives (cf. C.1.7). +Table 1 summarizes the properties of machine code corresponding to the same source file described in [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function), generated for a hypothetical three-address register machine (cf. [C.1.2](#c-1-2-three-address-register-machine)), with both “optimistic” and “realistic” instruction encodings; a two-address machine (cf. [C.1.3](#c-1-3-two-address-register-machine)); a one-address machine (cf. [C.1.4](#c-1-4-one-address-register-machine)); and a stack machine, similar to TVM, using either only the basic stack manipulation primitives (cf. [C.1.5](#c-1-5-stack-machine-with-basic-primitives)) or both the basic and the composite stack primitives (cf. [C.1.7](#c-1-7-stack-machine-with-compound-primitives)). -The meaning of the columns in Table 1 is as follows: +The meaning of the columns in [Table 1](#table-1) is as follows: -* “Operations” — The quantity of instructions used, split into “data” (i.e., register move and exchange instructions for register machines, and stack manipulation instructions for stack machines) and “arithmetic” (instructions for adding, subtracting, multiplying and dividing integer numbers). The “total” is one more than the sum of these two, because there is also a one-byte RET instruction at the end of machine code. -* “Code bytes” — The total amount of code bytes used. -* “Opcode space” — The portion of “opcode space” (i.e., of possible choices for the first byte of the encoding of an instruction) used by data and arithmetic instructions in the assumed instruction encoding. For example, the “optimistic” encoding for the three-address machine assumes two-byte encodings for all arithmetic instructions `op r(i), r(j), r(k)`. Each arithmetic instruction would then consume portion `16/256 = 1/16` of the opcode space. Notice that for the stack machine we have assumed one-byte encodings for `XCHG s(i)`, `PUSH s(i)` and `POP s(i)` in all cases, augmented by `XCHG s1,s(i)` for the basic stack instructions case only. As for the compound stack operations, we have assumed two-byte encodings for `PUSH3`, `XCHG3`, `XCHG2`, `XCPU`, `PUXC`, `PUSH2`, but not for `XCHG s1,s(i)`. +- **Operations** — The quantity of instructions used, split into “data” (i.e., register move and exchange instructions for register machines, and stack manipulation instructions for stack machines) and “arithmetic” (instructions for adding, subtracting, multiplying and dividing integer numbers). The “total” is one more than the sum of these two, because there is also a one-byte `RET` instruction at the end of machine code. +- **Code bytes** — The total amount of code bytes used. +- **Opcode space** — The portion of opcode space (i.e., of possible choices for the first byte of the encoding of an instruction) used by data and arithmetic instructions in the assumed instruction encoding. For example, the “optimistic” encoding for the three-address machine assumes two-byte encodings for all arithmetic instructions `op r(i), r(j), r(k)`. Each arithmetic instruction would then consume portion `16/256 = 1/16` of the opcode space. -The “code bytes” column reflects the density of the code for the specific sample source. However, “opcode space” is also important, because it reflects the extendability of the achieved density to other classes of operations (e.g., if one were to complement arithmetic operations with string manipulation operations and so on). Here the “arithmetic” subcolumn is more important than the “data” subcolumn, because no further data manipulation operations would be required for such extensions. + Notice that for the stack machine we have assumed one-byte encodings for `XCHG s(i)`, `PUSH s(i)` and `POP s(i)` in all cases, augmented by `XCHG s1,s(i)` for the basic stack instructions case only. As for the compound stack operations, we have assumed two-byte encodings for `PUSH3`, `XCHG3`, `XCHG2`, `XCPU`, `PUXC`, `PUSH2`, but not for `XCHG s1,s(i)`. -We see that the three-address register machine with the “optimistic” encoding, assuming two-byte encodings for all three-register arithmetic operations, achieves the best code density, requiring only 23 bytes. However, this comes at a price: each arithmetic operation consumes 1/16 of the opcode space, so the four operations already use a quarter of the opcode space. At most 11 other operations, arithmetic or not, might be added to this architecture while preserving such high code density. On the other hand, when we consider the “realistic” encoding for the three-address machine, using two-byte encodings only for the most frequently used addition/subtraction operations (and longer encodings for less frequently used multiplication/division operations, reflecting the fact that the possible extension operations would likely fall in this class), then the three-address machine ceases to offer such attractive code density. +The **code bytes** column reflects the density of the code for the specific sample source. However, **opcode space** is also important, because it reflects the extendability of the achieved density to other classes of operations (e.g., if one were to complement arithmetic operations with string manipulation operations, and so on). Here the “arithmetic” subcolumn is more important than the “data” subcolumn, because no further data manipulation operations would be required for such extensions. -In fact, the two-address machine becomes equally attractive at this point: it is capable of achieving the same code size of 31 bytes as the three-address machine with the “realistic” encoding, using only 6/256 of the opcode space for this! However, 31 bytes is the worst result in this table. +We see that the three-address register machine with the “optimistic” encoding, assuming two-byte encodings for all three-register arithmetic operations, achieves the best code density, requiring only `23` bytes. However, this comes at a price: each arithmetic operation consumes `1/16` of the opcode space, so the four operations already use a quarter of the opcode space. At most 11 other operations, arithmetic or not, might be added to this architecture while preserving such high code density. On the other hand, when we consider the “realistic” encoding for the three-address machine, using two-byte encodings only for the most frequently used addition/subtraction operations (and longer encodings for less frequently used multiplication/division operations, reflecting the fact that the possible extension operations would likely fall in this class), then the three-address machine ceases to offer such attractive code density. -The one-address machine uses 29 bytes, slightly less than the two-address machine. However, it utilizes a quarter of the opcode space for its arithmetic operations, hampering its extendability. In this respect it is similar to the three-address machine with the “optimistic” encoding, but requires 29 bytes instead of 23! So there is no reason to use the one-address machine at all, in terms of extendability (reflected by opcode space used for arithmetic operations) compared to code density. +In fact, the two-address machine becomes equally attractive at this point: it is capable of achieving the same code size of `31` bytes as the three-address machine with the “realistic” encoding, using only `6/256` of the opcode space for this! However, `31` bytes is the worst result in this table. -Finally, the stack machine wins the competition in terms of code density (27 or 28 bytes), losing only to the three-address machine with the “optimistic” encoding (which, however, is terrible in terms of extendability). +The one-address machine uses `29` bytes, slightly less than the two-address machine. However, it utilizes a quarter of the opcode space for its arithmetic operations, hampering its extendability. In this respect it is similar to the three-address machine with the “optimistic” encoding, but requires `29` bytes instead of `23`. So there is no reason to use the one-address machine at all, in terms of extendability (reflected by opcode space used for arithmetic operations) compared to code density. -To summarize: the two-address machine and stack machine achieve the best extendability with respect to additional arithmetic or data processing instructions (using only 1/256 of code space for each such instruction), while the stack machine additionally achieves the best code density by a small margin. The stack machine utilizes a significant part of its code space (more than a quarter) for data (i.e., stack) manipulation instructions; however, this does not seriously hamper extendability, because the stack manipulation instructions occupy a constant part of the opcode stace, regardless of all other instructions and extensions. +Finally, the stack machine wins the competition in terms of code density (`27` or `28` bytes), losing only to the three-address machine with the “optimistic” encoding (which, however, is terrible in terms of extendability). -While one might still be tempted to use a two-address register machine, we will explain shortly (cf. C.3) why the two-address register machine offers worse code density and extendability in practice than it appears based on this table. +To summarize: the two-address machine and stack machine achieve the best extendability with respect to additional arithmetic or data processing instructions (using only `1/256` of code space for each such instruction), while the stack machine additionally achieves the best code density by a small margin. The stack machine utilizes a significant part of its code space (more than a quarter) for data (i.e., stack) manipulation instructions; however, this does not seriously hamper extendability, because the stack manipulation instructions occupy a constant part of the opcode space, regardless of all other instructions and extensions. + +While one might still be tempted to use a two-address register machine, we will explain shortly (cf. [C.3](#c-3-sample-non-leaf-function)) why the two-address register machine offers worse code density and extendability in practice than it appears based on this table. As for the choice between a stack machine with only basic stack manipulation primitives or one supporting compound stack primitives as well, the case for the more sophisticated stack machine appears to be weaker: it offers only one or two fewer bytes of code at the expense of using considerably more opcode space for stack manipulation, and the optimized code using these additional instructions is hard for programmers to write and for compilers to automatically generate. + ### Table 1 | Machine | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | @@ -3152,32 +3977,60 @@ As for the choice between a stack machine with only basic stack manipulation pri | stack (basic) | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | | stack (comp.) | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | -Table 1: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. C.1.1). The two most important columns, reflecting code density and extendability to other operations, are marked by bold font. Smaller values are better in both of these columns. +**Table 1:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)). + +The two most important columns, reflecting **code density** and **extendability to other operations**, are marked by bold font. Smaller values are better in both of these columns. --- ### C.2.1. Register calling conventions: some registers must be preserved by functions. -Up to this point, we have considered the machinecode of only one function, without taking into account the interplay between this function and other functions in the same program. +Up to this point, we have considered the machine code of only one function, without taking into account the interplay between this function and other functions in the same program. + +Usually a program consists of more than one function, and when a function is not a “simple” or “leaf” function, it must call other functions. Therefore, it becomes important whether a called function preserves all or at least some registers. + +- If it preserves all registers except those used to return results, the caller can safely keep its local and temporary variables in certain registers; however, the callee needs to save all the registers it will use for its temporary values somewhere (usually into the stack, which also exists on register machines), and then restore the original values. +- On the other hand, if the called function is allowed to destroy all registers, it can be written in the manner described in [C.1.2](#c-1-2-three-address-register-machine), [C.1.3](#c-1-3-two-address-register-machine), and [C.1.4](#c-1-4-one-address-register-machine), but the caller will now be responsible for saving all its temporary values into the stack before the call, and restoring these values afterwards. + +In most cases, calling conventions for register machines require preservation of some but not all registers. We will assume that `m ≤ n` registers will be preserved by functions (unless they are used for return values), and that these registers are `r(n−m)…r(n−1)`. -Usually a program consists of more than one function, and when a function is not a “simple” or “leaf” function, it must call other functions. Therefore, it becomes important whether a called function preserves all or at least some registers. If it preserves all registers except those used to return results, the caller can safely keep its local and temporary variables in certain registers; however, the callee needs to save all the registers it will use for its temporary values somewhere (usually into the stack, which also exists on register machines), and then restore the original values. On the other hand, if the called function is allowed to destroy all registers, it can be written in the manner described in C.1.2, C.1.3, and C.1.4, but the caller will now be responsible for saving all its temporary values into the stack before the call, and restoring these values afterwards. +- Case `m = 0` corresponds to the case “the callee is free to destroy all registers” considered so far; it is quite painful for the caller. +- Case `m = n` corresponds to the case “the callee must preserve all registers”; it is quite painful for the callee, as we will see in a moment. +- Usually a value of `m` around `n/2` is used in practice. -In most cases, calling conventions for register machines require preservation of some but not all registers. We will assume that m ≤ n registers will be preserved by functions (unless they are used for return values), and that these registers are r(n − m). . . r(n − 1). Case m = 0 corresponds to the case “the callee is free to destroy all registers” considered so far; it is quite painful for the caller. Case m = n corresponds to the case “the callee must preserve all registers”; it is quite painful for the callee, as we will see in a moment. Usually a value of m around n/2 is used in practice. +The following sections consider cases `m = 0`, `m = 8`, and `m = 16` for our register machines with `n = 16` registers. -The following sections consider cases m = 0, m = 8, and m = 16 for our register machines with n = 16 registers. ### C.2.2. Case m = 0: no registers to preserve. -This case has been considered and summarized in C.2 and Table 1 above. +This case has been considered and summarized in [C.2](#c-2-comparison-of-machine-code-for-sample-leaf-function) and [Table 1](#table-1) above. -### C.2.3. Case m = n = 16: all registers must be preserved. +### C.2.3. Case `m = n = 16`: all registers must be preserved + +This case is the most painful one for the called function. It is especially difficult for leaf functions like the one we have been considering, which do not benefit at all from the fact that other functions preserve some registers when called — they do not call any functions, but instead must preserve all registers themselves. + +In order to estimate the consequences of assuming `m = n = 16`, we will assume that all our register machines are equipped with a stack, and with one-byte instructions `PUSH r(i)` and `POP r(i)`, which push or pop a register into/from the stack. + +For example, the three-address machine code provided in [C.1.2](#c-1-2-three-address-register-machine) destroys the values in registers `r2`, `r3`, `r6`, and `r7`; this means that the code of this function must be augmented by four instructions: + +```asm +PUSH r2; PUSH r3; PUSH r6; PUSH r7 +```` + +at the beginning, and by four instructions: + +```asm +POP r7; POP r6; POP r3; POP r2 +``` -This case is the most painful one for the called function. It is especially difficult for leaf functions like the one we have been considering, which do not benefit at all from the fact that other functions preserve some registers when called—they do not call any functions, but instead must preserve all registers themselves. +right before the `RET` instruction, in order to restore the original values of these registers from the stack. -In order to estimate the consequences of assuming m = n = 16, we will assume that all our register machines are equipped with a stack, and with one-byte instructions `PUSH r(i)` and `POP r(i)`, which push or pop a register into/from the stack. For example, the three-address machine code provided in C.1.2 destroys the values in registers r2, r3, r6, and r7; this means that the code of this function must be augmented by four instructions `PUSH r2; PUSH r3; PUSH r6; PUSH r7` at the beginning, and by four instructions `POP r7; POP r6; POP r3; POP r2` right before the `RET` instruction, in order to restore the original values of these registers from the stack. These four additional `PUSH/POP` pairs would increase the operation count and code size in bytes by `4 × 2 = 8`. A similar analysis can be done for other register machines as well, leading to Table 2. +These four additional `PUSH/POP` pairs would increase the operation count and code size in bytes by `4 × 2 = 8`. A similar analysis can be done for other register machines as well, leading to [Table 2](#table-2). We see that under these assumptions the stack machines are the obvious winners in terms of code density, and are in the winning group with respect to extendability. + + ### Table 2 | Machine | r | **Operations** data | **Operations** arith | **Operations** total | **Code bytes** data | **Code bytes** arith | **Code bytes** total | **Opcode space** data | **Opcode space** arith | **Opcode space** total | @@ -3189,13 +4042,21 @@ We see that under these assumptions the stack machines are the obvious winners i | stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | | stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | -Table 2: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. C.1.1), assuming all of the 16 registers must be preserved by called functions (m = n = 16). The new column labeled r denotes the number of registers to be saved and restored, leading to 2r more operations and code bytes compared to Table 1. Newly-added PUSH and POP instructions for register machines also utilize 32/256 of the opcode space. The two rows corresponding to stack machines remain unchanged. -### C.2.4. Case m = 8, n = 16: registers r8. . . r15 must be preserved. +**Table 2:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)), assuming all of the `16` registers must be preserved by called functions (`m = n = 16`). + +The new column labeled `r` denotes the number of registers to be saved and restored, leading to `2r` more operations and code bytes compared to [Table 1](#table-1). Newly added `PUSH` and `POP` instructions for register machines also utilize `32/256` of the opcode space. + +The two rows corresponding to stack machines remain unchanged. -The analysis of this case is similar to the previous one. The results are summarized in Table 3. -Notice that the resulting table is very similar to Table 1, apart from the “Opcode space” columns and the row for the one-address machine. Therefore, the conclusions of C.2 still apply in this case, with some minor modifications. We must emphasize, however, that these conclusions are valid only for leaf functions, i.e., functions that do not call other functions. Any program aside from the very simplest will have many non-leaf functions, especially if we are minimizing resulting machine code size (which prevents inlining of functions in most cases). +### C.2.4. Case `m = 8`, `n = 16`: registers `r8…r15` must be preserved + +The analysis of this case is similar to the previous one. The results are summarized in [Table 3](#table-3). + +Notice that the resulting table is very similar to [Table 1](#table-1), apart from the **Opcode space** columns and the row for the one-address machine. Therefore, the conclusions of [C.2](#c-2-comparison-of-machine-code-for-sample-leaf-function) still apply in this case, with some minor modifications. + +We must emphasize, however, that these conclusions are valid only for *leaf functions*, i.e., functions that do not call other functions. Any program aside from the very simplest will have many non-leaf functions, especially if we are minimizing resulting machine code size (which prevents inlining of functions in most cases). ### Table 3 @@ -3208,17 +4069,25 @@ Notice that the resulting table is very similar to Table 1, apart from the “Op | stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | | stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | -Table 3: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address and stack machines, generated for a sample leaf function (cf. C.1.1), assuming that only the last 8 of the 16 registers must be preserved by called functions (m = 8, n = 16). This table is similar to Table 2, but has smaller values of r. -### C.2.5. A fairer comparison using a binary code instead of a byte code. +**Table 3:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)), assuming that only the last `8` of the `16` registers must be preserved by called functions (`m = 8`, `n = 16`). + +This table is similar to [Table 2](#table-2), but has smaller values of `r`. -The reader may have noticed that our preceding discussion of kaddress register machines and stack machines depended very much on our insistence that complete instructions be encoded by an integer number of bytes. If we had been allowed to use a “bit” or “binary code” instead of a byte code for encoding instructions, we could more evenly balance the opcode space used by different machines. For instance, the opcode of SUB for a threeaddress machine had to be either 4-bit (good for code density, bad for opcode space) or 12-bit (very bad for code density), because the complete instruction has to occupy a multiple of eight bits (e.g., 16 or 24 bits), and 3 · 4 = 12 of those bits have to be used for the three register names. +### C.2.5. A fairer comparison using a binary code instead of a byte code -Therefore, let us get rid of this restriction. +The reader may have noticed that our preceding discussion of k-address register machines and stack machines depended very much on our insistence that complete instructions be encoded by an integer number of bytes. If we had been allowed to use a “bit” or “binary code” instead of a byte code for encoding instructions, we could more evenly balance the opcode space used by different machines. -Now that we can use any number of bits to encode an instruction, we can choose all opcodes of the same length for all the machines considered. For instance, all arithmetic instructions can have 8-bit opcodes, as the stack machine does, using 1/256 of the opcode space each; then the three-address register machine will use 20 bits to encode each complete arithmetic instruction. All MOVs, XCHGs, PUSHes, and POPs on register machines can be assumed to have 4-bit opcodes, because this is what we do for the most common stack manipulation primitives on a stack machine. The results of these changes are shown in Table 4. +For instance, the opcode of `SUB` for a three-address machine had to be either `4`-bit (good for code density, bad for opcode space) or `12`-bit (very bad for code density), because the complete instruction has to occupy a multiple of eight bits (e.g., `16` or `24` bits), and `3 · 4 = 12` of those bits have to be used for the three register names. + +Therefore, let us get rid of this restriction. + +Now that we can use any number of bits to encode an instruction, we can choose all opcodes of the same length for all the machines considered. For instance, all arithmetic instructions can have `8`-bit opcodes, as the stack machine does, using `1/256` of the opcode space each; then the three-address register machine will use `20` bits to encode each complete arithmetic instruction. + +All `MOV`s, `XCHG`s, `PUSH`es, and `POP`s on register machines can be assumed to have `4`-bit opcodes, because this is what we do for the most common stack manipulation primitives on a stack machine. The results of these changes are shown in [Table 4](#table-4). + +We can see that the performance of the various machines is much more balanced, with the stack machine still the winner in terms of the code density, but with the three-address machine enjoying the second place it really merits. If we were to consider the decoding speed and the possibility of parallel execution of instructions, we would have to choose the three-address machine, because it uses only `12` instructions instead of `21`. -We can see that the performance of the various machines is much more balanced, with the stack machine still the winner in terms of the code density, but with the three-address machine enjoying the second place it really merits. If we were to consider the decoding speed and the possibility of parallel execution of instructions, we would have to choose the three-address machine, because it uses only 12 instructions instead of 21. ### Table 4 @@ -3230,15 +4099,20 @@ We can see that the performance of the various machines is much more balanced, w | stack (basic) | 0 | 16 | 11 | 28 | 16 | 11 | 28 | 64/256 | 4/256 | 69/256 | | stack (comp.) | 0 | 9 | 11 | 21 | 15 | 11 | 27 | 84/256 | 4/256 | 89/256 | -Table 4: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address and stack machines, generated for a sample leaf function (cf. C.1.1), assuming that only 8 of the 16 registers must be preserved by functions (m = 8, n = 16). This time we can use fractions of bytes to encode instructions, so as to match opcode space used by different machines. All arithmetic instructions have 8-bit opcodes, all data/stack manipulation instructions have 4-bit opcodes. In other respects this table is similar to Table 3. + +**Table 4:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample leaf function (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)), assuming that only `8` of the `16` registers must be preserved by functions (`m = 8`, `n = 16`). + +This time we can use fractions of bytes to encode instructions, so as to match opcode space used by different machines. All arithmetic instructions have `8`-bit opcodes, all data/stack manipulation instructions have `4`-bit opcodes. In other respects this table is similar to [Table 3](#table-3). + +--- # C.3 Sample non-leaf function -This section compares the machine code for different register machines for a sample non-leaf function. Again, we assume that either m = 0, m = 8, or m = 16 registers are preserved by called functions, with m = 8 representing the compromise made by most modern compilers and operating systems. +This section compares the machine code for different register machines for a sample non-leaf function. Again, we assume that either `m = 0`, `m = 8`, or `m = 16` registers are preserved by called functions, with `m = 8` representing the compromise made by most modern compilers and operating systems. -### C.3.1. Sample source code for a non-leaf function. +### C.3.1. Sample source code for a non-leaf function -A sample source file may be obtained by replacing the built-in integer type with a custom Rational type, represented by a pointer to an object in memory, in our function for solving systems of two linear equations (cf. C.1.1): +A sample source file may be obtained by replacing the built-in integer type with a custom `Rational` type, represented by a pointer to an object in memory, in our function for solving systems of two linear equations (cf. [C.1.1](#c-1-1-sample-source-file-for-a-leaf-function)): ```c struct Rational; @@ -3255,19 +4129,29 @@ return (r_div(Dx, D), r_div(Dy, D)); // Dx/D, Dy/D } ``` -We will ignore all questions related to allocating new objects of type Rational in memory (e.g., in heap), and to preventing memory leaks. We may assume that the called subroutines r\_sub, r\_mul, and so on allocate new objects simply by advancing some pointer in a pre-allocated buffer, and that unused objects are later freed by a garbage collector, external to the code being analysed. +We will ignore all questions related to allocating new objects of type `Rational` in memory (e.g., in heap), and to preventing memory leaks. We may assume that the called subroutines `r_sub`, `r_mul`, and so on allocate new objects simply by advancing some pointer in a pre-allocated buffer, and that unused objects are later freed by a garbage collector, external to the code being analysed. -Rational numbers will now be represented by pointers, addresses, or references, which will fit into registers of our hypothetical register machines or into the stack of our stack machines. If we want to use TVM as an instance of these stack machines, we should use values of type Cell to represent such references to objects of type Rational in memory. +`Rational` numbers will now be represented by pointers, addresses, or references, which will fit into registers of our hypothetical register machines or into the stack of our stack machines. If we want to use TVM as an instance of these stack machines, we should use values of type `Cell` to represent such references to objects of type `Rational` in memory. -We assume that subroutines (or functions) are called by a special CALL instruction, which is encoded by three bytes, including the specification of the function to be called (e.g., the index in a “global function table”). +We assume that subroutines (or functions) are called by a special `CALL` instruction, which is encoded by `3` bytes, including the specification of the function to be called (e.g., the index in a “global function table”). -### C.3.2. Three-address and two-address register machines, m = 0 preserved registers. +### C.3.2. Three-address and two-address register machines, `m = 0` preserved registers -Because our sample function does not use built-in arithmetic instructions at all, compilers for our hypothetical three-address and two-address register machines will produce the same machine code. Apart from the previously introduced PUSH r(i) and POP r(i) one-byte instructions, we assume that our two- and three-address machines support the following two-byte instructions: MOV r(i),s(j), MOV s(j),r(i), and XCHG r(i),s(j), for 0 ≤ i, j ≤ 15. Such instructions occupy only 3/256 of the opcode space, so their addition seems quite natural. +Because our sample function does not use built-in arithmetic instructions at all, compilers for our hypothetical three-address and two-address register machines will produce the same machine code. -We first assume that m = 0 (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for `r_f` does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. A size-optimizing compiler might produce the following code: +Apart from the previously introduced `PUSH r(i)` and `POP r(i)` one-byte instructions, we assume that our two- and three-address machines support the following two-byte instructions: -``` +- `MOV r(i),s(j)` +- `MOV s(j),r(i)` +- `XCHG r(i),s(j)` + +for `0 ≤ i, j ≤ 15`. Such instructions occupy only `3/256` of the opcode space, so their addition seems quite natural. + +We first assume that `m = 0` (i.e., that all subroutines are free to destroy the values of all registers). In this case, our machine code for `r_f` does not have to preserve any registers, but has to save all registers containing useful values into the stack before calling any subroutines. + +A size-optimizing compiler might produce the following code: + +```asm PUSH r4 // STACK: e PUSH r1 // STACK: e b PUSH r0 // .. e b a @@ -3277,8 +4161,6 @@ PUSH r3 // .. e b a f c d MOV r0,r1 // b MOV r1,r2 // c CALL r_mul // bc -161 -C.3. Sample non-leaf function PUSH r0 // .. e b a f c d bc MOV r0,s4 // a MOV r1,s1 // d @@ -3313,17 +4195,24 @@ POP r0 // x ; .. RET ``` -We have used 41 instructions: 17 one-byte (eight PUSH/POP pairs and one RET), 13 two-byte (MOV and XCHG; out of them 11 “new” ones, involving the stack),and 11 three-byte (CALL), for a total of 17 · 1 + 13 · 2 + 11 · 3 = 76 bytes.[32](#footnote-32) +We have used `41` instructions: `17` one-byte (eight `PUSH/POP` pairs and one `RET`), `13` two-byte (`MOV` and `XCHG`; out of them `11` “new” ones, involving the stack), and `11` three-byte (`CALL`), for a total of `17 · 1 + 13 · 2 + 11 · 3 = 76` bytes.[32](#footnote-32) -### C.3.3. Three-address and two-address register machines, m = 8 preserved registers. +### C.3.3. Three-address and two-address register machines, `m = 8` preserved registers -Now we have eight registers, r8 to r15, that are preserved by subroutine calls. We might keep some intermediate values there instead of pushing them into the stack. However, the penalty for doing so consists in a PUSH/POP pair for every such register that we choose to use, because our function is also required to preserve its original value. It seems that using these registers under such a penalty does not improve the density of the code, so the optimal code for three- and two-address machines for m = 8 preserved registers is the same as that provided in C.3.2, with a total of 42 instructions and 74 code bytes. +Now we have eight registers, `r8` to `r15`, that are preserved by subroutine calls. We might keep some intermediate values there instead of pushing them into the stack. However, the penalty for doing so consists in a `PUSH/POP` pair for every such register that we choose to use, because our function is also required to preserve its original value. -## C.3.4. Three-address and two-address register machines, m = 16 preserved registers. +It seems that using these registers under such a penalty does not improve the density of the code, so the optimal code for three- and two-address machines for `m = 8` preserved registers is the same as that provided in [C.3.2](#c-3-2-three-and-two-address-m-0), with a total of `42` instructions and `74` code bytes. -This time all registers must be preserved by the subroutines, excluding those used for returning the results. This means that our code must preserve the original values of r2 to r5, as well as any other registers it uses for temporary values. A straightforward way of writing the code of our subroutine would be to push registers r2 up to, say, r8 into the stack, then perform all the operations required, using r6–r8 for intermediate values, and finally restore registers from the stack. However, this would not optimize code size. We choose another approach: -``` +### C.3.4. Three-address and two-address register machines, `m = 16` preserved registers + +This time all registers must be preserved by the subroutines, excluding those used for returning the results. This means that our code must preserve the original values of `r2` to `r5`, as well as any other registers it uses for temporary values. + +A straightforward way of writing the code of our subroutine would be to push registers `r2` up to, say, `r8` into the stack, then perform all the operations required, using `r6–r8` for intermediate values, and finally restore registers from the stack. + +However, this would not optimize code size. We choose another approach: + +```asm PUSH r0 // STACK: a PUSH r1 // STACK: a b MOV r0,r1 // b @@ -3339,10 +4228,6 @@ XCHG r0,s0 // b; .. a D MOV r1,r5 // f CALL r_mul // bf PUSH r0 // .. a D bf -with size-optimization enabled actually occupied 150 bytes, due mostly to the fact that -actual instruction encodings are about twice as long as we had optimistically assumed. -163 -C.3. Sample non-leaf function MOV r0,r4 // e MOV r1,r3 // d CALL r_mul // ed @@ -3369,15 +4254,27 @@ POP r0 // x RET ``` -We have used 39 instructions: 11 one-byte, 17 two-byte (among them 5 “new” instructions), and 11 three-byte, for a total of 11 · 1 + 17 · 2 + 11 · 3 = 78 bytes. Somewhat paradoxically, the code size in bytes is slightly longer than in the previous case (cf. C.3.2), contrary to what one might have expected. This is partially due to the fact that we have assumed two-byte encodings for “new” MOV and XCHG instructions involving the stack, similarly to the “old” instructions. Most existing architectures (such as x86-64) use longer encodings (maybe even twice as long) for their counterparts of our “new” move and exchange instructions compared to the “usual” register-register ones. Taking this into account, we see that we would have obtained here 83 bytes (versus 87 for the code in C.3.2) assuming three-byte encodings of new operations, and 88 bytes (versus 98) assuming four-byte encodings. This shows that, for two-address architectures without optimized encodings for register-stackmove and exchange operations, m = 16 preserved registers might result in slightly shorter code for some non-leaf functions, at the expense of leaf functions (cf. C.2.3 and C.2.4), which would become considerably longer. +We have used `39` instructions: `11` one-byte, `17` two-byte (among them `5` “new” instructions), and `11` three-byte, for a total of `11 · 1 + 17 · 2 + 11 · 3 = 78` bytes. -### C.3.5. One-address register machine, m = 0 preserved registers. +Somewhat paradoxically, the code size in bytes is slightly longer than in the previous case (cf. [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers)), contrary to what one might have expected. This is partially due to the fact that we have assumed two-byte encodings for “new” `MOV` and `XCHG` instructions involving the stack, similarly to the “old” instructions. -For our one-address register machine, we assume that new register-stack instructions work through the accumulator only. Therefore, we have three new instructions, LD s(j) (equivalent to MOV r0,s(j) of two-address machines), ST s(j) (equivalent to MOV s(j),r0), and XCHG s(j) (equivalent to XCHG r0,s(j)). To make the comparison with two-address machines more interesting, we assume one-byte encodings for these new instructions, even though this would consume 48/256 = 3/16 of the opcode space. +Most existing architectures (such as x86-64) use longer encodings (maybe even twice as long) for their counterparts of our “new” move and exchange instructions compared to the “usual” register–register ones. Taking this into account, we see that we would have obtained here `83` bytes (versus `87` for the code in [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers)) assuming three-byte encodings of new operations, and `88` bytes (versus `98`) assuming four-byte encodings. -By adapting the code provided in C.3.2 to the one-address machine, we obtain the following: +This shows that, for two-address architectures without optimized encodings for register–stack move and exchange operations, `m = 16` preserved registers might result in slightly shorter code for some non-leaf functions, at the expense of leaf functions (cf. [C.2.3](#c-2-3-case-m-%3D-n-%3D-16%3A-all-registers-must-be-preserved) and [C.2.4](#c-2-4-case-m-%3D-8%2C-n-%3D-16%3A-registers-r8…-r15-must-be-preserved)), which would become considerably longer. -``` +### C.3.5. One-address register machine, `m = 0` preserved registers + +For our one-address register machine, we assume that new register–stack instructions work through the accumulator only. Therefore, we have three new instructions: + +- `LD s(j)` (equivalent to `MOV r0,s(j)` of two-address machines) +- `ST s(j)` (equivalent to `MOV s(j),r0`) +- `XCHG s(j)` (equivalent to `XCHG r0,s(j)`) + +To make the comparison with two-address machines more interesting, we assume one-byte encodings for these new instructions, even though this would consume `48/256 = 3/16` of the opcode space. + +By adapting the code provided in [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers) to the one-address machine, we obtain the following: + +```asm PUSH r4 // STACK: e PUSH r1 // STACK: e b PUSH r0 // .. e b a @@ -3402,8 +4299,6 @@ CALL r_mul // bf POP r1 // d ; .. e D a f c PUSH r0 // .. e D a f c bf LD s5 // e -165 -C.3. Sample non-leaf function CALL r_mul // ed POP r1 // bf; .. e D a f c CALL r_sub // Dx:=ed-bf @@ -3427,17 +4322,20 @@ POP r0 // r0:=x ; .. RET ``` -We have used 45 instructions: 34 one-byte and 11 three-byte, for a total of 67 bytes. Compared to the 76 bytes used by two- and three-address machines in C.3.2, we see that, again, the one-address register machine code may be denser than that of two-register machines, at the expense of utilizing more opcode space (just as shown in C.2). However, this time the extra 3/16 of the opcode space was used for data manipulation instructions, which do not depend on specific arithmetic operations or user functions invoked. +We have used `45` instructions: `34` one-byte and `11` three-byte, for a total of `67` bytes. Compared to the `76` bytes used by two- and three-address machines in [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers), we see that, again, the one-address register machine code may be denser than that of two-register machines, at the expense of utilizing more opcode space (just as shown in [C.2](#c-2-comparison-of-machine-code-for-sample-leaf-function)). -### C.3.6. One-address register machine, m = 8 preserved registers. +However, this time the extra `3/16` of the opcode space was used for data manipulation instructions, which do not depend on specific arithmetic operations or user functions invoked. -As explained in C.3.3, the preservation of r8–r15 between subroutine calls does not improve the size of our previously written code, so the one-address machine will use for m = 8 the same code provided in C.3.5. -### C.3.7. One-address register machine, m = 16 preserved registers. +### C.3.6. One-address register machine, `m = 8` preserved registers -We simply adapt the code provided in C.3.4 to the one-address register machine: +As explained in [C.3.3](#c-3-3-three-address-and-two-address-register-machines%2C-m-%3D-8-preserved-registers), the preservation of `r8–r15` between subroutine calls does not improve the size of our previously written code, so the one-address machine will use for `m = 8` the same code provided in [C.3.5](#c-3-5-one-address-m-0). -``` +### C.3.7. One-address register machine, `m = 16` preserved registers + +We simply adapt the code provided in [C.3.4](#c-3-4-three-address-and-two-address-register-machines%2C-m-%3D-16-preserved-registers) to the one-address register machine: + +```asm PUSH r0 // STACK: aPUSH r1 // STACK: a b MOV r0,r1 // b MOV r1,r2 // c @@ -3476,18 +4374,20 @@ POP r1 // D ; .. x CALL r_div // y:=Dy/D MOV r1,r0 // y POP r0 // x -167 -C.3. Sample non-leaf function RET ``` -We have used 40 instructions: 18 one-byte, 11 two-byte, and 11 three-byte, for a total of 18 · 1 + 11 · 2 + 11 · 3 = 73 bytes. +We have used `40` instructions: `18` one-byte, `11` two-byte, and `11` three-byte, for a total of `18 · 1 + 11 · 2 + 11 · 3 = 73` bytes. ### C.3.8. Stack machine with basic stack primitives. -We reuse the code provided in C.1.5, simply replacing arithmetic primitives (VM instructions) with subroutine calls. The only substantive modification is the insertion of the previously optional XCHG s1 before the third multiplication, because even an optimizing compiler cannot now know whether CALL r\_mul is a commutative operation. We have also used the “tail recursion optimization” by replacing the final CALL r\_div followed by RET with JMP r\_div. +We reuse the code provided in [C.1.5](#c-1-5-stack-machine-with-basic-stack-primitives), simply replacing arithmetic primitives (VM instructions) with subroutine calls. -``` +The only substantive modification is the insertion of the previously optional `XCHG s1` before the third multiplication, because even an optimizing compiler cannot now know whether `CALL r_mul` is a commutative operation. + +We have also used the “tail recursion optimization” by replacing the final `CALL r_div` followed by `RET` with `JMP r_div`. + +```asm PUSH s5 // a b c d e f a PUSH s3 // a b c d e f a d CALL r_mul // a b c d e f ad @@ -3519,13 +4419,13 @@ XCHG s2 // x Dy D JMP r_div // x y ``` -We have used 29 instructions; assuming one-byte encodings for all stack operations, and three-byte encodings for CALL and JMP instructions, we end up with 51 bytes. +We have used `29` instructions; assuming one-byte encodings for all stack operations, and three-byte encodings for `CALL` and `JMP` instructions, we end up with `51` bytes. -### C.3.9. Stack machine with compound stack primitives. +### C.3.9. Stack machine with compound stack primitives -We again reuse the code provided in C.1.7, replacing arithmetic primitives with subroutine calls and making the tail recursion optimization: +We again reuse the code provided in [C.1.7](#c-1-7-stack-machine-with-compound-stack-primitives-and-manually-optimized-code), replacing arithmetic primitives with subroutine calls and making the tail recursion optimization: -``` +```asm PUSH2 s5,s2 // a b c d e f a d CALL r_mul // a b c d e f ad PUSH2 s5,s4 // a b c d e f ad b c @@ -3549,7 +4449,7 @@ XCHG s2 // x Dy D JMP r_div // x y ``` -This code uses only 20 instructions, 9 stack-related and 11 control flowrelated (CALL and JMP), for a total of 48 bytes. +This code uses only `20` instructions, `9` stack-related and `11` control flow–related (`CALL` and `JMP`), for a total of `48` bytes. --- @@ -3566,22 +4466,25 @@ This code uses only 20 instructions, 9 stack-related and 11 control flowrelated | stack (basic) | − | 18 | 11 | 29 | 18 | 33 | 51 | 64/256 | 4/256 | 71/256 | | stack (comp.) | − | 9 | 11 | 20 | 15 | 33 | 48 | 84/256 | 4/256 | 91/256 | -Table 5: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. C.3.1), assuming m of the 16 registers must be preserved by called subroutines. + +**Table 5:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. [C.3.1](#c-3-1-sample-source-code-for-a-non-leaf-function)), assuming `m` of the `16` registers must be preserved by called subroutines. + --- -# C.4 Comparison of machine code for sample non-leaf +## C.4 Comparison of machine code for sample non-leaf function + +[Table 5](#table-5) summarizes the properties of machine code corresponding to the same source file provided in [C.3.1](#c-3-1-sample-source-code-for-a-non-leaf-function). We consider only the “realistically” encoded three-address machines. -function +Three-address and two-address machines have the same code density properties, but differ in the utilization of opcode space. The one-address machine, somewhat surprisingly, managed to produce shorter code than the two-address and three-address machines, at the expense of using up more than half of all opcode space. -Table 5 summarizes the properties of machine code corresponding to the same source file provided in C.3.1. We consider only the “realistically” encoded three-address machines. Three-address and two-address machines have the same code density properties, but differ in the utilization of opcode space. The one-address machine, somewhat surprisingly, managed to produced shorter code than the two-address and three-address machines, at the expense of using up more than half of all opcode space. The stack machine is the obvious winner in this code density contest, without compromizing its excellent extendability (measured in opcode space used for arithmetic and other data transformation instructions). +The stack machine is the obvious winner in this code density contest, without compromising its excellent extendability (measured in opcode space used for arithmetic and other data transformation instructions). -## C.4.1. Combining with results for leaf functions. +### C.4.1. Combining with results for leaf functions -It is instructive to compare this table with the results in C.2 for a sample leaf function, summarized in Table 1 (for m = 0 preserved registers) and the very similar Table 3 (for m = 8 preserved registers), and, if one is still interested in case m = 16 (which turned out to be worse than m = 8 in almost all situations), also to Table 2. -We see that the stack machine beats all register machines on non-leaf functions. As for the leaf functions, only the three-address machine with the “optimistic” encoding of arithmetic instructions was able to beat the stack machine, winning by 15%, by compromising its extendability. However, the same three-address machine produces 25% longer code for non-leaf functions. +It is instructive to compare this table with the results in [C.2](#c-2-comparison-of-machine-code-for-sample-leaf-function) for a sample leaf function, summarized in [Table 1](#table-1) (for `m = 0` preserved registers) and the very similar [Table 3](#table-3) (for `m = 8` preserved registers), and, if one is still interested in case `m = 16` (which turned out to be worse than `m = 8` in almost all situations), also to [Table 2](#table-2). -### C.4. Comparison of machine code for sample non-leaf function +We see that the stack machine beats all register machines on non-leaf functions. As for the leaf functions, only the three-address machine with the “optimistic” encoding of arithmetic instructions was able to beat the stack machine, winning by `15%`, by compromising its extendability. However, the same three-address machine produces `25%` longer code for non-leaf functions. **Operations** | **Code bytes** | **Opcode space** @@ -3596,23 +4499,32 @@ We see that the stack machine beats all register machines on non-leaf functions. | stack (basic) | − | 18 | 11 | 29 | 18 | 33 | 51 | 64/256 | 4/256 | 71/256 | | stack (comp.) | − | 9 | 11 | 20 | 15 | 33 | 48 | 84/256 | 4/256 | 91/256 | -Table 6: A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. C.3.1), assuming m of the 16 registers must be preserved by called subroutines. This time we use fractions of bytes to encode instructions, enabling a fairer comparison. Otherwise, this table is similar to Table 5. +**Table 6:** A summary of machine code properties for hypothetical 3-address, 2-address, 1-address, and stack machines, generated for a sample non-leaf function (cf. [C.3.1](#c-3-1-sample-source-code-for-a-non-leaf-function)), assuming `m` of the `16` registers must be preserved by called subroutines. + +This time we use fractions of bytes to encode instructions, enabling a fairer comparison. Otherwise, this table is similar to [Table 5](#table-5). + +If a typical program consists of a mixture of leaf and non-leaf functions in approximately equal proportion, then the stack machine will still win. + +### C.4.2. A fairer comparison using a binary code instead of a byte code + +Similarly to [C.2.5](#c-2-5-a-fairer-comparison-using-a-binary-code-instead-of-a-byte-code), we may offer a fairer comparison of different register machines and the stack machine by using arbitrary binary codes instead of byte codes to encode instructions, and matching the opcode space used for data manipulation and arithmetic instructions by different machines. + +The results of this modified comparison are summarized in [Table 6](#table-6). We see that the stack machines still win by a large margin, while using less opcode space for stack/data manipulation. + +### C.4.3. Comparison with real machines -If a typical program consists of a mixture of leaf and non-leaf functions in approximately equal proportion, then the stack machine will still win. +Note that our hypothetical register machines have been considerably optimized to produce shorter code than actually existing register machines; the latter are subject to other design considerations apart from code density and extendability, such as backward compatibility, faster instruction decoding, parallel execution of neighboring instructions, ease of automatically producing optimized code by compilers, and so on. -## C.4.2. A fairer comparison using a binary code instead of a byte code. +For example, the very popular two-address register architecture x86-64 produces code that is approximately twice as long as our “ideal” results for the two-address machines. On the other hand, our results for the stack machines are directly applicable to TVM, which has been explicitly designed with the considerations presented in this appendix in mind. -Similarly to C.2.5, we may offer a fairer comparison of different register machines and the stack machine by using arbitrary binary codes instead of byte codes to encode instructions, and matching the opcode space used for data manipulation and arithmetic instructions by different machines. The results of this modified comparison are summarized in Table 6. We see that the stack machines still win by a large margin, while using less opcode space for stack/data manipulation. +Furthermore, the actual TVM code is even shorter (in bytes) than shown in [Table 5](#table-5) because of the presence of the two-byte `CALL` instruction, allowing TVM to call up to `256` user-defined functions from the dictionary at `c3`. This means that one should subtract `10` bytes from the results for stack machines in [Table 5](#table-5) if one wants to specifically consider TVM, rather than an abstract stack machine; this produces a code size of approximately `40` bytes (or shorter), almost half that of an abstract two-address or three-address machine. -## C.4.3. Comparison with real machines. +### C.4.4. Automatic generation of optimized code -Note that our hypothetical register machines have been considerably optimized to produce shorter code than actually existing register machines; the latter are subject to other design considerations apart from code density and extendability, such as backward compatibility, faster instruction decoding, parallel execution of neighboring instructions, ease of automatically producing optimized code by compilers, and so on. -For example, the very popular two-address register architecture x86-64 produces code that is approximately twice as long as our “ideal” results for the two-address machines. On the other hand, our results for the stack machines are directly applicable to TVM, which has been explicitly designed with the considerations presented in this appendix in mind. Furthermore, the actual TVM code is even shorter (in bytes) than shown in Table 5 because of the presence of the two-byte CALL instruction, allowing TVM to call up to 256 user-defined functions from the dictionary at c3. This means that one should subtract 10 bytes from the results for stack machines in Table 5 if one wants to specifically consider TVM, rather than an abstract stack machine; this produces a code size of approximately 40 bytes (or shorter), almost half that of an abstract two-address or three-address machine. +An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in [2.2.2](#2-2-2-basic-stack-manipulation-primitives-suffice) and [2.2.5](#2-2-5-semantics-of-compound-stack-operations). The only exception is the unimportant “manual” `XCHG3` optimization described in [C.1.7](#c-1-7-stack-machine-with-compound-stack-primitives-and-manually-optimized-code), which enabled us to shorten the code by one more byte. -## C.4.4. Automatic generation of optimized code. +By contrast, the heavily optimized (with respect to size) code for register machines shown in [C.3.2](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers) and [C.3.3](#c-3-3-three-address-and-two-address-register-machines%2C-m-%3D-8-preserved-registers) is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. -An interesting point is that the stack machine code in our samples might have been generated automatically by a very simple optimizing compiler, which rearranges values near the top of the stack appropriately before invoking each primitive or calling a function as explained in 2.2.2 and 2.2.5. The only exception is the unimportant “manual” XCHG3 optimization described in C.1.7, which enabled us to shorten the code by one more byte. -By contrast, the heavily optimized (with respect to size) code for register machines shown in C.3.2 and C.3.3 is unlikely to be produced automatically by an optimizing compiler. Therefore, if we had compared compiler-generated code instead of manually-generated code, the advantages of stack machines with respect to code density would have been even more striking. ## References @@ -3658,11 +4570,11 @@ By contrast, the heavily optimized (with respect to size) code for register mach **19.** Versions of this operation may be introduced where `f` and `g` receive an additional bitstring argument, equal to the key (for leaves) or to the common prefix of all keys (for forks) in the corresponding subtree. [Back ↑](#3-3-10-basic-dictionary-operations) - **20.** If there are no bits of data left in `code`, but there is still exactly one reference, an implicit `JMP` to the cell at that reference is performed instead of an implicit `RET`. [Back ↑](#414-normal-work-of-tvm-or-the-main-loop) + **20.** If there are no bits of data left in `code`, but there is still exactly one reference, an implicit `JMP` to the cell at that reference is performed instead of an implicit `RET`. [Back ↑](#4-1-4-normal-work-of-tvm%2C-or-the-main-loop) - **21.** Technically, TVM may simply invoke a virtual method `run()` of the continuation currently in `cc`. [Back ↑](#415-extraordinary-continuations) + **21.** Technically, TVM may simply invoke a virtual method `run()` of the continuation currently in `cc`. [Back ↑](#4-1-5-extraordinary-continuations) - **22.** The already used savelist `cc.save` of the new `cc` is emptied before the execution starts. [Back ↑](#418-restoring-control-registers-from-the-new-continuation-c) + **22.** The already used savelist `cc.save` of the new `cc` is emptied before the execution starts. [Back ↑](#4-1-8-restoring-control-registers-from-the-new-continuation-c) **23.** The implementation of REPEAT involves an extraordinary continuation that remembers the remaining number of iterations, the body of the loop c, and the return continuation c'. (The latter term represents the remainder of the body of the function that invoked REPEAT, which would be normally stored in c0 of the new cc.) [Back ↑](#422-iterated-execution-and-loops) @@ -3678,8 +4590,8 @@ By contrast, the heavily optimized (with respect to size) code for register mach **29.** Notice that any modifications after launch cannot be done unilaterally; rather they would require the support of at least two-thirds of validators. [Back ↑](#5-3-1-upgradability) - **30.** The preliminary version of TVM does not use codepage −2 for this purpose. This may change in the future. [Back ↑](#b27-codepage-2) + **30.** The preliminary version of TVM does not use codepage −2 for this purpose. This may change in the future. [Back ↑](#b-2-7-codepage-−2) **31.** It is interesting to compare this code with that generated by optimizing C compilers for the x86-64 architecture. First of all, the integer division operation for x86-64 uses the one-address form, with the (double-length) dividend to be supplied in accumulator pair `r2:r0`. The quotient is also returned in `r0`. As a consequence, two single-to-double extension operations (**CDQ** or **CQO**) and at least one move operation need to be added. Secondly, the encoding used for arithmetic and move operations is less optimistic than in our example above, requiring about three bytes per operation on average. As a result, we obtain a total of 43 bytes for 32-bit integers, and 68 bytes for 64-bit integers. [Back ↑](#c13-two-address-register-machine) - **32.** Code produced for this function by an optimizing compiler for x86-64 architecture. [Back ↑](#c32-three-address-and-two-address-register-machines-m--0-preserved-registers) \ No newline at end of file + **32.** Code produced for this function by an optimizing compiler for x86-64 architecture. [Back ↑](#c-3-2-three-address-and-two-address-register-machines%2C-m-%3D-0-preserved-registers) \ No newline at end of file From 343611e8a026615c7b4579e00b8bcbe50fa815ef Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Tue, 9 Sep 2025 03:20:59 +0100 Subject: [PATCH 12/18] fix markdown header --- ton/tvm.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index aa704237..44cc6cb6 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -1323,7 +1323,7 @@ TVM makes special provisions for simple and concise implementation of selector f Another instruction, useful for the implementation of sum-product types, is `PLDUZ` (cf. [A.7.2](#a-7-2-cell-deserialization-primitives)). This instruction preloads the first several bits of a Slice into an Integer, which can later be inspected by `IFBITJMP` and other similar instructions. -## 4.6.12 Alternative: using a hashmap to select the correct function +### 4.6.12 Alternative: using a hashmap to select the correct function Yet another alternative is to use a Hashmap (cf. [3.3](#3-3-hashmaps%2C-or-dictionaries)) to hold the “collection” or “dictionary” of the code of all functions in a program, and use the hashmap lookup primitives (cf. [A.10](#a-10-dictionary-manipulation-primitives)) to select the code of the required function, which can then be `BLESS`ed into a continuation (cf. [A.8.5](#a-8-5-creating-simple-continuations-and-closures)) and executed. Special combined “lookup, bless, and execute” primitives, such as `DICTIGETJMP` and `DICTIGETEXEC`, are also available (cf. [A.10.11](#a-10-10-getmin%2C-getmax%2C-removemin%2C-removemax-operations)). This approach may be more efficient for larger programs and switch statements. From 160d2ce39eda70fb76a5f1e2f933ae608c49b876 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Tue, 9 Sep 2025 23:35:44 +0100 Subject: [PATCH 13/18] fix unordered list --- ton/tvm.mdx | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 44cc6cb6..b2fc49fa 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -3231,7 +3231,7 @@ specific primitives are in fact TON Blockchain-specific. Most of the primitives listed below use 16-bit opcodes. -* * `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value +* `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value `gm`, and resets the gas credit `gc` to zero (cf. `1.4`), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action @@ -3416,24 +3416,23 @@ Most of the primitives listed below use 16-bit opcodes. do not fall into any other specific category. +### A.11.8. Currency manipulation primitives -### A.11.8. Currency manipulation primitives. +* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s′)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s′` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDUX`. -* `FA00` — `LDGRAMS` or `LDVARUINT16` `(s – x s0)`, loads (deserializes) a Gram or `VarUInteger 16` amount from `CellSlice` `s`, and returns the amount as `Integer` `x` along with the remainder `s 0` of `s`. The expected serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDUX`. +* `FA01` — `LDVARINT16` `(s – x s′)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDIX`. -* `FA01` — `LDVARINT16` `(s – x s0)`, similar to `LDVARUINT16`, but loads a signed `Integer` `x`. Approximately equivalent to `LDU 4`; `SWAP`; `LSHIFT 3`; `LDIX`. +* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b′)`, stores (serializes) an `Integer` `x` in the range `0 ... 2¹²⁰ − 1` into `Builder` `b`, and returns the resulting `Builder` `b′`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2⁸ˡ`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. -* `FA02` — `STGRAMS` or `STVARUINT16` `(b x – b 0)`, stores (serializes) an `Integer` `x` in the range `0 ... 2¹²⁰−1` into `Builder` `b`, and returns the resulting `Builder` `b 0`. The serialization of `x` consists of a 4-bit unsigned big-endian integer `l`, which is the smallest integer `l ≥ 0`, such that `x < 2⁸ˡ`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. If `x` does not belong to the supported range, a range check exception is thrown. +* `FA03` — `STVARINT16` `(b x – b′)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2¹¹⁹ ... 2¹¹⁹ − 1`. -* `FA03` — `STVARINT16` `(b x – b 0)`, similar to `STVARUINT16`, but serializes a signed `Integer` `x` in the range `−2¹¹⁹ ... 2¹¹⁹ − 1`. +* `FA04` — `LDVARUINT32` `(s – x s′)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2²⁴⁸`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 5`; `SWAP`; `SHIFT 3`; `LDUX`. -* `FA04` — `LDVARUINT32` `(s – x s0)`, loads (deserializes) a `VarUInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `0 ≤ x < 2²⁴⁸`. The expected serialization of `x` consists of a 5-bit unsigned big-endian integer `l`, followed by an `8ˡ`-bit unsigned big-endian representation of `x`. The net effect is approximately equivalent to `LDU 5`; `SWAP`; `SHIFT 3`; `LDUX`. +* `FA05` — `LDVARINT32` `(s – x s′)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷`. -* `FA05` — `LDVARINT32` `(s – x s0)`, deserializes a `VarInteger 32` from `CellSlice` `s`, and returns the deserialized value as an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷`. +* `FA06` — `STVARUINT32` `(b x – b′)`, serializes an `Integer` `0 ≤ x < 2²⁴⁸` as a `VarUInteger 32`. -* `FA06` — `STVARUINT32` `(b x – b 0)`, serializes an `Integer` `0 ≤ x < 2²⁴⁸` as a `VarUInteger 32`. - -* `FA07` — `STVARINT32` `(b x – b 0)`, serializes an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷` as a `VarInteger 32`. +* `FA07` — `STVARINT32` `(b x – b′)`, serializes an `Integer` `−2²⁴⁷ ≤ x < 2²⁴⁷` as a `VarInteger 32`. * `FA08–FA1F` — Reserved for currency manipulation primitives. @@ -3465,12 +3464,9 @@ A deserialized `MsgAddress` is represented by a `Tuple` `t` as follows: * `addr_none` is represented by `t = (0)`, i.e., a `Tuple` containing exactly one `Integer` equal to zero. * `addr_extern` is represented by `t = (1, s)`, where `Slice` `s` contains the field `external_address`. In other words, `t` is a pair (a `Tuple` consisting of two entries), containing an `Integer` equal to one and `Slice` `s`. * `addr_std` is represented by `t = (2, u, x, s)`, where `u` is either a `Null` (if `anycast` is absent) or a `Slice` `s′` containing `rewrite_pfx` (if `anycast` is present). Next, `Integer` `x` is the `workchain_id`, and `Slice` `s` contains the address. - `135` - A.11. Application-specific primitives * `addr_var` is represented by `t = (3, u, x, s)`, where `u`, `x`, and `s` have the same meaning as for `addr_std`. - -### A.11.9. Message and address manipulation primitives. +The following primitives, which use the above conventions, are defined: * `FA40` — `LDMSGADDR` `(s – s′ s′′)`, loads from `CellSlice` `s` the only prefix that is a valid `MsgAddress`, and returns both this prefix `s′` and the remainder `s′′` of `s` as `CellSlices`. * `FA41` — `LDMSGADDRQ` `(s – s′ s′′ −1 or s 0)`, a quiet version of `LDMSGADDR`: on success, pushes an extra `−1`; on failure, pushes the original `s` and a zero. From d801c51d6b80190d795ce54f7388a9824ac8068a Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Sun, 14 Sep 2025 01:24:30 +0100 Subject: [PATCH 14/18] fix broken links --- ton/tvm.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index b2fc49fa..a229a477 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -152,7 +152,7 @@ The original version of TVM defines and uses the following control registers: - **c0** — Contains the next continuation or return continuation (similar to the subroutine return address in conventional designs). This value must be a `Continuation`. - **c1** — Contains the alternative (return) continuation; this value must be a `Continuation`. It is used in some (experimental) control flow primitives, allowing TVM to define and call “subroutines with two exit points”. - **c2** — Contains the exception handler. This value is a `Continuation`, invoked whenever an exception is triggered. -- **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in [4.6](#4-6-...-reference), this value is also a `Continuation`, not a `Cell` as one might expect. +- **c3** — Contains the current dictionary, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in [4.6](#4-6-functions%2C-recursion%2C-and-dictionaries), this value is also a `Continuation`, not a `Cell` as one might expect. - **c4** — Contains the root of persistent data, or simply the data. This value is a `Cell`. When the code of a smart contract is invoked, `c4` points to the root cell of its persistent data kept in the blockchain state. If the smart contract needs to modify this data, it changes `c4` before returning. - **c5** — Contains the output actions. It is also a `Cell` initialized by a reference to an empty cell, but its final value is considered one of the smart contract outputs. For instance, the `SENDMSG` primitive, specific for the TON Blockchain, simply inserts the message into a list stored in the output actions. - **c7** — Contains the root of temporary data. It is a `Tuple`, initialized by a reference to an empty `Tuple` before invoking the smart contract and discarded after its termination.[4](#footnote-4) From 59f78e8fa7cc859ac1e695cfcb7cae53dc23d628 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Fri, 19 Sep 2025 14:11:23 +0100 Subject: [PATCH 15/18] merge ch --- .vale/config/vocabularies/Custom/accept.txt | 54 + .vale/config/vocabularies/Mintlify/accept.txt | 18 + CODEOWNERS | 56 + contribute/index.mdx | 2 +- docs.json | 140 +- ecosystem/analytics.mdx | 158 + ecosystem/ton-connect/appkit.mdx | 6 - .../dapps/check-jetton-balance.mdx | 6 + ecosystem/ton-connect/dapps/check-nfts.mdx | 6 + .../dapps/check-toncoin-balance.mdx | 6 + .../ton-connect/dapps/check-usdt-balance.mdx | 6 + ecosystem/ton-connect/dapps/request-proof.mdx | 6 + ecosystem/ton-connect/dapps/send-jetton.mdx | 6 + ecosystem/ton-connect/dapps/send-nft.mdx | 6 + ecosystem/ton-connect/dapps/send-toncoin.mdx | 6 + ecosystem/ton-connect/dapps/send-usdt.mdx | 6 + ecosystem/ton-connect/dapps/sign-data.mdx | 6 + .../ton-connect/dapps/track-transaction.mdx | 6 + ecosystem/ton-connect/index.mdx | 58 +- ecosystem/ton-connect/walletkit.mdx | 6 - .../walletkit/browser-extension.mdx | 5 + ecosystem/ton-connect/walletkit/index.mdx | 55 + .../ton-connect/walletkit/native-web.mdx | 5 + ecosystem/ton-connect/walletkit/qa-guide.mdx | 5 + guidebook/get-support.mdx => get-support.mdx | 0 guidebook/dapp.mdx | 440 ++- guidebook/from-ethereum.mdx | 118 + guidebook/start-here.mdx | 72 - guidebook/wallet.mdx | 65 +- language/fift.mdx | 5 - package-lock.json | 154 +- package.json | 2 +- .../images/from-ethereum/burn-tx-eth.png | Bin 0 -> 499193 bytes .../images/from-ethereum/burn-tx-ton.png | Bin 0 -> 316628 bytes start-here.mdx | 5 + ton/address.mdx | 5 - ton/addresses/address-formats.mdx | 132 + ton/addresses/addresses-general-info.mdx | 88 + ton/config.mdx | 5 +- ton/{states.mdx => statuses.mdx} | 0 ton/tbl.mdx | 3282 +++++++++++++++++ 41 files changed, 4757 insertions(+), 250 deletions(-) create mode 100644 CODEOWNERS create mode 100644 ecosystem/analytics.mdx delete mode 100644 ecosystem/ton-connect/appkit.mdx create mode 100644 ecosystem/ton-connect/dapps/check-jetton-balance.mdx create mode 100644 ecosystem/ton-connect/dapps/check-nfts.mdx create mode 100644 ecosystem/ton-connect/dapps/check-toncoin-balance.mdx create mode 100644 ecosystem/ton-connect/dapps/check-usdt-balance.mdx create mode 100644 ecosystem/ton-connect/dapps/request-proof.mdx create mode 100644 ecosystem/ton-connect/dapps/send-jetton.mdx create mode 100644 ecosystem/ton-connect/dapps/send-nft.mdx create mode 100644 ecosystem/ton-connect/dapps/send-toncoin.mdx create mode 100644 ecosystem/ton-connect/dapps/send-usdt.mdx create mode 100644 ecosystem/ton-connect/dapps/sign-data.mdx create mode 100644 ecosystem/ton-connect/dapps/track-transaction.mdx delete mode 100644 ecosystem/ton-connect/walletkit.mdx create mode 100644 ecosystem/ton-connect/walletkit/browser-extension.mdx create mode 100644 ecosystem/ton-connect/walletkit/index.mdx create mode 100644 ecosystem/ton-connect/walletkit/native-web.mdx create mode 100644 ecosystem/ton-connect/walletkit/qa-guide.mdx rename guidebook/get-support.mdx => get-support.mdx (100%) create mode 100644 guidebook/from-ethereum.mdx delete mode 100644 guidebook/start-here.mdx delete mode 100644 language/fift.mdx create mode 100644 resources/images/from-ethereum/burn-tx-eth.png create mode 100644 resources/images/from-ethereum/burn-tx-ton.png create mode 100644 start-here.mdx delete mode 100644 ton/address.mdx create mode 100644 ton/addresses/address-formats.mdx create mode 100644 ton/addresses/addresses-general-info.mdx rename ton/{states.mdx => statuses.mdx} (100%) create mode 100644 ton/tbl.mdx diff --git a/.vale/config/vocabularies/Custom/accept.txt b/.vale/config/vocabularies/Custom/accept.txt index b31622e0..dcac5cb6 100644 --- a/.vale/config/vocabularies/Custom/accept.txt +++ b/.vale/config/vocabularies/Custom/accept.txt @@ -1,9 +1,12 @@ +ABI +ABIs Alefman Alibaba Altcoin Basechain Binance Blockchain +Blockscout BoC BoCs Booleans @@ -21,11 +24,16 @@ DEXes DEXs Datagram Durov +EVM +EVMs Ethena Ethereum +Ethers +Etherscan FTs Fift Frontmatter +Ganache Gbps Grafana Gunicorn @@ -55,12 +63,15 @@ Pavel Phaser Precompiled Preloads +Reth +Revm SBTs SDKs Scannability Sharding Solana Soulbound +Spellbook Stablecoin TEPs TMAs @@ -78,15 +89,20 @@ Tonkey Tonlib Tonstarter Tonviewer +UIs +USDe USDt Unary Uninit +Viem VSCodium Vadim Validator Validators Vultr +Wagmi Walkthrough +Walletconnect Watchlist Webserver Whitepapers @@ -99,6 +115,7 @@ api asm asms basechain +bene bitwise blazingly blockchain @@ -181,6 +198,8 @@ nanotons nft nonexist offchain +nota +nonexist param performant pragma @@ -207,6 +226,7 @@ stablecoin standart styleguide subnetworks +subpage subslice subtree subwallet @@ -222,6 +242,7 @@ tonlib tonscan tonviewer tonweb +tsUSDe ts unary undecodable @@ -235,3 +256,36 @@ whitepaper whitepapers workchain workchains +Tblkch +shardchain +shardchains +accountchain +accountchains +bitstrings +anycast +nanograms +unixtime +componentwise +dequeueing +dequeued +doa +subcell +fwd_fee +Schnorr +abelian +isogeny +involutive +Hasse +Kiayas +Yung +cryptowallet +enqueued +datagrams +deserializing +Kademlia +Dodis +virtualized +sidechains +sharedlibrary +subtransactions +deserialized \ No newline at end of file diff --git a/.vale/config/vocabularies/Mintlify/accept.txt b/.vale/config/vocabularies/Mintlify/accept.txt index 8799898d..c1b9b01c 100644 --- a/.vale/config/vocabularies/Mintlify/accept.txt +++ b/.vale/config/vocabularies/Mintlify/accept.txt @@ -60,6 +60,7 @@ null undefined struct bool +thes cors csrf @@ -265,3 +266,20 @@ nav prev next toc +anin +tock +unparsed +unimported +antecessors +inis +prepended +cofactor +birationally +birational +antecessor +Constructivization +constructivized +subinterval +cofactors +unenveloped +subcases \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..055f44fb --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,56 @@ +start-here.mdx @novusnota @verytactical @anton-trunov +get-support.mdx @novusnota @verytactical @anton-trunov +guidebook/first-dapp.mdx @novusnota @verytactical @anton-trunov +guidebook/from-ethereum.mdx @Kaladin13 +guidebook/payment.mdx @tact-lang/smart-contracts +guidebook/debug.mdx @tact-lang/smart-contracts +guidebook/telegram.mdx @tact-lang/smart-contracts +guidebook/tma.mdx @tact-lang/smart-contracts +guidebook/react.mdx @tact-lang/smart-contracts +guidebook/auth.mdx @tact-lang/smart-contracts +guidebook/game.mdx @tact-lang/smart-contracts +guidebook/dapp.mdx @tact-lang/smart-contracts +guidebook/wallet.mdx @tact-lang/smart-contracts +guidebook/cex.mdx @tact-lang/smart-contracts +guidebook/more.mdx @tact-lang/smart-contracts +ecosystem/overview.mdx @verytactical +ecosystem/wallet-apps/overview.mdx @tact-lang/smart-contracts +ecosystem/wallet-apps/tonkeeper.mdx @tact-lang/smart-contracts +ecosystem/wallet-apps/web.mdx @verytactical +ecosystem/wallet-apps/dev.mdx @verytactical +ecosystem/explorers/overview.mdx @tact-lang/smart-contracts +ecosystem/explorers/tonviewer.mdx @tact-lang/smart-contracts +ecosystem/ide/ @tact-lang/smart-contracts +ecosystem/blueprint/ @thekiba +ecosystem/testing/overview.mdx @tact-lang/smart-contracts +ecosystem/testing/sandbox.mdx @thekiba +ecosystem/testing/test-utils.mdx @thekiba +ecosystem/ton-connect/ @thekiba @TrueCarry +ecosystem/sdks.mdx @verytactical +ecosystem/analytics.mdx @anton-trunov +ecosystem/status.mdx @anton-trunov +ecosystem/rpc/overview.mdx @tact-lang/smart-contracts +ecosystem/rpc/toncenter.mdx @tact-lang/smart-contracts +ecosystem/node/overview.mdx @tact-lang/smart-contracts +ecosystem/node/usage.mdx @tact-lang/smart-contracts +ecosystem/node/mytonctrl.mdx @tact-lang/smart-contracts +ecosystem/ai.mdx @Gusarich +ecosystem/more.mdx @tact-lang/smart-contracts +standard/overview.mdx @tact-lang/smart-contracts +standard/wallets/ @tact-lang/smart-contracts +standard/tokens/ @tact-lang/smart-contracts +standard/dex.mdx @tact-lang/smart-contracts +standard/vesting.mdx @tact-lang/smart-contracts +standard/governance.mdx @tact-lang/smart-contracts +techniques/ @tact-lang/smart-contracts +techniques/security.mdx @Karkarmath +techniques/zk.mdx @Kaladin13 +language/tolk.mdx @tact-lang/smart-contracts +language/tlb.mdx @verytactical +language/fift/ @pyAndr3w +language/func/ @tact-lang/smart-contracts +language/tact.mdx @novusnota +tvm/ @tact-lang/smart-contracts +ton/ @tact-lang/smart-contracts +services/ @tact-lang/smart-contracts +contribute/ @anton-trunov @verytactical diff --git a/contribute/index.mdx b/contribute/index.mdx index 946e9fde..c8c5aa5d 100644 --- a/contribute/index.mdx +++ b/contribute/index.mdx @@ -1,6 +1,6 @@ --- title: "Contribute to this documentation" -sidebarTitle: "Overview" +sidebarTitle: "How to contribute?" --- This page is a placeholder, a stub. It's here to help visualize the new structure, but it is temporarily devoid of content. diff --git a/docs.json b/docs.json index f74c4536..b56c0fba 100644 --- a/docs.json +++ b/docs.json @@ -35,12 +35,13 @@ }, "navigation": { "pages": [ - "guidebook/start-here", - "guidebook/get-support", + "start-here", + "get-support", { "group": "Step by step", "pages": [ "guidebook/first-dapp", + "guidebook/from-ethereum", "guidebook/payment", "guidebook/nft", "guidebook/tokens", @@ -54,6 +55,19 @@ "guidebook/dapp", "guidebook/wallet", "guidebook/cex", + { + "group": "Frontend", + "expanded": true, + "pages": [] + }, + { + "group": "Backend", + "pages": [] + }, + { + "group": "Mobile", + "pages": [] + }, "guidebook/more" ] }, @@ -110,8 +124,31 @@ "pages": [ "ecosystem/ton-connect/index", "ecosystem/ton-connect/manifest", - "ecosystem/ton-connect/appkit", - "ecosystem/ton-connect/walletkit", + { + "group": "Applications (dApps)", + "pages": [ + "ecosystem/ton-connect/dapps/send-toncoin", + "ecosystem/ton-connect/dapps/send-usdt", + "ecosystem/ton-connect/dapps/send-jetton", + "ecosystem/ton-connect/dapps/send-nft", + "ecosystem/ton-connect/dapps/check-toncoin-balance", + "ecosystem/ton-connect/dapps/check-usdt-balance", + "ecosystem/ton-connect/dapps/check-jetton-balance", + "ecosystem/ton-connect/dapps/check-nfts", + "ecosystem/ton-connect/dapps/track-transaction", + "ecosystem/ton-connect/dapps/sign-data", + "ecosystem/ton-connect/dapps/request-proof" + ] + }, + { + "group": "WalletKit", + "pages": [ + "ecosystem/ton-connect/walletkit/index", + "ecosystem/ton-connect/walletkit/qa-guide", + "ecosystem/ton-connect/walletkit/native-web", + "ecosystem/ton-connect/walletkit/browser-extension" + ] + }, { "group": "TON Connect articles from Google Docs", "tag": "TMP", @@ -124,6 +161,7 @@ ] }, "ecosystem/sdks", + "ecosystem/analytics", "ecosystem/status", { "group": "RPC providers", @@ -144,6 +182,45 @@ "ecosystem/more" ] }, + { + "group": "Standard contracts", + "pages": [ + "standard/overview", + { + "group": "Wallets", + "pages": [ + "standard/wallets/comparison" + ] + }, + { + "group": "Tokens", + "pages": [ + "standard/tokens/comparison", + "standard/tokens/nft", + "standard/tokens/jetton", + "standard/tokens/sbt", + "standard/tokens/airdrop" + ] + }, + "standard/dex", + "standard/vesting", + "standard/governance" + ] + }, + { + "group": "Contract patterns", + "pages": [ + "techniques/examples", + "techniques/carry-value", + "techniques/sharding", + "techniques/security", + "techniques/gas", + "techniques/offchaining", + "techniques/tokens", + "techniques/upgrades", + "techniques/zk" + ] + }, { "group": "Languages", "pages": [ @@ -191,31 +268,6 @@ "language/tact" ] }, - { - "group": "Standard contracts", - "pages": [ - "standard/overview", - { - "group": "Wallets", - "pages": [ - "standard/wallets/comparison" - ] - }, - { - "group": "Tokens", - "pages": [ - "standard/tokens/comparison", - "standard/tokens/nft", - "standard/tokens/jetton", - "standard/tokens/sbt", - "standard/tokens/airdrop" - ] - }, - "standard/dex", - "standard/vesting", - "standard/governance" - ] - }, { "group": "TVM: TON Virtual Machine", "pages": [ @@ -236,11 +288,18 @@ ] }, { - "group": "Foundations", + "group": "Blockchain foundations", "pages": [ "ton/overview", - "ton/address", - "ton/states", + "ton/comparison", + { + "group": "Addresses", + "pages": [ + "ton/addresses/addresses-general-info", + "ton/addresses/address-formats" + ] + }, + "ton/statuses", "ton/transaction", "ton/phases-and-fees", "ton/shards", @@ -252,11 +311,12 @@ "ton/network", "ton/blocks", "ton/tvm", + "ton/tbl", "ton/glossary" ] }, { - "group": "Services", + "group": "Web3 services", "pages": [ "services/dns", "services/payment", @@ -265,20 +325,6 @@ "services/storage" ] }, - { - "group": "Smart-contract patterns", - "pages": [ - "techniques/examples", - "techniques/carry-value", - "techniques/sharding", - "techniques/security", - "techniques/gas", - "techniques/offchaining", - "techniques/tokens", - "techniques/upgrades", - "techniques/zk" - ] - }, { "group": "Contribute", "pages": [ diff --git a/ecosystem/analytics.mdx b/ecosystem/analytics.mdx new file mode 100644 index 00000000..744bc9ee --- /dev/null +++ b/ecosystem/analytics.mdx @@ -0,0 +1,158 @@ +--- +title: "Analytics and data providers" +sidebarTitle: "Analytics" +--- + +import { Aside } from '/snippets/aside.jsx'; + +Developers often need to run analytical queries on top of on-chain data — for example, to track historical changes and aggregate data from multiple accounts. + +Since blockchains are not designed for analytical workloads, you need to build an indexing pipeline and run off-chain analytical queries. + +Creating such pipelines from scratch can be resource-consuming, so we recommend using one of the tools mentioned on this page. + +## Dune analytics + +[Dune analytics](https://dune.com/) is one of the leading platforms for running analytical queries and building dashboards. It comes with 100+ blockchain integrations, and TON is among them. Basically, one needs to be familiar with SQL language to write queries, but the [Dune AI](https://docs.dune.com/learning/how-tos/dune-ai-prompt-engineering) prompt engine allows users to start working with data even without SQL knowledge. + +### Raw and decoded tables + +Dune analytics consumes data from the public [TON Data Lake](#public-data-lake) (see below) and comes with a variety of raw and decoded tables. + +The [raw tables](https://dune.com/queries?category=canonical&namespace=ton) include: + +- [Blocks](https://docs.dune.com/data-catalog/ton/blocks) +- [Transactions](https://docs.dune.com/data-catalog/ton/transactions) +- [Messages](https://docs.dune.com/data-catalog/ton/messages) — includes raw body and state init data. +- [Balances history](https://docs.dune.com/data-catalog/ton/balances_history) — allows you to get a precise point-in-time balance for any account. +- [Jetton events](https://docs.dune.com/data-catalog/ton/jetton_events) — comes with transfers, burns and mints. + + + +Apart from raw tables, there are decoded tables that allow you to work with high-level structures in a unified manner: + +- [NFT events](https://dune.com/queries?category=canonical&namespace=ton&id=ton.nft_events) — comprehensive source of NFT-related data including +sales, transfers and mints. +- [DEX trades](https://docs.dune.com/data-catalog/ton/dex_trades) — includes a unified data model for DEX trades. The full list of +supported DEXs is available [here](https://github.com/ton-studio/ton-etl/blob/main/datalake/README.md#dex-trades). +- [DEX pools](https://docs.dune.com/data-catalog/ton/dex_pools) — comes with the full history of DEX pool balances and TVL estimations. + +Finally, two tables with off-chain metadata are available: + +- [Jetton metadata](https://docs.dune.com/data-catalog/ton/jetton_metadata) +- [NFT metadata](https://dune.com/queries?category=canonical&namespace=ton&id=ton.nft_metadata). + +### Bespoke data marts + +Dune analytics allows projects to build bespoke data marts for each protocol — it is widely used for EVMs with the help of ABIs. + +#### Decoding raw data + +Since TON handles complex [data structures](/v3/documentation/data-formats/cells/overview/) and doesn't have ABIs, a [special decoding framework](https://github.com/duneanalytics/spellbook/blob/main/dbt_subprojects/daily_spellbook/macros/project/ton/README.md) was created. It works on top of the [Spellbook](https://github.com/duneanalytics/spellbook) — a powerful tool for building custom tables with [dbt](https://github.com/dbt-labs/dbt-core) and Jinja macros. It helps decode important information from raw protocol message payloads. + +The following protocols are decoded using this framework and serve as examples: + +- [EVAA](https://dune.com/queries?category=abstraction&namespace=evaa) ([implementation](https://github.com/duneanalytics/spellbook/tree/main/dbt_subprojects/daily_spellbook/models/evaa/ton)) +- [Affluent](https://dune.com/queries?category=abstraction&namespace=affluent) ([implementation](https://github.com/duneanalytics/spellbook/tree/main/dbt_subprojects/daily_spellbook/models/affluent/ton)) +- [StormTrade](https://dune.com/queries?category=abstraction&namespace=stormtrade) ([implementation](https://github.com/duneanalytics/spellbook/tree/main/dbt_subprojects/daily_spellbook/models/stormtrade/ton)) +- [TON DNS](https://dune.com/queries?category=abstraction&namespace=dns_ton) ([implementation](https://github.com/duneanalytics/spellbook/tree/main/dbt_subprojects/daily_spellbook/models/ton/dns)) + +#### Custom views + +In addition to decoding raw data, the Spellbook allows building custom materialized views. Some of them are widely used and maintained to be up to date: + +- [ton.prices_daily](https://dune.com/queries?category=abstraction&namespace=ton&id=ton.prices_daily) — prices calculated based on all other tables. The prices include jettons traded on DEXs, LP tokens for DEXs and perpetuals, tsUSDe and other core assets. It is recommended to use this table if you need to build an estimation of assets denominated in TON or USD. +- [ton.accounts](https://dune.com/queries?category=abstraction&namespace=ton&id=ton.accounts) — materialized view with information about all accounts. It comes with the latest TON balance, interface (if any), funding information and other fields. +- [ton.latest_balances](https://dune.com/queries?category=abstraction&namespace=ton&id=ton.latest_balances) — helper table to get the latest balances for TON and Jettons. + + + +### Getting started with Dune + +If you're just starting to explore TON data on Dune, we recommend checking these articles first: + + + + + + + +For inspiration to build your own dashboards, check out these examples: + + + + + + + +## Public Data Lake + +Dune integration runs on the public data lake from the [TON-ETL](https://github.com/re-doubt/ton-etl/blob/main/datalake/README.md) project. + +[TON-ETL](https://github.com/re-doubt/ton-etl/blob/main/datalake/README.md) is built on top of [TON Center](https://github.com/toncenter) indexer and allows extraction of data from TON Node into data formats suitable for MPP (Massively Parallel Processing) engines: Presto, Apache Spark, etc. + + + +The TON-ETL extracts raw data and performs decoding to create a unified view of high-level on-chain activity. The most important part is decoding DEX activity. + +The decoding implementation must solve the following tasks: +- Decoding of swap events. The code must check the authenticity of the swap. For example, you cannot rely on the opcode alone since anyone can generate messages with your opcode. +- Extracting all swap-related fields: tokens sold and bought, amounts, query IDs, trader, router (if any), and pool. +- Fetching pool reserves and LP token supply, if applicable. + +To add support for a new DEX and decode its activity, you need to prepare a relevant PR on GitHub [to TON-ETL's repo](https://github.com/ton-studio/ton-etl). Use those past PRs as a reference: [BidAsk](https://github.com/ton-studio/ton-etl/pull/186), [CoffeeSwap](https://github.com/ton-studio/ton-etl/pull/171/files), [MemesLab](https://github.com/ton-studio/ton-etl/pull/144). + +## Real-time streams + +In addition to bulk data export, TON-ETL provides real-time data streaming via Kafka. A [public endpoint](https://github.com/ton-studio/ton-etl/blob/main/datalake/README.md#near-real-time--data-streaming-via-pulic-kafka-topics) is available free of charge for non-profit projects. + +For projects that don't meet the non-profit criteria or require an in-house solution, you can deploy the infrastructure yourself by: + +1. Running your own [TON node](/v3/documentation/nodes/overview) +2. Launching [ton-etl](https://github.com/re-doubt/ton-etl/blob/main/README.md) +3. Setting up [ton-index-worker](https://github.com/ton-studio/ton-index-worker) + +## TON Labels + +While data availability and integrations are essential, building insightful dashboards requires enriching data with address labels. + +The [TON Labels](https://github.com/ton-studio/ton-labels) project simplifies this process by providing a comprehensive taxonomy of addresses in TON Ecosystem. It covers active addresses across various categories including centralized exchanges (CEXs), decentralized applications (dApps), and DeFi protocols. + +You can access the latest labels either directly from [the build branch](https://github.com/ton-studio/ton-labels/blob/build/assets.json) or through Dune analytics using the [`dune.ton_foundation.dataset_labels`](https://dune.com/queries?category=uploaded_data&id=dune.ton_foundation.dataset_labels) table. + +## Other platforms + +- [Chainbase](https://docs.chainbase.com/catalog/Ton/Overview) offers a set of raw and decoded tables with TON data. It allows you to run SQL queries and fetch results via API. +- [TON Console](https://docs.tonconsole.com/tonconsole/analytics) provides analysts with Analytics Service. +- [TokenTerminal](https://tokenterminal.com/explorer/projects/the-open-network) comes with high-level metrics across TON Ecosystem. +- [Artemis](https://app.artemisanalytics.com/project/ton?from=projects) contains key metrics for TON and allows you to build customized charts. diff --git a/ecosystem/ton-connect/appkit.mdx b/ecosystem/ton-connect/appkit.mdx deleted file mode 100644 index c26c5a0c..00000000 --- a/ecosystem/ton-connect/appkit.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "TON Connect for decentralized applications (dApps)" -sidebarTitle: "Application (dApp)" ---- - -Draft! diff --git a/ecosystem/ton-connect/dapps/check-jetton-balance.mdx b/ecosystem/ton-connect/dapps/check-jetton-balance.mdx new file mode 100644 index 00000000..531e72e5 --- /dev/null +++ b/ecosystem/ton-connect/dapps/check-jetton-balance.mdx @@ -0,0 +1,6 @@ +--- +title: "How to check Jetton balance" +sidebarTitle: "Check Jetton balance" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/check-nfts.mdx b/ecosystem/ton-connect/dapps/check-nfts.mdx new file mode 100644 index 00000000..f9339c18 --- /dev/null +++ b/ecosystem/ton-connect/dapps/check-nfts.mdx @@ -0,0 +1,6 @@ +--- +title: "How to check NFT items present" +sidebarTitle: "Check NFT items" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/check-toncoin-balance.mdx b/ecosystem/ton-connect/dapps/check-toncoin-balance.mdx new file mode 100644 index 00000000..6a77b134 --- /dev/null +++ b/ecosystem/ton-connect/dapps/check-toncoin-balance.mdx @@ -0,0 +1,6 @@ +--- +title: "How to check Toncoin balance" +sidebarTitle: "Check Toncoin balance" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/check-usdt-balance.mdx b/ecosystem/ton-connect/dapps/check-usdt-balance.mdx new file mode 100644 index 00000000..c5fb1f24 --- /dev/null +++ b/ecosystem/ton-connect/dapps/check-usdt-balance.mdx @@ -0,0 +1,6 @@ +--- +title: "How to check USDT balance" +sidebarTitle: "Check USDT balance" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/request-proof.mdx b/ecosystem/ton-connect/dapps/request-proof.mdx new file mode 100644 index 00000000..9f993601 --- /dev/null +++ b/ecosystem/ton-connect/dapps/request-proof.mdx @@ -0,0 +1,6 @@ +--- +title: "How to make a proof request and verify it" +sidebarTitle: "Request a proof" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/send-jetton.mdx b/ecosystem/ton-connect/dapps/send-jetton.mdx new file mode 100644 index 00000000..cac758e8 --- /dev/null +++ b/ecosystem/ton-connect/dapps/send-jetton.mdx @@ -0,0 +1,6 @@ +--- +title: "How to send a token (Jetton)" +sidebarTitle: "Send a Jetton" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/send-nft.mdx b/ecosystem/ton-connect/dapps/send-nft.mdx new file mode 100644 index 00000000..7d8ecf6f --- /dev/null +++ b/ecosystem/ton-connect/dapps/send-nft.mdx @@ -0,0 +1,6 @@ +--- +title: "How to send an NFT item" +sidebarTitle: "Send an NFT" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/send-toncoin.mdx b/ecosystem/ton-connect/dapps/send-toncoin.mdx new file mode 100644 index 00000000..e50e2170 --- /dev/null +++ b/ecosystem/ton-connect/dapps/send-toncoin.mdx @@ -0,0 +1,6 @@ +--- +title: "How to send Toncoin" +sidebarTitle: "Send Toncoin" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/send-usdt.mdx b/ecosystem/ton-connect/dapps/send-usdt.mdx new file mode 100644 index 00000000..f8c8952c --- /dev/null +++ b/ecosystem/ton-connect/dapps/send-usdt.mdx @@ -0,0 +1,6 @@ +--- +title: "How to send USDT" +sidebarTitle: "Send USDT" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/sign-data.mdx b/ecosystem/ton-connect/dapps/sign-data.mdx new file mode 100644 index 00000000..97b478fb --- /dev/null +++ b/ecosystem/ton-connect/dapps/sign-data.mdx @@ -0,0 +1,6 @@ +--- +title: "How to make a sign data request and verify signed data" +sidebarTitle: "Sign data" +--- + +Stub diff --git a/ecosystem/ton-connect/dapps/track-transaction.mdx b/ecosystem/ton-connect/dapps/track-transaction.mdx new file mode 100644 index 00000000..98abab7a --- /dev/null +++ b/ecosystem/ton-connect/dapps/track-transaction.mdx @@ -0,0 +1,6 @@ +--- +title: "How to track a transaction and confirm its status" +sidebarTitle: "Track a transaction" +--- + +Stub diff --git a/ecosystem/ton-connect/index.mdx b/ecosystem/ton-connect/index.mdx index d1c6bbd1..c24df097 100644 --- a/ecosystem/ton-connect/index.mdx +++ b/ecosystem/ton-connect/index.mdx @@ -50,22 +50,22 @@ Explore the demo apps made with React. /> - +Proceed with integration and usage recipes. -Go through the step-by-step guide with a tech that suits you most. + + + + - - - -Or skim the related reference pages. +Skim the related reference pages. + title="@tonconnect/sdk" + arrow="true" + href="https://ton-connect.github.io/sdk/modules/_tonconnect_sdk.html"> + + + + @@ -103,6 +113,11 @@ Or skim the related reference pages. icon="book" href="/ecosystem/ton-connect/walletkit"> + + For more, see the TON Connect articles from Google Docs. @@ -170,9 +185,6 @@ If you have questions about integrating TON into your project, need help trouble ## See also -- https://docs.ton.org/v3/guidelines/ton-connect/overview -- https://docs.ton.org/v3/guidelines/ton-connect/creating-manifest -- https://docs.ton.org/guidelines/install-ton-connect -- https://docs.ton.org/v3/guidelines/ton-connect/guidelines/developers#ton-connect-ui -- https://github.com/ton-blockchain/ton-connect -- https://github.com/ton-blockchain/wallets-list +- [Technical specification of the TON Connect protocol (GitHub)](https://github.com/ton-blockchain/ton-connect) +- [Official list of wallets that support TON Connect (GitHub)](https://github.com/ton-blockchain/wallets-list) +- [HTTP bridge for TON Connect](https://github.com/ton-connect/bridge) diff --git a/ecosystem/ton-connect/walletkit.mdx b/ecosystem/ton-connect/walletkit.mdx deleted file mode 100644 index 2d4d5cce..00000000 --- a/ecosystem/ton-connect/walletkit.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "TON Connect for custodial and non-custodial wallets" -sidebarTitle: "Wallets" ---- - -Awaits a partial or full release of the WalletKit diff --git a/ecosystem/ton-connect/walletkit/browser-extension.mdx b/ecosystem/ton-connect/walletkit/browser-extension.mdx new file mode 100644 index 00000000..6aa3a9cf --- /dev/null +++ b/ecosystem/ton-connect/walletkit/browser-extension.mdx @@ -0,0 +1,5 @@ +--- +title: Browser extensions and in-wallet browsers +--- + +Stub. diff --git a/ecosystem/ton-connect/walletkit/index.mdx b/ecosystem/ton-connect/walletkit/index.mdx new file mode 100644 index 00000000..791b937c --- /dev/null +++ b/ecosystem/ton-connect/walletkit/index.mdx @@ -0,0 +1,55 @@ +--- +title: "WalletKit: TON Connect for custodial and non-custodial wallets" +sidebarTitle: "Overview" +--- + +**TON Connect WalletKit** is an open-source SDK that help integrate your custodial or non-custodial wallet with TON in a secure and streamlined fashion. + +It's designed for institutions, non-custodians, and custodians that need full control over key management, signing, and access without compromising UX or compliance. + +## Features + +Awaits a partial or full release of the WalletKit + +## Use cases + +Awaits a partial or full release of the WalletKit + +## Quick start + +First, integrate your wallet with TON Connect WalletKit: + + + +Then, follow relevant usage recipes: + + + +## See also + +Read more about the TON Connect itself: + + + +Skim the reference pages with more in-depth information: + + + + + + diff --git a/ecosystem/ton-connect/walletkit/native-web.mdx b/ecosystem/ton-connect/walletkit/native-web.mdx new file mode 100644 index 00000000..ae88ce0e --- /dev/null +++ b/ecosystem/ton-connect/walletkit/native-web.mdx @@ -0,0 +1,5 @@ +--- +title: Native and web wallets +--- + +Stub. diff --git a/ecosystem/ton-connect/walletkit/qa-guide.mdx b/ecosystem/ton-connect/walletkit/qa-guide.mdx new file mode 100644 index 00000000..6e4497ed --- /dev/null +++ b/ecosystem/ton-connect/walletkit/qa-guide.mdx @@ -0,0 +1,5 @@ +--- +title: Integration QA guide +--- + +Stub. diff --git a/guidebook/get-support.mdx b/get-support.mdx similarity index 100% rename from guidebook/get-support.mdx rename to get-support.mdx diff --git a/guidebook/dapp.mdx b/guidebook/dapp.mdx index 0092c582..0dd390bb 100644 --- a/guidebook/dapp.mdx +++ b/guidebook/dapp.mdx @@ -1,8 +1,440 @@ --- -title: "How to make a decentralized application (dApp) on TON" -sidebarTitle: "Make a dApp" +title: "How to integrate a decentralized application (dApp) with TON" +sidebarTitle: "Integrate a dApp" --- -This guide helps you integrate your dApp with TON or build a fresh one from scratch with the help of TON Connect and auxiliary libraries. +import { Aside } from '/snippets/aside.jsx'; -> Akin to [React](/integrate/dapps/react), but for all kinds of frameworks and environments of apps. +This guide helps you integrate your dApp with TON or build a fresh one from scratch with the help of [TON Connect](/ecosystem/ton-connect) and auxiliary libraries. + +TON Connect is a standard wallet connection protocol used on TON. It consists of many supplementary SDKs and supervises two major use-cases: integrations of dApps with TON and custom wallet integrations. The former are the focus of this guide. + +To proceed with a dApp integration, select your framework or environment: + + + + + + + +## Integration + +### React + + + + To start integrating TON Connect into your dApp, you need to install the `@tonconnect/ui-react` package: + + ```shell + npm i @tonconnect/ui-react + ``` + + That is enough for the most basic usage. However, to allow for more complex examples and further tweaks, install the following packages as well: + + ```shell + npm i @ton-community/assets-sdk @ton/ton @ton/core + ``` + + + [TON Connect manifest](/ecosystem/ton-connect/manifest) is a small JSON file that lets wallets discover information about your dApp. It should be named `tonconnect-manifest.json`, placed at `https://[yourapp.com]/tonconnect-manifest.json` and be accessible with a simple GET request. + + + + Here's an example of such file: + + ```json title="tonconnect-manifest.json" + { + "url": "https://ton-connect.github.io/demo-dapp-with-react-ui/", + "name": "Demo Dapp with React UI", + "iconUrl": "https://ton-connect.github.io/demo-dapp-with-react-ui/apple-touch-icon.png", + "termsOfUseUrl": "https://ton-connect.github.io/demo-dapp-with-react-ui/terms-of-use.txt", + "privacyPolicyUrl": "https://ton-connect.github.io/demo-dapp-with-react-ui/privacy-policy.txt" + } + ``` + + After creating the manifest file, import `TonConnectUIProvider` to the root of your dApp and pass the manifest URL: + + ```tsx + import { TonConnectUIProvider } from '@tonconnect/ui-react'; + + export function App() { + return ( + + { /* Your app */ } + + ); + } + ``` + + See more detailed information here: [TON Connect manifest](/ecosystem/ton-connect/manifest). + + + + Users need a clear way of connecting their wallets to your app, so you must give a clear UI element to do so. Usually, that is a **Connect wallet** button. + + That said, opening your web dApp from the in-wallet browser of some wallets might automatically show up a wallet connection modal window. But even in those cases, it is good to provide a button alternative in case user dismissed the modal window and wants to connect a wallet after doing their research (DYOR). + + Adding `TonConnectButton` is straightforward: + + ```tsx + import { TonConnectButton } from '@tonconnect/ui-react'; + + export const Header = () => { + return ( +
+ My App with React UI + +
+ ); + }; + ``` + + The `TonConnectButton` is a universal UI component for initializing a connection. After the wallet is connected, it transforms into a wallet menu. Prefer to place the **Connect wallet** button in the top right corner of your app. + + You can add the `className` and style props to the button: + + ```jsx + + ``` + + +
+ + + +
+ +#### Manual connection initiation + +You can always initiate the connection manually using the `useTonConnectUI` hook and [openModal](https://github.com/ton-connect/sdk/tree/main/packages/ui#open-connect-modal) method. + +```tsx +import { useTonConnectUI } from '@tonconnect/ui-react'; + +export const Header = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + return ( +
+ My App with React UI + +
+ ); +}; +``` + +To open a modal window for a specific wallet, use the `openSingleWalletModal()` method. It takes the wallet's `app_name` as a parameter and opens the corresponding wallet modal, returning a promise that resolves once the modal window opens successfully. + +To find a correct `app_name` of the target wallet, refer to the [wallets-list.json](https://github.com/ton-blockchain/wallets-list/blob/main/wallets-v2.json) file. + +```tsx + +``` + +#### UI customization + +To customize UI of the modal, use the `tonConnectUI` object provided by the `useTonConnectUI()` hook, and then assign designated values as an object to the `uiOptions` property. + +```tsx +// Somewhere early in the component: +const [tonConnectUI] = useTonConnectUI(); + +// ... + +// Somewhere later in the same component: +tonConnectUI.uiOptions = { + language: 'ru', // sets the target language + uiPreferences: { + theme: THEME.DARK, // dark theme of the modal + } +}; +``` + +UI element will be re-rendered after such assignment. In the object assigned, you should only pass options that you want to change — they will be merged with current UI options. + + + +See all available `uiOptions` in the separate reference: [`TonConnectUiOptions` Interface](https://ton-connect.github.io/sdk/interfaces/_tonconnect_ui.TonConnectUiOptions.html). + +#### Minimal React setup + +Putting all the above together, here's a most minimal React dApp integration example. + +First, start with creating a new project with React and Vite: + +```shell +npm create vite@latest demo-react-dapp -- --template react-ts +``` + +Then, go into the project and add the `@tonconnect/ui-react` dependency: + +```shell +cd demo-react-dapp +npm i @tonconnect/ui-react # this will also install other missing dependencies +``` + +Edit your `App.tsx` to have the following imports present: + +```tsx title="src/App.tsx" +import { + TonConnectUIProvider, + TonConnectButton, + useTonConnectUI, + useTonWallet, + CHAIN, +} from '@tonconnect/ui-react'; +``` + +Finally, in the same `App.tsx` file, replace your `App()` function with the following: + +```tsx title="src/App.tsx" expandable +function App() { + const [tonConnectUI] = useTonConnectUI(); + const wallet = useTonWallet(); + + const sendToncoin = async (amount: string) => { + if (!wallet) return; + + // Once the user has connected, + // you can prepare and send a message from the wallet: + try { + await tonConnectUI.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 300, + network: CHAIN.TESTNET, + messages: [{ address: wallet.account.address, amount }], + }); + } + }; + + return ( + + + + + ); +} +``` + +Now, execute `npm run dev` to launch and preview your app in the browser at `http://localhost:5173`. All changes in code will be reflected live. + +Connect a wallet and try using the **Send 0.1 TON** button. Notice, that the exact sum of Toncoin shown in your wallet **will be different**, because there are certain fees required for such transfer by the blockchain itself. When building apps, make sure to **always take fees into consideration** and show them to the end-user. + + + +### Next.js + +`TonConnectUIProvider` relies on browser APIs and should be rendered only on the client side, i.e., on the frontend. As such, in a Next.js application you should mark the component that wraps the provider with [`"use client"` directive](https://nextjs.org/docs/app/api-reference/directives/use-client). Alternatively, dynamically import the provider to disable server-side rendering. Both approaches ensure that the provider is invoked only in the browser and works correctly there. + +Example for the `app` router: + +```tsx title="app/providers.tsx" +'use client'; + +import { TonConnectUIProvider } from '@tonconnect/ui-react'; + +export function Providers({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} +``` + +For the `pages` router, you can dynamically import the provider: + +```tsx +import dynamic from 'next/dynamic'; + +const TonConnectUIProvider = dynamic( + () => import('@tonconnect/ui-react').then(m => m.TonConnectUIProvider), + { ssr: false } +); + +function MyApp({ Component, pageProps }) { + return ( + + + + ); +} +``` + +### Vanilla JS + +For quick testing, use the following single-file HTML example. + + + +```html title="index.html" expandable + + + + + TON Connect sandbox + + + +
+ + + + +``` + +## Usage + +Once the app is [integrated](#integration), follow one of the following common usage recipes: + + + + + + + + + + + + + + + +## See also + +Read more about the TON Connect: + + + + + +Skim the reference pages with more in-depth information: + + + + + +Discover wallet integration guides or explore complete examples: + + + + + + diff --git a/guidebook/from-ethereum.mdx b/guidebook/from-ethereum.mdx new file mode 100644 index 00000000..c47f2f33 --- /dev/null +++ b/guidebook/from-ethereum.mdx @@ -0,0 +1,118 @@ +--- +title: "Coming from Ethereum" +--- + +import { Aside } from "/snippets/aside.jsx"; + +Learn how to develop and build on TON coming from the Ethereum (EVM) ecosystem. + + + +## Execution model + +### Asynchronous blockchain + +One of the biggest stepping stones to learn TON development is asynchronous execution model. Messages sent by one contract take time to arrive to another, meaning that the resulting transaction, for incoming message processing, will happen after the current transaction terminates. + +So compared to Ethereum, where you can have multiple processed messages and state changes on different contracts in the same atomic transaction, on TON transaction represents state change only for one account and single message processing. That means that a signed, included-in-block unit is called a "transaction" in both chains, however having the differences in execution models, it has different impact. + +Here is a table for comparison: + +| Action description | Ethereum | TON +| :--------------------------------------------------------------------------------------------- | -------------------------------------- | ----------- +| Single message processing with state change on one contract | Message call or "internal transaction" | Transaction +| Number of state changes and messages on different accounts produced from initial contract call | Transaction | Chain of transactions or "trace" + +Let's explore practical example, liquidity withdrawal on DEX. + +On Ethereum it will look like this, single atomic transaction, with multiple contract calls inside it. You can see that this transaction has a single hash and included in one block: + +![eth-burn](/resources/images/from-ethereum/burn-tx-eth.png) + +The same operation on TON will be different, it will consist of more than 10 transaction, triggered by one another. Each arrow on this image represents a distinct finalized transaction, with its own hash, inclusion block and all the other properties: + +![tvm-burn](/resources/images/from-ethereum/burn-tx-ton.png) + +If you want to execute a *really big* transaction on Ethereum (or any other EVM-based blockchain) you will have certain limitations: [EVM call-depth](https://ethereum.org/developers/docs/evm/#evm-instructions) of 1024 nested calls and [block gas limit](https://ethereum.org/developers/docs/blocks/#block-size). With TON asynchronous execution model you can have trace (chain of transactions) of whatever length you want, as long as you have fees to continue it. For example, [trace that resulted from this message](https://tonviewer.com/transaction/e887503f7dac857be80487e3ed0774db962379d1c153e6df7b9b5313c657ab94) consisted of more than 1.5+ million transactions, lasting more than 4000 blocks until its end! + +### On-chain get methods + +Another radical difference between two chains is get methods, a way to retrieve some data from the contracts without paying any fees. In TON you *can't* synchronously retrieve data from another contract - you can't call get method from another contract during the transaction. + +If you wonder how we can make any DeFi protocol or complicated on-chain system work with these limitation, read an article about on-chain [Request-Response pattern](/techniques/carry-value). + +### Account model + +There are two types of accounts in Ethereum: externally owned accounts (EOA in short) and contract accounts. EOA are human-controlled entities, represented each by private-public key pair. They are used to sign transaction and each have their own balance, they are commonly called "wallets" by community. + +In TON, there is no such separation, every valid address represents on-chain account, each with its own state and balance, that could be changed through transactions (read more about accounts [here](/ton/address)). This means that "wallets" in TON are smart-contracts, that operate under the same rules as any other contract on the blockchain. + +TON wallet smart-contract use familiar asymmetric cryptography to control message signing, meaning that user experience stay more or less the same. You can examine [Wallet Standard](/standard/wallets/comparison) implementation code and how it changed through ecosystem development. + +### Limited contract storage + +In Ethereum, you can store as much data as you want in a single contract. Unbounded maps and arrays are considered a normal practice and you will probably see them in most of the contract examples. This is not the case with TON - every smart contract on TON blockchain has a storage size upper limit. That means that you can't implement ERC20-like fungible tokens in the same way as in EVM chain, by using single map inside one contract. + +Instead, you should use [sharding](/techniques/sharding). + +You can read more about TON architecture design choices that have lead to such differences [here](/standard/overview). + +## Ecosystem + +### Tooling + + + +Recommended programming language for smart contract development in TON is [Tolk](/language/tolk). However, there are other established languages in the ecosystem, you can read more about them [here](/language/tact). + +Here is ecosystem overview table. + +| Use case | Popular Ethereum tool | TON counterpart +| :------------------------------------ | ------------------------ | --------------- +| Blockchain interaction | Ethers, Web3.js | [TonWeb](https://www.npmjs.com/package/tonweb) +| Low-level RPC client | Viem | [\@ton/ton](https://www.npmjs.com/package/@ton/ton) +| Wallet connection protocol | Walletconnect, Wagmi | [TonConnect](https://github.com/ton-connect) +| Dev environment framework / scripting | Hardhat, Truffle | [Blueprint](https://github.com/ton-org/blueprint) +| Simulation engine | Revm & Reth | [Sandbox](https://github.com/ton-org/sandbox) +| Local node | Ganache, Anvil | [MyLocalTon](https://github.com/neodix42/MyLocalTon) +| Reusable contracts | \@openzeppelin/contracts | [Asset-sdk](https://github.com/ton-community/assets-sdk) + +Another important library to know about is [\@ton/core](https://www.npmjs.com/package/@ton/core). This library handles low-level blockchain primitives (de-)serialization, you will probably need it together with any RPC-client or contract interaction library. + +### Services + +Most of the web3 developers also have their favorite set of products and services that they use for easier on-chain development. This table showcases some of the use-cases that existing TON services can cover + +| Use case | Ethereum service | TON service | +|-----------------------------------------|------------------|-------------------------------------------------------| +| User-friendly explorer | Etherscan | [Tonviewer](https://tonviewer.com/) | +| Open-source dev explorer | Blockscout | [explorer.toncoin.org](https://explorer.toncoin.org/) | +| Debugger | Remix Debugger | [TxTracer](https://txtracer.ton.org/) | +| IDE | Remix IDE | [Web IDE](https://ide.ton.org/) | +| Asm playground and compilation explorer | Evm.Codes | [TxTracer](https://txtracer.ton.org/) | +| Visual transaction composer | - | [Act](https://act.ghwnd.cc/) | + +If you are looking for commercial RPC and node providers, check our [Providers overview](/ecosystem/rpc/overview) section. + +### Standards + +This section showcases match between some of the Ethereum standards and proposals (ERC and EIP) and their counterpart or similar proposals in TON (TEP). + + + +| Description | Ethereum standard | TON Standard (TEP) | +|-----------------------------------------|-----------------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| Fungible token standard | ERC-20 | [Jettons (TEP-0074)](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md) | +| Non-fungible token standard | ERC-721 | [NFT standard (TEP-0062)](https://github.com/ton-blockchain/TEPs/blob/master/text/0062-nft-standard.md) | +| Token metadata | ERC-4955 (Not exactly, but close match) | [Token Data Standard (TEP-0064)](https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md) | +| NFT royalty standard | EIP-2981 | [NFT Royalty Standard (TEP-0066)](https://github.com/ton-blockchain/TEPs/blob/master/text/0066-nft-royalty-standard.md) | +| DNS-like registry | ENS (EIP-137) | [DNS Standard (TEP-0081)](https://github.com/ton-blockchain/TEPs/blob/master/text/0081-dns-standard.md) | +| Soulbound / account-bound token concept | EIP-4973 | [SBT Standard (TEP-0085)](https://github.com/ton-blockchain/TEPs/blob/master/text/0085-sbt-standard.md) | +| Wallet connection protocol | WalletConnect / EIP-1193 | [TonConnect (TEP-0115)](https://github.com/ton-blockchain/TEPs/blob/master/text/0115-ton-connect.md) | diff --git a/guidebook/start-here.mdx b/guidebook/start-here.mdx deleted file mode 100644 index d1c7b7f4..00000000 --- a/guidebook/start-here.mdx +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: "Start here" ---- - -## How to read documentation - -- Describe structure of documentation - - Basics: must read - - Step by step: guides for specific common cases - - Tooling: stuff developer needs - - Standard contracts: vetted good contracts that already exist - - Foundations: how TON works - - Techniques: how to develop new good contracts -- Link to its Github repo - -## Plan - -- what is on-chain/off-chain -- mainnet/testnet - - https://helloworld.tonstudio.io/01-wallet/ Mainnet or testnet - - https://docs.ton.org/v3/guidelines/quick-start/getting-started#step-2-mainnet-and-testnet -- contracts - - what does an address look like - - https://docs.ton.org/v3/guidelines/quick-start/blockchain-interaction/reading-from-network#accounts-address - - which states there are - - https://docs.ton.org/v3/guidelines/quick-start/getting-started#address-states -- deploy - - hashing a StateInit - - https://helloworld.tonstudio.io/02-contract/ Step 7 - - https://docs.ton.org/v3/guidelines/quick-start/developing-smart-contracts/func-tolk-folder/deploying-to-network#address-and-initial-state -- messages and transactions - - https://docs.ton.org/v3/guidelines/quick-start/blockchain-interaction/reading-from-network#what-is-a-message - - https://docs.ton.org/v3/guidelines/quick-start/blockchain-interaction/reading-from-network#what-is-a-transaction - - internal/external - - https://docs.ton.org/v3/guidelines/quick-start/developing-smart-contracts/func-tolk-folder/processing-messages#internal-messages - - https://docs.ton.org/v3/guidelines/smart-contracts/get-methods#invoking-get-methods-from-other-contracts -- wallet - - how to create - - https://helloworld.tonstudio.io/01-wallet/ Step 1-3 - - https://docs.ton.org/v3/guidelines/quick-start/getting-started#step-1-create-a-new-wallet-using-an-app - - https://docs.ton.org/v3/guidelines/quick-start/getting-started#step-3-creating-a-testnet-wallet - - what happens when it's created - - https://docs.ton.org/v3/guidelines/quick-start/blockchain-interaction/writing-to-network#sending-ton - - mnemonic - - how to get TONs on testnet - - https://helloworld.tonstudio.io/01-wallet/ Step 4 - - https://docs.ton.org/v3/guidelines/quick-start/getting-started#getting-funds - - wallets contract - - https://helloworld.tonstudio.io/01-wallet/ Step 5 - - v5 и subwallet id - - https://docs.ton.org/v3/guidelines/quick-start/developing-smart-contracts/func-tolk-folder/deploying-to-network#magic-storage-member - - wallet app -- nodes and api - - https://docs.ton.org/v3/guidelines/dapps/apis-sdks/api-keys - - https://docs.ton.org/v3/guidelines/dapps/apis-sdks/getblock-ton-api -- explorer - - https://docs.ton.org/v3/guidelines/quick-start/getting-started#step-4-exploring-ton-blockchain - - https://ton.app/explorers - - https://docs.ton.org/v3/guidelines/smart-contracts/get-methods#how-to-work-with-get-methods -- what are jetton, nft, ... - - reference is linked here -- prepare for development - - https://helloworld.tonstudio.io/01-wallet/ Step 6 - - https://helloworld.tonstudio.io/02-contract/ Step 2 - - how to install node, typescript - - https://docs.ton.org/v3/guidelines/quick-start/developing-smart-contracts/setup-environment#step-1-install-nodejs - - how to set up vscode - - https://docs.ton.org/v3/documentation/smart-contracts/tolk/overview#tooling-around-tolk - - what's blueprint - - https://docs.ton.org/v3/guidelines/quick-start/developing-smart-contracts/setup-environment#step-3-set-up-blueprint - - https://docs.ton.org/v3/guidelines/quick-start/developing-smart-contracts/func-tolk-folder/blueprint-sdk-overview - - tolk is included in blueprint \ No newline at end of file diff --git a/guidebook/wallet.mdx b/guidebook/wallet.mdx index 550f8f3e..5f37c414 100644 --- a/guidebook/wallet.mdx +++ b/guidebook/wallet.mdx @@ -1,5 +1,66 @@ --- -title: "Make a wallet app" +title: "How to integrate a wallet with TON" +sidebarTitle: "Integrate a wallet" --- -Stub \ No newline at end of file +import { Aside } from '/snippets/aside.jsx'; + +This guide helps you integrate your custodial or non-custodial wallet with TON or partially build a basic fresh one from scratch with the help of [TON Connect](/ecosystem/ton-connect) and [WalletKit](/ecosystem/ton-connect/walletkit). + +TON Connect is a standard wallet connection protocol used on TON. It consists of many supplementary SDKs and supervises two major use-cases: integrations of dApps with TON and custom wallet integrations. The latter are done via the WalletKit. + +To proceed with a WalletKit integration, select your framework or environment: + + + + + +## Integration + +Stub. + +## Usage + +- Integration QA guide +- Native and web wallets +- Browser extensions and in-wallet browsers + +## See also + +Read more about the TON Connect and WalletKit themselves: + + + + + + +Skim the reference pages with more in-depth information: + + + + + +Discover app integration guides or explore complete examples: + + + + + diff --git a/language/fift.mdx b/language/fift.mdx deleted file mode 100644 index d88b7fb4..00000000 --- a/language/fift.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Fift" ---- - -Stub \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 05445d18..f2f92049 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "ton-docs", "dependencies": { - "mint": "^4.2.112" + "mint": "^4.2.117" }, "engines": { "node": ">=20.0", @@ -1052,16 +1052,16 @@ } }, "node_modules/@mintlify/cli": { - "version": "4.0.716", - "resolved": "https://registry.npmjs.org/@mintlify/cli/-/cli-4.0.716.tgz", - "integrity": "sha512-iUwzpQSmk1IKaqyUPfFYmhwkTmUlocr55Dr6dfZBmXGcMRXn99ZO33RdL+i/pYbNeGbs97HUtoHFgLQJDeVkrA==", - "dependencies": { - "@mintlify/common": "1.0.526", - "@mintlify/link-rot": "3.0.663", - "@mintlify/models": "0.0.227", - "@mintlify/prebuild": "1.0.650", - "@mintlify/previewing": "4.0.699", - "@mintlify/validation": "0.1.465", + "version": "4.0.721", + "resolved": "https://registry.npmjs.org/@mintlify/cli/-/cli-4.0.721.tgz", + "integrity": "sha512-6hb5Ka+AvCMxAYoU/PdxKRa0bDONprab1V3K100JD7EKlxj1/GLqGRY9ZAk1sm1NuWidK8cOpw7W7PmGDFmV2Q==", + "dependencies": { + "@mintlify/common": "1.0.531", + "@mintlify/link-rot": "3.0.668", + "@mintlify/models": "0.0.229", + "@mintlify/prebuild": "1.0.655", + "@mintlify/previewing": "4.0.704", + "@mintlify/validation": "0.1.469", "chalk": "^5.2.0", "detect-port": "^1.5.1", "fs-extra": "^11.2.0", @@ -1082,15 +1082,15 @@ } }, "node_modules/@mintlify/common": { - "version": "1.0.526", - "resolved": "https://registry.npmjs.org/@mintlify/common/-/common-1.0.526.tgz", - "integrity": "sha512-VptyC/im6TDWIrB1BSG4/6L6x/prqJ8B8wbrGUGP5k/3669x0byxBxwIrArBvfhH/qis03pTVxCHHqJGciXTWQ==", + "version": "1.0.531", + "resolved": "https://registry.npmjs.org/@mintlify/common/-/common-1.0.531.tgz", + "integrity": "sha512-G8goOB2b/Pgf9m59vOUspB6bIhAq9nEig9IzcLsnh0yJqjCoHmULoNfM9MPiujxBbdQCSrTttkurzZvqy5hIEQ==", "dependencies": { "@asyncapi/parser": "^3.4.0", "@mintlify/mdx": "^2.0.5", - "@mintlify/models": "0.0.227", + "@mintlify/models": "0.0.229", "@mintlify/openapi-parser": "^0.0.7", - "@mintlify/validation": "0.1.465", + "@mintlify/validation": "0.1.469", "@sindresorhus/slugify": "^2.1.1", "acorn": "^8.11.2", "acorn-jsx": "^5.3.2", @@ -1207,14 +1207,14 @@ } }, "node_modules/@mintlify/link-rot": { - "version": "3.0.663", - "resolved": "https://registry.npmjs.org/@mintlify/link-rot/-/link-rot-3.0.663.tgz", - "integrity": "sha512-YCBxk0aIeUn2ZtohryIhwAEs/4+VxsVpfHrWE4nilpr6PHxW0jxbRJNYazxuxunLESCoqQTvt5EeY/u3Fbztbg==", - "dependencies": { - "@mintlify/common": "1.0.526", - "@mintlify/prebuild": "1.0.650", - "@mintlify/previewing": "4.0.699", - "@mintlify/validation": "0.1.465", + "version": "3.0.668", + "resolved": "https://registry.npmjs.org/@mintlify/link-rot/-/link-rot-3.0.668.tgz", + "integrity": "sha512-49r/nnscqsIL7RjdoYbrMVHLPB9Ztw7KfuOpPiJsp6EdV1gqjBcB/pbCbC4mt31qgj7ZCIEEn6v0WYhYanayKQ==", + "dependencies": { + "@mintlify/common": "1.0.531", + "@mintlify/prebuild": "1.0.655", + "@mintlify/previewing": "4.0.704", + "@mintlify/validation": "0.1.469", "fs-extra": "^11.1.0", "unist-util-visit": "^4.1.1" }, @@ -1267,9 +1267,9 @@ } }, "node_modules/@mintlify/models": { - "version": "0.0.227", - "resolved": "https://registry.npmjs.org/@mintlify/models/-/models-0.0.227.tgz", - "integrity": "sha512-rRoSA8Sikpi+r5hJJ06c5KanVg5flu3/7Tl30Bc4JSb2PXcoHAxwzzxYS1c8qFu6QaqPRBxlav+55m6kQMIiaA==", + "version": "0.0.229", + "resolved": "https://registry.npmjs.org/@mintlify/models/-/models-0.0.229.tgz", + "integrity": "sha512-1P3R6dQFNzjTbmVDCQf/vAGFGOEUdUv6sCaJAmZCNWY2mhwgvDU/Oa2YLiNmVrAqnWDH1Pkz5nq+i7gClrdXgA==", "dependencies": { "axios": "^1.8.3", "openapi-types": "^12.0.0" @@ -1311,14 +1311,14 @@ } }, "node_modules/@mintlify/prebuild": { - "version": "1.0.650", - "resolved": "https://registry.npmjs.org/@mintlify/prebuild/-/prebuild-1.0.650.tgz", - "integrity": "sha512-MUJ+Co2R6djo1THL7BFhAFVLhHF8DwKp/4A947PNF2fYI9Wpf5InzrIAk6a11QdazlTxdoUsJVR1+2cPJacSig==", + "version": "1.0.655", + "resolved": "https://registry.npmjs.org/@mintlify/prebuild/-/prebuild-1.0.655.tgz", + "integrity": "sha512-3A52dck+vkxCdOGMaOxsXBY3tevx7oKOZCOPgBE5NFfoTO/ra36+KdJ1imJLk1UwWU+GkKILReOvr01b7wqt5Q==", "dependencies": { - "@mintlify/common": "1.0.526", + "@mintlify/common": "1.0.531", "@mintlify/openapi-parser": "^0.0.7", - "@mintlify/scraping": "4.0.385", - "@mintlify/validation": "0.1.465", + "@mintlify/scraping": "4.0.390", + "@mintlify/validation": "0.1.469", "chalk": "^5.3.0", "favicons": "^7.2.0", "fs-extra": "^11.1.0", @@ -1374,13 +1374,13 @@ } }, "node_modules/@mintlify/previewing": { - "version": "4.0.699", - "resolved": "https://registry.npmjs.org/@mintlify/previewing/-/previewing-4.0.699.tgz", - "integrity": "sha512-m+oth6bXWoSYgzGKpu0SEZhlqUBKs4G17e7KYvVR0I95oQhoCfiSbWjTlkmLeJoEUtVte2YcnfmuoQ8PqoJeAg==", + "version": "4.0.704", + "resolved": "https://registry.npmjs.org/@mintlify/previewing/-/previewing-4.0.704.tgz", + "integrity": "sha512-gR2e9H1kR0L8e6My7sMQQLVmmR5jU5dKkiCERI+jnd6R1xuEdlHAUlmXa8dEfpWTt1xBfsSK53i2FrYSfhp49w==", "dependencies": { - "@mintlify/common": "1.0.526", - "@mintlify/prebuild": "1.0.650", - "@mintlify/validation": "0.1.465", + "@mintlify/common": "1.0.531", + "@mintlify/prebuild": "1.0.655", + "@mintlify/validation": "0.1.469", "better-opn": "^3.0.2", "chalk": "^5.1.0", "chokidar": "^3.5.3", @@ -1449,11 +1449,11 @@ } }, "node_modules/@mintlify/scraping": { - "version": "4.0.385", - "resolved": "https://registry.npmjs.org/@mintlify/scraping/-/scraping-4.0.385.tgz", - "integrity": "sha512-yQjjk/mhQUCVdvN4IQ/YV32amqQ1iOkZXQfMdv6BN02qh6V3QKBfod8b9ci8Mg3wEDoG/acptOqhvK3L7knBVg==", + "version": "4.0.390", + "resolved": "https://registry.npmjs.org/@mintlify/scraping/-/scraping-4.0.390.tgz", + "integrity": "sha512-KdJodHrEQpUApanM7nFjU4ricbxgKH3h+wj2I3KSbV8mHwnpwpBEcpx5o9IGhyCzaUerLYnxCpZSE2VsTAYmFA==", "dependencies": { - "@mintlify/common": "1.0.526", + "@mintlify/common": "1.0.531", "@mintlify/openapi-parser": "^0.0.7", "fs-extra": "^11.1.1", "hast-util-to-mdast": "^10.1.0", @@ -1479,11 +1479,11 @@ } }, "node_modules/@mintlify/validation": { - "version": "0.1.465", - "resolved": "https://registry.npmjs.org/@mintlify/validation/-/validation-0.1.465.tgz", - "integrity": "sha512-CeS/NHSACR5R9JxNm1cWm6/Vkg5r3e+yk+TVZqMZhVsy5+Pdz7wlQw0Q5dd7RYOOh4cZhWvoMsyBl1edqLwOmg==", + "version": "0.1.469", + "resolved": "https://registry.npmjs.org/@mintlify/validation/-/validation-0.1.469.tgz", + "integrity": "sha512-6u2AcDN+DvRMZexUZ6GneXLuNWbuPIzfMx+YJbefqyK/8au4xGwojjN0pS7Diy+/NxAxS7fXidKwppoZ385SuQ==", "dependencies": { - "@mintlify/models": "0.0.227", + "@mintlify/models": "0.0.229", "arktype": "^2.1.20", "lcm": "^0.0.3", "lodash": "^4.17.21", @@ -2104,11 +2104,11 @@ } }, "node_modules/@types/node": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.4.0.tgz", - "integrity": "sha512-gUuVEAK4/u6F9wRLznPUU4WGUacSEBDPoC2TrBkw3GAnOLHBL45QdfHOXp1kJ4ypBGLxTOB+t7NJLpKoC3gznQ==", + "version": "24.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.1.tgz", + "integrity": "sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q==", "dependencies": { - "undici-types": "~7.11.0" + "undici-types": "~7.12.0" } }, "node_modules/@types/react": { @@ -2498,9 +2498,9 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bare-events": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.1.tgz", - "integrity": "sha512-AuTJkq9XmE6Vk0FJVNq5QxETrSA/vKHarWVBG5l/JbdCL1prJemiyJqUS0jrlXO0MftuPq4m3YVYhoNc5+aE/g==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.7.0.tgz", + "integrity": "sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==", "optional": true }, "node_modules/bare-fs": { @@ -4448,9 +4448,9 @@ } }, "node_modules/fs-extra": { - "version": "11.3.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", - "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -7358,11 +7358,11 @@ } }, "node_modules/mint": { - "version": "4.2.112", - "resolved": "https://registry.npmjs.org/mint/-/mint-4.2.112.tgz", - "integrity": "sha512-6HZRwjFWozsCfWO6aVUXSAWVncsqOhCvRXaEeCxpsdJmDV82N4kFBoFpoiY076TVejo0vuTdg+6EmfG1kyhORA==", + "version": "4.2.117", + "resolved": "https://registry.npmjs.org/mint/-/mint-4.2.117.tgz", + "integrity": "sha512-rpkZYBpRrSXt8nBy+cTXH8vX/YwCx9KdzM5U/35vaqIm4l2kzZeuLKPOT1cLm/Ftv4tSUl2zroMs7Zr9V2GceQ==", "dependencies": { - "@mintlify/cli": "4.0.716" + "@mintlify/cli": "4.0.721" }, "bin": { "mint": "index.js", @@ -7973,19 +7973,25 @@ } }, "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { "camelcase-css": "^2.0.1" }, "engines": { "node": "^12 || ^14 || >= 16" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.4.21" } @@ -9750,9 +9756,9 @@ } }, "node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" @@ -9993,9 +9999,9 @@ } }, "node_modules/undici-types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.11.0.tgz", - "integrity": "sha512-kt1ZriHTi7MU+Z/r9DOdAI3ONdaR3M3csEaRc6ewa4f4dTvX4cQCbJ4NkEn0ohE4hHtq85+PhPSTY+pO/1PwgA==" + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz", + "integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==" }, "node_modules/unified": { "version": "11.0.5", diff --git a/package.json b/package.json index 802f15eb..3e7cc726 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "lint:all": "npm run check:all" }, "dependencies": { - "mint": "^4.2.112" + "mint": "^4.2.117" }, "engines": { "node": ">=20.0", diff --git a/resources/images/from-ethereum/burn-tx-eth.png b/resources/images/from-ethereum/burn-tx-eth.png new file mode 100644 index 0000000000000000000000000000000000000000..352c162d5e7fb17758d5d49e6ff98b6c3c04f768 GIT binary patch literal 499193 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
a`6(B0oGaCDeZu@h~{>F0Y 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
`x-vzmreReYi3*SkC*f}1P1PaiHMOMx8EDb0n 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

m+&Gx*mj#Bkm%?v6=^q7DmOB=cns1I7k7M}W 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

XM z7dzIvc;WRpWg_^mGfqR5?clIu)z*rkK*Z;|2^AzZHEjvhx$iWG{)Cv-qNnaw-3RB( zZa*x*zL@}+cId1+=OmBSrpe8jIZSjf+t^ty)bQURqVMl{3|@a8Do6T9A@o(h!F{Xm zK0!cFsn;r46}+Ni6l%iX;i4csp!ADG1`s>pF=e=h>Wu4DCIvI3ZZurmN}NrdAyq|y zVZIMS-Wh_b+cnaMN>0iu=lh-=MZ#$>I)jV}_ir6;k21=9?5bEnZ}>xSgR~fok{XJy zq@X*O`qW`_7i(_1WI90xU7`^RBv^!QYk1?HBz5opq*4G^b2Ng!ni0j|Y0Wh!Y@ga6 z?c9G|0pgTjtOOC&r8&5xm|yg>!@1L-KYlNG~(sOf3Fb z+457{pZXDGsBM>&5)6<%-O(|MJt$!3$$nIlF~8n6#(X#*mpw%?SGrVg!>_?Q+8`X6 zPNFxm#=JSWEqCkHZZ~Vu5Cm{O@B02;O?bgzNZopSI+vZ*jfly{MiqgV87d+VqX}bu zKho$t5{#^o&jPdi!EdzqD99wEaGl3m>sW>S*XDOw#r#P2g2Y--T&BuskMDBByrbYG zSWQI98EaUATc0*E=M^-Gu^9|M?_Q7&1^3s#tD+{!0bjfFJ^wW?jCr}b}!V5z~8nKClso|qSzCr&59Vvz7{e9t+h3;Eccz?ohw^opnOw~-#F zuXf@+gbRSBO}nmFJFB>dljvPuaBeDPF)N-=)&#QWiBbs&ZE=simS7YeMS*Y^q7zd3 z<4=M8`rK6pZMVFNRkzO^1YQ&JyKSe{5hOlW?~4w=H=VZqp96}AwS(Y}tR_BDIS2`^ z?^=U2=axjD-43r4p4$9M{A}+nTi5}e=H#4N*5~D=i_ZJUv*3Ke}~7 zxq;BgZ0Z>2mGh*s$c7??tjkDD(46O`XgUHdXBkVdTptYL4?uV$_w2j2|xA>_;Hv-E20ohs9cUkzT)E9CB~G603V+BUl~<y!a78Vpix&=`>Dk!~!bPxpv=}k)L zz4sQ1pn@Pp=^g1c^bP?5MIrPSdZdKVTYwNs@;&Zz?j2|E`@Z|Tf8VjkV893@c^>j> zYtA*-T=X*Be!(L`-co>j!+h(t+PkHX*o=-NkFQa2pLN}w+L>+@kI#=*;igM`sM9Zl zEoDG7%SC9ux8?Pl7YrW>^~nwAh$umRW40`?d#K;6?^j$lVqcOuU8^(1JYTjKl=e); zj_NseN#-d=eO%-R<2#*GXxMQko<)A%vcfKZ*8>@Lt`e3XGMI>Nbc_1HyzP*_X=!(y z9NXSW{$0MKT?p%#Gje#@iT~QJqB~{5{&8QqF+jWVVviz+RqVEezSCubA*ZzMwh*jg^umtu7X;BGZ=cMa;VqbO9^H>tk~7AuG~7-+FnX|q%=bZY#=%P zSEuD)L7p4mPiiJztl4Mk*;?-|RoHZ&rW0GHYkhwy|4^guC(i+F z|BLLeb=S@b7JfKj``MT8ENOK9w&d+EtD)#f%7b2@+nIMx#s<|;mGO+$*en0n4ztan z3M{u786jDke%ZtN04EFxt(|v-^h*Pa7kzh6ov0%CNth;z@WNAvYaiUH4f>wr1XjX~ z>b7F#S&H7Fa@B^9J+_1Lc)lB(2JPO7^WR-c2kg(L4@akBIc{&J!N|j<^`2_>Ws1L{ zHRoeE$E!<^4@MPzASGcaR%6=P_w!w^p4+&=0R0`LUt&hUh}*|zSM`l;b+?x5S1EU@ z%ccM+&qCBU+)3Ds?5lU|5Jt}LTu^RA6Swg`8O=bI?4$eg z)U%+DK!Y=?3qkdn*1pq>XGY_>-UV8vnkGv$6@F;g~lQl zYl18CO6)mabqtdE%z9O}zW;z>D&T92oD^}F!5$nzQ$cq97!M2v>;}@@8C5AAufOnX z=>^Q?ax#Wb;{@;{T>VoIfQq0OdglD>X^Mod15%(OeMR9kJVuSx^y^gDA0r(t(NJOe zwC_xGqX>t%inJwauPoVm)srDcm&h8yHD2xy%IOmD>eJ%jfUh;{*N3fL46q zuusxw@q5(0Vk78R)^Adqj$pIpeKVx#YXe76%BK`Z6gEpezPG=fef)}Zz4dO8fsY!X z>5`zSP%Abv>)+xaG5NmZu(rc?J+7NpAhfeyH3|aiVWS zF$4NppcUz19EC+8=)$=l-0!+i4+ZuYeh6qnMcMfDx-NyDHFo?%G)ih%W9t zh+dR#>m$CD8TY(6KzWFRPcn5)E9`C>v;}s=`doWVYL_GVD5XI^T#bYbvm3!{OC9j} z&ROxoZAih+O68>*_b6hK`vhbfvZVkO+wkYyUppGaSQZ+k#Ol#p^VlD{=JHW7QPP(; zqWPC_AnKjE>X^g{fc1o3PT#Vz_sC!_3}pNMkcEJ(0gC^4>HKkTyU}(}#(2n z@=K-Or3r_|H^$N{7L{_r#TTQG6|CeseJctdYSBoU?JTyL#+L43h&{ z6l2pvn&-=cX9U|-op6jU&$QsqW3_B{={DcdA#IIt_(fw3mo*?44RCF>_~8+Y((aTw z3pQ)rddQG+QIPpVsua-1Q`>LCOYsSyHVmm$DN=tgqt;qk+{BX_ z1JjyBX7%atuJ6U^4G!JfRBzta(6ig7(r-6XMjm<*0VaJu?>YXMpw|X$7|Yvfkqm|j zSx*dqSzx7DTL4OH0wp&?ZWwlJXPIcgi--ujn0S!4US@fu_;^;4FV+(}M+y|7=$Hde z-K$1|sU_qONX0&}Ze9()Tq9@IfQCaDqU_I8=Nk8FZGY%r7^oi$@h%HZ5>2~kV4kHp ziaiN*9}l(VtGMAPzuwiH3WCPa#}%iNJ!r6rYlK<_Wt^3ps2*=dlp-XAlS;-Kwco z6@RYlGbzyDb=T$Ajs3Fse@a=9} zH=FMUvEd#U?owo57nrKNpJQKTobCNfLE{iHy|{UAseG1G;j|au+rfEL$;ZINucCh| z5>4Fn^0Wvc{Rz^3u=tJ;JnQhAE7ziDZYMp?vz@)tu>_S0pWw^hUMsJHE(!$=dhXKu zt4(~(-a5>D+~I%Tx{aYaf2z53-e4=Dece^}zJl>GyLR%lk{_zpNGr01-xjD&pAp2V ziX$IJKj{|O&6N4ZQH%Dg6uAC$FGK8EBmOA#P{y0^g$za5F9ojP_>Vo3?VI_rdkG;* z7!SW)!5IFvWcMnACDs==1_EbVE;Fo#o#1@;c8>i(tnF)|2ql9bxJvpz9^y!JafMIz z4L_6uiKbt|r%zdc_yWf`sSQQY_D!nLwzp23=9?t_F_!+zFOqwq4?biey3EbCLw+26 zlgU~j6i^H&mp@@;tNY2|&Ft`}#M!{PxgE(q0z#N-PW3go*HKBN5gej*Q<4n$!)1S;+ zDs7X*tvPV3CzlD_qAoT00+6%Wr-MJ-J!ZS&fGBOd%aW!>{Sg4lihHtiIqHEw5kRd6 zA@P&!lf|Dok1-6UeD7xj?<(M11a1Q-$ zoD+gomBVxoX1YsvR1Nu`zD!XP7$-(ixH|a7R>$pftUa@;D&m<!RC<8I^+wH<0QOvR?Pawe_}=DDZ&lvR(O}kg%TimP^-T_|NZYX!wFRC=43y zigd*Qm*(WWyJB~rgvJ~PB6)b)&yH4_7zG+N}J=Me#i4cI;5Yp6Jm938YF=6?wMSA0hWs3?Vq%)Pkgd> zM155e5iI@YnF9LFaGOg7?i*-xSUZHKUC-_hPx+ae&|b(!Gk30E*$p>#%MkKGfag5IqxH}t9| zfkG}rFB+O)7MTS|W9hi{NM3U^E0OM-pDLW&OYSXhXCF;#3MLN%y4&&mLoHYFoS~Di zhS>$yM)|ZCEhHu$bc;SSF4eIWI60_zogyA#_3Ml2ZwRF^Zg?^1t&*mTIfJYm;d_l| z>+csoh27yGC3#t6MgW%o5e9eM+nELLEx%}aAgXhXEbndBqI@D{F6OTC%i$~`a~oUH zwu~zYp9gWBs7T4o(ajEM2 zA#lpUxvDA>wl+IFDZ?N#TS>Y$-y3pfcjA7sG>>SRPoF})b@-~A7!H*^{MaoZakOAb zwXnl^YIf`hbs#EgWA=M(vnueYFx*G69g{9Vr-3pixL3}{Lw?w)nS2e9qzhqv zhcilhGoSeGOHH85OwN4!&$Ow{dC$Mc+@K)2-0Q5$ASjg^#ve2B8Z^!`uxr1Q87k^A zRl9U<$AT+fyxHx*3mouG=gn;i;mut;R_O-&XX3&yan4dkCn31)dBtK8Q#ZIXp45+7 zB=w{ZWs1VKRiO@XZB?(T#?=}SLPINdL`}sxAtGikM_LxXyx#g{cD%`++O}R|NVh%U zI==Ko#MDe0PgS2o+4I!tG$L>B(rgEbVoD(+&a$kWvfYKKZQga#24m-XZD-yJou{MI zHSMPJ@}az$k56_M?hh5a=17L}X5^W%cZ*LHKA_=DOkpba`BK?Sn;d+T_iW1*dpW$3 zr@+rNTx7}sG-wtI50zp;)8dkBiOS_dEBAU)IyGg6A||t$BmLy2gQm^XBH_n1#`#4% zD=RAlTG@uTG+~9;9a=%!4?*+Y_bd$~7$?4W=n0PV4Rzb4Z#yrPwHUnO9(_`U#mK_K zvK{3!)mIcLR^LzYSPf@C8h!50UmW&SH0Z%wxm6M!=W(S?4D3ewrtY4J#EV;x?@f}% z@w40#w=m}TKW5l}PdGV#f;z%4nj$aBgjXkz#I1c-{L3ltr=&Iy1x}TP@*2jzmEqd< z4N%Y5_;5f~9^+t3_hd|N;97pv_^4FE)M!?KkL(XW+_aYPTVdy3C!nWP(Sfn}(J#g? z9y957Y$QN(4~w&C-dPJYaHG(sH9Ap-bv)`Rezix0ICoV{Cb9> z>Gxz(DfYfrBLfBB8?G@*Rp8o0dtPRd=sNXwQUy_l)M~yj#Mm!Hf2nooFPn_an}l8{ zjU6KP{08A=20a%QBaU$Lch|M_t6n7;c}IHPzo+39k4DLKBI+9(OcSW8yNv1$mGcw@!!qj zzqtDE&?}+5RMZ=U|NK^eKajxl_Mg3#OQDTA3jK@s`@5m?W0Cs`yZXHK|8Eff=WVo8 zvjCQz4}$*sBl_!$Gm%iQA71&w`|sxB|GdVZ=kZ-5@$%1o$^3sixWMz?5(5)XO0IzH z-%k2}zR-V$=L+F}hUY)4=Rd3G&nEbv&5h+hXV3qGXAevNC$;s5O>!w}jH|Imu6Kft zYoWLkx4Je!?_QO%Fh=`d!O0J;ug^=LaNO5b6x60-LLVn_GFqN|N%L7xJ3R!_ul0N9p2{Q>n(@ zwMfX!^E?aA)C?d9CHrqnTrj>n%!xs#}G5g@$t-TBVxcbHUpoehL$8Z$7zB zDmdJOhZH#fNKp^C^|daR9>lA5gi$b>Ii0=M%AML%l|<+JdA8WtX=uk3-{f?$V%f># zVZ$}y4Cro6oQD{u+n`)sAUdb-GiY;TCG#EJiNd z-)QEVIG+2u?3IZt(X2A zzo_SwahfcVy%As^$0{WU6d#eDW=9C;|Qbf)5J(ZxM$qF@YrWcoNT))z#=e!7*4`Ia5j z6c_c)%inlRMp zOgQe;r_wp9pAb@AkXxUgMSMT0KMzz~s0e^82Y+Eqft8NE`c+V6f(?7h+wiQ4^8)#w zW<0IWbir-6*a-3de3kaL_JNDiEv+M#>*~n0;{GT;rj&O^daJX&A@V=2JIAnCS;8$Y zvy^9`GY#A$uZ#1+uORcR}ntWg_=D9wcc|+0EkV#I62o5Pt9b|8uG`nib=H# za&U00dTwYHD)-wjsDB9#3V78}rfW4DJ#)D7-P8&;<&52sfr}EQmD%BT zK+dvncA2LA|gE)1|tacNerF;>V zQX$1OjG+&~#dovNl%Iq~mu{lV@{r_jk+$cf%v4Pg?h`?LjN2f#YJVa2xvqkTL_@!R zeP)M9GH>Q@tY|28~Vy+eITm>I(K}#^`V&gi_haM zJN*SWXS0F!i}@A70~7*@i^wKFE1ch|*GBd%o$-qnOCJoV94?iNPC0$kr|=xi!G417 z7R~Jnb-L{ky#_FI&COqqADgxZ<`ur#TURFQL!F3I>f@(EV^r84`se7BgyezD%NIA` zkzcMSF@9nvI*KYaR5vunMccjo?qGlJlTOnSEu8Xw%8uKb6JD=J)2C07#pcyHPwu&K zG+IB9_zqjfxypQJob~KM14aAqXXr88;dG7+Q5SNq>q5_wB%by!DuT9f@wXJIt1T`? zZ9Z%6c>_y2(K<(prEd-%-rjL~w|Ldiw8cPwMi9Ma49g z`NoiDuD+jv;%}yl9E;NLBKpcN;JsD@kBcW87Q>iUyVV#6OlrJRRVAB7NLF>SK*4L#vp3zYc7EV%KTIa4 zml<;{P3GgHH`))R-8}1IY;+XC(0+4c&2QfL5|GrDw z1uUo5eSFPqVK%9yf9BL9d(89hl1H~R9fv?n||!61;DewXx0o5m$Kq(ZB^7{ zdr>dYD%t!I<`YB>Z6G?~5nX(A$ecMZ#RvNrc~>)%TZSGNIehc}_mX z8pAp4n^hymVXkwc81QJ022Yvs3vu^#aO3$%C6*?=-{fig zn`WQD5dt11Y z^<09LvqLN2GwIJRu(_%yS~JU<-8md6?KOa2rYTytI}RSxZO#fKwMVPj{%#6=v?74e z9Rm#MD?oz|BF7B}fVjxa)^K1K8j7S34u-;3i$^)gWiHpxY$_?J*?Qn4Zb|-NNWI?T z4IIqYV^pTEj0>aWePej^)jBSYuC|~%lvd~V6yi3Qx4%1%KW1uC7Y2XUFMm@LHh;3W zg*?h$u>Q>kPtCW*?yc01peGQKLkq(s;>)_P@;?(m)=AxbN%t4+h#+B3CX`JjDF1!4 zT03Pp{wJR90=^Y!Qh4+7oCM>~LuKD^bmV34W1-)2u^G~*5GP~F!+WbrBHH}xd10in zEm?gGuViAph3gdNDEsilaTrPJ={!@bx;9|+9o&QFw?K{_ z!|SvIv^nI%&@eWDW{~T+ru=eJG-#X0``&ZOfkKs-VQ7-6EEnC#Sdjw1Udh~SrVp+- zaA&R3d^wrU{1%=+#U;cJb-hk`^t$C~Z{Few8*gG^{%!&?pSht5QSRw7f*|Q+Wa`(9 zaGl?uds)>=c^)i0QOH{5W@mF;zInW(4LbN?>65BLTlDyGUs=uY%+^Y}cXIq_2dU3V zRL||22D-W2UqOzvuV!(eH9E#_9R#>5y^b`cLtj6}zn9W;Lk65Y?6zYFQ8k523H=SD zB3E!@U1(l>oPCYdlgM+r!LiAJQH9Iu!`VSdHbaH1V~bw+A(f}S_Y(@04Y$w;N^G{| zR`uJ5;Y2v4o+0XFnJP-}*j5+R(83f)YSq~QwkdMO*t`;GgPoQy6NK-1?s=-@NW5?o zlali#oFXtp)&)X#vT0qk{K1x~k7li3P%-tDahsaWy&vzAA#aknnhSHK8DDYBsz#&+ zVzEEbbsTedGzmDp`~xk$KE7bQtC^uUHpW~Pra!cFUs}ewu1)kYhJ1Qw!n89*;zq-u zH@&D!{BCg@SMas@(p0|JFH5XVmt<8u9!KmX{q$eXgTp@pkzk0&bG)TK|}N*#Vj z6Ts`JfjyXnU86>xzAoT%L-1bNyslu~n6?$Z^@mo?(yKL_$=NK{bFmA{9g7b3Ows9V zI7@#nqvH-%?sl4e1R;-T%H+0`hJ~YuP%&IJP`_44s6eq8U7!q9SoSD5jDLmg7HV71 zWx7g3oRX}`U$uZY?&Q;ry?HgG%dddnpbko+JLgQO#GP38DXWWAl~?0$8uF$|peB#;%#L7Ee`htM*NImhGANyG zta3^}YjHG?AJ8e8Q$CvKoPgbL)s3lNURW#5_sp`aUeTAXY0?oL=zm--WeFOWbRClsBQZ$vSByml8w_H!GOJ2(7Z$U z4h0+aw9%);O%=D$r*$0yW!V%0va&*2C$L_GOl|8L&0imfQO(~hsSsQWm8}!r$#fp1 zA_dDFP>=9c&z)7V{ByieNYrJ!@64fYu+eIE(1k3f^{z?Cc-A4hDr6Q`KkRNAov6o? zkpXjPdyQa{)w8FBfM3!`mmJ1pme-t4v^lmrkwR2W*?NEw8!A6zXt#4P(;n2BIMQ8Ciq)Rx6s~z}$!Y>V ziHp-!bvJ_@HL5BvpjM?9I25^%zk~A%ezw6=DKcsZdz|H{6EXI@iZXP%N?l!i@bovL z-v5*MwdIM8x(nYyk*f2o*<&j-nL>|Jz+x+6cVRaotrdh)+Znus{rEn8nHa^%_9use z^3IVX;NzL`+kJ~0Yd5&f!A#E;xitmL(Y9Hwt(FvFCj?m{o0SFEF9`mi0W`x;_0-k* z!f!=6!Q1kYkq5fVBV|@suY)#}`HhHkE?|2euq>*6uq)JxC;ql!6MxJh`h`2vx|d(K zH>LlAC}ieb=no0L%0_Ke7YXgl-Pt0%&g}ILs`$2>)Jq&Q>dmJ7g5La7CjQF^c84r@ zA|>C&Jw{U5X~$*_mrA8xzAiF6S5I4CPZ8&y`xLf!G0&XamWw`z zh+YF_UXJ%!zV2vQz06=B-pab*_ImAGzZd@l4F2!M#X^29;AH<2RH0Ybis^d1dbB8Q z^)2nEXloachqa7oNnGlP$RR1s9rpEJWiP+Pp@j8QRZ<*BUPl-h^P_1;Z4YN%I+5YV zp_Lx7wqu5+n=g$zWuV(200eq`Xz?lxZ<^xHvW$B@*F^?IEd&I#!b5k68>T?{e|--@1RF?r?W~l=-?h@dODg~* zV2IolNb{6auJ>eyR;DRNLi470`NI??ddnvzytnu|al(4S>(&kRN92;<3+%^G*#XlR zzujX+z+K-64ySu8f={LPe~k;;Y-6T&*UF20Wtov=bqhY2p0yM$#CS}EX78Kop(5Ra z%8sR}x2#+gc0m#zshRVv#af>la)Oua#xkcq+u`o8f9|c9UGENaKjf0nq zPg691B8@BFgP_VPEW#&B8@nHEs)ufh@*T1T-cS?lv-zC&!M&Kmc$SGiZb~e%F8uS`17S;*+~*7 zNRLz0&X!WduxLV z0{`*MkgpH}GRXe%#=1Z(gizg~hK^B_YkJ)z6k}np2_)lmulVM&lzA<MZTL5qd*$Izd>7C7>@_+o@ypNB;0|VLk0El&IsLZk(wH*xj*AC%9_iV3 z#R;Be8AOsB%#U#oY)@ntj3KPwFo+;FGYg4n9JkVy(B+3;m)`mK2HrgkYaGsD$-rHF zUu16$<1>!G`E@L&!CXc0gV05c-Z@WNt+Nd(U{GD?9bxui1Si1C@K7_QWr;IH& z1awldpVTn>O7-ZDRLY$7T1N)?A_>M>I&5alXB~;!QDuA|#+N zsqMl@Cwgz#`aTEo_T-I)Dr!h?A&+}^MlW?JTzMl(9G}k!k{K%bZ0%~ua$BN(IjSnV zR>6+W(9wTVWsU!X#I-`opUuugzN~Rj>)v~#xpI)Au4eYD%>1?uTFI1<)b=1q!)$`S zh$p3G%RyWm2vv$H8x{BU_u!V0|C`xLJKYgf{Q3+_<-c1fCM9_aRQmE2Dr0f1XF*i5 zX|@Q65mpiS8Qopb#p5hNn0Qxp6g6KCuSmd>1#J;}mvwQLzg4lZDYEnCbZ&5j3oBkY zSl)d<`gW#QHRI}z3-8v9tJ#S65X}$@;dl!!u1|A%bR3)aB%qo~=HmIuwrW4R8Q+RD z!8$L$0k^?;neGXX6tdRv7&X1h4?iB{_R*CcT5ewD$&axhSNzpw#TrphmEGw!1+e1R#@*h}PJ+^W)}&T5Fi7eu@|c zv{z(L)-p)mX|6+o9e)-vU{w99;(@huaZ+=3Q1=ro(oPKFm&H|3zAsbr*#JE9`T@5#QF&dwwHt+oWucAf=qu#*)i+b;X})jiV9aak7>(UiGqz@4mN1VNBJ?lD1>Jyq}jP{ z#blG#t;7p0#Mkbk_o9x{#}K0(E!+h5d*H|jXcsg94)f8?&BtX<6=bZffiz&5@tfCb zXqmEqd0o@;($o<*ydLP~P)xbKo?UoXWi^c8M+BK12Bq$7+9Ow7)WV z|4QF|hf(Q74|yiUrjbI(5Pymul9SV%cZ&g{ks?x6b(I+O>GNh_U2uD zolY`0$Yq!~V}w*gYugF&=)@7`^zjc)tHrG2rO(Ux5irEWth4Ap(fv!1Un%r_^G zFE9O-mCOE6Q3GP(cA2<2sz12D4+tS2X@^{z+#SNH3J-YItD=dAP*YeA8;|;*r1gkb z&gyPF*@A=mB;OjkT@}%H^?s@9PeP35T*)vMHhP&Y;g6Z2>JF0?ON$>{9`MM0s3dHc zHhcvut0=5eqW@ldHljT#(^D#azPu$E`2A;#8n%^He;NjG*<2uX$#Grzt)=t5MEXkT z*u0{GZu-3}A=g}J9R9uDegJry1ngd(Jcx{N&zZfk$eSfOz2&t$fP?N}b<1yCe`7&l zFEH;k^DL*bJ$*tv=`ZCb<3FUEK@XBM-Qe@~3D3(z?2RrkTHuzJZ>Q>k$fy3lv*#)d zgg(qSpbTn5@C4vAN_GF^q?A;&Vd)mG%{9r^#Bb1KPc}ESsl2l7M~HjqF#MHU$j#TX zVM{V8Rd0}G+(na9!qImtKoX~lSj$7Pll?@)T<89Yw7kxT!q=!jG7vbv?AFk)Q0NrT z(1j|cSQnj@xrsN8Zd63;z#l+J62D~LUgQL^qC7!j`w}A!t_!B|?INeBoUMYW{nuFl zQ9O`YZFBkxaJ|}2aKK) z=+Aq@+C!TbYszu>{Jn)}g>%p2R$Jt2`_JB=#OI4Cp(Q!;p^f8=zTBrAaNOGAhlD}^ zy|1-;h|m+yuf4h3JLO`t*WtWKbyDwX@w5BYE%AE?nmd#T#mJH4sQV7fiP*`i@8N!dxXq=(ZB*}(|fmd%f7c! z<`X#{&iU*tKAfaP-N}@1l{DiWZ9w>9%=Ad2w%CiHijGpgq4-FG*xQ9r>EO1z$uyY1-eEIhqC-xKcu6=?`zM*t6u!anYINA1< zjA=EfGIP-9piu=Bozb6=@CDRu-v(A@i)@42g-6}$(fUQuk-X{gEpCn;c|m~ zAA>oNgU(QG_5t&2wd4jzv3n1FbsIhvuKUmto;xo;6`Cl_H#UHnWMy_zP5C=cD=`LW z<|J*En8nbGP%~!193-R)^bXGsw_G7FSWV0IVp5npuoJsRVjU~l_|<;S_uJp!B_*wJ z&Op~++N7n4E2zwpDZH*QsGFkndhr6uh`BFx0>1CJYvADk&kUI^pLwsu)DH7w$2)w? zuP!SgSyijOlO)8&j#{edN0R#@F^AnP5^&r6PRf9^v)lsY<?>T&g29^ZQZh@#wgdmbGdN9?vEN}RKC;zmk`r-Nm{H6JNR_Nrr{YYXPT`c!W-ljr zPk6=QX&iIiNarUt--B|;ooP|$~`r-{W0aw7X#B-JJ{#Eae z_kkQ#tyykWo)Wq!W=Gk#>%?3f$aH@Wc8iPosv8#8pk+P3CCH%gt8jP0X78?UWuElT zkN0)1d}mzSGQuSA_4!QBqyQ(#M{l#0v2K|dATLzO`n$Q z%y`ISCi#;m33a>6x9=&Bihs{*P#>d16mG`ewaB50IKB@DPatU}46%v%CQUx=3 z`2ux}PdmmQf-usYkU8&^I${%EM)jS?3jsMRWxop3-p;u)m9#L*i9`_KQvvIG*D>l`2|e?$pDSv>+YHdk6Zp>Nkz|`S=Zw8xQBVx2-~<`E zb9L&rW=^(vmAtTh%FSSmI|IM^H9m2)4fS2*mTvV;3P0XTpG=KCx~f7|?KX-ah^y;) z!g{X)dePe^xcRPWXC$@gt%y{yY&zl8!CM44q~PLWE2pcKq{aC5fZn)OMJzHye>|}! zxQmEXn&-_b*;C|X9DGa6b#ZgE7Ti>MxNw?d3=13dvO`QYaJobIzO5N9i3y#yW>^nR zyi)vJRnfBMv(j;~KR%qt_UIo7o+VUR=?!Z?Up;buF@!|U_6Zx0eH*k?sM&%~Dm>E6 zJj!ytR>Kz()c?bR;#Hc^#BzyLT&MpmtyZhWq*N2EA@nA{hn^bRw2C0LU=sbPa$_k3 zFs}^|GEN4lVSG{cK-_siv_avPo#Z$xeU<{RgKV8GvUAqjw>nG@=JlS{JMDTr=aj1@Bzd;j>@(vL}kltdkKGnI- z5f)scnX*k06Uiv)BW^pm5y2Fs*c*KQ&JhdXo5CCc&T;01&YE|Y?}lWJOahOc!EKPa zMp$f?_$A~`i(zH+8ap^kB)28<{cOW(9@&rxt-X0lM=>U`uk*siIetsm^MY7l$`~s4*K}e3b8CFeG~`HipMmhny>Ij}w$$UY&k7xleukq6Z*u`ciU& z&0H$eqBS2bCR2jW*KBniIyv;gttEvq3{$h_xvy`$^aMPm$B;& z!hU%QyTP>MZAGUb%49!oepMv$Z1a;kQiAw$WY6x}7nyq}>D!BS@KcMHmp;4X#*-}5 z?w0+G3mPC~^ksd8g{H$9a?|NdG7}-EkG6@)YU^)3rU#+BY$kpqnh=kfDMQBRpLgoW z;Mb+aw=Q7scDg-)aLE6GfzS55Sua*bfu50v%G*zI3QZchdbJ}O4DxG3Ez`ioKGv|q4SVx)0j_bC} zhR0-B0lZ$G0fF<-+oYkmd)QKJ{&?=JQIAYDP;L*JyKO{7;bs5EVeFKzKo3IalOkj@ zm}ImYIFik`9hn7C2vgr>oPJX73^-Vwgi+s4V*FrD$<9n#QwW{}%8{Qdy=l7`BO9Pe z;?zsTEC#$<8#G;A{M_<@jas*0s3+Q8W7KfmC2{nGbI~K_t_YWJlw@X0Ioh_(0nT6x9E{JQ z^mRF-M50Bkv(q5zxD11u+Y5vd9$t*ctv1ka-IQZ_Mx=#ts;O!Z%t}^F z|9+2Y%JtWqg|8MpJ|{lJqAd~R6Hy9=L7ZjAY@QhokB?K16FdoLPSn1Lnm-kl!0?`z z4d&hz-;cmpocHc#Zc>JK z1H5nt!B*O~5bEY=Exz(pk4S34b}nDVJq|Es02K728eGavgZ}P)GTL1UdFI7|$crwtHlK^ixlt`&K;r zCx}5U_q+MV#H$jX1+^U~=8&%LAGIEnbYPjP8$6%$9%^j7)WOI-7=u zJElbGNXKor&MH6|x;y=buFy?!d){36%Ydl|qg!p;W%N7P6#)U?#b+BnQN!(R0+1e+ zwMoEjanr*jV|cWtBA7W~+hD`nP)u@us@Ru`L%S%tAsznU2~gef*`@!B&c@iLaiv^} z=2H37h9XtEmTu#fjtmyx#VyLs^@wuHpQ#8coaKSR5nR>-#wc#NwYmRM4Ds~2OZ$=o z_`+DVcvGCYk2Xc`XiO_^R`}OZHlp3y03h1utI4uy5 zF7iGcw;ifsM_&e@g5vI(+GG_dCuI_6L%}{UOo!9QD}-Ozs%?L8mm=`&LhHFSu0Vn| z>0O5Y>a#zY8K@Itb{@ZJHa;<`)oD7!yjotrYfpJ2B`MotPkZDx4Sn__n$5GYx;a#A ziq}J{q8@nClO*&{Q40I*H^MU{9TN$sdJ8++vvp3bkAV0b1x+pSKlHaCk{QUo8$!SF zqAB|*m)Ef)K863lOD(5oI{7x){&=mg+vu<}RDJa|o#C9IWwig$(ncO|vf1Y$Zpg$Wq zen~sG*4mBFUKg}|TONIr8%<^PM_n3Bx!xFRc-Sanaosp32}qQ4Y$6e5jTHkWd9Hy*H-4afZ0z_3QW#ua-yLKx3B94ozazuxK2%& zWX3P!Lbm<@Vwn^;MaRXN(S4a^ORy2@IV4?Vn?HpYVZ|V;L64px8Kq8~1Xlijyko`8 z%E=iJy62@)ms3Dps-rKgynbo+2#X0UL*W%5;FD5}b00+6uElo&t%nl=drW+M-(wH! zWasWw%Hb^HKY-PK9NHNcs&F|Q3}UZ0BpXx><=)LYf3wwdc|2ct-p0H1LqBk3*^uk( zc*DTVyz&rfY5mRMa+{gL-9YtcTF^=s2HDugRC_nA3P?A5528fSTYK8usumXgt+yIa zNG+eevw)ifwP5q%#yWFxvX|Qu4Zy$10+N+}pH@4W16R|Bhogf> zO@og+qaR4_M$t@lupOoyH8!GvWO-E8+wjUvg$ofWv|gP@0y@gk8~Tgp+cZ7PeD&5I zB3eU9O_u@UGvTq1zGe4Ph$3ck+berQ0{H;N8tZS!br*QpacQZGD4jfh1~!O^MWz27 z<&W~5JM=bWKp$i=CPtRC-jJ@WrcG1evAF}`y#1;i)i=}`h|r`Uo;Sbd7pNPzoxt}! zvKx@jSr=~4nwe%%>X+oQ9;fKvdSp&!eNI-M)R`tiwbjr&&fZm}~m#x4D z1KYN4!(kul|Av{^zt#~f%id^_%+Q-J8+CsRwL8DKaZ)d`#84!F5&yU@A`#(Ke^O`C z1f;>zg~Re71s)hu->@ybyKF(nO6%EH?*46)b>@H5G}BK0VAVc-;3B|=+k9$5AV>u^=Nz%a=DW! zQY?!@w2gIu=)qXPx|24NKP6jZtRtw_XCdHxUO9!A2N8#TWF_+~LaCm#e?2zc@g8P} z%7+=7HL__l+`bu`UwsObZvoA`ev{Q;4ozsp?zfk1|YC;c_uhji7uj!U@8P zL9W*?HGLWT9UYQUUN51$jlbMlKu}<3_UxJr@G$&9uJCcN z9Z6N+S7NJ;pO^^pX@(sDNmW(%7zfB0DE@Lm*YgcMedK-qSaj60Ffd?Yd z%8pZR(P!Y!xziw@CZ`!0yi$JLr@%99Qd5owDeE#cuyqXQyKd3MF<3!QqBxHUn$7e+t@Dk~yKg_tU7lzB^mU!VtsqiL@AmQsl^ErvxY zoF8LKeM(d6eXX3`6Q!ENO%{_& zD?&7nD-iYJP?GKlzHuR7-Fq{u9|*fwE6WaOt`pOk(eCmfnqqtHPtKR`?;}979n_xBrR9(3?Wx}x9E>;j$`T4f=lDsQL5baW zAC{9An29cbO&E1vhNPG1s+R}4xWR^QfPRv-W?Z;96$6w5oU@P~P-cx^qFS9#6 zPY{(KW8ZMtxx8Z6FLw>MOFC1TRD;W8Y*XnPmbun??{!c)_slAzrHfXJA4zspp~Wnm z1|^!AVFZa&bUHHk~mSo9ABV-#1FibkuP4HJdcNW1(Hv?7F$xODJJ=9e0 zzmqz=W?^kbd!%^fj-PS!3rM3!M{y@bfi(1b#X?Sfcc-lXs9~4uVJkDk^!+Q}XC=`TMic`3a`KT$hVTxI-vGIM7mg4>!P!Jpv(GR!F!h;q8-&o%0s1v2-{r!y=chhn7~)2(u6sO& zuf4W!;+j*iZp)4na8ehUQ}WX3y6eo5uhBur#nu~f>n;v?(t5T6BG5d_V(8)8weq#3 zGfya@@}xZIfhCs3D{i*|8X!uG-sxkAf|fVB=`at!T(7E~@9}aBs4W|ehED&QboPh; zE6%M>V)Z)M*36X;ddq_(ZVzRxAuqDtyXg9+9)@@yAKgLn`UuXz4XJ>Nq9&M3E{zRi zA!eNFviD`bR*{5c>01VLpxKolqZ~b*#z1OXf~yAS-?k9KgL;vYTtXeZ5{b#`$U5dP}u$UjJkka(-C_9V*^ zM)nLIPbjzA!Xz|hmG=&h!+!qsypwxt+bzQk6A^pe9M2(S%o@j5H}t*Eggrp~u$^yb zSsP6F^~5CS;0-?qpMo$`38KQt62o`7gHQd*<9v5<5hPW0C4kmY<9gnD{2bRaY7()7 zBl2=c8zjbo zY~4js8wL=+kyW=afC}K79yFLW$N$Of#PF8++p>vlX^u69FO}30fe$Oz)C#J+_j0my zuNYN34*JRZolG_)xI_q*%n9JHjRKi3CjSHCD)`wB^L@;YsjJZv8Tv&+$@-WC=E^|E z{7A(u<8mxgFA7xsmP+Z&I*HAL`0`9jKdN#%oBL!vE2#GkrHp*tI&aJd<+yj z@C`7~mGM=%yX1IkQPmF`<_4m>=Wwab7p?MWyOH=e>Fenfe7j?;hNEXE{@Z-tuP%-7 z1Vs*G(@xc{5T}67LV{2WPeMhY(zKU784{cL8($|^?zW=jKcBu(?E~Y#V6R6|T2b)R z>GE18TrN!YyH`=w>tVbzFbyLVEy+-%SfgexR*vO|%;hqSp(j}SL-oTphJt$5K#R6_ z;*`P$8r&3yLKl3NmYO8^Qhh)Vorf|q5+#{)y6!-fK3#@a$hNg6l^ka@u!W7&@cu^T zK~`5v9#HQ)<8!vFCG`WucPK}TyOXLlZXsdi%NJF>PZxy;=1BKNKINJ=ANvZ`=u+U(M!ORtM)*?(UACebMQ%f-xqJWKmky z0{pa#lqwzTN#!F!XLj7|XXy7m%R*Xnjg6#f1>=!H3^jZUHaeo$=fBP|Q0w%_;lO5n z)?dUneLgidR=M{F+jur!P8~-YxfWm6ZEWyl)yQ_<_iW0Lc?(W`;#G7fflo#yorW@o zguj2JrC|7W!RnSX^>J`)o;22NqhF1bR`^_}Mkh0__I;8r6i804jhXO<%_d&%1PDk( zRjbdrke3{QvXvgLk{^}pix|InLJ~2${ij54+7c7XDOD4?6w;O?qYJg zEC41$z*`ntA^>A(H_Wt6k$}zhx+a$XxaLGyyb=R;viFyIa4j}cZh2~sI!`@ln^-4} zGurh#-e5i~ON1uf4dQW^`o@Tv-Faf>S1K4%j2C?JOe6$#M`4pUY%1-N!Z(NOt%Y(1 zwY3ygm16)}$0DQ@MYr9q1~{jR$LTX#ML+c7(PH4vZv9;u`FOT)X#93J99L-Eoy9zI zJlkYpey3X|Nx<5l$8~Y%=i3fKcU9cM=Hssj;&O8W}#tI|GQ_vd**FO09>5}=R#sX(%2@)C%qgT#8`(Yt=Uc_A`Uni#HF`kPw@ z-yVK|11W?ro2$qU08F}ue~UJJhj00Th?F|^VTBbwODnJ0znY=4X>R`%h$J(%J^yAka+kf4Q*7`!A(UV@G zcg=qywEvtVgiM*uY`S(sdH|J`9dMeJ3wam2n=NQ3xPsgrBjN1Unx$VEXIIJp4f^`$ zM*zmXoxntO&6Td&l!-L-f6ctxRZ`dH-(43m99yF$`{xz^^Xh;8mHGNouyQ8EV(#^u z+y5Acf5^f3&vQv7t{p-_HRED}VRfAHY12W$BMgOQSnh(GU4wv;Ch->X!x>=svaaoO`!dI*Fuu z?)~qH{+Cmau|mq-eY=C6B1uY5S9kj<34XoV;6J~9OEXj0G9p+llbx@*%S*=emyP>n z({C^l=(jxd(zYNlPHMR-@NDLa5z8+_!e8A|_St_w_C8!;%1G@ube~_X!0*b8<#&K4 zt7Iy-m3DW(9BbL~WPe@ttEc?(J6h8VJ+z>Mf|`nZhN?6RBkiTZIK1WwNugD{E>+6K`@3^8LqycJ(9t zomD8mo%WPL6tU~0udl4FEN%R{vbanEMELBov%`Pfjs^UImrvm4>Lbee%9BTm-_Wj2% z$Eb0gkpKP{{VWB54)1WiOH3(^xJ$r;Gcxxy&h%%fNqn&pFOaY4*JQd}`TrO=dAM-Va8j z;@2mo65K9$UW96!bVM_UY3NnNvQaQI@3$p#J%8q>^djZF*#19#K${|?nAqfXdk{~4 zarbo>;g;^uy-(0qiWR|+KABw}&zHgkH9c3O*NnRV${+i8dvt@6fVuhSV-dywc&!8K zBLsj(o$NQ&rCa|`8N+|h4aO(HH34ltKOg^pxaRNYNd4V!f6uq`MfCSP_2<*$mj`b?m5H1YyYMCG7C~0PAO7_-Ze?Ki=osm>4v`M9 zIGIR&F&sOQ;nR!Q^*h0%0)7)Id<+6~BDdbEh2Hw7ul@TF^B+G^@|UuBR3qwTw*O{m5+~b`WI|(;18&ANSsl`B{ zG9`yT+wKxakSIEsdS#tNtrs%;WZ_aM)we z^3Z~ctrC4i_l$Vsa?uT)=e_x93A@XEmXe^G_Mdr?F(FjU`x{C3guM>5ij)E6z}nYy z&koW=?9Yk2+E4>ywRBOl^u8ln&m&ZEn+ZQQ0ZDmRUk%XBf6%7>V0pj)8HVBJ-A6iX zdU51!G0f;^23Z-6HR@x9(pP}A0tfF->w2!cy?xg8<^H*5-Zz8Vch9!1%iQtD&qS;h zB^7=B*lXQ7`kW-ImwW9beK0x&8c)>{QDBo9Sr0fVUOD{_3?v$>QhOhGa}xkgZdvae z`F%ijRo`Dh>%vO19V~$~tzKcg?52C_vZ{^EHWt+ZM)me+-FXOff>w3v~A3Ry8m2a`M_o&QLtCuM)G4aJ+ z=lx2}Y7?K&;o$Dl5@iNQB9mK_4>>_?@`E}E!g6Qs2Efyc9 zYdCD({MCxr`;|!L^-(l|TStY{be#^bQ}2e#B*5c;^dZoQnZvL$PJw*IIoVgJ+Hw3L zD)F?VEnGBZT3vi|bAW7OpNrM^UOgD?inTPp!?U9c8m=jPtlyv!pX}GWe~} z_|?m3qX$vb8oPMgv4T=Xk>#`R6BAc3SYy3ol92`Bh=^fg;6vhPdS>WuyGSn;h-+J%}N>r1rA zeD$;klhqDA6^(CVtaxpS459UI`qMET4BScVFc^p}JFATWC@mB}8; zKrb!-TkDfqaOqyR->~2804p;~UKL8&J_PkRBlPSW22o72>jkTOv%iSoA*(klD_$0N z<$gMI7dOEytt((R8ZA%nH$lSoC3&{1F&(EhI;6O`!nV_IuCCakgkVevgfz?rHV2U= z_J5~wo>4KQDwy_Nh7UH#vR8*(uG4*Nx&{*?7Ux{Qua`0#G*o8dG(ITH>$SvhU5(R+ zdXjia&Tz-n4?XVYM;fj!dpbV4kYjJLtn-)v9C&K3e}8Y!7$qqTK1S z_GP;tXzk6F8UlK!eDMXU*Yu%sJZHj>`|_#A7bMMXN20qt_apr;9w)sUd)auQgo{-@ zrcoT*VE-9Kxn-19$CsxYIwiJrQ|M!oTk3Ix&!s({krpZ>whlcDf~z$t<+lapAVff5`3(K83?P6J`dNhWN# zhe8puzzm|Rdgm-%CG8~OG4DuwXVSYM-K#^O0oUN~#$qlAlMqU1?%B7dgQ?#Asx~Jc z3ebTiKteJ1Y7VO&bLhx>HFikW_Bk+H(8fO7kjz#aFMpo~w zEPv=810u8~nz=RuH{z=I8QuoCt_@B*8k9Q+G+6L8#J6V+qGevrQuHK!7zD5a{s^!(2(f;>jg;st3it+H0JEV*=}QF!ng|}>d;|w zu_7Z_T_o%|ZjHxtW8DdHzbn2Zw%s{uuu9bqdjr1o!CWpyNz>Y*qb&4m#3a)Xs!asu zf?=Gpp9{53>Pd@rnN3r5bZp{74ueWTtYNPUkjCH_X07CIZ*S9r>8!?LiRwop3mn%sEG@Y zc6?FYs!P~i5fk^7eAb7;JtFi1z`(mhWHH=*y}60c;;$Bm_XTLdNRBm^*UyXBt_gDI zP*{;NNIYOjnT@*qzQXv;;>ZDCf5u5V#4Y7OFfpg;6Sxh*W~lP^Vb5bbDeHsc)iUq# zS6<^1_$!~(ViL91T|E5A6$(JoSBX`>-OtbS&mS8Tb;nX=0Hy3zPUUkP(ANF^Vo-GC zEU`tU;M4F_0}Bh0yKlPC?$}lmyPiGs@%)D_;pjnlknu2RYQ}S(0!+j!aQaQbw6 z_D$dz#Rlk8{N*a=SVzN#Eipd)qPL-?ZAw!5b~AS7O+6{%m>R54WsuAmd^xQGzP%PA zn3|o=s-6}pQf}ROTnRxVbR8zf)t4hA8oO{LWsobXZaE+=);fw#{+jKBl#;QRN$K_K zsMB6E5np=VERHnaK|pyV>6NCT^G>PCWTpD6pJrI2>KXTh`jdcbhpNekh4zzGE#dMw zwc``=q{9|g$BfA*`023pfcU(L1YHjHOQ%ma3pn1ut8GK;-hlmq} zrQR-jsqSGBGImc+acj(}v`opIgXm?tknl%F$-2YAif3rGj5WyZ1kZy|lIKw4dL%AJ2h(>URLzZdDIw`sjhKUR(T-Qc~ zO#M0#hGdCbt9SX_vURtQXYpVQV^3yYk}_kL9+E0QH9r{Kw?@0Cc`rgFEeM^({td_G znn7|OU^_>%0<~%j;#!-(PyF~3T>CK!TMzWh^F8v&a{&buB@N||IT$dp-xGfjTNq=_ z+_*eQBs>wG`1)gDYMCHZG)MJ=3|jP<;Ep~{8>*>unFP`4m@WjadcYtSUl~$QugBGU zxmB|-J&tbMa2nnFeRGfP<%p{A<9xx5^;3FIzoR@FlGV?TUhhK-_H`}ETV zI)3rqjs2S?W_cmQoiEkwtlsNS^rnfiqjG74ajv5LB+($d{>;+yabMd+*%V!|U0rAy zO;3i87kIK|=lNoq>H*)VHgU+OEy5-iUqPlJ31dY?5e}~8LSj?jIflHoaq##7)#znt zuTHM5j+ZDDmUltYPnA8D!}urU`xh*&U7qS5GMt63G(~_re`GcovcEB)ib$5|PzhKe z9$gWp#mPQS?COf`Jsqq{$;O?;`Qa3 zX|d^%&ZV^1g_Jr2R5zwebWmmdG`IP*s%&@FAS)_kMu-1|Cc_`^=68d{qi~l{U{zqpOAR7gCHcJOXK`2%#}hTdgjB9=fOd)skZ`^+pi_cE@a#Ac{wR zsu$(aVs54N2>zygARs$hUveA*5mhqNchc()p%q!$mnvTH31kl0BDck9(q3t>+gmyS z+Ts-{YL;Lyh5%#t(-nT3w7TOw?GrQk24J*D`JM_nPzNgWGCd?o zsKoT^UnZ^71gbPa1U{Ck1?(-lJUeRa)?{oyB#npK^7B*AdXN|To;YplZJzc{duu(e zqZy>)|K>dRESUr{?W?zaNdtzk{i>3-_nF^zxSwvu<;-(H+p|sY<&`cC$?3J{X1 zk0{~zzI4?%F4dMN4m>=S)19U>5|4wb&&Sr+H!KvdC&mGW&X=fWnu!^okKhvOAXO`Ql})5$<54D*sc+E@5!$u1LmAr!r4vnK~JA zR3%8a5yACvx1)_gIB0QQtJx9=t4iA(jjA~(Mfh(ls$8jYX%iG9d0C~VFG#C?ptA*< zsL+oWN9Z`&e5Xl<=y&NcZP*MxZ){`ERUavcb7s@+E-;F<&C@V!Y^7SGc0>9&H*ckU zaY@+B*3y(XJ{;04G4b(2V3zy3TxUGpd?p263N94cEfi)vxqsiWPUo2P&V%YC#$moQ zT(LzOCGXHRA`mkR%V_$eMb}^yV+xj6R5efc`XD9Ex>#?$X+kCSKxknM+6sy>WTMJXLb1?kL%Kh`bv;3w1| z6Hs}sT3k9$_DFtR%HkxZL5~w7)<4r1EsH1uyEA{w!1N3kQ(Hkn2$u-)BP}m)Kr?z_ z!tDM+I*y@Aep3L$nie<;>gbSfDg3!?-?hpI828lP1Qa?BqFow9|0GeoB4t0-3ygLa z62Z8FrH|k1woTSqmK(1Fes-a88`e+0?7&?7UojY7An6(xy4-I3?`hxvVW4Q(5V*ba zp~#Akz?I15QYne}Oqi57dJ^WRa;BqP92CheuiOSvi|$mlw>vxULUX261NwPxJqy6NGNRzFi|<=tM*&Yz4ve*$H`y3FG`oG>z#af#5!Xv!iiBU z`7~7JBM%z;`X<_S^Jv0<_5uyWetY&4l)ZTIyOD1%(EUDA~{yL^-FNrT7 z_e_PZ-j#3YI4qVOM$0Ck!l;)2*&Dq`CBq))VQ5ch%2))uCT={MpD~>~M6o#y?+P?= z?W{VW6YFYEaoVNVUFnMJ*-M|eMP@4M{R)?RWs*&=*Ql^N{QfSHZ3%*g&8l`3q-lrtEBLBP3syF|GAZSfJ8?%GJM~lljC+a4NE39 z^zM^K(|V#wc=zh&&O=Twnhf>BevA{cRvweDwtbx8CvNSB5rzKDWYX*SdQ(Ud@RJ={ z8ks|=I&o)o>*5d8yN>Ya<<)z&D@L$XCr=%ceB+|DCvM->3JdT>I?#A?tYU_G0YPo*yi%kp!1WB zSI3B*Rf<68wM1ZmC+qb2g}Q8lEdl#M8(ctmfiFQNBgdlpa&Ty27{MtBQZ}v5X!}Ok7e$xPcu>A3N z!ai50MU}5TlQ6`AXKm|8qtrZ|Pn>z`lXn0&`pH)Rd|tMW+*=i#&S#iyy=B{~n?$gc6##1@|t(A%{Pi)+}(-xsznuEtt zH^xbl3)!xWa!JQ3XU_9~ErQyA#Lz92l&A@anVopK>$$pC7+Du34}8}H@RUOdF}d(R z2$-cAx6Xn&?qdIH?Y@(uzZ6b;pyNlR{h7J*q|MXe3MnBhF&5>Lo3!<9OvogDUfxHG zSkPun;W8;=P`hK*@&o1PATp(fYd)Z%U{SRpDb2RM+13P8Z_kd^qty8mAKP!NEO3MI zL$cNmCP}PkPLi*Nv~GudjKxv3?5Wy3*f9DU1TJ=mX;{a8?`nQk18+HK=xl%;E`6+IyIM-^{_7s+DbpA0FQ)7`cy> z#P@24P}^N(U(Ct2*h`d`fkcaN9Mw44Dj1)+e!miJlV`G56(LEztmZUUq-uzPJu{Z@ zn6Q3c?>=pmCdAUJXUWMt&7J>&|1tK6bsoK0Bw*YAk`HR}yo$>7ts1q!jw)f17EQSC z?DO%u5vpMJ&h@4JDZt4};lpQ#>$lMdt2UC~cdF~b(;*H9cXzOoXC~>muJWCokTZUr zY0_~Y14{@Hp?^RM>3zSpM?Ytf}k=7nES{9IFyE0+~bLPk)q!f+ZHZpXaQ6UxhYG%w+HsA zqBsY3zn3ql01FrpD8A~tC?972E0*GaefO}5Kutk8Uu+Lq5geuKI_S>Lbl-lV#OY~o zu1>s(&m!T`794D`xRV704`rr$jOYKEv(|#pmQMvrp zv3>ey(EW{(Hr=JcV3(34%=U9~nCry$f;sQOe!_xEFa`%4A3vdC?Kj$I)noWcH)rTz zGo_@CV#QT_-@ZsC=_J4&Ri&esYhBWXw)Q=>xheoSZ6`*o{XEu#kZUHk6Gr0l&4Gv; z*_;d=x7LOo^e2&dyxE8kmDA2`(@D>=^>JnN$p9kuY`2!14FLF!38He>-D?g1BH*uy z{noS>tUdtBC5bkOqA z6R9AfeUsoKsA;3FtAV@#Xu9fy{dk2$o3h)+Sj%*^<1{r`r2jiV`7mg-IG5!8v{@dF ziekxC%9X^14ZG>Gfb+n-Hs}eqgvxRvRDaX6fOF-JTXEmX21rZ>9;9#T1LUiu^NU{K z_r4DJ<8ddxl4<>BUAhhrI5}Sjz*<$kvt&quETMACPjWa?1eJCvp&MY?<`1X7LDR)g2hiIHsgy?FUO|DQ6+Cz$ zsx6~x4h5jWiyJ@ruAgVfnxtQS0y1Q5mkRoI*y#C$KL38>-XtWY>n?cf*7KF7jP5O( zL}veW}%_)lCNy?~$p9jx?2krqD zAEt6G7PZRvz_g6(re<6rJA9Vww${2R99naXAkzAr{w}+**J}vU6UVMM^YIx3w|-AG z1^3Lf(7Jbly*mztLZF&%znl+VRNfd6wcLQ4)5l+x#OR~@E4|b~(|K?-gyPgybZUw} z&0r@*#B>~{s=CO>nwgwpzN*zgFoP1tKz{mA8qr<2q*VO}MV%6McX{*oS-5tVOeW|d zG)0zu!X~%KjYGGq%E3@3-(cg7KEuGHOO+gkCq8-RC3RMbuIn?(qfise{OiMMN8(6P zEegBYS$0*0!n`SGT-wgj$8E>ROr7Xk!|nOKvUtYr#4bwf$B>?3X{<(V05wWi>0vYRB)R7 z>YK*T6IV41cEX6ma;YKaaYcw#&NQiyE*k*EJEdeGt;$?_5r>^ndPZGL?K=d$WmaSZ zN)ba+eR&-|SpoWxbPpE6Z#SS>L6D^Oc}bhH=y`ekl-F6an%;N~XO6+xbMj6NbGqe9 z7MTR^lSDC+G?U#X`SjN%wc~s2MS13FprTx3zxf`)b|KI1oSl*G!ZOQUIYTqmwrnj~ z6Q7=a$Ja6t$HiPa;jgBYzPPYGy0@|>r1ci43;5&CPjh!ErcMu+mpMID3fvCoGty%~ zF_M+dgI;&JVI|$BU%4Ly)_RT*;UxNl-(w~B6213k{HDS0eYqTI+^S{dHvN+*Om_0I6tzy~r(CWcTi!wR-^LA=A7m}10G9;W@I0?3K% zxa* z1`U*jot)@3#>}^c2L}pPh{g#*Jq64=7gWsKF-nzd0`_BFBEDO3dLgH~$X3JwgNV1V zIomToAI?e#AnX}zJYy_0$O$w8D$aRdetRk6w)0U&4{DYFaA+Qk9-9;57F-QcUkI<4 zoBTS~tbX!BEqV1;P7Zth(>ztH<5oP7S)~5{-f3CMg`5#`m)wp$(oLvIEG?cV+gk+d z>G>|OuT0lCMZ_W4<1!Ro&HzOI2lbK3(XZMzjbtE6i~O=_L;0B*c1YN*G?Nm@U9T1; z3d@hzzJi8u{ccW%WpA_WXA*ZSLT3;&i%yMc=6UWLFVh+(iOWvLa>#0e{De=*^(%y3 zYWk+{ekTrze@sD#GtO}=&l&b2iUZCGZL4ciffh2UlaS&!{Cpi6a}36N3q|ukjQ*i} z5+4S0K6|P+hN-x$?M6L>o~%mlFStgkmT?bh1pXj?&?KL68~PQ@xu1#;7tzU!j-caf zj5|?H(vL(T#15Ys^uN>P;B$jg+feYO1s}XG{N}c~A%gRL!zqtD1G2jve2c(7E1A=y6!ZPH;gUPV4-_H+5jpR!JNr4Fy?xPyc zAa3hq$gT>iQJ(bWV@6FnA?|@zwPwe|mipAli~Fmpaq-pJMTRhPDdw?{wABOLl=z(9^`gv4d_4Y}kQpgwM_$aA4s zNacn@Pv@eupuosMiMGfDJpHn^#2swBjci&m2lHY@!`_LcOupezp7{u4vYcx{C!@8<$mz2|_PgdtuR$;3xP!$X>Xyf` zih>J;=7X35@}aE z;Q)7n+I;Q6$2JqMBM+R3OL)ieD!#|GeP`xTyOZR)o3jDfS4)iok$Rja3GUTp9s1)7 zUv8mVQ-QCVvcecEreQzXe!Q$>e8E=~xxE|gf?FA`I`&RoYM@GUlaQ7NOvTC*V!8K# z9Vn1WqOPPNJVq5i{EO-isYg@=Go3_r1(z!^=C#6!?fh1!)c>@ybc!F3MkD8SV*V^ zq6~O=SY}-(F0HyJ_r=t{`pjnfbgi`|DH912@m|UFsj3zE`l>}~u;7i>XWqC$cl!{s zJGLD?M?{0Ht(RtB*&<7aRzWrk{r(@{p?cmMu{X8>iX45N_sOQ6$j*S=AfN1F#Eusm zRu~XWFAC5u((agcFAQ*5?(K5d+D4C+E-1T^)SPjUXE&_2&Qa_({mNdw5$F0y^9ia!xX>z(QX<+_ z`{#UhSE|!e$1zFD)XOYv%?W2vGmfnh+xiA@?nKX_xA5g||6IGzJoNhqVbTPv3sJ@I zA3P_05eBdM0T>WHR3n z1FDUitl#$k`q4_M-!h-#r@WE{ykPZ4cZmJ-u09Uky&~FHJnk|zJ>%snR0i~{8S5;b zgK8AVR^;vBu@QA;LH!InX{3G=Vm1P(Wt*mZ?f@Zs)-!)P4^xW7NOB;$<{^@yoUg3? ze-+6vYi9OY!l!V@?xzIc+OJeraW7sVaP{NcYvzI7T;Jnxg+RBR$%-vtci_4LEt0gNoCrUFabO;yv_+5y;NGlWLvhyL7qv z#_w@~Kl#xQuMq$&I(H}Yj={xEXS2s|^NpUQzLjZ3?3#X#K$+ahM=XdmV1L5fl<5_& z08>H#0>)_^N7ILS2kg=vbk(SPK!pBUy%e-d>9Ns~(LUiuGvxq@fX0m2jdsL>_!h(T zOd=hP>&JWs1_pSYe~|2;!NiL{KF2toHE_Pgw0K2$h?C)g!S(-n<7H>dPmSf|-_QSZ zVA|}FM!8jJh0TcI?3iJ-J=0=mT)EG|#yItKw_$^XbM<7`*N? z(x9((w;$ttPS(@+SdA01Xm0J<6vTWFr;`M@Ra-dUj)@a%lj$&8TBG0@VWY3f)}KX!&3O2oh<6FvBg#_!C5iz_zK*D z?~SY0{y#lUS7Se;C#s^xCQ3O`qFQmv5Qp5{+}gGmR^wG}T6tzj zh*q01pvl!_%=w6T#%pKBPO(;U^P+z=qlOU%;vDrSZQ@aeNv;M*LW$A2-M?5yuc#EA z;?&6cGUH@p!6%MEApGec{u%&)OhKgX&-2?XLF|hQX`AgJ0dw9W9pOoUgXzCT*{_ix z=u`kPsI=WwHD>!U>)ze`Ubp;>forbPV6K*Yp-y>T`J&2lZa zjRGSs;55Mdva;++dh#YB~h;DZWkHBHTI_=f_b=bLF? zQbp!Dsal@d+lMv)jDid5_~ph^tyBCUL_`ftx%E;~435>#H%T?D>{izk1mN{g*KY6Q z*m&=0X6LZig43*?rl~d>a5O&Mw_h#TKV}FkN87<_E$3^}g$H{Zo{co9ve_i;qS8afkI9)6q zsDDnBTEAtDHjmZd-M=tqKE6C|D}9W=7AtFFgjZv$cS~Y4n93 zG^KFw{yidx2|esW?Tf8HTWmzDLC~n&QZd0^`xJ%J z_N}ehuJs6T2dh zxTsh@Ym3(I@v`}#G!gok6uO2I=Ny@Hokv+ExaZls53$k~5Qy@jiZjCb`mJlQEfvNm5#ensfQoQjHhK*B$)R@g%iMXv* zXv1h79*McxaHWa5MLI3@R6phNL+sE0TtGG+2e<-4{hJc*kM#i^HoaLXDh#{dggw9$ zd41y{4e1Aq(0?8C|LyyH43-+@Mv{_mZV4?K6oe+c0k-2gBKyg@M=ukVORAWCQ&Ppi zy(Tqg&6jU!L3HOxv+wlfVY9JcR58ynae;pjWIfWL#Xv%+xH_rHe;6QM<%VcN4RkyX z{c&I1(J#O$U?#u~xXa_6SOJ$M*Z>C4H-O`9ZsFf; z0R9@cYzB&;!^L;!Nfn!ojv18yJaa(TKMpcllXC6@8k1rPG4Qt-o+(Vo_I-_H!iGjm zjMI}w7Df4pP8@?;WNhqh>}@?$ffpto+Zlrm9(>>wP8*7nAo>P%-=mNW1q+MTOXjA1 zM{=aJPhtz5O!WTTjvLa0PJzCYdIPL)Hc~g(Z&AS;?gZ3JwxeZXVvgU9I0=cbGS14s z9Ei@{90jH;3@pQ#Z>?el`-&X||9znyPP?3p9A4PhWkIQ8TE@7_uJ0~G|FSQ^K$?Td7ZVy!;SKmruWX%q&XHF2LzT_i zGc&-C@-2iVO!eW`qGenGn|y=nQ^6f$^!N>i`^~>TPVu~(GRH2Rs8%MrJ}4b))iU6k zDsnSi9fStOav16YoS{e1>r>#wYr_#CG4#{*6VK)2Lt;C$tZ$!?ssM5{pUKN!EwUXs zHeq?4P6_nko@oHj=Jv@{f^c(*-@eQF2_NWv0D)*vt=;8(BeOcygDY~Cz`kx=zvp3k z7ceK9J@r2gllVQ7)1H+&FWMAp7iPx_#nn{=BacaF7D7I2EpYka@*8$Hanar*v4_xV67q8tCu|e zOv>l6SzBjSL}CY^$!ABj{agx8tkoHrtVxJ8Va4KMcUA{nQCyB!Ty?Nqp$R8 ze__Z27W(LjR=AzC$&3WEg9ngjQvjBLgnSO$hXrnwT~4>^Nxv^$Lj9`k zFo%^siUEH}#UwT(brCl(A5l}kpZ*MJ*F~bev^k#^Tql0e`P)g_-uO;;+1Wr-b2ZiK&ERrI`;m(^hqN2{Gh4GFixxl(=BVJ| z=g);45#syg9*Zr0od8#uuILt4A1+7Y)u;o}?LxvqZm>cv#Md@Cg}a3&koXEalp;01 z{e%6rk%aoqTGJT@tUIEYuJeixOmkc%>Mj!nyKX0v8;*h(vkIra6<*JaH1D$QI-{3$;(CXM z;A-r-E0&A??9%w#>3Vca*!_#^<+`dA&;_l&ygDmoDz1typ&9QK5@sN8U;?1S5hqCP zB%gND;%iv7xi&1nuvd#p-%wYW)q$|Lp?YR|O2h7D)XSWTe} z05`mMSuP_fQAy&>K65>;$+ofVaT(CnUgl~~EceCkIK!@zKd67b{obhIEe}@^g(B+Q zG$q93cYK;_-Z=8ZrC2WjWY0&@b`&Fuez`Qu47<$p7W!4Z;q<{;yl&2J=+K3ZJvfaVFmwx~X;7;Wz=Y zraMl`P2+pe?PNa-04aBJs%1Q3u6M^ocEm^|RO~LJt46J!2!+-t z4i0j*`<>#!;QDFMsZ3l1a5BwlZEa)O&NwT>IR|{wxDJlWY;vdWFlg1Eyh;9I%JIDw z@lsFE?b#t8Y^bl)+HhD*NnNvD4v6R*3zz7V{$+%-9K=#rUf+5^SNPvSs z_^~b@e3pPhoM10|GmcRHx$jFH23>>9sFXjDgsY=D=c$ISIq54F8|z$Dqn1Rj>F2c? zG%IV{oaNe|O)#31JB!-f)9+N>EMYj{ll${Prm3@&+} zp*WSgrk#OZ^nd$T|MC%_by44PHbBzf^(ULoGlM+`Pg_eXQZEha)+*_&j^(C2+1i@7 zqDBO}r(pXyz*8JP$E07)IHyfoFGaZ;w0Uj%y|8Wh;aOkT^_+rj?CXo8z5clR=EpKA z-;zw~<-(F@dItTzy{tVN729xA!Ly4v5okVN>{9+97q+;a@5jco%9KwO$2LCiMmw>m z)t7(P8P5^3ntG%^Q1rsn!J)KreL|h262H>cr?BieJq;)>_P^Adbf;S!X!8TG62!al zUb;z#vEo;`!Gl@S)?N)*b(~sS?)x{RQWNRMVrWhhaG3Ax&D!ouBd=cBO?s8}TIpA> zO61!nxWI}=ytUNi!N`mNw652 z00|@nm*AcR3+@h$y9Ez458pzAKRqeo5Tkv7yIU(s?pZS(@I-$b2uc%{3|z*z$X|o2#y5&pXC$E%@26 zRW4O%L`_zJUS6KKDA}P&l`GJ7Awg=jM)TV4Vl!PN{*+fePG=eg%xS>t7Wz42E5l_4 zRi$?tmw18V&G=jkw*Kar!x!N$pmb-tZ1Kd_m4U!<&cWYYAZWD>=t0{^4~s7|m#ewi z^WEeC(oQV^cJ$y0+a@Y?h5H3D`PPLZx1ifE#DFjuIM8}yVTfRq&1=S@W|yrQRUB&x zj+KnqCKqO)TKl`j8=U*TQ*ty{msh*WGsxNcV!FY`{i4C7hlg{{EJ?p*JaC=scdk5> zeTi-rjMe?mta@oPTBk|zLhfu+xJg*lcisyndQxt1y?$dGTiW|XG#a&|v9Y1%As`8H z0$OJ2s`3=0gqz&gwx$eSu7{Y)WYa~Urkmw`ik#ecp@fH+~36l@jV zbM2Rtk~(7hw7UO(gn_gM9XI9)a%&(s+~o3GnJ2d?QcA6As&zmxt^j@bYO|idHF}Dy z!$*eWYWK{oCGBpldRF4euoY0H`dPJpmTce9IjxqVSTeB|SU{3cNL{lXRx5rKwm^B2 z#AQ7S5B7iH5~cUNc#JB%5nR3N(H>X=WZ|p&z^8v=635>3Mg0<=u5k{T%k#k_?dMdz zfAW)29U=qKD6z|sb>HR+pxFEl%=A5?d%iB$Q?OB{o1Z4^)0-7^qRQmJpV@$HNu`w~ zy{JVTC72O}TLm%gW_wdU1ApSUY`AHcTI=Wvoi0srLdP_V?(NzlhJbE)hh}uvg?Hb? zODrCtt7wZ=$X0ZYGVM_^hx%kU^r~?d=#!gnrgv<97*q!bPXPFS4c3&|1 zDn_2FU(a@2(F3b~jYTdB#P>}=U->6r|1j$R7AyRpKmClK^2KlC*=(u#DcB5`XX?*Z znu*nZ8b}jvnk@qTNaCuBO?I(v2G|UzOh}R<)hB8_Ry_HWlaj0`T8q7%ntc9DDK}Vt z&=VL~ED%IS^BW9B{#d`H2$Yc%vb|Y5(QDY9tkuVrZaN@A=p$=%YPMC%eD01E-m4i% z7L;Pm!;L@Ln`S`|A-ME%Rn^i&yhm{wvzRR8yz9-PDbnj+a;LhD6poIUn!Eu=Y}X!z z?4GzdqLydJd~W9I_A09~5CGS+{KX#kcywaZ((FnOu7JaZc4;Jo~}qS*zsT2dmiFo0=jidIZeo8l+vz*Y$3)+zv=YxRlKSV zyx<#wOIL!mB}MsYtpk#(buRkn&m4PUgD!?vN~Z?p09EIfG_!otV$&j`IYWO9v||3Y zZmU}jvq9}gAo(5JSGCrn8=|0J={jLJ-P}-R222r~%}kaXnLH_O?9dQl(kxA}i7r${ zf1e-Hc(M&tc%1XBNSj=CjKG^QKNM_cs~hy?gq^$P+BYF`>wm@+=khLGWaM^rXZ=da z0eZ3{I=PsdRN-XrI^;R;ooYU`uzn_8~@uQLx?U~{TKT2nB8bU5@>-Rd)JmKHdEMZob>@_rkJ_kYgY zfBWq=exrZ(lH&WQ+aJrHf-?Zgc70zDkcTp}$h5Ap&O#`r9Pfs*XTHu)6-Bn9Rdi;w z^JV=+0n+ffCU=?iz6)7SPN<>U`JqaQr|XuWVdU}Fq=Cru({Rhz6&a!Z38TBXN#!9wNQEbE&r!KXj>48;1=@%+0eUK?r|AIW&cB@IeSwd~iWF_5T-#P>nl&qNQ_nVM(XRf~;>Eea z8O+gi>$3iq>J41-fW}Z{-;w78SB(yjg-iRcg zP4~E!6eVIRcj^NtHnNf~hi5qtvARZjvxF@7vO}2Wxuo!WJC%l0vTrgXkegBB=d)qR z;r6?Gj_$MkGg!kqjXQ%Kes?eI)H$FAscsdv;@Z07J7>T!DA(54F?qMdhq?w;c`t><$h!zS)xhOV*PpJe4jHL^K(6IXg=G}}z`q=<` zm7zuuh%jfQhJFBbFOCPMa+U^R0gL}8gnj`~f2RWUxMP@v6#)|r51_;)fDdg`R|hng z;Dl7pYp>7^KpNK63X`+BS3#5BVMC#)LMDQ*x1+%E^P9r zvQ<<8yU1-0pXN#f~Gvvxb+|a+D9OB=Sk&3?wyHvlq6;r5 z$5Uw~=dCXYDV8B|>r_hOfb70WT7Z*zoDlgAxCAvx&QZ9?!~PQsfG)H(nf4ZM0G}#G znSf0-->Z1D;W#CfwEqz_xNeIK7-Gx&^-kOQYlSg`<2sk0U50^9r-Zw z;^$t|#&yW5t#y&OxTK7@cp!n4M3UKU|Jx5e?*VqiO?R?G^iC=D%btigvaU}woYAb8 zd%DP%m4L<1TB4r2SyfDnf&*Nzv82~8EmXYUm&v8#)mOTX;aE*pR9U)K+yLY8YsXuv zkM$eA3-2^ITj)m=$B#U)z#V{xx^ANxBX$u@ePKs(6ZVJmO%8o4bZt4YZF^K#U-*az z;j+5l@0VFoJLuXmdZRX{`$Pn}Wo4VDaav$f66axKo$m7{F4{d~!-3r{a;<0S3o^#b zFUc>^ecDaL=Z!d%DUrH2ewy`uojzAMGe|!l_ZipCR}c->s`k>8ZUbGU$d&1Q%Cv-t z$Oh(($C_&*YJBoPAO?t>dHUpe3F~fvnyU??$3QGl(2jg98!x*Y6}H7SH|RrR{C}_p zV8f8$ghi78TWCv)ko@(@>`~=wkqejnX@QV^oO#WT3&#Eh&6k%)FfOin%|t$}TM*js z;=u43Q{G3`cIkgv8UrdMDOjv}&56n$dRzJ%uFq?{n!4^EGA!}MbI z=D^b96x_4yaT*yqhgX=1H+J1mojv_;O9EhI7%>4p_pLvj4~u1CqcBe5x2q(W<#HH- zog9Ha4QvyuOk<_pTCLzzF4G(qpFTQHv!(a9_F9j9!z~H45ledWns?4Ego{H})Y_LI z%4$pro-_33cWJ6%%HE0dK^AtcN&-#^*I7<%B@K-{b_HB+uChdrOH~@J(~YWfg;g4j z{!#=`Uy@wdRcYcl-ZKyYJ=i;Vt;rTW!xL)14`&tfvNf4?87JpHWzW@`R+JfQ<`J5| z9uFLz_gOJ(F#0v{*uq~}!B8RfG`Vd!hQVM;WPauG6QaJ`fsBE=@X8@&g5z|Y>h;9M zc_3=v-Q8pLJ@3kYd)cjP%O{V_m5H_9Ye^w#UVv8LSr9`Wkg}b5p{CI`V0UDt-v2?-x6B>-LQ}qd?u9fbFxB5&P-zk9D(@sLKn(an=bF;%UMZ4tr zFZ2SSFajfiGNIjV`OQsSP>#FMPM0@mc(cQXUWbFJ){T-s(Mu0VG)F<&cho{RhVpwW zOr#sO%TkNf#}>7)`F|!@h6~3-R*E#s7yuNbR|muIpX4}UYF!hJ7vf~g-H~guVlOJt zl`A28wk_cFYDAB7f69gV3T^Q6ZYh~D#Qtif>?R&!l48XcT_wkvI0luFP>-Rgv6eX; zdG%zyFV#@4a!%pf>y;tXT{J4lY4E4Z<9W?~Pqrvp33B8v)th5a{Qv@5&VGw#VG;pho!@=n z_3yoSA=mIb{$DzVw@=(t_49NjSUnNki;{`W-lg0;_FEY26G}Bpn5XC*q{(>C>_7$q zFiuA6rD+Q_^TP`jGzT=^kBO-a<;XZWRlZ7KkOD^9Sp--p2!QScVASn_;!8dg;OBFT zQowe+zNHiE^=X-<{8wfKI4&`UelkD?ihWXo^Ysca#Bn%+dlP$g0o@zoq9^f&48!e=D~;n19=zFMr#fzg+{sh4|ZZd-1nx@V9I5 zw`=f^IOFfQ=Wo{l2$}y5OaH&f8tmWvNySZhDlyY-(ED+af8z!J$H5Gm7c`9Y#)KA) zV}fkn?i&({$m9O|#GL-GdOu3Oy}c@h(?FP87b;vOT*WCYY!sh=w(C|@x}TmJ^1uNq zf%)p)KYKjn#pK%j{><83{GUDhPjC4z|IEBUoWaCJE%F-U@r%Fu@T-56@m_OQiIeuP z-;441p8OXa{mk=yhWn9s{_^A3k2?g7%fU(HQGfm3$aj{&iai(zQI!6I_3^JhUf5$< z4iodj`@jD6d%s|Pcmk}LrHGfz|75QmY2O8u)@Pba{_}(IUv~AMT<|anSg{XBORE2q zz54nLgTkeYfSZ%%ubvU$dcWb@6-y#Y|M@@JtJ!3|g*_BxCC zpX}ALByd0-#RkIu@)-fn)C(?P#e&v5^Z&_K{QHdpp8Z>-|LRHkTcrQ0_WoO>|FY)) zTcrP@SpIFL|6f)8f4kuSzgF5bR9E4D`$SLuD8`Fqg1)cis(pK`lJO3sH<2lS-D&9( zo8NIc@Q>i9cW$--G%JrC9owxh@{t~6Tm8cUr!(Lw+`Fe#M)Res05F>OU%!LO(EFGx z0Ok+_qY0#5s3R{E!&tH)QjVmXuJm})Q$}OhdwXTYYr{#V@VcHjZq+v!kH3cBK`{#W zcqLT}jvqgzC;I_@w+P~gK)WwkuBui%pqh157C`N1ETcfYF8*PL74eCFd z52nyoZS)iD2uuFM&#A*I(6sM85C%Tj=O-DUu4KL=T8zh^WWRW>#XVmDe*MY|eDvmT zoT9+@_~#e@4#TpiS8Kkk>DS_z_y)KIj#%5{B}`X)P+89f$EK%j8vW7!&xKq*O8%gF zBi8bal}WSg?_5zW~a47Vt(Hxy-H%1mutOAEXk{V$p#9kLN7H-LDC<|6Rg(X zyn{NOk{dX9uGO|QIIYL^X|ndM^~KNnDfrg`aQ-yshoq557DK&3p&QW|;*$=K3N-gb zz;z1-?hWVj9jA2ed$UgK{fS?HI$nUp6Q^h_)YtkUEen=5`cTjDlUG+`&+O~pm+FVw z(!aEcEB-0#%%AFm!x0|Et02nZ4!N3N3jx<9B;*+OZ}ORBGvgQ zH9XIkOzY%R*^0gb?|G1J{KpkD^SLaL1bT8Y6q(!oIZ=bJ#&ImfNl~$?JwmgcGzh0tX2Gp1JGmv zjFXQf+`U1cv4$|n`XRd@~15w8ciNJQeiIh;Sp-(*YMM;&xo_ zb+u;UGt^#Vmh1+g?r_#{S4ObV=&3$Q1|%>Jfa9l6om)Q*Z}@!tEkE|9ER}YnX=V|U z*;#O)LOI%ew8#}4JI_jfeig|ziYx`)3qeglYS~`^z&lI^)peQ%Yqfb`mJ@Spc*(Y#d;|4L1&0J)5Xc2 z!joL%Tt+AGkl^dqnd?~q3gx6XL78@SvHfaYBgupyw~)8anx*S|EFA52(1D$sjB9q? z+)!zhdgPCXFXy`F34s@A_rQ>&xuKQ5NGft}uY|Nua?#3d1o-sA$5W~p?qUW$m)E-1 z9VmZ;oZufxz<7k+Yv0TdKBtP$1sR=vl3p{#-TZN1(1Sx3J_4fTGO&mu1i>0>JSJQ1J#~{XC-}~%@J*Brs*Qy6IyDc}0b(?hP6rb-{e2)C; zMmEDfr`B5Sb^iS)o5YGjnh*m(5)~=E(vvfSee^AsSzoeMGfSKSLhZSH=BQn5nZ^ua z9}>s&Fnz}SDlG^65&Hd-_CTd^G}os0?fV8I8D(ZwgH8MFiT_Ag({#KjeBS8ZQU0;8Dfpls8f zIQf$TpABq0lDIS|@@M55O!u^++;B9o;yuFht5&ro$5zga)oa<OahjnOzxmY*`4XEyU{4W_AdmEkX7RV@v)6*5G3|8RYtEtO;G zQYw!KSE+KdV^FIvupdeh_6DZlXY;$qd}9D;I01FV1!sh4^&7Hp6U6FQ+k~pLHMIR?^M)dXtBx&T}n~Xw5C`w>-!YOTSn>KYT)>x+EhMH; zOCt0lmN;0h1mUK1mofJPA@dpZ=_kKxWaEZUuXnc2`-I2Uela)AacvJ;$|>3oXkzF= zDjtr#)NU$(jO>SoN_PleoK(@_{2@|y!?ztTR+o}2_;w@zOof2wA)CdZp2ocUg5bM( zud9Xk!pj*ZVNN70%kt3OwN;Npz{oaSg#CP9mLlWRqknp4WtoA~uJv+1O;w;iUhwqC z1Z^EkV&kwqgt`vjMc#k^<5;PQ#hl-z?J({Z;bjP9iO&0?;vJT2H`q`2B`KqxIF;wB zv`t4x8V|l2yYweODVko-PJ1d1Uq9cF7|-Cvk3qQpq0!}W_<41aic1hhB$BM6DT7Vd zzVj3l&gAa<;8x2xL3DDHW<7?yC$M}6pNb8%ow=Vj85C(itmc9-UbWy^4hf_B+05X- zjr=jT+ZIothr~?Mpf$=jYQLRL(zqf<=C`xApOAfLq74qA_Laf$J*1qqqR3C9r>awa$0wr*Oqy~3#CmFL4qBNk#OF+x(B|1 zNG~YvmR+QhDo4K=hCOqTyAthU`#=Z1U2j9qBv2*+`#YAb_60u7mLWbV!F;2YJe39~ z;`7z)Qx+umfqjTk)KFVU+VGQr6UCf&?f(AhF!iFojdY(EJuwHt!fFLt+UPmaVe8g* zGE(#p_eK|}JnC5}Oxz4V4rKU@S@=WmL5k0c8H6TH)pmPztifcK>yy0 zo;1%v3Qf+W5Xai&miUa2D!2!>$eW0%|R~eID~Wwm%}&>r!9V!pGUkB zv*@Vriuw5mVd1QK_79yr#L=viBi%pO#7#ddVGuFH)dG~w=UW9ZZ_p~5*9>3*L~4*QuZ~*I_sez zU5g&9tY&Gb6Yek|uxsl)EY*}$pU=K=tuW@vtJGK%oa>+%FneTYx1Wb`pb0*+%lqPX ztHd5^!~$T!cWL3VOmTUId5CKx!w*Z=l+|m4O&8j`tT`st`L0djDiu!ZJtBz+C$}xP zWG=h;(Xx8}*u8k=tEsopJ_epx)64o1ADm*JC{@-1T?I82q;i>xwz$)}hDpldr{p+Y zsMCKsHeq*Bnk&j~ChngCST)od&o-lne*ZQSyCeyIR=N~^S0(NJGpa;j5hH%Z-J6hOXZuCaZ{-3w_6lRbxVU8#wr_-HIv2z995fdXC9O?P#lk zLBmma+Qbg~i_W1wU$Dfy4^nK$N0NVQcuk}4p;6c9>ls>7p-dMI${#XCNB+|7o+t_! zEVhrPR7GKu`JC5qEp?Zz z9@#CQyrb)e^tIm(?FF0kW6NI|{ZguN0tZmEH7V=VYB05p-+7ErH&ea!qRL#pij;Q1 zqn;vdUBcC5{QH{IuXQVY$89)-t;TvGNBCVh)phEE%|?tS!ISczJ4-$38j#=K(G-X} z`#5fhW-r>+CimkAjmkzITE##f^v=R)%1?bEQ;2dN;hWKXv<|tyQ286qMoU?!xhKlP zyI_z%%RcO)dkRufBtL(FHAXJfRB}NX$1w@KkSRK**J=3|$L^!*h_@Oc6=Fkzdp`%B z@t%>VGcJZd;x(8!XfWiPFjlcl3YS%}txl@~K;%~3%sHF) z2J-^tt2FPmLcBwn(q@vuvF^`m_9p?d+3CWje3VndWo=LJA-RXrc1$+RM2 z+YRr9jSYAWRODHYp;SPxGPs5J{xAi^X4(|oVdL*?JvvQOdPlD9DxG-zJfAE@Q}=P= zr(GOnQ1xK4tngRdPEM@Psah4bg`>5xGjl$vji?-8S{E~$75^BubNa=rB&^XN8=mhI z(ET3jfemKkT*wDC+_-T51evMh*`kR)YbjnDD1mC1g6w-vN@RE|ZHC-SW?Y9CvTG>? zwQ+C{Y(th*>vz(w!thp zS~Nt>o@1MoD%lCf9L--)4>w|zsdu(q$kaN_(F}K-P&UbMnt27CD9Vms10Bwv7g$q7 zm=68@0)PeH7>=S1wqk?qKXe6{CpLLx#>`nv2a1R*H9h2NL%?W)VLLvu?7eP<$hi&+ZeFM6+DrvSlOxdN6 zXO51}9J5{AEFET002pb?3g>p_Ow&Cn!VsPb#k^X5aLq%jPIQgVh3iuEDk%zfg}Wqa z;(x2!$e1&U?xiMjITjb|*T|ST%6qVsvecoP#Ucu4bJ5>UC^@o58YXrHwYv4#7gO?^ ziA;9Xj~zUj6vx>2o1v4bm2SI?qO@vtSDo)bfVRU|2;-Qv8h3bJLL$67U87ppG(&Gv zivE$b`Igsm_@j>oioM;Ae#b|c4b*<1j zIOo`tKemd1L#pLEpeum-8+A{Pdj@qvgg9|ZuJV-C?h0B9V=ytxfSL_kW?<;B81=N2 ziz10|GK6H)8fx;|Xh|IO4?W0ii+-hzP`%FWpVHKR>vo{+2?Y4!kLW?g1^DOaDz0w5 z1$=Tk-nzYrO>aM*VG&$q1Lnt42iZ^kUjdd0~%-{j5f-6Iu7Jy)TYs9^#ii z7jRK(xmd>&&hQVR6mb7hFY`$=jCk~(s!z(pL+_Qt^WvnKg-Va?m7!XeC69NVB*IhM z{nyUx)eim#zrL;boIdJlsnK3&QWcgk+$kB!ZiydA9?#jxl|@5Gtl9C>Smf#vBnz`u z)DQ;b6D_;n?=WAygMQybzR*5~f$-$0PE_U_9!`{M7t-zBoh8Z>4{ldxx9hyJwqAUW zv0?rNVduTnK{@}N-H=zyBW1eWD3!-lARDJ8UoP#1ED77NM~&r}M!Bn0`NMC)g1LV0 z1)B(0F55)XF^WgjE{^oA@o1hjLf-qD^w;Rg>-k)uHfAg_5TQoPcbGbG83J_VtY5gO z-AEY?b7-{{bJvU?djO==_Er5K=P~Itv4mZ3^&yum~nM^Y{{8P8L&%S zrr(tJgHpuj#?DUee%bvg&ta`4^lsni5xTS za{T$8blGXxaB%ho$KPX*L7CFwqwEfc~*AtU+1hBY)D-*ZK6 zhHy1wDt6R!qlWF|-oA*TS5}E-I4;M6Sx&N~IH*$Hk)LYrZN2)|{&_Xv%SncI)P0lE z2)IVr(fZ&hj{8|kIq@DY63XxEY@Y$~oDSc+Mhq zf@^XEPWL-tNAT1!g0QkuE|AqlAJ$M{La65m1d&!#wDbz}HHn z9dWGUz1k2b>vs#)3pn2UwcMEzCkRs5QMlC+Tp2HH6wfvwSBlh;erT5s084MSFuB;y#7I}_SkZrQHS;pYoY82XNvStbuE~68_+ot(`*%)& z$=jM;LwFuRoI`y(=vQE>YFU;T5|CLZ*JKj9bEAjf*o|h1VDw%UC!p`Uixrk&_*W!~ z)Anw}N$CBNO}!Ew-Yrv}LPz?~Yl0rzfqO)|vlaRxUK_r2c!k*{=;;8&b*Au-kJY8M zI&yb+{V=w{$mW;y3&goBWDx=J%(ekvA5Kxb>MAhneQ48Y&=SXz4~okc#VhN}hm$1S zLv8cIdz4xWbgj0O%0}OQTMgI!;Rx%r)3Hav?5JS_WKoFb?QxqNWfnblO(eS?58*LR z=+7`e0TP)GXUP4iFu<3>=U(8Lo&j`7-*e4ODFsd`N^LwK2^evo%Wm|ePYSz^1K9E> zsNAw5sd|@b==zYik|S96h5c;3_QnWQ)8Ks?ogtoN%zd-Idl&%&=KH3zM6{RR!@|3A z?wg>XLLNt3c8{)T0_)qT;ND26LC;jKfP@y5l=10rWOA5*^Mu7`Vn+Mow06OGMlDJ8v3k6Nvj9$5=FO39+ zlA6sDW&erj5Gl(P0stt2B%Kc`5oirX^8S!X3jD{|!2qGsj_&aF4DUHnR$_gWb-l+> zC@md}^*Aba=gSP8W5?M@cyC8ExkdqP2I~(BUiUDI>Uw)9j!L17dJkXomLiZP9qJs2 zMIg&mLHsd20{C1J6e4O@UKaA(xZPcDLR#KG?yO|AeR-d4XRShjF`ps#>4Iv$C*v88 ztdfXHz3C`{YjHuXnAjB5Iph!F{$9E5mNCCGI>raUcHs8rY7J*ne3TsXXdF)cCP{bV z(RsQklCucP;Q-nZQ5X&n>ggDVjMYljF)A9|8;-g>zY=cV#-+Nl9x3{vum$954!bO< z`42x(;y^6unLdP0w74G!?M_OV3E{60#+=V%+_h6IZB^Y?KTh|M9A$#n0y;;kE$7O9 zP5LGKC7)GF^F`~;?+XX$-kC677}8Y`-}7!Nps^lztQs2fdF@BG1oaYv=?yadulG9n z?mj6wxnsxY2H!Bti_zgChP3f$75_$$=7J=KCS{>c$#JCKC70F^>(4~*68OEpw;^Q8 zm2~X#zeRLn|fRaCs|~>=G8%C;|O`P1JQ8Uj6w;KBSgt&HOeWvT3k8 zUnRRU(9z&L`a;l!-E~&Pp~Y+B2uOz<0Ho<1<}8tNaVKily>BNIZ$3({7d^8P0}2Lr zG4-2V)b^}Gq|Xo6is1&}E0%_m9{snzOEf#6Vnty1FXu>no-RX<{uwOcPo{XUO5;~D z7mie1a3XK9uAM#!(~|DE$=p51Q60NA>=k;seIsHc&zA<@-%l1s=fhXkNc=)gi?x1< zjQ9o2ZRM_=cyz{;gzaDdAy*Zn<5VTUPgH7+8p2C#;F0>wCw5h3KEQZNuZhN=WW(5w z9+G2z$3fPx~^EIwliaNUZ+;oc#g8R7X{)cauaNikrzZ9A|p@;LkLCx9vL) z$HyOPopW%(DM8}#lUjC_cV||4Lubrddc{g1V6VU#21!FdM+*p7|Epeo_ft(A`UcGG z{TazGo@N1$x(aVaFwSPOcp~`z4!rhh=7)-(g}c>vFT9z)-(A^Ifm}cA=lRCx4oDw& zcLC|3!LQsHMtzN>`B@cvm6-(2K-@NeY_I6>X8~kG4ywBMUp{5nbKnv+nTa@r&K!QS z`EHaH9&?C?b28P9kD)6wb60P&^`tDGMN#C$LIUpg&c2PNVdnJS!O$@8PLS5+H6+N|XDp7j2%6k%_B=LYdhb`H_T3V<%@6}H(U8c11 zfg$>4|1HK{7br1go0q4lAvWnbbIy<*uD1ja2+LIP4)4BZ0YHn8L(}Dge?2n1st+yOXIPe3u=(>3vJPG zsKKVdU#`eqy7UkY62H^wUTp-rIbEnW(llJ{2nyZS-Iqi@rP-}Y;#oFAU}X!>Wm}I# z-tYRJUn?A%U+sKSc-V1=g&oMqYAnE#*~ahT^J=i_<{>)+Y!{cGSvF5Qc_Aj$A_~w! zFIpQ5N}Ae9<{RSJ^dG;{IIe@*BX%`{Z6KOwT86T+mkV(P@1Tdl&9~-h&Q6ES;O)w5 zdH905p`~XPlB$Ib7eL~nlFD{YRzuMgKEKH+bgnDn1kIzDV-gyA?4S6sKT0^c zc|Tbc21IQIc2rGR2tn=t!~*D@gFW2N6>VldJ@$PeFU1b!qV)!GnSCJIi%7-E__Ngx z6>g?|@sw#j`CheX&$%>r29M(`nRk;~;ag9CPIkgFPEkNq-P0W_H;Jutgtc;Q8yfXJ z+}kIL?J+fol4B!*LdmIYhn@Fn&Swa{{>*ehz#PPIgr?>G9dNfj*X*@V^@jP|J6ltA zM)+}i?RP~wV=ozk+x-rPJ+3vbe8UDEPyX=d49%V5NG`cPxP7aCWE&M;e|dKD3IB;3 zgM%iW8sYMf(s%FEUlK19(=Q%3T(Ra3dozGk~Vi8ws2 zV#^^f?*;?3pugT@5>On=&x-y@W@a{JD)TT8XCDl7=fEd3e$+;*C{#k-ZbOt1^n|^4 zSh{F;^^}j%!v`41jBo`EDihu!7RpDrIC)*;aZ!`1 z86b~SD~ngq4)+N;ERag@v7+dy4f+1CN#nxT64P{_JqeG4+?%n+hlH70)c|N<7W6BU zeMV!dWz!FrI@*btaZ5tfL^7gWiohd$m-Yv4w>ra<>z4+f&Li#E;}=Iget5XP zarI+eWDRvlc-i%vFo5jjo;wRARjSjH?5z%_ZXc|71UbjORBgSW0w5`nF=zsco!YtR z*3TgJxL|gN6FF~u6rQIpBz$P>=(sT2WTI4z+<2t+nW$TgAw)K?>4G4#81|cG-p_N5 z(h(>_s`*=vCh>b0QQ=wT%sf5?@)7{U9IK_KVG7g?;wI1(bmX0ODmOo}Ior%%g%#S3 z2jMu$PxE-cq1@_2+fV~$8#f2*Szu%bwO!kBU5WAPSZsf%ZLt|9vSd8Q^`3gp@4S5; zHqDub$Zp&N7;9TKz~Sv#NCTl$|J&R#o4@r!W|jSraq)vRvI=$g;t%FyEVl=VVZ>6- zkReOD?*|Bb-J#X(9~r`@_MoXQTu;?ZW3!S_NCb_VJ?g>!Ags4S81>3m*84pg!fv}WEW*fUDIhIqJ0}aj5BpM?AxD={ zOz&J7{J6`DXU$a8s+bf|{+t_<@}vUiRT*eYj@gzn_(tL|j3M`+Vb4 z5nj>XQw0~6>qu*bsfIY;076rjZgVT2L4Is2L7(7XjY^qj8v07mbMn^2CK(oFb*Q<> zx9vn?9Ax}cVgO)yuHu5vM9Bw2UFZ6dPfYKL6b?!EJu<#rr>inajNyS#&hV+jqUuz= zY@7Jx3ASk$ZxTJN-$k{j-$B9BrK&Z7YQV@Uo{2N(eRrVzHfDPoc3<4&U4+;7JhB`h z?Pj&gr1TIMYK9|pZG?TsT7!y63}ejTTCaGMhDxqyDhR6%a~z8j8`M>Ju5fUD=Wei} zU8`S&5Zw^;OxI)eAistKm+sz1QE!WpSj(u{gALMJTq!E{v**H2pZUt_zpK6odIFla zLd?9b-T<1n~I0OGe##~0Q6y*>vp2Sl_Yu0X*2+=3?yIDeGjAlEHw2{ zac_D^*K`?A>e^2ZO)??90p3Ic3f>vqe^||3z-m^@Wi_naT1}>;780~^-RXA8BWCU9 zcZ8IOKNuQ}{O!u9l|p464evS4*dyfAT`j&V3*l#DLdDysGR=}}H5@~UrN_0$Cip29 zy@$nX!6%I5<@=WXM6{-(fgA$c@&pvp0OheOqBL^U%kmNzdCfLJGDoL>QL$rJx5Gn6 zV#R7eB8b%cJq9P;0M+c4m%IF~OQ)5#Yo3L;8+cQd8Nitwq?>@UpNe?&giH7>0!4vCi(65(AIVvhEWXVOJZ^5OSX#BheBR)4;J*|Az&#$H`>YT$${{34Ns`;a+SWnfSJPPH(?9+}(y_A*okl>9W=F@gL865D&MdpG| zuvG<*44wwge8jCiJ?)Q{C@cS&Cx1cM=&u?}+5yn!G!`*yT+b!&M)7F8*d2$ZryYhJn)=25q|;NAR6SYL=-jmu2dA-wI=ns{XVUDH z*&glM=K@Dj@Xgi@@p^dbMu1?t!9$;zi{;*WyaL{ux*UOYsDABdp@wBEd=_e900$8o zPEFrj4= zw8;mzwIAbweetZxs;w);y1L8>?)W)Vi^6gUZjoKX;~eIXnM_mEz>`e9kNSz9aQA3iT4R}o)g`Fv;`jW_KbQs6BWVW zP|PmQzSPmBW*1;2+>y&PXx9X(Jv7q{wmTU{O(3vCAIY_KP>q=nB+`Zm9Zs>0a*qy_ zg>BeO6lF&zh`9cgW;E~70;G0#POk==4Rbr-+CvBv1p~u?khAdBNRE1yo4&{X$eZE{ zo8#1eh3CKVc3*!Ut_-nsAq>Sy_qmp^DaKncBQsAL*0Tc$por3qAPuDQH^U_piOr5c z_dre=)ST%J{`{VDQ%GBK`2CR>PRJ-6H~&6GThrPBLf19!Vrk7OLh~&nLJMw!{nX?R&g&Et2&-Esz}yd_11^ zfLT5Rge@{uFqsI;fLI+Rk53TjQ~EZ#?W8G-(#9oYJyuv`;g(iwX&&O{ujP4OpfL~R zfcTfz9x&g51y&~Rk}8|W2$Oe4iG{dUJiwYRdO+k{be|^h3RetV+5!4AWsGYyJrugO zza)khN-@CO7#I&AF(9OhF&{tpbzp)u-}10XqwJA_Q|WSw$d0oesQGhm`8=Brd}Hp9 zo`9~5aiq77yFhd^+nq&`n7z_2U*kEC?W`P85v7RByRrx3J}2r+BbJ{Hr?VSG za_N{KEgI3L*wM+v9>{+M5x(^>Wa}$;XoYuEpIz=jeKW2`T)h>bhu16a7gs-OU+qkk z{&ZwOd~Tn@xRt>BLoQ_OXva}LrqCJN9$0^<-hkWZTKc_rnH*& zh)8%jXY)ZGHw@;lpp{@BKioJ+YcL~ts>z~G?#eN%MLp-!NCs%fc$%;(eq+(^N+%!W zyGwm2nyVT8COnoiUvcYX>I*J)Yzn_KBKsnBLu39fwZ}5Kosi%CRz*=CgMNRS)~{5c za)R}jac z#|yxLNW`(DzbI>Rn<)j>z7m2Ok2;7xmT0DfFNNm1i$K8H>Ah{G`B^WIw}OBon-LVP=*3iCmxZkwUnn!O z1!Yhp*7g1hpQ;*`7Y2FZTPF~5kc><1Ap?FFY_uNfAVTUDZve#8@S%mSIsdh<(i@`rQlII?4JaG!hlXHN+0p%3x^Sk5>le1Y_2Xo^k0$_<=-KVqSV!15gh)&>2MwHe6%U z;|5hH!_mC!TWc>bvJxGJmg;meFu+O!qoubda--F^@?)OOnjZF>5i_r0nTe6hznfML zF~#fth^On!kB#qUBJsS#&!yIVGb8K?`>?;lZ#2rL8thhY$ty~CRY}aa*-LkE=VXSP z3FTXOTi)=Ql}c;|}E2>Ghihuk%D^{mPHvJpV!C!^IV%`A1db%h%q80b3)M_0ZXo zG?T~efp3j0&9-88zYL{GFR0Ftn|-+KkfV*tl5BBZm`u?y(lq-JfAc9%u`a}+ z6C9Hm7~mJD{lm7_8{ez$qjI_hLY1())X&lJhsfy^2d!D^D1V?N!;=6s%_6BrhRFdj z=8QR~g&e`xrK`1XF+6lCth$4Be6Q75&D1ZZ1E2JaQCucjtn;aRoU z$s0gU^-rxIpWRS^ROD|S^%%dF*|uO09=?*VIg%>Bqo|!HDqs%(G#ynbktOU??XAI# z_Bax~QPCA7dO~)EoU4*$o4Hi+c%Q=VQ$3q78o@mu5mm=g&!YExIs>Bhy+WiLPch{q zrI?MQvyJ|-zBQ{Ed>?sP%ZsS73BmV7%3nP<`7v%I0ET>6nD`7$6zQ^nLkzwzm1))O z0`*GSUB|~anzM7r7P1NPV=e9;1XSwzk8Z5EZaW?M{~WuB%|#G`;KuG!tMV4}i?0m2toQ&$no)cL;9H zdjY>G{2cocSV z0*P0x8$VFwMneEEOQu8sx3s6~s6FtEHAn0;T{-oHTu6sm~ z6!f*WWfN}nMf6i7^^>b0)#l|tiqrlN&n2>#J}*GZjRJ=5U~K`6y5ep{?N^2v0jK7l z?8fLU0)Do+PeNiBl6i^&nrcM#&Wp(-W4vwkMS~Fc$q^slY?fZ>wXMNI#Thxf)~}yt z);VBlnmI^yP0+IkB+Sf$ZnnhrTtxWVm3gIzN{3y?!&OHpW`o!HgPFFM`_NG{uU$n^ zAan7e+3I`d#B$J4@%v8~O+X9YgdIP#WLs9CP3^AtL!z~=2QFBf4#jnBW8{Sf32l6Z zBzM|WZCJ*;f4vjonqe>$4BzIq*^$~;3iWF_#vDbTK!#So83>h;8qZGG8F-eN)^ETe zQ{JY43%y@QIOKg6-kAYsFda(lZ1ldK_1KwB`PE1n+}ouBoAOH6!6%-=5hGVf=g$@X zZRn_UU@SsQsLJy^6N5+;9b>)lbU6BaN^;cR(kx;J#Si$=4*@^AbA*AI4aGQ9O|$#I z=z7brDBGxQ^bt`+K%`4R1w=X|q)S>_8U`uJ0cjXYq?B%?L7D-E?g8nN9D0DEyJKkh zZl33T_dfP6QD`ZD^tXfj$fJ zVa=O>eAWP<$Y0il*m3x}C!Ik8CS!fl7Af+_6SM33c?2>{s_cDb%+VA5-)4G-QnQXE z-ZIt)ndbNx#P|UNDST7*`s56nsWWjS?4VfA zAFPHA#UhH{G=+nj1v=6#SPv`O`Cxz10p$x=T}qZ%SxP~|&u35Yvqu^r*3tMi8nb0S zB^g;MOxtVWg~^zP??9(>ag||5C*~NJnaU5AKh?VK=hDW*bkz8YxL9CPGLrx#HR(%G zxLH5`Ym8WZXf}_e1XRB(RZl?|LJyPdb7HDd=~{Y`&ljc=?6w6?@Tcg^A9WGUW*2a3 zopZ0w$54z?J7q4TX$5AzLi{@yyn$wo?Sw!3AV_P`)pzO8RTKdWzYlSd|KQ;zrHzj2${9{%zVk&1_%P+rJ?s7bBc}Lho19z{kS^?eZ(0IlxAl z2ylP-T(s?nT?tk=@mBGXZ!ezv<0wL8jOU#<75m zIiUHj@B8=UzB(q~Z;4YtIiRTb&*)6b49t2D`?y{9P>>l6<i0R$d}@APk%s28Y5ZgHc8&@XwqCfFZu-CoEo&stf7(qX2HU^KU8iPe9!#Z zjvJveBu8=-ukod)1FV%Vp08(~pEmnNGW$<1iJF!UiMsM6oO<@Q7|ykm8rf2 zX5|3m;M~@%o%xHPC=t(RHj8P^##fq!AwwHD%UoT*a3bgawK`x_%NANMQQxjIp8d2+ zGFM@ub1$vAhS9E$Dc?I~y00j0gBTe1WIQ+Di1ZlwPVy=wHmq2G4Ek2|+!^EoJhrz% zslNo2g-edOZxwwfLu>`|I9?goLo7!$j!h*F{Sb-LFH~=S6z*voTKaG~pdpVv@HZWV zWlyK}-uR*c<6~C_@>{7yjYl4l{~}8@CHnHP^tqD6yW643;^Q#Kqch*8H_P2#u+Y$k zs+-^Of79RbGlk&Ol_*)KyeRH!RcO)FOoZ;@@oxmF#;&npB7woKyR_XWYZr)g~BkH#KN77fJpo8w}FRrUE^XGS~A zW_VV~J~V*ow@?QE!gQu*EYyssMUBW(3E_I3%fm@1wYEQ-(?8BySb}e})#}HZ9W;>0 zPqp~M{-*It=`q1Lag!neGD%H_754^7(^JZ!@5Vdy>alPD0*r7H8JLcgE^dcwdEp5zlBviCy=GPXN&O zX@j8XP5}4U4_lhHV!{ARD<7>{$IzKGlP)4ueI`()8BwqwaQHQt@2|)i-Y|;k<8$SV z7{SF=v`Cx{P_0zgq|p3~gHSfKkGB$2t_neldrUzSO?1jTYvvxm{+lddxHVy4(2uy< z^Wok>a>NHuI6+coK=Azut3Tw+>kNfK$(&(8k6Nr{ru|b~2b%%n+RIGxdW6+KB+_RcQ$STlO;9UX)uT)hK&W>OUQu6mr z7hNn?ON$=JXK5!ln;O0!-L#`DFNFJddjTjOVI2*XZ;bd6zhe5xhii* zn-(68R7E}(JqiH$UHOh5*}9~@v7>j!WuFqW7Ql8JGVKE{`on$H6Wao|U+aAthMp8D z`InwNITXM)$j1c6UlTyr?i($S$#T+O*1o3S?7a>Q#WZh$W!Qgz>Y_mE&;ByyJsPX< z+`wE!{HxpD1ITl1{guzsco=Wud@il>MEP5id8|r>EP<+o+Er6z`D25>$8wR!0H4am zdJ++P>^;^&Ln*lN=W})1w4FnF^2rP-=PPn6(alby!WyrD(8-`a9k#RZ`VxTU)3!WA zLs}%Vzep%B%4svfQ%$XE$YfBZlLO=SiMi)~-ab@#3=hdm7#Qy}vn2}PbQwK&j&;;9 zsv`mwKHmE*=hs?j1e}JBN9SCvFKM(s(tZBpxirPKxt3Azq&t!}o>m5r%>AbI^Go6P zOIWclrk%`cZ;iw+(1j!)MNO-E6hf6xV>)q)$oNEr=?Qq?ldb2u)78R33yrSNPC515pW8@@TRzF$<*Q`Wyum)){P;phuQbP9nKuLI%Ik}VX5uki z&O5cBiy>Mbqy zFm_IXivhBX9`WjU%3In$E37_Y+Rxf?E+n>_)gF4g4v{S;JnV89x;|nEm95)na1sX6 z7_qdl9BsyUF5xgT!^WI!)N`nJOz7nWpO|B&7s zoYo(!qRX1~*|NQ^X2#G-O0+2HN8`3>ngx*-uMi8Em4*fx$<%VkkuVKd=wn?3Io}7T z(+2i27TC``r6C~a-o|f`$MLS_g=$%5v$LMNAJ+Pg-Qb>Zg{=$4QFdtp30XDsg4TN3 zKNbLA&YEhBM({>9!%ODOh25|&2PrOtGi+4F!714VG+}9F(FyBTnSZEdY$aA89U~}2B*BGOKa{EFla2qlD1-6Rh1}So86np``ArcAzHeZDlNBW+13w^g|?&tc~Vh!_)02ZD+Vc%WE7NI)Fk;F7CPhGOO!c3;1V z)s`-JV}7Z(AGf3tH0*1u2|a%N-xZMs5s$ek8wO_PO91Bg3$9t^ast+{Q0* z)Bxbf%5(uhL}NWa{;vPN4%<6D@TB>fr16rWQZLqImg6Nlg@d@3<&u|?=8Xu=yJtYo z?Ij8Ya&A>#UOhKWyeNUd1hDt~#RBzq4&{O}M_nPu=nH<=xR09Yj%9*`(5&)KDA(Fd zNewgQ$%v5S{8}0d-0>IW6^JL9BrH_p)@JoPBzdAPOQ|PBs29MwaMq&E0!w6$3>c=WqAk}XkEok(cB%A2A6_LS zipSDMAjUdouj?yagmL$%BJmIY@~U}!42<^v{64S7&TGHqZp)c~L%+t>S|}1jZ(UUk z_q+GO{M`!BlBPK(_fS8zli8qr6TUmfCFD+cy|8=Nx2Cl10w=&O{@6(MS2g%-UOgkL z$mVm|Oy%HR=f=iVUau&@!igK$tIyl>(BGykFm74V$E8Q4>?!xaDh5ro_*GCrGkeo znz^GIod4_fuc3~@XA4gw$3Ty_;uCrN^H%{1#VOWYPGC%y5vK%OT}(3Gx-+EjwHkx{ICjbVbIFt=sis!=U?6pPf=_ zq{|h_MXS@h2+JW8(G~A;tl4@~{p9Pm`sgH}p^IeDNc_ZM))MgJ@&6&>wI1NvGG$R< zFN-K+8FqZPLCAd92u(ud^#JKyfGth{C00kiilM?sPv(P^#H17EGCTA()l(7FPy6<;Lilh>s-b~SHZoc^!+qko$nf1uKb}qWVZ@mu?)dc&Bx^`Bd(Ji zWCG=!RTK?=^r+SrLC4QmJ9+kSe@J%CISeiGgZ}PR+)yTc{PWo!DslMegPu=UB<%y( z>C@y-x!l6*0zzDYuU4&iUsie!(Fk~O?~2P+@#cf16^F0R=teAJg=YEN!=0xcSF6ub zyse*a1{|40k4XCPQm8h4U|K!R|AyvsK0h!P`9m5Z;UELG5$@Zr1_)&o4`adlwQ*|$ z$#T;bxw+pc$weGbe%a1cN#_mxVuDT zZa=^qO{iGC5`gTvmp9HX>Ajz<<@5v?`I`pOFn`iF;5J+3%?&YPIk4|Bu+Uu2HSbT* z7SxxFpb_{z6VuqHM~peg0-bS{4k6XVVHoPO%N@|^pil;AtBKaM@e}%~)Pn9Wi)+l@ zZ+6is%UB~jC1E>Z#>9vkFpCwUC^wGDP~ixekx{cCTy*7+uo#Tdgic!1kzNUnq-wyt zkZ!r%!&UNjs>^!^30T>ACz4fySSk>HW)*KN^e&E~m})vuO4=M}oN~$*Irthb{eCgP zvhOEaGkU3W^#>*LyKL2mz_3hx&?d=kf?_-~lX-ufR*U!u+qEhoRrVrN()QW`+8z!j9Z1coe! z<5M$m6r};>k}{uDLMG7PTDCdEGu)`ncNU(Y^km*5=s3tf$1yiV5X|!zel7^%v_8@Cxa~x3JrdWFBuFjuCV9Xr!{CQ2^9NXIw6#-zr`cVAjws=e zcYXj60nmyX$G$;W!|I1eIyy}2E6huPh_P6s8?9bfW?$WO`p2JW?178Kw=BvnfHg%Q zb%@;|1(Q@OQqQfpzFEDC{b?$@A@OcQrwaJKY!b~X7`^f@wIJ~t^|-z#i&!gHuZ#kC z)-d8zwk8s?P+si5H~q9#X9bq>YOvo7J!kSS1+Y65U~Prq3rBMoq&50Pel*_=mPw=0 zF5gcR3^C7dbt3E$#x%**=9fFU5v+{^Jk`CXjGP@t`6$%u;;3&QbQzCJb!0AQ%04XN zd(a5O0*VqhZcIz9=R&8<^>=GJf`I7E9~=0QNz*LY@UQ0>i_~{n!X5+6rU_trtdxJL z*{!nFZYKNH8$K0&{hd!042frdE%VY3SN0_-BrrZiMda|u z^)k%&X+QL3rt!<&pR%+u>**c}jzE7BFCa}Z_9O||u+)A!8=5)stXfq+n(hXvj!rZp zad5TaPsUg{-g4s+%CTegW@?wel!S*o(#(^`_{s1b2mamSLhKqnd9=ilq4chcrnqJU z|JjRSBarthOugW9>*tZSW)=8TDiXRF@t{}0?-hdjG+;4{8lNfT{^(;QX~I(9nmaZ0 zdfq!D4nIKNM>jr$*E7OpZ&iL(AwI`yS;i_RAWJ*g6>PTG^vH3sEs$p@yPnGiZLr#E zlBwJV>b4wRX#}qR$?*A(y;}j6z-IL74swduN=o@;iU_W}o6Mbg2gi_NC)%1Qp<~nM zi6zMH>H!Kk1K|J17-EvYO+o_w&c7&8^}lOzH&|$!$Fx;Lw{~ar#TC9YL*3q}mrHtB z0Rcy3A)jiYI)e*O9n5#@FxY&xPm|ktG_HUr6k^_UEQgU44BUxC?lF@28LfccV1^JZ z{NrL)JpeK|IvwXtBv86DdZKNQwv9wsgj{!GxR&4a08_y+Vna5PAtVIsGH?8FC0^wb6pmmh_-SSnHsQjsY2pVkej~=jK$y_<(w`j#@W8vc`&m zLF`J>b!T?dA*OjyXCHr3a9{_OXcRz3Yg1k?m@W&hk7*7$bMX#vtnRIBrzdogW+Pj%&s z^;;y;A#2+AGlaJ1kCvfk7a^M5uGjPz8}K_IAzbN=m4%#by{hy{X31Aht67qTn7~5e z5z%?==fIZemHO|taOTC!Q>xXpGtna({a0YtJ&*I&2iC|;GS+r>_w@5sraul$8(dSJv$Gc2yh69K zw>{vp$xe`L?dHE4RUJhCKI^a}k+p&F- z`IL+unASV_RJRDIgcijQPrIZVTCbig(#cA8xgD3OW_=&c)xfgR@01FT?0K;o-5*e- z$t-_!$*(&!aAO%+fU_0wP4IUq?)@^!14LA2;xwt?XZ( zA7eUB#f(W2|9!%2z|6_+z3(q^)GcO+W?4Oj0M<^xa3razMH|fD@2ce3`wWS^NM1 zWtDzy#)_ZZKTW3q*PlHsE9GE$Y!jGdE$FoAK3nZn%eR#bCDm#V?F2+l7>wqH)u;wE zU@shw-(b^|_*DU%O9ACkf&Y_Y@MO{*U&c-K-AkxhfU9M z|6*v{X-sJ0NGZ2*@2I)s$p#njhlCwZ3Qp=Rz7eylN!)!Z@`(k?7DHTi^!$a|(ZePN zgmSpRmGLPvZ5oq6;Pc2^ny5${YI6E&K!hI%fvBv#f-#pAU(#)Avi1U@v_?bPzHbPi%6Xx=OdY|quFO7jy92^qmBFC+;(j%nW5ib5INKV z+9KcD^zTg)xLQ6)qCmSB{j*G%J}LnyP_Plr_O5ve-MT@U>4+W!<~&949uUVk+ zWd!ThMlGVenE*=j2$WPYfi=2o;bfsz>IkNdI@l(bNrA(a$Do#0N8W@#X#LzbG$T?4 za=hv*v~m|lzVs)674p@?X^Vp$-e-Y2A8=Q`^do=%BN$ZA#3zhb3Y^dp8Sh_phLDcP z6SEuWctrJVzY%D0E710N?=FEs5hUJpx|M8jY-+ksbSWZNUk5oY0u`T^&hYVx_&?1* zOWOlP(a4(*0A}YMQm4`^llbzc|)M0H5o$mBe2AE4(+67#~ zUC8!!{AW?mtRpxNnnj*S$(=Q|^xL?A zJ=c-=4{pzJO2t#asAC9jt1xFVTQ4>I9{=HZOyRdIEzR2l zuUHXJzRl4>|1b)E2|$g@{I{%k)nws^!choLUjdQ%y%IDqH(Q3P_&Abz`BOk@y`$d6 zObc>CDN=c%t=WMtqr6ZfW_>U%mLKI~v^HS0vAK{0EH(?{QIjl2uOi^;?C{hn_)*RZ3mPrZZWYCwXY^ZPd~O5p1A4j^x&xdn zhBjSe>$|vYCW=REhp0zeP;(ggL&}RWde3>Br=Cz;-t-iZVgX-eTw(f<^UD zQ>Mu0kqF&7(-zuDr!7t4x9{)?f8gDJF zm6r*Sz*G#8x%2fsuSXn)+Jq}E!}TAU6oEJy7t^FfyH`~<0qCuN>Gb?ZKFHV)zo`!? zmB7j`7x;8F*QGyYw-%9lf8Ue^nRGc698c$0NBE-})LG3< z@Fjugv7tT~`Bqv7O9oJ_eBv+u%KVA(Sy!NT8D6$`f9K8BmLAh;P02~Qos5HesV#-o z`0x673@w9fF06L8fEUx1{mnO6CF@h^<+&j()~7QCTG+bSMMR!y&vuY3`urueVr%#2 z9P|8bL5)9~E%G&KXWQ9$^D5ACLsmTcKl{sdZ-%X1HX`A8eQ=w&lBtAQ_jlb`v6`Vh zkxdwLS=x@#-I46YDo#s$c6WqyTI0Qm7dUVO!j}|&A2!BUSrS*T13%&YjbVVIzdjZD zPVk`#aQE{aNwnB?bbt$$l%I3oXw#D9pZ~S>^PsIW)R8@xZLJjD3_!{w!^@5I&&4o) zjzT~4255g_mBi)w#d&C~(*haLYi*N;0nOknF&~35O%z`eKmtn)fdRE^eMtyCacbm@ zV7@ZkajmV9KFSu8FiTq*_ZhY5Yh(==zy2+OKD*XiqruJ70^n5m-PWCWFZ~%K4O`M$ zadp@zi*`KkiT=}FTDt2p1C&fN9DYDCF9@-tzO7?s zYWsB=C_`M9I=liALTp*9!HfS6(mz4hZYNi(2`A2o&j>qlK!N(Y_(9{9$r~X@)w%p6X``1kz&%AQw zeQ*DGTWz;1oQj#l@IsPMTnIO)fJ68$?D|rBs1Knc@+O`|6Zb;-J$|9~qN>RYLOIrd z!vekaPoOt|rtIdrmC14*TROQqpf~09`u{H|0CJ0%U8I{{d{3HC?O2IEl6$u8VVJHr zziq(Dj(6njOm^gL>%}DMS@pbB%hA-~GR88@662Ja65^GJxg-Sy&mrM#_O?aY3D^0cIQZdOp<9s0s>{vHU!V>N1v6YI^Tz@PLyf5WT1>%0!G2{N=p#tq_ zFTyZIjGwQf-oo1!u9K^`$BT9-T<{;@>-5w5-cc3m=O_5ApC1xc zcy%&Q7a7dS68*28)85;;oK0}er+(6b)xmj@67BN9X@gb6w&v=nQ_eP`EzN*Gk8>?^2nyON#*vkly+k&~b(EKXP>&{AIf{cP3h2vTkVQb9Uqbdm*(+>5d@ja2~jqR>o=!Qf& zV%QJ3%}pyN^I4gR%+%Y|+RitP4;@#Ya{dLr(63DLaLkx*z?(B;7lBFqAm&*M*x2+U ze%pqyRMD4|&H`$SB7}7j*q_U00|03Jm&RoG_eW3V)|IJ?*?JbNY*sePxh?j*bj!Xv zBxeA)#ifg!%_rEKDG1kB*sdIo+5aW)HZ_#2tK6S0gnM1L>W`L739$&d_v-@OpfREd zbi>rPrFqByH~R;kVR|&qFLe{P(CE7Pb{~Ff1i;%BMimE3r@ts?@8;}%7&xo=jkl^O zD(?PBIBjlO-aodKa9I)X*YXnoo9-I`$6Sv5vdoMWX48k+nUYZ9s}mw_>+{;ne6POO zFIKQ335r=N(3x_}q8bN4GrIQ{oHe z^Pxb4B0K_=Gr$APlpy>cXkjklai~)>1@|X5y=Gg6!!e@BzAO6{_HZg*V%80=SH8Di zN3#f(-a97yfjqGv(vsx$&~@l)^7W9Y25z z%T+1)3SdU9eZQaWBKyL0#iXkTWEyKqln5|g%mDrFo^t?)WMO>G88ubo5Rb^_IRj$U zxBZE*5Nj7Y!dy_UL_ZaPGh(}!XmdLL67&w@i)n$O=16JDlLnInbSFxXFQ+8wECy56 zvmu&(uZl!iK^32x&$slcyM4q)fj}{*gFFK>CgUCy(=k0cZl*nwUI2G*bD1*skQw=~ z=nxZw0eu_AsQp;+BLX14N}>$T*2no{G;mbG+qvXl(>W9EHxdp*DoK9;mpy;^<=Ze9( z)X%)C`sT!6jB@K%*3By{_UAKu4L?!$W~>dyBJziH9A>KQUIA_86{T~j&KfclZ-A}6 zcPIz!r^9=Mc4SMlsv1>L<8af>0>chd&&C6iEo>m!k`u)!ABJk=EBB*rFN$!fMEhWE zmcG0NzOj76-CV=JaKPmjJ{LCA`s63 zS{2rm*~26Evi=DGXxl|m5$dV^k1+cWYyj0A&uW)l!S}s|elA!3{D(BO+Gd>C9Uqrx zO|RC+|9Z{M*Tk3eIVB93sl#)R0dr@XUolgNJ^}*fCWe2}K|;KSf3q}$Zp<%3Ni10S z)T5Yvg}dy6%=h+Fgl$7vs1IDixO3GI8+d+*V_1nO^2DPgBHz$w^DMA-A` z9(@P!#01pMA;;0?0>|lu*`@>)w{sn?`-a1G71QNze}VSq$Qppu|GNL};;^{U*RH?Q zqqQjUO|b=nR#!<7=2kozanfUKdRjlAKd;yl@KDkTn=#@h_wYZT{e01tTZZ>-{2v?b zf^QBU9gW-bSOC(v0q@skY%4)jc2T)fznn^sy#Rm0|&fE7=>0~Tg23x$A^g#1ZB10&tS&v{x!*I4tWGo|% zr5c5nbeLOxFz{+nHy)PSr!8+Ol{ub z;veFxRJQd5m3uPpqCn=t`M|~W-u8ttn?_llx6;3U+z$L0uQ!b)k&d23dN56l1JLuE z+}k!LCMXGoc*=~i2;rs20%Ka(^lG93rg=}CJkiSeVYW~7NKlC(v@}j*s1kZSU76QE zl0D)%eB4jph68-p^wYy-#+6#%^H8s&=|o50JI^t#ad3|0g(HN4ugM)eTO|*`J**n} z15rR|pi;kZT4G?QB2Gan`|e^0i=TTe$NH7 zZYCS;(F66TsmMV#kBNP^eF2M%YNXSi_t3mei)YF8RFYFOTJ*tTkqGrZfhBWU6RnZ- zEaV_77%9SN%RF(gRXvH4!`GhuHKmuPm-kb<`fYC2;Tw(6=?F5Hd}& zdB~W~I@6rYk^K(V2^}m*%Ad#ZE(aIPKTgv%a_fY?hc%)vsSwD!i*Vw}Y*a7IzG*XI z31Xy=B7Hy!(gMJY0wK@A*{YR+L3{!hP<1Z&QvCU^x{;Nt#g6dN*hsO2 zwZEH?;Dnan;o&rOs*?CVz=xfS0@^5uGT~FGetz6 zeL83m`(w-Ps)~LSEs^r=m<1wJ0-6iGbCqtm+7r?%LCkjyd2iB&hB9g!_{b-_An>He z$b06Z12rH4dNa%TQM49ZlIW2E435T@~ z@S~#aT22$*D9+jiry=IA_KZF@uKYemq`A$`tlZq5zmC~MBkvYY^k_!+g;2MU#>TRd zoN&YgENU&Dw|7g7s3EdH^R|_@4cp;LwC}g1Ie*uh3rCL>bC9Fa+o9TED=nGFJPRYI>359mM8HFs-uN zoQJ-^^s?jIm!Q-6V0I91HEqwKb>%>9$vgtIOM-1L9?;}#D z&v={n!Wow|?F;yeHJYrg#iEuq5hABWl^9E!7OM@S8Sdj_Ute~!bZaY#Z4WjR!US2g zue|7FBNV#R4h~7*bx6->gS-XUAh#DhEGSN7Z1?Sew$EQI6*(eCCFM%mI*yyo9TdNB zqe`>rL1sH*4G`P1)sID&)S?uC0;9W~TUzYeU~`Kl{!XmWFb>uD1PXMl^mChH(#TEo zxYv8H+I`%U_UAIx98G&M#W-4K+@7dZaI_O6mVvS-vbeHFs*)Uu9@gCd${%=F(LpRM ze3}^chJ{(4{gKj0zG3Ihhs)!OvNUOVc7k*Ro-0|-Yxcf#d&*!zaAnn`=)O&@@@h&b zNavT2XBUi_@w9&ZArq)NSm-lk19Cd9J-Q_oloPL|$E1`dSTY_^%2qS`ri9P^D`ia= zrIq`hw9R3t5)t(GdfvzdW8ZISrTrs&{POwzw99&q{Bg&jSLTEWlqOzuQegLNpz ziYKE3pp5_I)k3kG(nb82FpQii}Ka(YP&b= z#SQvj*i0Q+i?5AX$zC|HJQJ^(vW9x8IzS-#3X@B#UNl$<-+-0Q$Ol#$kOGGi2yhjJ zwaQW-x1NZ#T$m%$VD8mx1tV60UQLykTTtzfyR!(nHk9d*H=-@@SbsLG{5-d_Gm6mR z#c9WKB)@L!my2H|AJ-t9s3ab@!5xG3kvA@o2Vp#GF{)+p!vkH8x7la2g zPirHCF5ha$4iLhUzmA;({~=Cj5Q{F@c&f};3ANDyMb9J&mDl+Q^dBs?BZW)t!NDeD zq0OMj>P^-|kU#X!oywv&E6Y~bmsEK_sgx9aTaJ$2T)|}q1tZN$D?awi|HE(K>vB=y z9=4a9{UK6QMfgzXu!-ZAQqb0t;Lqzax11LqV_2bPrDsRfpR}d%&D`dqLB2QDRTDGY z#3EYZRAR4`dV9aV<3m=Icc(BOQ%m064BWldI=V{NjZw(DD9@b`eXF0%~D$DT8I34PHzga;f^fb)Re>ax-s}{ zPgP3KXqp2#A_5#aXYbKy^`g#f>-{q{I&qtJ48Z7|GJN-FHBNrfn14`~ zOpf#H)#G4v?&P}K7_rG$@kZl#IEUEhPJ%p3=t6h3UFay@q20oHt@ju69I>+9O2v#$ z@=Zn+tO9vV26#hLNU{w@XEMZ`uVs;NzdT3Xn@tbx7JKG9bn^b$_duLvm90v^bBkV$ zI9s+C-H2#=wn(vTuk~4^dC2T(dXK+R6j>@T4c!iRoAc3!e6>R?Hl!DA9Ax!=yjhSo zvZLC<@{(`b!p~4Y1s9V>7Qv0Y@ow^EJa_-zSa3AdoK-h)`{H zhVLM4a&czMN+524`#5HEJejvpc1}E=o&D&}ESp1|oT@d5FHJPNHzz#*qt%fhsN;RM z+RXNAL5R*)@2EyUEsy2b5gct>Puw*3WxUC}jd9k!bC11gi&2XFJ61qJwPmV$*LAAA zm%U5Ow%T`wq;X+%#Cy;3hD1x}6>XI3ty7ANh7`;o8hcjDo``CVzD-lh>izTPi>~eD z^LUO4LpONU>I9OM!&Gjt8B|)ocj??3NXBos*5b8W)wO=J+S_t{Tmg>o{^?CAmz#Zu zGgrQ!rfYG1*Li2G-Phz1nbVzcD||gX>pY!Hmb>q}P9Z zBbQa`a0coUBbSFWg~Nz#2sbL~cB37iL=0c#`f~#>zBa|~QKemT)>M()fkA!v{PTvH zuDL-wGJEN!h>T_(U~~1gv>tKUtysavMr$VLujek(-N)0CMJkKaBOa81T`VT1rgvAc+-;r|wOS6(C+;;F+5VI&Zus@K-l|`?$((*<&Sf3E8PcD?z>#*D#F0CG z^jz5Yy4@a8b$$CL<)b1LpIZGyhvYc@F252{IaKpv#^F=*woQJTMc&VgL0DFO%H%mN zjpxqDtov7~=oK|PjaAbVn)1#GM*@K% zH^}o8rT=M;9lw@*HCH-x6sIKhLlk=rbey3icGrs^V(!cr#5?^D2jqiz(-y%5JKLuw>puSHOPViyJA3tT z9en;CGUjC5YqQQU*izrL z;;-XS;N>$Dgx)Q(+^MtP{KgqlbfT%Nb@w@9%3vexU)sy6Bd?fjz9Q?+GYa!|S0 zBM0j^qnm5l5}Irh`-zK0cTI}}N-ZEvk*0idShPvwF|G@o2$hZ^{P&Tx>&uRRBWc8c zk@Td)d&rBH@U***r1s4A~Ej$HyG39}^9R zhZ{9@VMm9G`Q9a#`*#;AzEPwtbp=NyRi}K&ToLpPhe(=diokJgi`~)u8;$&Y5vQU3 zcBg%PuHvB-#e|$k7mqilU`LN*k{WlDYLLe3UQ+waolP2fA8mwXFK*qM0&*?VXW*^h?*MFF%w;yT^ zriq^SSf4wA?_alcZFZ(yOlE3g<*ER_^ys$a*C3FdSb^*&LkSUX)80cS#YXpZ35doYhHYd;LQ9)G`ic7+R&po7Yt+R-;eO8r~oh`XA z2Df4GbQ+(pt_|S)#ns@qODN^Wy@WUR+zcfG*3J-qBNm^v&HPajH&paq9ayWr zuyeV`%X`_B(YK*4{W>(`hLifx&vaC9yI9}L;)A+fm^07wQ1|gOQO!f<+`hYRTCcN~ z(JQg9&Xn)$Bnc9M6-hgBAEf?aT1TG6s!+1~SFKhHRiNL`C2L_i7jVk|HsVfZWr}Fh z%(Ufo@KTYmpkeC6$;wZVv(@v-jAc!>3=34#>hAo9chFCg{%ChO` zckS0u5gs|e1$pix&zp|q4OBz3n3tbHD~g+rm^%ecL5d0`^Z=UXg zwL6$inB@jUG{{cm(aaDq>RaHyn?O~;rbb(hOiIU-W76bN9KeT*Yz)JvNEL#8h~pb4Jl z3Kl@@GgxpsE4-wsi1d37dtp?4Z6Necx@jv+?`)7rUebKpF~yu;r>iQW1LjB}yGCW| z_Lu)mhFd%CeNCiO)Up`FQSV)?SgqFMk{Z4CLthpV1H4{r3kSRBWVy`!rSH!El3_$L zO;k$KU~t(9{#@+oQqmDiJF4f%t7BqNn9ZD>sP774VYlHgGH{hmm%VZ-7V6VegzdkmTOQ?{;%Qu!rDGi%pC%qb?8AFAXgn!pWj=o0Q^0}Y3T3wzDWb4Hewr_qA z(xK1k9OzQ}t#lO->HQjZw7)0=jJUIDt56RLT1RPm3~XhL*E(S!YGAF) z%fyhi7&#BrH3_bPp-v`Wyj-e9bRaZ5Rm*p>(Tg$TZs(C0RcgrOB7ac#vId@)tY}R8W{r z9f~_-fRK)3cZvzrG77MNNTfBmHOp9U&_q_h_Cz`1l|N4%Q&12+ma*B>wKp)zrfuMU zb*nF4)#NiV^^$|<(cwEHWjBDN&r&Vol?VTE(7Dv_YFH-hxm>ROQ z5S0l(KW0BeX#G$zyYDmGBPo@%}t-Dq7qzy6$nD<-7g5;+Kkj=#u`wMea5(#=-kJ5Nbp7tIjbGN_$*v5l5bbR5bCg z55htFmB8H?Ch=UK%4w=kYMoZv?zwd(FdIX0USG3&^pC5^ z*T^H&>N>#ml)%bK#tc1>;Dawohi5r6*Cv{ieDFcbRi3KhQFaB(d&3n6)~bg*uTxxQ zgC~(xo}y_?!?Gy2#-v%U01j#@Y<3x+#J!6Jb*VaG>(8A5duyN=Gn}YHK8+rMI2ESI zH&=m=&t+8eo_}AZiPc@pg2_X(vF#``W~|auT0qD|?MMR4>c=A>=58m!Xh_#-fDk|Q zbHsEy3s5~BmdFoFH5Ya6S!DG4kuwtUDMYcj+Q~-=@*$&Q2z_=}%Ve8v@}%%sVMp{S z%k^t~8x6&+Y>_051}y=QlAYh4 ziYz~_CM`GqcnPPW)T^Wb)||Ut;%wGmF@dfwNAyHCk~Ti-G6S#IPi>lORJ32Dr;W2~ z3B)Tk@gzN(PXD-Ezp$CZ|JDNE`@k>ZC3^Ujk;}(CZkrdVpy{o&crb0uq50ecS=&X= zx`OryfwW2&yJS`PF$K5Uy?L+YOxT-bPei1y#}5BTfPwL5BYkn(Rl0F!8$NByZ*}jT;jCy1KJs zZoNCI;N?foo1(;Q1CN{p;c#l8hrl_}&Rm47mmD89d765I>GA2=Q*k=KPeblgGaZM8?+=rAihi0i!NktB*-nYSky-uu1}tG> zXSF~h?uMv{zvjpV80YRM<%~(t9zBFp#ad(2snouGJzT&?z;E`w*QYjeK^vSqkH=;M z6R@lkvNaAZ62DkqgW1B8xw&W0v5WX0N>^$4TFG1K))Hzg`tSw?BU3F?kK5};1zQ{- zUX3EQ>I3S16#TcBsfzYvRqftx>6M_|TeJ}%oPxaNGwMA{Td{S;3R z+lnDvWzSpOtIzOG&s%`InM_UB`6(=Z%!S`VYt%K&cYX~^8(!!_snMPd^iLtw3|%IB z1Gz__!Ss0L!ADCW5*uSRBl#oMBkh;UyUUmMzaCTqhmBU_m&|(Gn2_^G%~c04Yaq>- z`L%|PNp|PHbCet3*m{s*vpXr=rpzt}Z6f7=bGmTiCiOpbf>CK${MdrZ>h;eK&FhJi z!jnUWg379;YVNkw5PESov(_lGu(VV-zpa|Nt~DX1KQb9ok7h1d*qK=_Tx}u)%1Ksb zsrM&<3m`z`>;TiK^fNhp0R$~e0(yK0dI2Lm$vCGI7}83+9hlup)A0)Bmz2>_2=k`e zDr{W;F7H0svYy3dZAAq%+>&vq<$i zyd7vvMtan31V$UGe2b%5?zDC*mnK?_ZCa$GvIbg<{hezt$ez}Mp=4vmAZCyVW|+zi z2F`!#h&q6+C33ZtYu<_K?=!=dRfT_J3Pkgi}>a&iA1_<6>2y_W;*Euxyy zkv);foduhy@yMygM9aCD>Y<<|ou<8CnQ4HBb`ffm277nGOJ)7b;s?37z?_KEOS}?# zLsvNJC|FqKt;h!_S=gLwYpW==?rl}0v7i!w0Ul-WdTZOdd3R6`h)!0=&0T5MXOo%6Wu}41 zLduBESS&)pAo)SLxqVvRfTXxEF>|)OYK0&NCHd*)$ z$v;hP=yXdOmh6pX1ylm4l`Gq%$<2Fo^;i(Q5O#a_R9p59!ZR;*N-U=7Ua&zcO*1e= zT7pEo10y<31o8(_fzTZzJIYsPWy)lknaCC`2ADcb&y%P_!T%$~9sVuEp-rQ`ZahNb z33<6xkuhQf8?Wi-;2`}9XYk}?Q1oOk|An#iu1%_)+SW^HyGpUs_%`kt;?t>mb%O7B zru}^Wz`)rEe)AnZ|1Fk#N6&83C74Eb29luNrOx*0C$)a^)vx&;oUax-!9K~ih*rL* znQ-=IG8)zWsY$q_EJkvlCaDab-ZN5?!sWJ>MEr~)rr681XhD^_bxBp7_1z1&g^jm_ z1 z?hG+D@gzn@mkr+r292K5JIV57_=!6OIyIPR^xpxyQJ{hX+i?O&Ol zw~({@>Ql0qsRegZ(*(MY+$L=md6HFoAL`mYM+I%Foq;*XNtR}DuyjgnUrbb_+jc9< zdM1d~5RqF>5J`@UF1_aqOG^FGcO)u@rl#fef0_z&nUC%sc$DsHew12kN;$!}*^!;n zBfsn5D(-ft?TF1$`wtLnTogeaGE+!bJCT9O79ltYN*baoHnn2WRPUf5q z(}3EDwpkz{kzFUOxi$Uf=fWSNJpAcfcPOqR?Y&EmsoqmDe$Q*dkx09b9Xw#i_8H5Q zAsp@w?+AG+(TQEwPHl<(@976rbPjxRJUolFA1bXOySEwis6aBni<;;4t+xs)`wKjv z+T1q&<|xWoC}SCPw9;(zGbb+x{xn|su1?dGhL?dwd&6p2VI2vGUc$vyJIFk^#>N*@ zkJnZ;DWtMWQjT)ikc!`INyV*<=dQ}iutL5Vg$Tajhms{O55L0DjjR1#CftUQqs8@S zIREXaOyj-+789giIlbtX>1`xwJo(6PD>lGmcqozk^cCj)&gIB0qGM^ogjAoWYwPA- z@aMrX)oK~NMrYl8)q%ERk`Ne2Mmc>!0SebR)~wM&buw|Pm_k?MK-G7YOX-?Jmb{}z z!G3vXM=ycBqybG*U;_Zwyz%acp8I@JHdT1+6KZF{zHQ|<_cf2IsdfXxa}TK7(|Yfr z7!#<4TgAK6Hg~X*cHO$?ldLytMEdo*-LeGKf_JMH+ydTgw8vs^sw4YHOos#aeEAtt za>CxOY4~lC2y23Ev1`=432p^3-2lTPc6R>#s!G294AF(PjQ^bw+7(q99b#B)N- z-w6Uv5_M7#oBtM^2sCe^S~SkHZP+g?ItE(EI*_w)Cnn}ciNwC9=dYpoEBuiriCu5e zF}t6H1q~20XYHoy!L2RFgSJ}ForPV;^!VaSEc?e{MDY3no4Up7ENEF3N2D*a*oHx? zF5>)D>CPsj$t)C=oa|jS1GIqM!M5U|-CPiEhP08#-*gKK`r%A1#qbLGOax32SQiE- zw;@%@w8Va!Nt-oa9B8M$g1^fxd9L%`_DG|rV1|*4q1O>*1z~TENRIN`(^qs;Yh~=m z)-$$b@=_Y*5jQRTY=2cz3EEy`-i=P>gJEt(W)(zLp#D; z+ymfXdv}&(E6WY}UnAqoMfN=0w|i>#DsP9u6@W6lpz{G}bV72{W+%rof=4w6=X^7n zsEwOX_nQpp@@Xo)(zb5mG2~>P#%NuTAB~9zx^#zNN|HD}oX*1R4&h@4u4FgvZYm{8 zK!W%ByWndF+rwF3;>lmH<+`9Zs@tXrqcpU98Qw0NmS@7kcBR_gCs^&6vq(tPsWp`Q z0?LM9cz2Tvq`wSDB->DHyzU5C6fPEuoOruO9#+$}QCWgFRo9hMM#8V9id2hLOICZI zN%Zf4cZw_Fx3ez?lv_BFl2}fvj1N4PzNdi-Qe#kQQ4PnZDznPllDruoAu$iU@n=Mw z&z=FJ&lKVhP>U{a00JhYX)$inOlEWIqg`y5+-*@Mw_@W<&BC2i5uLP2KS0KiXa;Nk z`!~L!L%#V<{)I-!512P`IQR_{;2oq&Eh_v93>1q>3m(c0x&ZbzMXs&2#gvksACs7o z-K+r4Myau6*d3DJjk-qPKyv1VM2UuV<#6sDoJ4Sjz(+YXEr~9}9P*b;2TGRe+B2Xr z5kb84Rbp!H@UvAi&>%u2oRty6q(j9tKaBXNFRii_3v&uVZt;4aH*bpLxYD^fXUdi7 zW}*1TR$QNl9ULtsPo;{S6Z50#xTH!1tpd}cwPh$WQV!uIuI7k=~BWq zbu`*J0Qe(3(zi8;6DxIDb`-&EJPHVKprNG7i>yGUu8Z!AG{(f9VrGC(%j``_WmiHp z#z#QkhxzoFUcroS)AoFq=HBJxiLt3ydm|;SIehCHsP#=Umza*k`kKC-|0ah^-TE~!Ichm6=-xfr*9ogNjDyPiRQUvU={j z1-UuidgLn(v@6EHxtANY|FxlC!`M9k*=y96ha~0o$?2Gas<+%fJG8zvM7vouY}i_j z)=oJG3oy68h4UJ`yX0(oBEdkmQ)lY-6u=_Ti?5wNkJvZ)C9Vx_18gH5jt!b3sBAhX zTc_m&3|*2VmMwoGKeG)pOl{)ZWywg@b ztg%ML*GTFz1w}x33y-;ZT@Eji1wYlRz(&v7wQ4JlWgM&W<&U4JQL^?@;u-GYKtDkP8@xoK~8CAX5|pNRCkh>&E%oWpy}+pZltoB>=pzyf!ZN z?cNk{FBYY^C)Yc~_wBBVR8WDngRJ;gkCGcCkl43bLg&2s2#pg!&!n;Cf~ApfM&n;Y zN(>1H%oOSx%^QGJ#+}iEY#nmuTEryjG<}A|4;zy~*^>sob;t)lm}fE)@`FN(MBbL@`{Vi zkTVEhnY*1&7GE!hH@X#;?*P8Zk3!1Ev{&dv^amE?Jk^G-(}XemTp!&)egP; zdG$*M1O70)6DcESKDGuTT~pfLnai{0>`-$gU42UOu;rW8%fF)wISSb#ixngz__cLL zytW@{+?<+PUjc7$kgGXty0o-GLJuBR7<61- z)Y_*lF(#ce(uCXQvClRTQcP|5En`r=sUh1%+3#L?EL=jlLHio$o9z;Ed&WY9slv3Q z^vDHkMmwhM$h)>bI%rOsxP51K&bLoF>sDg`ofJ-aT0?L)@3*4+#eUX~7t)Lt1*>j4 zc7l7TVo%I%Q0FN~A-f|~7;qdeNpYg;XFv)x^%#)E zG<+W^<_Pahisi9k%erL}?N%UEnn?s&AJXmwE*lF#le^5kaVDJw`?n2&=1mT~4_bq-^a*`q?Re^#ncHQ7@+@`{Pr?6Zc2qdDzJhBZvIt-+OmR6Uunw zZ7glgds{b+hS`BKXm&okSPU&8y8qjXeOMBGxuIf{^V+sk@!b++Di!X*u($1%Eo<6i`LcX>%58Cd!7}c-pTuN^Fuap#b|nT* z*6*k$3*u;fPLy-ve5!vbS_-!Ai*~3M&5MlZwe2rPHCnCDSX}gM+s^Mv=`$)u6N1n5 zO5^hcT^^UFZ+TIUoYC>p;*PX@`3~2ptcp5&$VnyO^m;I$o1)P1R0z*`9-+%7dkQph+dmV@88|ajqM&+mOHPPupkm~BBOkC z=JIKj^JO`)rR&a#CZ^p-K-nL)ZClbm%U+<#qZwev$$_j-pR~J|JDu(+G;a+EhS=1$ zU&nUn?|CV1NZIHJXRXh9jj8R1DA1iVKUC6{GlBYYUnAhtja$*SboZ+!N!s-L3$5{L zi60!dqwR%LX#_t9!wVIwyx~lzt;KU^7i$q2DIZ={UZ`&ja&d|qee=mEs*T_`Tv{ql znN-Wp#;h%&YPQz~1cM6Pv%X;yG%|<$)tyTQS+YOdlwAe9NRe|u2LFOyHRWc9K%!gy zW+x$cj5d(ffOS~~gTSp7wyAQ~F#9NP z#zG7lohJ&CV961_Ch(_M046UjPqO@^yC&t4&f&-8^Q%F*H#YSnMk>kaH^&mgJ_@NO1|U3|K;x6Z|>JPxbQ9HMGwg zb(?#{Z|H}C=GZZ?_XSg2b$GZ%!!)FV9i`?sPret(Ot^sLZin4W=pc8C2o&%7GfHcs zUPk8-0c6?mG~*odLf~S20oO1eZ4}CMhFc&fV1YO~VuF63yi|Y90e}u>Du9?Qw|BUT5?4+2iDbZ00lz)im9nI;k-i8z|h9 zWC;aje9YW_CQ)z!ib(}y7vSP?APc8FTcW&S<4!*uZ>3MyJle3O*1V@7ptBM-iF_-g z8GFZG&6YO(;24Ov(O;6!&b+x2@huf#dmIFaCcM4y~k$x(VQmn^C+f_!m$cM4g$ zu$rl3?>GBe!D&cLF5k5VFR1}5rjE8@+Q~c@{9B?ZZZscnj|5e^Im>HP7FV|! zffJ0c2L1NQOqrmKDvA7?#}&%lVX^XyFHWifaNmcNPYckwc?eQhZo&g%v9(h{Y2p>B zS$(*k2FYKl!CzdG^(0qKs0NVsFSv_2TR;BVHpdK}!aMam6^q#KVpw-v?|B2;GG;Bd zif(Gj&Fm`J9ca#zf5}s2adY*77cF4i8zeJ2nH9yo)D|y-+R~L&Ha%ZPd3l^GM+^8SlCj$;~3@^DrvAy0au5>KIoW;1CPLyEIs{>)Kr!g%SNi`hMbc zKQl?_taH~l-vhk)u^}^)CLP^L!@e6GfuQNaY_(EqO2s`&cc3!&1UC>Qo<1r3rXU!A z3&A?#s+?6r;nQC(tqDX+n+`8>`Cen z-WX<;Emw58wMn`XmIPJsM0ZBXxpK%@fBGSx5%**-AgyGuK23a>1Er{c3G7X9@rwcR zCtuSF094-q#nNVBFq+a&93;tr6)?`rsGOD!Q`d(>MxFJ(9&dNx@WrU`EzXn9b{hiTorlo(;5x1 zKCXmpP!faEB(lW7?1yjn`FOp%9+966w#d+&ei+I_7wX&?23srWrqO0w+StOWdxbXg zrSd5H*N_k?4PGBua@}!4vTQe5$USCCq;6>iJ-m81iXM1HCt&zuPO0)3V{+_zLP1tw z39h<9N}p-3cwwUVgi0ts01t>tFUk$}%lxvD(a7a}Mb`n3AA^LHSOpuX!BpQiHLXHR zq^Or?P@6OYkr7nb)YP9Nf>q)zR;=iOFoW&W;^G6R#uf`a2vJ1Hxpu9_Sf9MvvZpUG`!;g;6lB8AOr_>u1m1v@s zwEm;>w+YUrpHqWE6femfO_!sEGAxbjXjw{dj+EVF^0o4jaDnU`P97% zwB{QKAVma_MBQc1fl1JLb>pOTx7v#&!+D@}sv?A|r9LUsEBFkn4 z0C1jFC_k$|GnwsgR!OY3_*~}o0f?cd1SF>=Z>nvTojWUZg17U0!P|<*?{~arP8Ae@ zz^*)x#PUttprqi|fWExBnr6D72Gk~AZuERMPjkHO^VT+cPoACH`pdWdISJy+n1R8w zS1=8O6(vSJJJUu6`D!zVLdR(YrBd{!qF$W#BQkbH0tnk0=uC(fb0a`Iq{*D&T&Dq9 z34I+qH9MP}fI0G7Fa`GRtlm6qy6xt1wGrQbKG0m za@XgH#SGPrPYBKX}Y@9@dtaf>Id!q&4B(H5IcIZmfohhv!dnGMHi{)m!U~i|L zp`774w0t_?w_*Y@>p3@W@{{1|!R@EVRFz?BjqWcGpZa9wenW~`N1s~`X()NVKM}u0 zY+$1zSD}royRoWJ0b3C=B0TRIYnEOO!NW6c?Og@2E~n?iGuHm)5Jvj?-f=$5R$RaQ ziTkL|$f~{oo3(pg)yWLpOP--X6)+76WR$pvP>WTq&8$0PM zE}nK2>^iz~h2-ul9cG;5F;2201sKdAH@aBWX@v3KVn|~MNWUtU_u?ea&U*zm;W+m| zx(h|pb6nCcYKqxO8l0*FW@Z2HSvhmuEp7nJ{8)Gt2%X9{4X8Lk;)^TuV3W!AC}sCc28)N%kf#$lwLz|0ts}gBM{S1^k|z|a zc+vGmz=7E9+~mzGzmny?1!Lixb+alG{!b%s6+1$rd@2%6d*lkGUDMpYmX*W=je7sa zm6)a{ua<4o6p#OsPd>{&bz1$rr$#yfU~?ueErSH1AWQevYV(>m`&VV2T#~DCm+~O^ zu61Saok0k!>{Wr?n#Hux&mWc-crunWxOXpq18}8oR;M&uFziT*o#e!jfaR(+nAs4b z!`U^UhsBb3)q2|rx{O)y#O)CS8k(ARK6iDjro8dPcUI7NCru$sUkwWY?^*OjsaPd? zAq)U6r)WXx*A-W1kLS&5h)h1%x#bcA@p9Oug!Jo5NQleT`HBu3s+wX>Y1cOI&=Ej5 zp}r%35deCS_t};Rj*F##InuTUBd8oB5GU zqFB#&Be*S#@%-5^t>m*{ocKjB&J8!3)}`AxUxHl)QXx$kHcxy_8cZA@;u7C-(8zl? z0B>`hw>>hp+M%ufT<8_I^TE_MZfEeu%2)TPb>}(yGggS3oS>wwabI}j<2_G>mqoii zt33PM@9O^qckYhQawdK}X3W<#GkdPEcxZEpXY$dEKmccxThQ79vp8Rt`c+7i%krcg zWcZ#UhYiFjq{M#Qx^!SnA#3gW($XJrppcGTbW>9)^F0uHtWFvru0L;v%%t#qvO}$yFO0EVscnmK zR!aq^5eU}>#Ji7C$KH;w!$6wD1ojCX~~em-z`5J-i^9nL%b^S&l= zASrfR>;C@3zrHn8Z!BWhL90q!_4-)0K8I!A?0Y)WP1juDnbbRFwhzFLY%4FZg@%fr z0kcgT3}e{O+?DwGi1kLC!2N|tB^Lc|;c$D<=kkD;?1JNJ$)xrLl=ip0yVX3ceb3%q zj2F(^kV|>dUQ(%lTD9>tt;%<*TaI`K&Ml#jofhvEOsDxqxmj@TJ8*bCACM;L+e3O! z)V02;x{igqPt>8mJO_Ym(D4I@y>7j_26mNp^009D?BBMCRax`$-+Il0w(&k-G+uu= z+8k=7xScWuHM{B06>0a$Hw69-=eB6~oZ8uE&*sJexQhQ$QIM1Ki8Ja?e)<`h z=C40oyn-INGv@1@ChwJ#6G{PT*x&*WdkFy?;IYchVD?f>}mK@EW5)+wc7|BI6UG48*Kj5~PV z%S7(p)Boeoz1e};a6c0HyY>FZQq;YH#o}THfB2w(J&pf)PTl&zc`w|vQJp_+fxmy^ zt~Ib&Zy}lg>(Boo{on4Qe@OoyTldEU@z1XR`vd$B!}%}#=^uvk55xJFFKVtSDG5arF^dD>X??uBu z*6e>dB>z~mf3J)F8`KC(eC^Z&3f`vD3TS3XVt&H@MDmop0X?K3AqWrJ5`@06A5oG1w+WHvT z)UhoB$B)kfK}n;1C+humhCGh^B?(_muo@pLmvLD1k6Kz#Ol^dXdVQ~k#9 zDpdim`{z~sPN&&7>PH*iCL{GHQ)9kA27FCL(KD}$TOL08%bETZO49o>#EWtzkY@8B z{q08o``gqT0ns&>vjx|WJL5Z-KWY|g&Z%w9A#Ct+Q0Bgxlal6-vnFx^JFH=ENdJeM zKa8_`>lM8h9#_BpiN!(cM~VQ)0%)A|aI1Nv(zUwoM+*M1j8~uoS;4DRX^(Xarfsb7bb;1Pjptg7}>XK^p4Et%FGMW&A&m^nIee z&;vOI$k|j8|Jf^WV!h50#DPP|cRbY$fl{|_brp$q3y9Y&2N9z&Y&{I%Zptl zmjBq_Ui$A|z%xCixc_GLjwhdk11{=k^>5YFoLm~Wo80&94 z#N_(gU!SC(LLcpmYe)l*+cMe#&h`;YVX3ZgTG{>=f_i{AYrG@P{p zM!AJ1{tY$%*8D+VX))W!+A0|)zJB%sa+ zH~br*_$N>x^07Y&D47n2gWvjDTS6Ox(iB}a{bjJ+YU76A%1u^%8gz1^!r}c3sAeKR zd{L@v_6SO~(o^;iRK+VSYYBl|(+l*y{Qaf>apBF$Bk5tRxEF?~F(WrDW70Vy!TRv5 z5Y_H_Qv3Sn0R!~g0V9s;F@MIlG(u_H){pBeH$4NKWyY%sL7Pfv^ima7RH)N-b32|r z&gBH$q0%JPy-(OT-|7?Zek((|pEfa&1EdPLrhlt><-ddm^-F|o=1%Um0A(F5>=R7} z>h0R|p&@H(7M}-(!mJ-rQp1m)iUSAJ^Q4(|4)~&>*K<-Zyi}>8<6R5+kYN7@PcDpZ zgn=R+oBV-`F+&34PHb4PIaBy=mMM1d5b0s=14v2VYK*e|50%Z|JYyvnNMYqwnpQiz zN{9F_aU5s9lXS|Bj33~Kebxbi_mb0m7Gel?COrD76;3a!Hi!YsGN}^&)fRSJE4E{% z3hu?|FyyIpsJZA=j2sw}0eing?)M)J+4ICo>%)a}hxsy9SE&YhW>^?zV`IIiVOiR5 zg7t?zw2c5Z*4~===%2;G_YZX!7P^Mrwex2zU1;;yinfx{>uh?cal>%^v$X&E*ql)| z{l@lJSaV{)ON%5gV_MAOS58gT{qp9PA;;VAitN2<;{mWSZ(7spuP;SN#Ht}kU;1eN zK)#&#qs6czF<6o8);Br>;(&RW=82YzvbsqD@#;7BojvkGrS8c2I`i#a z6>?UKwg-pD8M(UmSffNw;u;3q5JaRMZ`|0R{mxy!aqD+SPMVePq*gg#DV?X7D-5mG zRot*u@MTiFABZ~EU!_1r-?OvYV<_b{JYza2lg?pL~surPIQw@%^)? zKp6?JWE7+m254OhmwIKY z9dSIlg-!-zwGV>8v54bV^w-ir&#b3oYI}6%mQCT!HJSDdiHRLhp>>~sc`)_EdU^mQ z+Jq&>Tmz^JGU4quZ#XQqByq*Bjk?V29(USc#R^JG1g|gRl)A>F4%X3hY*ZR@tXHNG4u6tp#l$Pe9*{n%a;yo`71h8M3X%tv|JcyFNR zqAL%PU_x0NzyJd|&kXV-g5_#F_~nB3bPFA@#5rQa@*TDfR*{9NdbjOL3DU$wGs%+W zRLm(kjQplne@~`Tzg+Vkx>J>`ucW4zty)>TEI{|)TqI`7y7(%LQ@d=cwp2}hs=l+P zF9%pp%E0~}E2qA+kGWZyZS12+ZY)eBnLWQcydlUmJ}u=Fn8$hl!1Mf!ApPw->|1kV z=!NTRQypl*-CJqF?@LZTK=Ld_JpomDH-2qT@1NVN;MBy8@*?R+6vIEz* z`QvL0gy0Ycfg6*dFOqbeKT|QOhaXFd&)#-XT>E^T&L@eoZipLw@?i>YgHd4Pm%L`< zKr{u~V2&$wX9Q_S%|l7$x#g1BLN~)x_>1~!al;)!`dL=1qRUdR4==QBXDY#xKzWFr zPaOjcafUkk-361ntQ0B7m9q6ZiM<->`|sXk-&W)v{LZ0;ud6>p#y_DX{J`#hS2DkG z#V<=|R>mMGld)fpmHg6rtKps6<*}>nz9f>jhD-r|AbbP$hFwUj0D@$gMU`O-RCnvv zyP-RF&mL??r`DyJl$cpm@np!+YBcgnmYi%2W9C;yP(2T_JEv=EukL;rr60zMLT=YE zCkr$Zi*^-Sy{GhSJ|`o-z`cBDX|-^$eW8Q z)_GkxpA==+k^I3DD{dV(&nJd0We;F@9|o?BSD^50S7Od(n*8q{=aA zA!Hp8J0^+>3t0>4C+6pK!6F~yJw>wgXgk}ngT__;%FwZOudj=6kB?408MHU};GL(P z!NVbo@ridwpv+x4r@r5W;p(6W>5ZK^pq#IHqMw$<^WKqM#Ev*l!dFp-GGbmuAtV-H zXcZ!>^qlPxR}E5?H)QyYuYx`o)2oK;EUPPbd&v_~s1zOrOK+6lXN zu+r=l?sJjID>h!$YgjS7hDMd72EL1jHQWDMchCxE(ju*Y#CALpWD|eWSxP)5HQ1Yh zUE>q{{^|6qpZsDi%s3+dcj~nKvxBm(z87qQ>L!hLQno3l6w20|4bRT8)C3CGoQUo< zJ`fqa+G4r7^Y#O$E3I>ikmF$-4J4nX;|1JC8!t!1aft;g?#?H7NH}r;O)6xHBgojU z2T1wlc0Jw!8fLAVkn{LD`?i9Bki|7wF4qHg(XPmMoURvg=gp#PYviE^l5@6)XC>{{ zwjJM(l)v@jw40MWP`}!0w=+`h4cVSEaO-xx09zs^e(QF%-LfqBDd4#BR7t1d7!0WD zev~&WMC}^${rZ;O@q)uEOCxTZ6P`; z*JzksiMoB}jl8^aZnt5k2a7agub5o2tgbR9l|X8cm#^fvJ=d{uIEib`v3|It)a09d z?kIQeO~b-cq{Cd3#l7ZBD99K-0n6Rd%s}D?icuH~V|$2>Zq%1A{o!qXJuh;^-d_L1 z!hThH_^=l`QTVIkca`GDm$K#Hj{5j_vpXpTU(PsxovA@nK z$lAJjEQ`e1@zu_r-4-qh^swJiv7JugBS!r?Jaev!YpO1>YmL_W$!Ha(u!F8VY_N3Y zgI0&9a-4k&A4VFEqzwx*iSjJX4~0RL*1YZQ#el9GY9A?bTwItMqwpiO>seitMEqNx7m(7pXEGYjM8c3Px* z11M5`1L;|iw*`A6={5WOCmK}wBJcN$lL*4E{sYfU(Ilbm42yP&!LoF0XS9A@OJrFXgL0XF}TlzIX zzw>TaZS_~hVk$tw&>#En&lmbe31;@a$+YC~6}{ zNe8d!wP;2(HeMeCnIpj?HK@XEvZX~V*VAH3Ua#bnsa2nJfAWBjZMS1MEP9V$;85(()$MxhuE%| zbVOYp`E(js?r#?CDT@7$lvloQy0xsBUlCT>?FK2vqXM{2AI|sXDgi!u!5Z%tdi(BH z=|`)B6duZYcooXnR~bk9#3Wnqy_fcAoo&RIeHB`x#cdBS^~gi+ZcoR^<*lkb^A6kG zJSip|K%)o|yf4*G{J|H6t<_&Gyiwc7{U7`5k29*T7YcOQHW3ee|C_K#m*G;8!NkCT z9iqp;Q?RzVV(&KVf=zH?#azkzr}uOd3-#54)a~_kS-n*P@?&_9Aysir3NAzaJITYP zdNs@)o3;F`CjWvtsYhI|U$1$HG#9ISS#NKv?FQ*K;2OpEX)O#lTN%$PiZoRozR)J4 z@oKh?lxG_4{_gD)ps%?E`ImUy(t;wszHJB8CKtTr4qmLlaBCrL?;cU?pnlr zU!G-+j(U;*F0U9&WK$%fE=gKc=Qsfd&6BZRWN_QioiWV$sYbJ~<;~@ZAAJ*uZ$NdMvP{)vdiME4(;%h&88VaJ`DNXq4rztSv0_zNy-qz>f>b>)-Bd0nH zbe6`Nz@^23&=$?;J5y1v-rg!}MTc1v@qAfEVOhuc9oSB1)Sq-+wKz@s<=#}gp0dl@ ziw7;oEx9?%!Vx@)hfL8>0>%|mzf80#h?r4HArIql{M9xkvwdjen3A>_Epxg{-!E6& z2c5{|<-<_^vG&KKap8@wV+{r5WxaG+K3QR?d^kd2JbQ%j#w19rDc`x+C8Xk3L#j6Il6b#4= zTW9-o|D3hz>tlYo_vCfd8r<33kn@UWbMWrKM%#{1j99uHNe^hUr~NeIXz87F@4gFd zmiylRiBoaIjQX38)@=${E74>_*%?qDRCyT-doo`NOTcsYq!HFncO1%I(D6d z_@$$NW;3LKQ|yXeLW?D?LCnqVy;;`UV#U3~CH_5qNibPiQ&|JC8xO<|&RyY%eeeL* z7hC2MKu-h}yl&B)Zknu}64uw}?y2A6iS^h@@P_C^YM{C4*#DoUX}i`)5hGHXO|EwveRH~aI`T~$+4e&3M9?XSZ!knU{V6{lrPQ=wglKE1a*MAxKV zAY}2SR~w63Ld|Y6FH|SMXIXzq$?I*^$iiJw5F&hAW3DMV=nS@bJ8hw#Bv^aJbplg* zIC(>lREJPrZI*hciti1f7^kLs0R3zJ225T85dfn;E(T2P?&O0@Bk~ z*Pfdu^jVbiITsT{oLVNm<^m?NL2ViHFuWgMZRD__Kuidd373ZA^47V=-(&Y@(+F zuCN4X{p>SQ@48VT8}KS0*TREeLcPAc+T{}Wy|znv&$8M$^6TqNz#1+fX{5Jw2nNYx zW9*W(L_?;S%;qX*QWT(Fr3jv_IJ{p2-yz6cNy_;!VnmvwGpHQ``fzUL#G7}@&;4e; zq?AzP$}dg5q&8F%tO||kH4Uq=IE^j!y@-kph^-D4i|NcX9yjtMV*lUreg|rWFXno^ zYo6`t*+GSyD|g;nv}fbe(v7*t`;L8CEMH^3_sgYQIil+d@8m{rU-tg~r?pqMEMNI^ z#`^vGzxzMEn{xj9+WMc*znnV#`qTM>{_^DS>tcV-tysHL>efH!clu1(iQ>t?9{=Tq z*JHl*I>hhX6frNR=8AsYgm?QsfBW<9=&pCJ8G7%Me{Mc~>F;-7$7HMZlN$HWr>uV< zT3r{qnBM;4k%;=4|3A#8-x)rtgI>VbFJXFXUFPxkH@}bdw*2#o3zHK&!ny_DSZ(?H z@Zz_(S9klry0p~$)|SHLjrp26C0l-OTwA`;|9R5<-q-P-zq=Z)Uv%5j_$G$sK+>&u zch}42zVf^)rmN?#&6HliX{U7srkKWtcmW9uD4nMx@{lsUkvrpF@ zHC+7b);8x`F>;ynx9_rxvUU^Q;_E7XEV$*chJEFw7L%kO8?J26zb{;9^&C-K!1_=bVmJ0w z7Ds*k!@Y7}q9)q<4u~SZCWqa2%x!WOoX>MVP64*{FS%~k6M2#qc-#xoi-lx?1D(Ph z3D@`h|R839bq}pVHw7a>jV$C&)u=ROby-L42{V`AIxVb zCmD4j7yD386@v8YUESGt+qhH#UF(5DVW7^(ZZ93+E=4fmdzs~n*tZS~dCa%~ ziX6Bd0n%ZXfA5c3T3I&2BxnW;4nA-{$M5X(XRDCcdO+hTw$V)Z1t=<)uUn*zQFHF` zW&LyZS?;fdyO`@x9A=Axg6CJ;(v$xmZ$7(ET@SXD0_NHu$|4>6uO7LdgLQ7%Z;r!k z&XS|L=V$-l5OBS-`Wt4%TP$*D+4%@}+{VslbmpIPBY5A(n`-{ECb;p)Py6-l?eAlg z&te9YMIMvjlPJVh`s}35!srPRk?K&=Qr~`{`j6(NF6b!;MHQlh>qX7mTN!}B)78&qol`;+0ICA(NB{r; literal 0 HcmV?d00001 diff --git a/start-here.mdx b/start-here.mdx new file mode 100644 index 00000000..b6bfb407 --- /dev/null +++ b/start-here.mdx @@ -0,0 +1,5 @@ +--- +title: "Start here" +--- + +Stub \ No newline at end of file diff --git a/ton/address.mdx b/ton/address.mdx deleted file mode 100644 index d144f0f9..00000000 --- a/ton/address.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Address" ---- - -Stub diff --git a/ton/addresses/address-formats.mdx b/ton/addresses/address-formats.mdx new file mode 100644 index 00000000..8fcfd88a --- /dev/null +++ b/ton/addresses/address-formats.mdx @@ -0,0 +1,132 @@ +--- +title: "Internal address formats" +--- + +Accordingly to [TEP 0002](https://github.com/ton-blockchain/TEPs/blob/master/text/0002-address.md#smart-contract-addresses) +there exist two internal address formats on TON Blockchain: +- **raw**; +- **user-friendly**. + +Every internal address can be represented in each of these formats. However, these representations are equivalent: refer to exactly one address, +although visually differ greatly from each other. + +## Raw format + +The raw format is the canonical, on-chain representation of the address of a smart contract. +It is this format that is used by developers of smart contracts in the manual creation +of messages and is inspired by the [corresponding TL-B schemes](https://github.com/ton-blockchain/ton/blob/cac968f77dfa5a14e63db40190bda549f0eaf746/crypto/block/block.tlb#L100-L110). + +### Structure + +In existent workchains, the raw format consists of two components separated by a colon: + +- `workchain_id`: a signed 32-bit integer identifying the workchain.
+Examples: `-1` for the MasterChain and `0` for the BaseChain. +- `account_id`: a 256-bit identifier that is derived from a smart contract `state_init`. + +Example: +`0:ca6e321c7cce9ecedf0a8ca2492ec8592494aa5fb5ce0387dff96ef6af982a3e` + +Uppercase letters (A–F) may be used in address strings instead of their lowercase counterparts (a-f). + +### Drawbacks + +Raw addresses lack built-in safety features, making them unsuitable for general use: + +- **No error detection**: the format includes no checksum. A single-character mistake can cause irreversible loss of funds. +- **No metadata**: for instance, each smart contract can be deployed on both Testnet and Mainnet, in which it will have the same address. +An attempt to send real funds to the Testnet variant will result in their loss. It is desirable to have a flag in the address that prevents users from such a mistake. + +## User-friendly format + +The main purpose of the user-friendly format is to help prevent users from accidentally losing their funds due to a small mistake +in the raw format or unwise use of the bounce flag and from having to manually compose a message when they interact with the +intended recipient through wallet applications (for instance, [Tonkeeper](https://tonkeeper.com/)). + +In fact, the user-friendly address format is a secure, base64-encoded (or base64url-encoded) wrapper around the raw format. It adds metadata +flags and a checksum to prevent common errors and provide greater control over message routing. + +**Nota bene: this format can be applied only to addresses that are described according to the `addr_std` TL-B scheme, see addresses [general info](https://companyname-a7d5b98e.mintlify.app/ton/addresses/addresses-general-info) subpage.** + +### Structure + +A user-friendly address is a 36-byte structure with the following components: + +1. Flags (1 byte): metadata that changes the handling of messages in the wallet application. `0x11` for sending bounceable messages, `0x51` for non-bounceable, add the `0x80` summand if that address should not be accepted by software running in Mainnet. +2. `workchain_id` (1 byte): an 8-bit signed integer. +3. `account_id` (32 bytes): the 256-bit ([big-endian](https://www.freecodecamp.org/news/what-is-endianness-big-endian-vs-little-endian/)) account identifier. +4. Checksum (2 bytes): a [CRC16-CCITT](https://github.com/ton-blockchain/ton-kotlin/blob/main/crypto/src/crc16.kt) checksum of the preceding 34 bytes. + +The checksum mechanism in user-friendly addresses is similar to the [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm), providing a first-line defense against input errors by validating format integrity upfront. + +### Flag definitions + +The first 8 bits of the user-friendly format encode the handling of messages, as defined in [TEP 0002](https://github.com/ton-blockchain/TEPs/blob/master/text/0002-address.md#smart-contract-addresses): + +| Address prefix | Binary form | Bounceable | Testnet-only | +|:--------------:|:-----------:|:----------:|:------------:| +| `E...` | `00010001` | Yes | No | +| `U...` | `01010001` | No | No | +| `k...` | `10010001` | Yes | Yes | +| `0...` | `11010001` | No | Yes | + +As we can see, there are 4 variants of the handling: +- send a **bounceable** message to a **Mainnet** address; +- send a **non-bounceable** message to a **Mainnet** address; +- send a **bounceable** message to a **Testnet** address; +- send a **non-bounceable** message to a **Testnet** address; + +### Encoding + +The 36-byte structure is encoded into a 48-character non-space string using either standard base64 (i.e., with digits, upper- and lowercase Latin letters, `/` and `+`) or URL-safe base64 (with `_` and `-` instead of `/` and `+`). Both encodings are valid and must be supported by applications. + +Examples: +- Bounceable: `EQDKbjIcfM6ezt8KjKJJLshZJJSqX7XOA4ff-W72r5gqPrHF` +- Non-bounceable: `UQDKbjIcfM6ezt8KjKJJLshZJJSqX7XOA4ff-W72r5gqPuwA` +- Bounceable-Testnet: `kQDKbjIcfM6ezt8KjKJJLshZJJSqX7XOA4ff-W72r5gqPgpP` +- Non-bounceable-Testnet: `0QDKbjIcfM6ezt8KjKJJLshZJJSqX7XOA4ff-W72r5gqPleK` + +**Nota bene: the same encoding is used for the so-called armored versions of [public keys](https://companyname-a7d5b98e.mintlify.app/techniques/security) and [ADNL addresses](https://companyname-a7d5b98e.mintlify.app/ton/network).** + +### Wallets applications + +At the moment, TON wallets work with addresses as follows: + +For receiving: + +- Wallets display the user's address in a user-friendly bounceable or non-bounceable form. + +When sending: + +0) A user sends a message with funds and, possibly, a comment to the destination's wallet address in one of the user-friendly formats through the wallet application. + +1) The wallet app checks the validity of the destination address representation - its length, valid characters, prefix and checksum. If the address is not valid, then an alert is shown and the sending operation is not performed. + +2) If the address has a testnet flag, and the wallet app works with the mainnet network, then an alert is shown and the sending operation is not performed. + +3) The wallet app retrieve from address bounceable flag. + +4) The wallet app check the destination address. If it has `unitialized` status, the app force set `bounce` field of sending message to `false` and ignore bounceable/non-bounceable flag from address representation. + +5) If destination is not `unitialized` then the wallet app uses the bounceable/non-bounceable flag from the address representation for the `bounce` field of sending message. + +### Custom address safety + +When developing custom solutions on TON Blockchain, it is critical to implement proper address handling logic. First, always verify whether the recipient address is initialized before sending funds to prevent unintended losses. + +For user-friendly format forms selection: use _bounceable_ addresses for user smart contracts with custom logic to ensure funds are returned if the contract is invalid, and _non-bounceable_ addresses for wallets to guarantee funds are credited even if the recipient is uninitialized. + +### Drawbacks + +- **Public key extraction**: it is impossible to extract the public key from the address, which is needed for some tasks (for example, +to send an encrypted message to this address). Thus, until the smart contract is deployed for this address, there is no way to get the public key on-chain. +- **UI**: most OS do not allow you to select an address with double click because of `_`, `-`, `/`, `+` base64 symbols. + +## Summary + +- **Raw format** is for system-level use and lack safety features. +- **User-friendly format** is for application-level use, include flags and a checksum. + +## Next steps +For more technical details, refer to: +- [Account statuses](/ton/statuses): how addresses evolve (active, frozen, etc.). diff --git a/ton/addresses/addresses-general-info.mdx b/ton/addresses/addresses-general-info.mdx new file mode 100644 index 00000000..5f0b2f93 --- /dev/null +++ b/ton/addresses/addresses-general-info.mdx @@ -0,0 +1,88 @@ +--- +title: "General information" +--- + +TON implements **Actor model**, where all entities, including wallets, are smart contracts. Each actor: + +- processes incoming messages; +- updates its internal state; +- generates outgoing messages. + +As a result, every actor must have a unique address to ensure the correct message routing. This section explains how these addresses are structured and why they are fundamental to the TON architecture. + +There are several types of addresses used in the TON blockchain. Here, we will focus on the two most important ones for developers: **internal** and **external**. + +For the so called **Intermediate** and **DNS** addresses see the [Hypercube Routing](/ton/hypercube-routing) and [DNS: .ton domains](/services/dns) pages respectively. + +## Internal addresses + +Each smart contract deployed on TON blockchain has this type of the address. Let's look at the corresponding TL-B schemes: +``` +addr_std$10 anycast:(Maybe Anycast) + workchain_id:int8 address:bits256 = MsgAddressInt; +addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) + workchain_id:int32 address:(bits addr_len) = MsgAddressInt. +``` +As we can see, there are two constructors: +- `addr_std`: standardized addresses with a fixed length that are suitable for [SHA256 encryption](https://en.wikipedia.org/wiki/SHA-2). Must be used whenever possible. +- `addr_var`: represents addresses in workchains with a _large_ `workchain_id`, or addresses with a length not equal to 256. Currently is not used and intended for future extensions. + +And four components: + +- `workchain_id`: the WorkChain id (signed 8- or 32-bit integer). +- `address`: an address of the account (64-512 bits, depending on the WorkChain). In order not to confuse this field with a whole address, it is usually called `account_id`. +- `addr_len`: a length of the non-standardized address. +- `anycast`: not currently used in the blockchain and is always replaced with a zero bit. It was designed to implement [Shard splitting](https://docs.ton.org/v3/documentation/smart-contracts/shards/shards-intro/) of _global_ (or _large_) accounts, but then was deprecated since [TVM 10](https://github.com/ton-blockchain/ton/blob/master/doc/GlobalVersions.md#anycast-addresses-and-address-rewrite). + +### WorkChain id + +TON Blockchain is actually a collection of blockchains, with WorkChain being one of them. TON supports up to `2^32` unique WorkChains, each with its own rules and even virtual machines. The 32-bit `workchain_id` prefix in smart contract addresses ensures interoperability, allowing contracts to send and receive messages across different WorkChains. + +Currently, two WorkChains are active: +- **MasterChain** (`workchain_id = -1`): contains general information about the TON blockchain protocol and the current values of its parameters, the set of validators and their stakes, the set of currently active workchains and their shards, and, most importantly, the set of hashes of the most recent blocks of all workchains and shard chains. +- **BaseChain** (`workchain_id = 0`): the default WorkChain for most operations. + +Both use **256-bit addresses** for accounts. + +### Account id + +In currently used WorkChains an account id is defined as the result of applying a hash function to a `state_init` structure that stores initial code and data of a smart contract. +``` +account_id = hash(initial_code, initial_data) +``` +So, for each pair (`initial_code`, `initial_data`), there exists a unique account id to which a smart contract with such code and data can be deployed (this logic may become more complex when [TVM 11](https://github.com/ton-blockchain/ton/blob/master/doc/GlobalVersions.md#version-11) is deployed on the main network.). + +**Nota bene: although the deployed smart contract code and data may change during its lifetime, the address where it's deployed does not change.** + +Additionally, a 64-bit prefix of an account id is crucial for sharding process and delivering messages from one shard to another during [Hypercube Routing](/ton/hypercube-routing). + +## External addresses + +External addresses are closely related to [External messages](http://localhost:3000/ton/transaction): ones that originates outside the blockchain or is intended for actors outside it. These messages enable interaction between smart contracts and the external world. + +Actually, external addresses are ignored by the TON Blockchain software altogether, but may be used by external software for its own purposes. + +The corresponding Tl-B schemes are as follows: +```tlb +addr_none$00 = MsgAddressExt; +addr_extern$01 len:(## 9) external_address:(bits len) + = MsgAddressExt. +``` +- `addr_none`: it is used as a stub for the source or destination field in incoming and outgoing external messages when there is no need to put any explanatory information for off-chain actors. It is also used as a stub for the source address of internal messages, since this field is always overwritten to the correct one by the validators. +- `addr_extern`: contains up to nine bits of additional information. For example, a special external service may inspect the destination address of all outbound external messages found in all blocks of the blockchain, and, if a special magic number is present in the `external_address` field, parse the remainder as an IP address and UDP port or a (TON Network) ADNL address, and send a datagram with a copy of the message to the network address thus obtained. + + +## Summary + +- **Every actor is a smart contract**, each with a unique address for message routing. +- **Main internal address fields**: + - `workchain_id` (32-bit): identifies the WorkChain. + - `account_id` (256-bit): a hash of the contract’s initial code and data. +- **Active WorkChains**: MasterChain and BaseChain, both using 256-bit ids. +- **Flexibility**: TON supports up to `2^32` WorkChains, allowing future chains to customize address lengths (64–512 bits). +- **External addresses**: may be used by external software for its own purposes but are ignored by the TON Blockchain software. + +## Next steps +For more technical details, refer to: +- [Internal address formats](/ton/addresses/address-formats): encoding rules and practical examples. +- [Account statuses](/ton/statuses): how addresses evolve (active, frozen, etc.). \ No newline at end of file diff --git a/ton/config.mdx b/ton/config.mdx index f9c5fcb0..5a40b3cf 100644 --- a/ton/config.mdx +++ b/ton/config.mdx @@ -2,7 +2,4 @@ title: "Node configuration" --- -- https://docs.ton.org/v3/documentation/smart-contracts/limits -- https://docs.ton.org/v3/documentation/network/configs/network-configs -- https://docs.ton.org/v3/documentation/network/configs/blockchain-configs -- https://docs.ton.org/v3/documentation/network/configs/config-params \ No newline at end of file +Stub \ No newline at end of file diff --git a/ton/states.mdx b/ton/statuses.mdx similarity index 100% rename from ton/states.mdx rename to ton/statuses.mdx diff --git a/ton/tbl.mdx b/ton/tbl.mdx new file mode 100644 index 00000000..2fdfe7fa --- /dev/null +++ b/ton/tbl.mdx @@ -0,0 +1,3282 @@ +--- +title: "Telegram Open Network (TON) Blockchain Specification" +sidebarTitle: "Telegram Open Network (TON) Blockchain" +--- + +**Nikolai Durov** +*February 8, 2020* + +## Abstract + +The aim of this text is to provide a detailed description of the Telegram Open Network (TON) Blockchain. + +## Introduction + +This document provides a detailed description of the TON Blockchain, including its precise block format, validity conditions, TON Virtual Machine (TVM) invocation details, smart-contract creation process, and cryptographic signatures. In this respect it is a continuation of the TON whitepaper (cf. [3](#3-messages%2C-message-descriptors%2C-and-queues)), so we freely use the terminology introduced in that document. + +Chapter 1 provides a general overview of the TON Blockchain and its design principles, with particular attention to the introduction of compatibility and validity conditions and the implementation of message delivery guarantees. More detailed information, such as the TL-B schemes that describe the serialization of all required data structures into trees or collections (“bags”) of cells, is provided in subsequent chapters, culminating in a complete description of the TON Blockchain (shardchain and masterchain) block layout in Chapter 5. + +A detailed description of the elliptic curve cryptography used for signing blocks and messages, also accessible through TVM primitives, is provided in Appendix A. TVM itself is described in a separate document (cf. [4](#4-accounts-and-transactions)). + +Some subjects have intentionally been left out of this document. One is the Byzantine Fault Tolerant (BFT) protocol used by the validators to determine the next block of the masterchain or a shardchain; that subject is left for a forthcoming document dedicated to the TON Network. + +And although this document describes the precise format of TON Blockchain blocks, and discusses the blockchain’s validity conditions and serialized invalidity proofs,[¹](#footnote-1) it provides no details about the network protocols used to propagate these blocks, block candidates, collated blocks, and invalidity proofs. + +Similarly, this document does not provide the complete source code of the masterchain smart contracts used to elect the validators, change the configurable parameters or get their current values, or punish the validators for their misbehavior, even though these smart contracts form an important part of the total blockchain state and of the masterchain block zero. Instead, this document describes the location of these smart contracts and their formal interfaces.[²](#footnote-2) The source code of these smart contracts will be provided separately as downloadable files with comments. + +Please note that the current version of this document describes a preliminary test version of the TON Blockchain; some minor details are likely to change prior to launch during the development, testing, and deployment phases. + +## 1. Overview +This chapter provides an overview of the main features and design principles of the TON Blockchain. More detail on each topic is provided in subsequent chapters. + +## 1.1 Everything is a bag of cells +All data in the blocks and state of the TON Blockchain is represented as a collection of cells (cf. [3.2.5](#3-2-5-augmented-hashmaps%2C-or-dictionaries). Therefore, this chapter begins with a general discussion of cells. + +### 1.1.1. TVM cells + +Recall that the TON Blockchain, as well as the TON Virtual Machine (TVM; cf. [4.3.1](#ref-4)), represents all permanently stored data as a collection or bag of so-called cells. Each cell consists of up to `1023` data bits and up to `4` references to other cells. + +Cyclic cell references are not allowed, so the cells are usually organized into trees of cells, or rather directed acyclic graphs (DAGs) of cells.[³](#footnote-3) Any value of an abstract algebraic (dependent) data type may be represented (serialized) as a tree of cells. + +The precise way of representing values of an abstract data type as a tree of cells is expressed by means of a TL-B scheme.[⁴](#footnote-4) A more thorough discussion of different kinds of cells may be found in [4.3.1](#4-3-1-reasons-for-omitting-data-from-a-transaction-description). + +### 1.1.2. Application to TON Blockchain blocks and state +The above is particularly applicable to the blocks and state of the TON Blockchain, which also are values of certain (quite convoluted) dependent algebraic data types. + +Therefore, they are serialized according to various TL-B schemes (which are gradually presented throughout this document), and are represented as a collection or bag of cells. + +### 1.1.3. The layout of a single cell + +Each single cell consists of up to `1023` data bits and up to `4` references to other cells. When a cell is kept in memory, its exact representation is implementation-dependent. However, there is a standard representation of cells, useful, for instance, for serializing cells for file storage or network transmission. This “standard representation” or “standard layout” `CellRepr(c)` of a cell `c` consists of the following: + +• Two descriptor bytes come first, sometimes denoted by `d₁` and `d₂`. The first of these bytes `d₁` equals (in the simplest case) the number of references `0 ≤ r ≤ 4` in the cell. The second descriptor byte `d₂` encodes the bit length `l` of the data part of the cell as follows: the first seven bits of `d₂` equal `⌊l/8⌋`, the number of complete data bytes present in the cell, while the last bit of `d₂` is the completion tag, equal to one if `l` is not divisible by eight. Therefore, + +```math +d₂ = 2⌊l/8⌋ + [l mod 8 ≠ 0] = ⌊l/8⌋ + ⌈l/8⌉ (1) +``` + +where `[A]` equals one when condition `A` is true, and zero otherwise. + +• Next, `⌈l/8⌉` data bytes follow. This means that the `l` data bits of the cell are split into groups of eight, and each group is interpreted as a big-endian 8-bit integer and stored into a byte. If `l` is not divisible by eight, a single binary one and a suitable number of binary zeroes (up to six) are appended to the data bits, and the completion tag (the least significant bit of the descriptor byte `d₂`) is set. + +• Finally, `r` references to other cells follow. Each reference is normally represented by `32` bytes containing the SHA-256 hash of the referenced cell, computed as explained below in [1.1.4](#1-1-4-the-sha256-hash-of-a-cell). + +In this way, the standard representation `CellRepr(c)` of a cell `c` with `l` data bits and `r` references is + +```math +2 + ⌊l/8⌋ + ⌈l/8⌉ + 32r bytes long. +``` + +### 1.1.4. The sha256 hash of a cell + +The `sha256` hash of a cell `c` is recursively defined as the `sha256` of the standard representation `CellRepr(c)` of the cell in question: + +```math +Hash(c) := sha256(c) := sha256(CellRepr(c)) (2) +``` + +Because cyclic cell references are not allowed (the relationships among all cells must constitute a directed acyclic graph, or DAG), the `sha256` hash of a cell is always well-defined. + +Furthermore, because `sha256` is tacitly assumed to be collision-resistant, we assume that all the cells that we encounter are completely determined by their hashes. + +In particular, the cell references of a cell `c` are completely determined by the hashes of the referenced cells, contained in the standard representation `CellRepr(c)`. + +### 1.1.5. Exotic cells + +Apart from the ordinary cells (also called simple or data cells) considered so far, cells of other types, called exotic cells, sometimes appear in the actual representations of TON Blockchain blocks and other data structures. + +Their representation is somewhat different; they are distinguished by having the first descriptor byte `d₁ ≥ 5` (cf. [4.3.1](#4-3-1-reasons-for-omitting-data-from-a-transaction-description)). + +### 1.1.6. External reference cells + +(External) reference cells, which contain the 32-byte `sha256(c)` of a “true” data cell `c` instead of the data cell itself, are one example of exotic cells. + +These cells can be used in the serialization of a bag of cells corresponding to a TON Blockchain block in order to refer to data cells absent in the serialization of the block itself, but assumed to be present somewhere else (e.g., in the previous state of the blockchain). + +### 1.1.7. Transparency of reference cells with respect to most operations + +Most cell operations do not observe any `reference cells` or other `exotic` kinds of cells; they see only `data cells`, with any reference cell transparently replaced by the cell referred to. For example, when the transparent cell hash `Hashᵇ(c)` is recursively computed, the hash of a reference cell is set to be equal to the hash of the cell referred to, not the hash of the standard representation of the reference cell. + +### 1.1.8. Transparent hash and representation hash of a cell + +In this way, `sha256ᵇ(c) = Hashᵇ(c)` is the **transparent hash** of a cell `c` (or the tree of cells rooted in `c`). + +However, sometimes we need to reason about the exact representation of a tree of cells present in a block. To this end, a **representation hash** `Hash♯(c)` is defined, which is not transparent with respect to reference cells and other exotic types of cells. We often say that the representation hash of `c` is *the* hash of `c`, because it is the most frequently used hash of a cell. + +### 1.1.9. Use of representation hashes for signatures + +Signatures are an excellent example of the application of representation hashes. For instance: + +* Validators sign the representation hash of a block, not just its transparent hash, because they need to certify that the block does contain the required data, not just some external references to them. +* When external messages are signed and sent by off-chain parties (e.g., human clients using an application to initiate blockchain transactions), if external references may be present in some of these messages, it is the representation hashes of the messages that must be signed. + +### 1.1.10. Higher hashes of a cell + +In addition to the transparent and representation hashes of a cell `c`, a sequence of higher hashes `Hashᵢ(c)`, `i = 1, 2, ...` may be defined, which eventually stabilizes at `Hash∞(c)`. (More detail may be found in [4.3.1](#ref-4).) + +--- + +## 1.2 Principal components of a block and the blockchain state + +This section briefly describes the principal components of a block and of the blockchain state, without delving too much into the details. + +### 1.2.1. The Infinite Sharding Paradigm (ISP) applied to blockchain block and state + +Recall that according to the Infinite Sharding Paradigm, each account can be considered as lying in its separate “accountchain”, and the (virtual) blocks of these accountchains are then grouped into shardchain blocks for efficiency purposes. + +Specifically, the state of a shardchain consists, roughly speaking, of the states of all its “accountchains” (i.e., of all accounts assigned to it); similarly, a block of a shardchain essentially consists of a collection of virtual “blocks” for some accounts assigned to the shardchain.[⁵](#footnote-5) + +We can summarize this as follows: + +```math +ShardState ≈ Hashmap(n, AccountState) (3) +``` + +```math +ShardBlock ≈ Hashmap(n, AccountBlock) (4) +``` + + +where n is the bit length of the `account_id`, and `Hashmapⁿ(X)` describes a partial map `2ⁿ → X` from bitstrings of length n into values of type X. + +Recall that each shardchain — or, more precisely, each shardchain block[⁶](#footnote-6) — corresponds to all accountchains that belong to the same “workchain” (i.e., have the same `workchain_id = w`) and have an `account_id` beginning with the same binary prefix `s`, so that `(w, s)` completely determines a shard. + +Therefore, the above hashmaps must contain only keys beginning with prefix `s`. + +We will see in a moment that the above description is only an approximation: the state and block of the shardchain need to contain some extra data that are not split according to the `account_id` as suggested by [(3)](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state). + +### 1.2.2. Split and non-split part of the shardchain block and state + +A shardchain block and its state may each be classified into two distinct parts. The parts with the ISP-dictated form of [(3)](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state) will be called the split parts of the block and its state, while the remainder will be called the non-split parts. + +### 1.2.3. Interaction with other blocks and the outside world. Global and local consistency conditions + +The non-split parts of the shardchain block and its state are mostly related to the interaction of this block with some other “neighboring” blocks. + +The global consistency conditions of the blockchain as a whole are reduced to internal consistency conditions of separate blocks by themselves as well as external local consistency conditions between certain blocks (cf. [1.3](#1-3-consistency-conditions)). + +Most of these local consistency conditions are related to message forwarding between different shardchains, transactions involving more than one shardchain, and message delivery guarantees. + +However, another group of local consistency conditions relates a block with its immediate antecessors and successors inside a shardchain; for instance, the initial state of a block usually must coincide with the final state of its immediate antecessor.[⁷](#footnote-7) + +### 1.2.4. Inbound and outbound messages of a block + +The most important components of the non-split part of a shardchain block are the following: + +* `InMsgDescr` — The description of all messages “imported” into this block (i.e., either processed by a transaction included in the block, or forwarded to an output queue, in the case of a transit message travelling along the path dictated by Hypercube Routing). +* `OutMsgDescr` — The description of all messages “exported” or “generated” by the block (i.e., either messages generated by a transaction included in the block, or transit messages with destination not belonging to the current shardchain, forwarded from `InMsgDescr`). + +### 1.2.5. Block header + +Another non-split component of a shardchain block is the block header, which contains general information such as `(w, s)` (i.e., the `workchain_id` and the common binary prefix of all `account_id`s assigned to the current shardchain), the block’s sequence number (defined to be the smallest non-negative integer larger than the sequence numbers of its predecessors), logical time, and generation `unixtime`. + +It also contains the hash of the immediate antecessor of the block (or of its two immediate antecessors in the case of a preceding shardchain merge event), the hashes of its initial and final states (i.e., of the states of the shardchain immediately before and immediately after processing the current block), and the hash of the most recent masterchain block known when the shardchain block was generated. + +### 1.2.6. Validator signatures, signed and unsigned blocks + +The block described so far is an unsigned block; it is generated in its entirety and considered as a whole by the validators. + +When the validators ultimately sign it, the signed block is created, consisting of the unsigned block along with a list of validator signatures (of a certain representation hash of the unsigned block, cf. [1.1.9](#1-1-9-use-of-representation-hashes-for-signatures)). + +This list of signatures is also a non-split component of the (signed) block; however, since it lies outside the unsigned block, it is somewhat different from the other data kept in a block. + +### 1.2.7. Outbound message queue of a shardchain + +Similarly, the most important non-split part of the shardchain state is `OutMsgQueue`, the outbound message queue. It contains undelivered messages included into `OutMsgDescr`, either by the last shardchain block leading to this state or by one of its antecessors. + +Originally, each outbound message is included into `OutMsgQueue`; it is removed from the queue only after it has either been included into the `InMsgDescr` of a block of a “neighboring” shardchain (the next one with respect to Hypercube Routing), or has been delivered to (i.e., has appeared in the `InMsgDescr` of) its ultimate destination shardchain via Instant Hypercube Routing. + +In both cases, the reason for the removal of a message from the `OutMsgQueue` is made explicit in the `OutMsgDescr` of the block in which such a state transformation has occurred. + +### 1.2.8. Layout of InMsgDescr, OutMsgDescr and OutMsgQueue + +All of the most important non-split shardchain data structures related to messages are organized as hashmaps or dictionaries (implemented by means of Patricia trees serialized into a tree of cells as described in [3.3](#3-3-outbound-message-queue-and-descriptors) and [4.3.3](#4-3-3-description-of-a-storage-phase)), with the following keys: + +* The inbound message description `InMsgDescr` uses the 256-bit message hash as a key. +* The outbound message description `OutMsgDescr` uses the 256-bit message hash as a key. +* The outbound message queue `OutMsgQueue` uses the 352-bit concatenation of the 32-bit `destination workchain_id`, the first 64 bits of destination address `account_id`, and the 256-bit message hash as a key. + +### 1.2.9. The split part of the block: transaction chains + +The split part of a shardchain block consists of a hashmap mapping some of the accounts assigned to the shardchain to “virtual accountchain blocks” `AccountBlock`, cf. [(3)](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state). Such a virtual accountchain block consists of a sequential list of transactions related to that account. + +### 1.2.10. Transaction description + +Each transaction is described in the block by an instance of the `Transaction` type, which contains in particular the following information: + +* A reference to exactly one inbound message (which must be present in `InMsgDescr` as well) that has been processed by the transaction. +* References to several (maybe zero) outbound messages (also present in `OutMsgDescr` and most likely included in `OutMsgQueue`) that have been generated by the transaction. + +The transaction consists of an invocation of TVM (cf. [4](#4-accounts-and-transactions)) with the code of the smart contract corresponding to the account in question loaded into the virtual machine, and with the data root cell of the smart contract loaded into the virtual machine’s register `c4`. + +The inbound message itself is passed in the stack as an argument to the smart contract’s `main()` function, along with some other important data, such as the amount of TON Grams and other defined currencies attached to the message, the sender account address, the current balance of the smart contract, and so on. + +In addition to the information listed above, a `Transaction` instance also contains the original and final states of the account (i.e., of the smart contract), as well as some of the TVM running statistics (gas consumed, gas price, instructions performed, cells created/destroyed, virtual machine termination code, etc.). + +### 1.2.11. The split part of the shardchain state: account states + +Recall that, according to [(3)](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state), the split part of the shardchain state consists of a hashmap mapping each “defined” account identifier (belonging to the shardchain in question) to the state of the corresponding account, given by an instance of the `AccountState` type. + +### 1.2.12. Account state + +The account state itself approximately consists of the following data: + +* Its balance in Grams and (optionally) in some other defined cryptocurrencies/tokens. +* The smart-contract code, or the hash of the smart-contract code if it will be provided (uploaded) later by a separate message. +* The persistent smart-contract data, which can be empty for simple smart contracts. It is a tree of cells, the root of which is loaded into register `c4` during smart-contract execution. +* Its storage usage statistics, including the number of cells and bytes kept in the persistent storage of the smart contract (i.e., inside the blockchain state) and the last time a storage usage payment was exacted from this account. +* An optional formal interface description (intended for smart contracts) and/or user public information (intended mostly for human users and organizations). + +Notice that there is no distinction between “smart contract” and “account” in the TON Blockchain. Instead, “simple” or “wallet” accounts, typically employed by human users and their cryptocurrency wallet applications for simple cryptocurrency transfers, are just simple smart contracts with standard (shared) code and with persistent data consisting of the public key of the wallet (or several public keys in the case of a multi-signature wallet; cf. [1.7.6](#1-7-6-example%3A-creating-a-cryptocurrency-wallet-smart-contract) for more detail). + +### 1.2.13. Masterchain blocks + +In addition to shardchain blocks and their states, the TON Blockchain contains masterchain blocks and the masterchain state (also called the global state). The masterchain blocks and state are quite similar to the shardchain blocks and state considered so far, with some notable differences: + +* The masterchain cannot be split or merged, so a masterchain block usually has exactly one immediate antecessor. The sole exception is the “masterchain block zero”, distinguished by having a sequence number equal to zero; it has no antecessors at all, and contains the initial configuration of the whole TON Blockchain (e.g., the original set of validators). +* The masterchain blocks contain another important non-split structure: `ShardHashes`, a binary tree with a list of all defined shardchains along with the hashes of the latest block inside each of the listed shardchains. It is the inclusion of a shardchain block into this structure that makes a shardchain block “canonical”, and enables other shardchains’ blocks to refer to data (e.g., outbound messages) contained in the shardchain block. +* The state of the masterchain contains global configuration parameters of the whole TON Blockchain, such as the minimum and maximum gas prices, the supported versions of TVM, the minimum stake for the validator candidates, the list of alternative cryptocurrencies supported in addition to Grams, the total amount of Grams issued so far, and the current set of validators responsible for creating and signing new blocks, along with their public keys. +* The state of the masterchain also contains the code of the smart contracts used to elect the subsequent sets of validators and to modify the global configuration parameters. The code of these smart contracts itself is a part of the global configuration parameters and can be modified accordingly. In this respect, this code (along with the current values of these parameters) functions like a “constitution” for the TON Blockchain. It is initially established in masterchain block zero. +* There are no transit messages through the masterchain: each inbound message must have a destination inside the masterchain, and each outbound message must have a source inside the masterchain. + +--- + +## 1.3 Consistency conditions + +In addition to the data structures contained in the block and in the blockchain state, which are serialized into bags of cells according to certain TL-B schemes explained in detail later (cf. [Chapter 3](#3-messages%2C-message-descriptors%2C-and-queues), [Chapter 4](#4-accounts-and-transactions), [Chapter 5](#5-block-layout)), an important component of the blockchain layout is the consistency conditions between data kept inside one or in different blocks (as mentioned in [1.2.3](#1-2-3-interaction-with-other-blocks-and-the-outside-world-global-and-local-consistency-conditions)). This section describes in detail the function of consistency conditions in the blockchain. + +### 1.3.1. Expressing consistency conditions +In principle, dependent data types (such as those used in TL-B) could be used not only to describe the serialization of block data, but also to express conditions imposed on the components of such data types. (For instance, one could define data type `OrderedIntPair`, with pairs of integers `(x, y)`, such that `x < y`, as values.) + +However, TL-B currently is not expressive enough to encode all the consistency conditions we need, so we opt for a semi-formalized approach in this text. In the future, we may present a subsequent complete formalization in a suitable proof assistant such as Coq. + +### 1.3.2. Importance of consistency conditions +The consistency conditions ultimately are at least as important as the “unrestricted” data structures on which they are imposed, especially in the blockchain context. + +For instance, the consistency conditions ensure that the state of an account does not change between blocks, and that it can change within a block only as a result of a transaction. In this way, the consistency conditions ensure the safe storage of cryptocurrency balances and other information inside the blockchain. + +### 1.3.3. Kinds of consistency conditions +There are several kinds of consistency conditions imposed on the TON Blockchain: + +- **Global conditions** — Express the invariants throughout the entire TON Blockchain. For instance, the message delivery guarantees, which assert that each message generated must be delivered to its destination account and delivered exactly once, are part of the global conditions. +- **Internal (local) conditions** — Express the conditions imposed on the data kept inside one block. For example, each transaction included in the block (i.e., present in the transaction list of some account) processes exactly one inbound message; this inbound message must be listed in the `InMsgDescr` structure of the block as well. +- **External (local) conditions** — Express the conditions imposed on the data of different blocks, usually belonging to the same or to neighboring shardchains (with respect to Hypercube Routing). Therefore, the external conditions come in several flavors: + - **Antecessor/successor conditions** — Express the conditions imposed on the data of some block and of its immediate antecessor or (in the case of a preceding shardchain merge event) two immediate antecessors. The most important of these conditions is the one stating that the initial state for a shardchain block must coincide with final shardchain state of the immediate antecessor block, provided no shardchain split/merge event happened in between. + - **Masterchain/shardchain conditions** — Express the conditions imposed on a shardchain block and on the masterchain block that refers to it in its `ShardHashes` list or is referred to in the header of the shardchain block. + - **Neighbor (block) conditions** — Express the relations between the blocks of neighboring shardchains with respect to Hypercube Routing. The most important of these conditions express the relation between the `InMsgDescr` of a block and the `OutMsgQueue` of the state of a neighboring block. + +### 1.3.4. Decomposition of global and local conditions into simpler local conditions +The global consistency conditions, such as the message delivery guarantees, are truly necessary for the blockchain to work properly; however, they are hard to enforce and verify directly. + +Therefore, we instead introduce a lot of simpler local consistency conditions, which are easier to enforce and verify since they involve only one block, or perhaps two adjacent blocks. These local conditions are chosen in such a fashion that the desired global conditions are logical consequences of (the conjunction of) all the local conditions. In this respect, we say that the global conditions have been “decomposed” into simpler local conditions. + +Sometimes a local condition still turns out to be too cumbersome to enforce or verify. In that case it is decomposed further, into even simpler local conditions. + +### 1.3.5. Decomposition may require additional data structures and additional internal consistency conditions +The decomposition of a condition into simpler local consistency conditions sometimes requires the introduction of additional data structures. + +For example, the `InMsgDescr`, as considered in [1.3.8](#1-3-8-example%3A-consistency-condition-for-inmsgdescr), can contain both messages processed in the block and transit messages. We might introduce a field in the inbound message description to indicate whether the message is transit or not, and, in the latter case, include a witness field for the transaction processing the message. + +### 1.3.6. Correct serialization conditions +Apart from the high-level internal consistency conditions, which treat the contents of a block as a value of an abstract data type, there are some lower-level internal consistency conditions, called “(correct) serialization conditions”, which ensure that the tree of cells present in the block is indeed a valid serialization of a value of the expected abstract data type. Such serialization conditions can be automatically generated from the TL-B scheme describing the abstract data type and its serialization into a tree of cells. + +Notice that the serialization conditions are a set of mutually recursive predicates on cells or cell slices. For example, if a value of type `A` consists of a 32-bit magic number `mA`, a 64-bit integer `l`, and two references to cells containing values of types `B` and `C`, respectively, then the correct serialization condition for values of type `A` will require a cell or a cell slice to contain exactly 96 data bits and two cell references `r1` and `r2`, with the additional requirements that the first 32 data bits contain `mA`, and the two cells referred to by `r1` and `r2` satisfy the serialization conditions for values of types `B` and `C`, respectively. + +### 1.3.7. Constructive elimination of existence quantifiers + +The local conditions one might want to impose sometimes are non-constructible, meaning that they do not necessarily contain an explanation of why they are true. + +A typical example of such a condition `C` is given by + +```math +C ≔ ∀₍ₓ:𝑋₎ ∃₍ᵧ:𝑌₎ A(x, y)  (5) +``` + +“for any `x` from `X`, there is a `y` from `Y` such that condition `A(x, y)` holds”. Even if we know `C` to be true, we do not have a way of quickly finding a `y ∈ Y` such that `A(x, y)`, for a given `x ∈ X`. As a consequence, the verification of `C` may be quite time-consuming. + +In order to simplify the verification of local conditions, they are made constructible (i.e., verifiable in bounded time) by adding some witness data structures. For instance, condition `C` of ([5](#1-3-7-constructive-elimination-of-existence-quantifiers)) may be transformed by adding a new data structure `f : X → Y` (a map `f` from `X` to `Y`) and imposing the following condition `C′` instead: + +```math +C′ ≔ ∀₍ₓ:𝑋₎ A(x, f(x))  (6) +``` + +Of course, the “witness” value `f(x) : Y` may be included inside the (modified) data type `X` instead of being kept in a separate table `f`. + + +### 1.3.8. Example: consistency condition for InMsgDescr + +For instance, the consistency condition between `X := InMsgDescr`, the list of all inbound messages processed in a block, and `Y := Transactions`, the list of all transactions present in a block, is of the above sort: “For any input message `x` present in `InMsgDescr`, a transaction `y` must be present in the block such that `y` processes `x`".[⁸](#footnote-8) + +The procedure of `∃`-elimination described in [1.3.7](#1-3-7-constructive-elimination-of-existence-quantifiers) leads us to introduce an additional field in the inbound message descriptors of `InMsgDescr`, containing a reference to the transaction in which the message is actually processed. + + +### 1.3.9. Constructive elimination of logical disjunctions + +Similarly to the transformation described in [1.3.7](#1-3-7-constructive-elimination-of-existence-quantifiers), condition + +```math +D :≡ ∀(x : X) A₁(x) ∨ A₂(x)  (7) +``` +“for all `x` from `X`, at least one of `A₁(x)` and `A₂(x)` holds”, may be transformed into a function `i : X → 2 = {1, 2}` and a new condition + +```math +`D′ :≡ ∀(x : X) Aᵢ(x)(x)   (8) +``` +This is a special case of the existential quantifier elimination considered before for `Y = 2 = {1, 2}`. It may be useful when `A₁(x)` and `A₂(x)` are complicated conditions that cannot be verified quickly, so that it is useful to know in advance which of them is in fact true. + +### 1.3.10. Constructivization of conditions +This process of eliminating the non-constructible logical binders `∃` (existence quantifier) and (sometimes) `∨` (logical disjunction) by introducing additional data structures and fields — that is, the process of making a condition constructible — will be called constructivization. + +If taken to its theoretical limit, this process leads to logical formulas containing only universal quantifiers and logical conjunctions, at the expense of adding some witness fields into certain data structures. + +### 1.3.11. Validity conditions for a block +Ultimately, all of the internal conditions for a block, along with the local antecessor and neighbor conditions involving this block and another previously generated block, constitute the validity conditions for a shardchain or masterchain block. A block is valid if it satisfies the validity conditions. It is the responsibility of validators to generate valid blocks, as well as check the validity of blocks generated by other validators. + +### 1.3.12. Witnesses of the invalidity of a block + +If a block does not satisfy all of the validity conditions C₁, ..., Cₙ (i.e., the conjunction V ≡ ∧ᵢ Cᵢ of the validity conditions), it is invalid. This means that it satisfies the “invalidity condition” ¬V = ∨ᵢ ¬Cᵢ. If all of the Cᵢ — and hence, also V — have been “constructivized” in the sense described in [1.3.10](#1-3-10-constructivization-of-conditions), so that they contain only logical conjunctions and universal quantifiers (and simple atomic propositions), then ¬V contains only logical disjunctions and existential quantifiers. + +Then a constructivization of ¬V may be defined, which would involve an invalidity witness, starting with an index i of the specific validity condition Cᵢ which fails. + +Such invalidity witnesses may also be serialized and presented to other validators or committed into the masterchain to prove that a specific block or block candidate is in fact invalid. Therefore, the construction and serialization of invalidity witnesses is an important part of a Proof-of-Stake (PoS) blockchain design.[⁹](#footnote-9) + +### 1.3.13. Minimizing the size of witnesses +An important consideration for the design of the local conditions, their decomposition into simpler conditions, and their constructivization is to make the verification of each condition as simple as possible. + +However, another requirement is that we should minimize the size of witnesses both for a condition (so that block size does not grow too much during the constructivization process) and for its negation (so that the invalidity proofs have bounded size, which simplifies their verification, transmission, and inclusion into the masterchain). These two design principles are sometimes at odds, and a compromise must be then sought. + +### 1.3.14. Minimizing the size of Merkle proofs +The consistency conditions are originally intended to be processed by a party who already has all the relevant data (e.g., all the blocks mentioned in the condition). On some occasions, however, they must be verified by a party who does not have all the blocks in question, but knows only their hashes. + +For example, suppose that a block invalidity proof were augmented by the signature of a validator that had signed an invalid block (and therefore would have to be punished). In this case, the signature would contain only the hash of the wrongly signed block; the block itself would have to be recovered from a different place before verifying the block invalidity proof. + +A compromise between providing only the hash of the supposedly invalid block and providing the entire invalid block along with the invalidity witness is to augment the invalidity witness by a Merkle proof starting from the hash of the block (i.e., of the root cell of the block). Such a proof would include all the cells referred to in the invalidity witness, along with all the cells on the paths from these cells to the root cells and the hashes of their siblings. + +Then an invalidity proof becomes self-contained enough to provide sufficient justification on its own for punishing a validator. For example, the invalidity proof suggested above might be presented to a smart contract residing in the masterchain that punishes the validators for incorrect behavior. + +Since such an invalidity proof must be augmented by a Merkle proof, it makes sense to write the consistency conditions so that the Merkle proofs for their negations would be as small as possible. In particular, each individual condition must be as “local” as possible (i.e., involve a minimal number of cells). This also optimizes the verification time of the invalidity proof. + +### 1.3.15. Collated data for the external conditions +When a validator suggests an unsigned block to the other validators of a shardchain, these other validators must check the validity of this block candidate — i.e., verify that it satisfies all of the internal and external local consistency conditions. + +While the internal conditions do not require any extra data in addition to the block candidate itself, the external conditions need some other blocks, or at least some information out of those blocks. Such additional information may be extracted from those blocks, along with all cells on the paths from the cells containing the required additional information to the root cell of the corresponding blocks and the hashes of the siblings of the cells on these paths, to present a Merkle proof that can be processed without knowledge of the referred blocks themselves. + +This additional information, called collated data, is serialized as a bag of cells and presented by the validator along with the unsigned block candidate itself. The block candidate along with the collated data is called a collated block. + +### 1.3.16. Conditions for a collated block +The external consistency conditions for a block candidate are thus (automatically) transformed into internal consistency conditions for a collated block, which greatly simplifies and speeds up their verification by the other validators. + +However, some data — such as the final state of the immediate antecessor of the block being validated — is not collated. Instead, all validators are supposed to keep a local copy of this data. + +### 1.3.17. Representation conditions and representation hashes +Notice that once Merkle proofs are included into a collated block, the consistency conditions must take into account which data (i.e., which cells) are actually present in the collated block, and not just referred to by their hashes. + +This leads to a new group of conditions, called representation conditions, which must be able to distinguish an external cell reference (usually represented by its 256-bit hash) from the cell itself. A validator can be punished for suggesting a collated block that does not contain all of the expected collated data inside, even if the block candidate itself is valid. + +This also leads to the utilization of representation hashes instead of transparent hashes for collated blocks. + +### 1.3.18. Verification in the absence of the collated data +Notice that a block must still be verifiable in the absence of the collated data; otherwise, no party except the validators would be able to check a previously committed block by its own means. + +In particular, witnesses cannot be included into the collated data: they must reside in the block itself. The collated data must contain only some portions of neighboring blocks referred to in the principal block along with suitable Merkle proofs, which can be reconstructed by anybody who has the referenced blocks themselves. + +### 1.3.19. Inclusion of Merkle proofs in the block itself +Notice that on some occasions Merkle proofs must be embedded into the block itself, and not just into collated data. For instance: + +- During Instant Hypercube Routing (IHR), a message may be included directly into the `InMsgDescr` of a block of the destination shardchain, without travelling all the way along the edges of the hypercube. In this case, a Merkle proof of the existence of the message in the `OutMsgDescr` of a block of the originating shardchain must be included into `InMsgDescr` along with the message itself. +- An invalidity proof, or another proof of validator misbehavior, may be committed into the masterchain by including it in the body of a message sent to a special smart contract. In this case, the invalidity proof must include some cells along with a Merkle proof, which must therefore be contained in a message body. +- Similarly, a smart contract defining a payment channel, or another kind of side-chain, may accept finalization messages or misbehavior proof messages that contain suitable Merkle proofs. +- The final state of a shardchain is not included into a shardchain block. Instead, only the cells that have been modified are included; those cells that are inherited from the old state are referred to by their hashes, along with suitable Merkle proofs consisting of the cells on the path from the root of the old state to the cells of the old state referred to. + +### 1.3.20. Provisions for handling incomplete data +As we have seen, it is necessary to include incomplete data and Merkle proofs into the body of a block, into the body of some messages contained in a block, and into the state. + +This necessity is reflected by some extra representation conditions, as well as provisions for the messages (and by extension, the cell trees processed by TVM) to contain incomplete data (external cell references and Merkle proofs). + +In most cases, such external cell references contain only the 256-bit `sha256` hash of a cell along with a flag; if a smart contract attempts to inspect the contents of such a cell by a `CTOS` primitive (e.g., for deserialization), an exception is triggered. However, an external reference to such a cell can be stored into the smart contract’s persistent storage, and both the transparent and the representation hashes of such a cell can be computed. + +--- +## 1.4 Logical time and logical time intervals + +This section takes a closer look at so-called logical time, extensively used in the TON Blockchain for message forwarding and message delivery guarantees, among other purposes. + +### 1.4.1. Logical time + +A component of the TON Blockchain that also plays an important role in message delivery is the logical time, usually denoted by `Lt`. It is a non-negative 64-bit integer, assigned to certain events roughly as follows: + +If an event `e` logically depends on events `e₁, ..., eₙ`, then `Lt(e)` is the smallest non-negative integer greater than all `Lt(eᵢ)`. + +In particular, if `n = 0` (i.e., if `e` does not depend on any prior events), then `Lt(e) = 0`. + +### 1.4.2. A relaxed variant of logical time +On some occasions we relax the definition of logical time, requesting only that: + +```math +Lt(e) > Lt(e′) \quad \text{whenever } e \succ e′ \quad (9) +``` + +without insisting that `Lt(e)` be the smallest non-negative integer with this property. In such cases we can speak about relaxed logical time, as opposed to the strict logical time defined above (cf. [1.4.1](#1-4-1-logical-time)). + +Notice, however, that the condition ([9](#1-4-2-a-relaxed-variant-of-logical-time)) is a fundamental property of logical time and cannot be relaxed further. + +### 1.4.3. Logical time intervals + +It makes sense to assign to some events or collections of events `C` an interval of logical times: + +```math +Lt•(C) = [Lt⁻(C), Lt⁺(C)) +``` + +meaning that the collection of events `C` took place in the specified “interval” of logical times, where `Lt⁻(C) < Lt⁺(C)` are some integers (64-bit integers in practice). In this case, we can say that `C` begins at logical time `Lt⁻(C)`, and ends at logical time `Lt⁺(C)`. + +By default, we assume `Lt⁺(e) = Lt(e)+1` and `Lt⁻(e) = Lt(e)` for simple or “atomic” events, assuming that they last exactly one unit of logical time. + +In general, if we have a single value `Lt(C)` as well as logical time interval `Lt•(C) = [Lt⁻(C), Lt⁺(C))`, we always require that: + +```math +Lt(C) ∈ [Lt⁻(C), Lt⁺(C)) \quad (10) +``` + +or, equivalently: + +```math +Lt⁻(C) ≤ Lt(C) < Lt⁺(C) \quad (11) +``` + +In most cases, we choose `Lt(C) = Lt⁻(C)`. + +### 1.4.4. Requirements for logical time intervals + +The three principal requirements for logical time intervals are: + +* `0 ≤ Lt⁻(C) < Lt⁺(C)` are non-negative integers for any collection of events `C`. +* If `e′ ≺ e` (i.e., if an atomic event `e` logically depends on another atomic event `e′`), then `Lt•(e′) < Lt•(e)` (i.e., `Lt⁺(e′) ≤ Lt⁻(e)`). +* If `C ⊃ D` (i.e., if a collection of events `C` contains another collection of events `D`), then `Lt•(C) ⊃ Lt•(D)`, i.e., + +```math +Lt⁻(C) ≤ Lt⁻(D) < Lt⁺(D) ≤ Lt⁺(C) \quad (12) +``` + +In particular, if `C` consists of atomic events `e1, . . . , en`, then `Lt⁻(C) ≤ infᵢ Lt⁻(ei) ≤ infᵢ Lt(ei)` and `Lt⁺(C) ≥ supᵢ Lt⁺(ei) ≥ 1 + supᵢ Lt(ei)`. + +### 1.4.5. Strict, or minimal, logical time intervals + +One can assign to any finite collection of atomic events `E = {e}` related by a causality relation (partial order) `≺`, and all subsets `C ⊂ E`, minimal logical time intervals. + +That is, among all assignments of logical time intervals satisfying the conditions listed in [1.4.4](#1-4-4-requirements-for-logical-time-intervals), we choose the one having all `Lt⁺(C) − Lt⁻(C)` as small as possible, and if several assignments with this property exist, we choose the one that has the minimum `Lt⁻(C)` as well. + +Such an assignment can be achieved by first assigning logical time `Lt(e)` +to all atomic events `e ∈ E` as described in **1.4.1**, then setting + +```math +Lt⁻(C) := inf₍ₑ ∈ C₎ Lt(e) +``` + +and + +```math +Lt⁺(C) := 1 + sup₍ₑ ∈ C₎ Lt(e) +``` + +for any `C ⊂ E`. + +In most cases when we need to assign logical time intervals, we use the minimal logical time intervals just described. + +### 1.4.6. Logical time in the TON Blockchain + +The TON Blockchain assigns logical time and logical time intervals to several of its components. + +For instance, each outbound message created in a transaction is assigned its logical creation time; for this purpose, the creation of an outbound message is considered an atomic event, logically dependent on the previous message created by the same transaction, as well as on the previous transaction of the same account, on the inbound message processed by the same transaction, and on all events contained in the blocks referred to by hashes contained in the block with the same transaction. As a consequence, outbound messages created by the same smart contract have strictly increasing logical creation times. + +The transaction itself is considered a collection of atomic events, and is assigned a logical time interval (cf. [4.2.1](#4-2-1)). + +Each block is a collection of transaction and message creation events, so it is assigned a logical time interval, explicitly mentioned in the header of the block. + +--- + +## 1.5 Total blockchain state + +This section discusses the total state of the TON Blockchain, as well as the states of separate shardchains and the masterchain. + +For example, the precise definition of the state of the neighboring shardchains becomes crucial for correctly formalizing the consistency condition asserting that the validators for a shardchain must import the oldest messages from the union of `OutMsgQueues` taken from the states of all neighboring shardchains (cf. [2.2.5](#2-2-5)). + +### 1.5.1. Total state defined by a masterchain block +Every masterchain block contains a list of all currently active shards and of the latest blocks for each of them. In this respect, every masterchain block defines the corresponding total state of the TON Blockchain, since it fixes the state of every shardchain, and of the masterchain as well. + +An important requirement imposed on this list of the latest blocks for all shardchain blocks is that, if a masterchain block `B` lists `S` as the latest block of some shardchain, and a newer masterchain block `B′`, with `B` as one of its antecessors, lists `S′` as the latest block of the same shardchain, then `S` must be one of the antecessors of `S′`.[¹⁰](#footnote-10) + +This condition makes the total state of the TON Blockchain defined by a subsequent masterchain block `B′` compatible with the total state defined by a previous block `B`. + +### 1.5.2. Total state defined by a shardchain block +Every shardchain block contains the hash of the most recent masterchain block in its header. Consequently, all the blocks referred to in that masterchain block, along with their antecessors, are considered “known” or “visible” to the shardchain block, and no other blocks are visible to it, with the sole exception of its antecessors inside its proper shardchain. + +In particular, when we say that a block must import in its `InMsgDescr` the messages from the `OutMsgQueue` of the states of all neighboring shardchains, it means that precisely the blocks of other shardchains visible to that block must be taken into account, and at the same time the block cannot contain messages from “invisible” blocks, even if they are otherwise correct. + +--- + +## 1.6 Configurable parameters and smart contracts + +Recall that the TON Blockchain has several so-called “configurable parameters” (cf. [Chapter 3](#3-messages-message-descriptors-and-queues)), which are either certain values or certain smart contracts residing in the masterchain. This section discusses the storage of and access to these configurable parameters. + +### 1.6.1. Examples of configurable parameters +The properties of the blockchain controlled by configurable parameters include: + +- The minimum stake for validators. +- The maximum size of the group of elected validators. +- The maximum number of blocks for which the same group of validators are responsible. +- The validator election process. +- The validator punishing process. +- The currently active and the next elected set of validators. +- The process of changing configurable parameters, and the address of the smart contract `γ` responsible for holding the values of the configurable parameters and for modifying their values. + +### 1.6.2. Location of the values of configurable parameters +The configurable parameters are kept in the persistent data of a special configuration smart contract `γ` residing in the masterchain of the TON Blockchain. + +More precisely, the first reference of the root cell of the persistent data of that smart contract is a dictionary mapping 64-bit keys (parameter numbers) to the values of the corresponding parameters; each value is serialized into a cell slice according to the type of that value. If a value is a “smart contract” (necessarily residing in the masterchain), its 256-bit account address is used instead. + +### 1.6.3. Quick access through the header of masterchain blocks +To simplify access to the current values of configurable parameters, and to shorten the Merkle proofs containing references to them, the header of each masterchain block contains the address of smart contract `γ`. + +It also contains a direct cell reference to the dictionary containing all values of configurable parameters, which lies in the persistent data of `γ`. Additional consistency conditions ensure that this reference coincides with the one obtained by inspecting the final state of smart contract `γ`. + +### 1.6.4. Getting values of configurable parameters by get methods +The configuration smart contract `γ` provides access to some of configurable parameters by means of “get methods”. These special methods of the smart contract do not change its state, but instead return required data in the TVM stack. + +### 1.6.5. Getting values of configurable parameters by get messages +Similarly, the configuration smart contract `γ` may define some “ordinary” methods (i.e., special inbound messages) to request the values of certain configuration parameters, which will be sent in the outbound messages generated by the transaction processing such an inbound message. + +This may be useful for some other fundamental smart contracts that need to know the values of certain configuration parameters. + +### 1.6.6. Values obtained by get methods may be different from those obtained through the block header +Notice that the state of the configuration smart contract `γ`, including the values of configurable parameters, may change several times inside a masterchain block, if there are several transactions processed by `γ` in that block. + +As a consequence, the values obtained by invoking get methods of `γ`, or sending get messages to `γ`, may be different from those obtained by inspecting the reference in the block header (cf. [1.6.3](#1-6-3-quick-access-through-the-header-of-masterchain-blocks)), which refers to the final state of the configurable parameters in the block. + +### 1.6.7. Changing the values of configurable parameters +The procedure for changing the values of configurable parameters is defined in the code of smart contract `γ`. + +For most configurable parameters, called ordinary, any validator may suggest a new value by sending a special message with the number of the parameter and its proposed value to `γ`. If the suggested value is valid, further voting messages from the validators are collected by the smart contract, and if more than two-thirds each of the current and next sets of validators support the proposal, the value is changed. + +Some parameters, such as the current set of validators, cannot be changed in this way. Instead, the current configuration contains a parameter with the address of smart contract `ν` responsible for electing the next set of validators, and smart contract `γ` accepts messages only from this smart contract `ν` to modify the value of the configuration parameter containing the current set of validators. + +### 1.6.8. Changing the validator election procedure +If the validator election procedure ever needs to be changed, this can be accomplished by first committing a new validator election smart contract into the masterchain, and then changing the ordinary configurable parameter containing the address `ν` of the validator election smart contract. + +This will require two-thirds of the validators to accept the proposal in a vote as described above in [1.6.7](#1-6-7-changing-the-values-of-configurable-parameters). + +### 1.6.9. Changing the procedure of changing configurable parameters +Similarly, the address of the configuration smart contract itself is a configurable parameter and may be changed in this fashion. In this way, most fundamental parameters and smart contracts of the TON Blockchain may be modified in any direction agreed upon by the qualified majority of the validators. + +### 1.6.10. Initial values of the configurable parameters +The initial values of most configurable parameters appear in block zero of the masterchain as part of the masterchain’s initial state, which is explicitly present with no omissions in this block. + +The code of all fundamental smart contracts is also present in the initial state. In this way, the original “constitution” and configuration of the TON Blockchain, including the original set of validators, is made explicit in block zero. + +--- + +## 1.7 New smart contracts and their addresses + +This section discusses the creation and initialization of new smart contracts — in particular, the origin of their initial code, persistent data, and balance. It also discusses the assignment of account addresses to new smart contracts. + +### 1.7.1. Description valid only for masterchain and basic workchain +The mechanisms for creating new smart contracts and assigning their addresses described in this section are valid only for the basic workchain and the masterchain. Other workchains may define their own mechanisms for dealing with these problems. + +### 1.7.2. Transferring cryptocurrency to uninitialized accounts +First of all, it is possible to send messages, including value-bearing messages, to previously unmentioned accounts. If an inbound message arrives at a shardchain with a destination address `η` corresponding to an undefined account, it is processed by a transaction as if the code of the smart contract were empty (i.e., consisting of an implicit `RET`). + +If the message is value-bearing, this leads to the creation of an “uninitialized account”, which may have a non-zero balance (if value-bearing messages have been sent to it)[¹¹](#footnote-11), but has no code and no data. Because even an uninitialized account occupies some persistent storage (needed to hold its balance), some small persistent-storage payments will be exacted from time to time from the account’s balance, until it becomes negative. + +### 1.7.3. Initializing smart contracts by constructor messages +An account, or smart contract, is created by sending a special constructor message `M` to its address `η`. The body of such a message contains the tree of cells with the initial code of the smart contract (which may be replaced by its hash in some situations), and the initial data of the smart contract (maybe empty; it can be replaced by its hash). + +The hash of the code and of the data contained in the constructor message must coincide with the address `η` of the smart contract; otherwise, it is rejected.[¹¹](#footnote-11) + +After the code and data of the smart contract are initialized from the body of the constructor message, the remainder of the constructor message is processed by a transaction (the creating transaction for smart contract `η`) by invoking TVM in a manner similar to that used for processing ordinary inbound messages. + +### 1.7.4. Initial balance of a smart contract +Notice that the constructor message usually must bear some value, which will be transferred to the balance of the newly-created smart contract; otherwise, the new smart contract would have a balance of zero and would not be able to pay for storing its code and data in the blockchain. + +The minimum balance required from a newly-created smart contract is a linear (more precisely, affine) function of the storage it uses. The coefficients of this function may depend on the workchain; in particular, they are higher in the masterchain than in the basic workchain. + +### 1.7.5. Creating smart contracts by external constructor messages +In some cases, it is necessary to create a smart contract by a constructor message that cannot bear any value — for instance, by a constructor message “from nowhere” (an external inbound message). Then one should first transfer a sufficient amount of funds to the uninitialized smart contract as explained in [1.7.2](#1-7-2-transferring-cryptocurrency-to-uninitialized-accounts), and only then send a constructor message “from nowhere”. + +### 1.7.6. Example: creating a cryptocurrency wallet smart contract +An example of the above situation is provided by cryptocurrency wallet applications for human users, which must create a special wallet smart contract in the blockchain in which to keep the user’s funds. This can be achieved as follows: + +- The cryptocurrency wallet application generates a new cryptographic public/private key pair (typically for Ed25519 elliptic curve cryptography, supported by special TVM primitives) for signing the user’s future transactions. +- The cryptocurrency wallet application knows the code of the smart contract to be created (which typically is the same for all users), as well as the data, which typically consists of the public key of the wallet (or of its hash) and is generated at the very beginning. The hash of this information is the address `ξ` of the wallet smart contract to be created. +- The wallet application may display the user’s address `ξ`, and the user may start to receive funds to her uninitialized account `ξ` — for example, by buying some cryptocurrency at an exchange, or by asking a friend to transfer a small sum. +- The wallet application can inspect the shardchain containing account `ξ` (in the case of a basic workchain account) or the masterchain (in the case of a masterchain account), either by itself or using a blockchain explorer, and check the balance of `ξ`. +- If the balance is sufficient, the wallet application may create and sign (with the user’s private key) the constructor message (“from nowhere”), and submit it for inclusion to the validators or the collators for the corresponding blockchain. +- Once the constructor message is included into a block of the blockchain and processed by a transaction, the wallet smart contract is finally created. +- When the user wants to transfer some funds to some other user or smart contract `η`, or wants to send a value-bearing message to `η`, she uses her wallet application to create the message `m` that she wants her wallet smart contract `ξ` to send to `η`, envelope `m` into a special “message from nowhere” `m0` with destination `ξ`, and sign `m0` with her private key. Some provisions against replay attacks must be made, as explained in [2.2.1](#2-2-1-message-uniqueness). +- The wallet smart contract receives message `m0` and checks the validity of the signature with the aid of the public key stored in its persistent data. If the signature is correct, it extracts embedded message `m` from `m0` and sends it to its intended destination `η`, with the indicated amount of funds attached to it. +- If the user does not need to immediately start transferring funds, but only wants to passively receive some funds, she may keep her account uninitialized as long as she wants (provided the persistent storage payments do not lead to the exhaustion of its balance), thus minimizing the storage profile and persistent storage payments of the account. +- Notice that the wallet application may create for the human user the illusion that the funds are kept in the application itself, and provide an interface to transfer funds or send arbitrary messages “directly” from the user’s account `ξ`. In reality, all these operations will be performed by the user’s wallet smart contract, which effectively acts as a proxy for such requests. + +We see that a cryptocurrency wallet is a simple example of a mixed application, having an on-chain part (the wallet smart contract, used as a proxy for outbound messages) and an off-chain part (the external wallet application running on a user’s device and keeping the private account key). + +Of course, this is just one way of dealing with the simplest user wallet smart contracts. One can create multi-signature wallet smart contracts, or create a shared wallet with internal balances kept inside it for each of its individual users, and so on. + +### 1.7.7. Smart contracts may be created by other smart contracts +Notice that a smart contract may generate and send a constructor message while processing any transaction. In this way, smart contracts may automatically create new smart contracts, if they need to, without any human intervention. + +### 1.7.8. Smart contracts may be created by wallet smart contracts +On the other hand, a user may compile the code for her new smart contract `ν`, generate the corresponding constructor message `m`, and use the wallet application to force her wallet smart contract `ξ` to send message `m` to `ν` with an adequate amount of funds, thus creating the new smart contract `ν`. + +--- + +## 1.8 Modification and removal of smart contracts + +This section explains how the code and state of a smart contract may be changed, and how and when a smart contract may be destroyed. + +### 1.8.1. Modification of the data of a smart contract +The persistent data of a smart contract is usually modified as a result of executing the code of the smart contract in TVM while processing a transaction, triggered by an inbound message to the smart contract. + +More specifically, the code of the smart contract has access to the old persistent storage of the smart contract via TVM control register `c4`, and may modify the persistent storage by storing another value into `c4` before normal termination. + +Normally, there are no other ways to modify the data of an existing smart contract. If the code of the smart contract does not provide any ways to modify the persistent data (e.g., if it is a simple wallet smart contract as described in [1.7.6](#1-7-6-example-creating-a-cryptocurrency-wallet-smart-contract), which initializes the persistent data with the user’s public key and does not intend to ever change it), then it will be effectively immutable — unless the code of the smart contract is modified first. + +### 1.8.2. Modification of the code of a smart contract +Similarly, the code of an existing smart contract may be modified only if some provisions for such an upgrade are present in the current code. + +The code is modified by invoking TVM primitive `SETCODE`, which sets the root of the code for the current smart contract from the top value in the TVM stack. The modification is applied only after the normal termination of the current transaction. + +Typically, if the developer of a smart contract wants to be able to upgrade its code in the future, she provides a special “code upgrade method” in the original code of the smart contract, which invokes `SETCODE` in response to certain inbound “code upgrade” messages, using the new code sent in the message itself as an argument to `SETCODE`. + +Some provisions must be made to protect the smart contract from unauthorized replacement of the code; otherwise, control of the smart contract and the funds on its balance could be lost. For example, code upgrade messages might be accepted only from a trusted source address, or they might be protected by requiring a valid cryptographic signature and a correct sequence number. + +### 1.8.3. Keeping the code or data of the smart contract outside the blockchain +The code or data of the smart contract may be kept outside the blockchain and be represented only by their hashes. In such cases, only empty inbound messages may be processed, as well as messages carrying a correct copy of the smart-contract code (or its portion relevant for processing the specific message) and its data inside special fields. + +An example of such a situation is given by the uninitialized smart contracts and constructor messages described in [1.7](#1-7-new-smart-contracts-and-their-addresses). + +### 1.8.4. Using code libraries +Some smart contracts may share the same code, but use different data. One example of this is wallet smart contracts (cf. [1.7.6](#1-7-6-example%3A-creating-a-cryptocurrency-wallet-smart-contract)), which are likely to use the same code (throughout all wallets created by the same software), but with different data (because each wallet must use its own pair of cryptographic keys). + +In this case, the code for all the wallet smart contracts is best committed by the developer into a shared library; this library would reside in the masterchain, and be referred to by its hash using a special “external library cell reference” as the root of the code of each wallet smart contract (or as a subtree inside that code). + +Notice that even if the library code becomes unavailable — for example, because its developer stops paying for its storage in the masterchain — it is still possible to use the smart contracts referring to this library, either by committing the library again into the masterchain, or by including its relevant parts inside a message sent to the smart contract. + +This external cell reference resolution mechanism is discussed in more detail later in [4.4.3](#4-3-3-description-of-a-storage-phase). + +### 1.8.5. Destroying smart contracts +Notice that a smart contract cannot really be destroyed until its balance becomes zero or negative. It may become negative as a result of collecting persistent storage payments, or after sending a value-bearing outbound message transferring almost all of its previous balance. + +For example, a user may decide to transfer all remaining funds from her wallet to another wallet or smart contract. This may be useful, for instance, if one wants to upgrade the wallet, but the wallet smart contract does not have any provisions for future upgrades; then one can simply create a new wallet and transfer all funds to it. + +### 1.8.6. Frozen accounts +When the balance of an account becomes non-positive after a transaction, or smaller than a certain workchain-dependent minimum, the account is frozen by replacing all its code and data by a single 32-byte hash. + +This hash is kept afterwards for some time (e.g., a couple of months) to prevent recreation of the smart contract by its original creating transaction (which still has the correct hash, equal to the account address), and to allow its owner to recreate the account by transferring some funds and sending a message containing the account’s code and data, to be reinstated in the blockchain. + +In this respect, frozen accounts are similar to uninitialized accounts; however, the hash of the correct code and data for a frozen account is not necessarily equal to the account address, but is kept separately. + +Notice that frozen accounts may have a negative balance, indicating that persistent storage payments are due. An account cannot be unfrozen until its balance becomes positive and larger than a prescribed minimum value. + +--- + +# 2 Message forwarding and delivery guarantees + +This chapter discusses the forwarding of messages inside the TON Blockchain, including the Hypercube Routing (HR) and Instant Hypercube Routing (IHR) protocols. It also describes the provisions required to implement the message delivery guarantees and the FIFO ordering guarantee. + +## 2.1 Message addresses and next-hop computation + +This section explains the computation of transit and next-hop addresses by the variant of the hypercube routing algorithm employed in TON Blockchain. The hypercube routing protocol itself, which uses the concepts and next-hop address computation algorithm introduced in this section, is presented in the next section. + +### 2.1.1. Account addresses +The source address and destination address are always present in any message. Normally, they are (full) account addresses. + +A full account address consists of a `workchain_id` (a signed 32-bit big-endian integer defining a workchain), followed by a (usually) 256-bit internal address or account identifier `account_id` (which may also be interpreted as an unsigned big-endian integer) defining the account within the chosen workchain. + +Different workchains may use account identifiers that are shorter or longer than the “standard” 256 bits used in the masterchain (`workchain_id = −1`) and in the basic workchain (`workchain_id = 0`). To this end, the masterchain state contains a list of all workchains defined so far, along with their account identifier lengths. An important restriction is that the `account_id` for any workchain must be at least 64 bits long. + +In what follows, we often consider only the case of 256-bit account addresses for simplicity. Only the first 64 bits of the `account_id` are relevant for the purposes of message routing and shardchain splitting. + +### 2.1.2. Source and destination addresses of a message +Any message has both a source address and a destination address. Its source address is the address of the account (smart contract) that has created the message while processing some transaction; the source address cannot be changed or set arbitrarily, and smart contracts heavily rely on this property. + +By contrast, when a message is created, any well-formed destination address may be chosen; after that, the destination address cannot be changed. + +### 2.1.3. External messages with no source or destination address +Some messages can have no source or no destination address (though at least one of them must be present), as indicated by special flags in the message header. Such messages are the external messages intended for the interaction of the TON Blockchain with the outside world—human users and their cryptowallet applications, off-chain and mixed applications and services, other blockchains, and so on. + +External messages are never routed inside the TON Blockchain. Instead, “messages from nowhere” (i.e., with no source address) are directly included into the `InMsgDescr` of a destination shardchain block (provided some conditions are met) and processed by a transaction in that very block. Similarly, “messages to nowhere” (i.e., with no TON Blockchain destination address), also known as log messages, are also present only in the block containing the transaction that generated such a message.[¹²](#footnote-12) + +Therefore, external messages are almost irrelevant for the discussion of message routing and message delivery guarantees. In fact, the message delivery guarantees for outbound external messages are trivial (at most, the message must be included into the `LogMsg` part of the block), and for inbound external messages there are none, since the validators of a shardchain block are free to include or ignore suggested inbound external messages at their discretion (e.g., according to the processing fee offered by the message).[¹³](#footnote-13) + +In what follows, we focus on “usual” or “internal” messages, which have both a source and a destination address. + +### 2.1.4. Transit and next-hop addresses +When a message needs to be routed through intermediate shardchains before reaching its intended destination, it is assigned a transit address and a next-hop address in addition to the (immutable) source and destination addresses. + +When a copy of the message resides inside a transit shardchain awaiting its relay to its next hop, the transit address is its intermediate address lying in the transit shardchain, as if belonging to a special message-relay smart contract whose only job is to relay the unchanged message to the next shardchain on the route. The next-hop address is the address in a neighboring shardchain (or, on some rare occasions, in the same shardchain) to which the message needs to be relayed. After the message is relayed, the next-hop address usually becomes the transit address of the copy of the message included in the next shardchain. + +Immediately after an outbound message is created in a shardchain (or in the masterchain), its transit address is set to its source address.[¹⁴](#footnote-14) + +### 2.1.5. Computation of the next-hop address for hypercube routing +The TON Blockchain employs a variant of hypercube routing. This means that the next-hop address is computed from the transit address (originally equal to the source address) as follows: + +1. The (big-endian signed) 32-bit `workchain_id` components of both the transit address and destination address are split into groups of `n1` bits (currently, `n1 = 32`), and they are scanned from the left (i.e., the most significant bits) to the right. If one of the groups in the transit address differs from the corresponding group in the destination address, then the value of this group in the transit address is replaced by its value in the destination address to compute the next-hop address. +2. If the `workchain_id` parts of the transit and destination addresses match, then a similar process is applied to the `account_id` parts of the addresses: The `account_id` parts, or rather their first (most significant) 64 bits, are split into groups of `n2` bits (currently, `n2 = 4` bit groups are used, corresponding to the hexadecimal digits of the address) starting from the most significant bit, and are compared starting from the left. The first group that differs is replaced in the transit address with its value in the destination address to compute the next-hop address. +3. If the first 64 bits of the `account_id` parts of the transit and destination addresses match as well, then the destination account belongs to the current shardchain, and the message should not be forwarded outside the current shardchain at all. Instead, it must be processed by a transaction inside it. + +### 2.1.6. Notation for the next-hop address +We denote by + +```math +\mathrm{NextHop}(\xi, \eta) \qquad (13) +``` + +the next-hop address computed for current (source or transit) address `ξ` and destination address `η`. + +### 2.1.7. Support for anycast addresses + +“Large” smart contracts, which can have separate instances in different shardchains, may be reached using anycast destination addresses. These addresses are supported as follows. + +An anycast address `(η, d)` consists of a usual address `η` along with its “splitting depth” `d ≤ 31`. The idea is that the message may be delivered to any address differing from `η` only in the first `d` bits of the internal address part (i.e., not including the workchain identifier, which must match exactly). This is achieved as follows: + +* The effective destination address `η̃` is computed from `(η, d)` by replacing the first `d` bits of the internal address part of `η` with the corresponding bits taken from the source address `ξ`. +* All computations of `NextHop(ν, η)` are replaced by `NextHop(ν, η̃)`, for `ν = ξ` as well as for all other intermediate addresses `ν`. In this way, Hypercube Routing or Instant Hypercube Routing will ultimately deliver the message to the shardchain containing `η̃`. +* When the message is processed in its destination shardchain (the one containing address `η̃`), it may be processed by an account `η′` of the same shardchain differing from `η` and `η̃` only in the first `d` bits of the internal address part. More precisely, if the common shard address prefix is `s`, so that only internal addresses starting with binary string `s` belong to the destination shard, then `η′` is computed from `η` by replacing the first `min(d, |s|)` bits of the internal address part of `η` with the corresponding bits of `s`. + +That said, we tacitly ignore the existence of anycast addresses and the additional processing they require in the following discussions. + +### 2.1.8. Hamming optimality of the next-hop address algorithm + +Notice that the specific hypercube routing next-hop computation algorithm explained in [2.1.5](#2-1-5-computation-of-the-next-hop-address-for-hypercube-routing) may potentially be replaced by another algorithm, provided it satisfies certain properties. One of these properties is the **Hamming optimality**, meaning that the Hamming (`L1`) distance from `ξ` to `η` equals the sum of Hamming distances from `ξ` to `NextHop(ξ, η)` and from `NextHop(ξ, η)` to `η`: + +```math +\|\xi - \eta\|_1 \;=\; \|\xi - \mathrm{NextHop}(\xi,\eta)\|_1 \;+\; \|\mathrm{NextHop}(\xi,\eta) - \eta\|_1 \qquad (14) +``` + +Here `‖ξ − η‖₁` is the Hamming distance between `ξ` and `η`, equal to the number of bit positions in which `ξ` and `η` differ:[¹⁵](#footnote-15) + +```math +\|\xi - \eta\|_1 \;=\; \sum_i |\xi_i - \eta_i| \qquad (15) +``` + +Noticing that in general one should expect only an inequality in ([14](#2-1-8-hamming-optimality-of-the-next-hop-address-algorithm)), following from the triangle inequality for the L1-metric. Hamming optimality essentially means that `NextHop(ξ, η)` lies on one of the (Hamming) shortest paths from `ξ` to `η`. It can also be expressed by saying that `ν = NextHop(ξ, η)` is always obtained from `ξ` by changing the values of bits at some positions to their values in `η`: for any bit position `i`, we have `νᵢ = ξᵢ` or `νᵢ = ηᵢ`. + +### 2.1.9. Non-stopping of NextHop + +Here’s your section with math terms and variables made consistent using **plain Unicode mathematical symbols and subscripts/superscripts where needed**: + +--- + +### 2.1.9. Non-stopping of `NextHop` + +Another important property of the `NextHop` is its non-stopping, meaning that `NextHop(ξ, η) = ξ` is possible only when `ξ = η`. In other words, if we have not yet arrived at `η`, the next hop cannot coincide with our current position. + +This property implies that the path from `ξ` to `η`—i.e., the sequence of intermediate addresses + +```math +ξ⁽⁰⁾ := ξ, ξ⁽ⁿ⁾ := NextHop(ξ⁽ⁿ⁻¹⁾, η)` +``` +—will gradually stabilize at `η`: for some `N ≥ 0`, we have `ξ⁽ⁿ⁾ = η` for all `n ≥ N`. Indeed, one can always take `N := ‖ξ − η‖₁`. + +### 2.1.10. Convexity of the HR path with respect to sharding + +A consequence of Hamming optimality property ([14](#2-1-8-hamming-optimality-of-the-next-hop-address-algorithm)) is what we call the **convexity** of the path from `ξ` to `η` with respect to sharding. Namely, if + +`ξ⁽⁰⁾ := ξ, ξ⁽ⁿ⁾ := NextHop(ξ⁽ⁿ⁻¹⁾, η)` + +is the computed path from `ξ` to `η`, and `N` is the first index such that `ξ⁽ᴺ⁾ = η`, and `S` is a shard of some workchain in any shard configuration, then the indices `i` with `ξ⁽ⁱ⁾` residing in shard `S` constitute a subinterval in `[0, N]`. + +In other words, if integers `0 ≤ i ≤ j ≤ k ≤ N` are such that `ξ⁽ⁱ⁾, ξ⁽ᵏ⁾ ∈ S`, then `ξ⁽ʲ⁾ ∈ S` as well. + +This **convexity property** is important for some proofs related to message forwarding in the presence of dynamic sharding. + +### 2.1.11. Internal routing + +Notice that the next-hop address computed according to the rules defined in [2.1.5](#2-1-5-computation-of-the-next-hop-address-for-hypercube-routing) may belong to the same shardchain as the current one (i.e., the one containing the transit address). In that case, the “internal routing” occurs immediately, the transit address is replaced by the value of the computed next-hop address, and the next-hop address computation step is repeated until a next-hop address lying outside the current shardchain is obtained. + +The message is then kept in the transit output queue according to its computed next-hop address, with its last computed transit address as the “intermediate owner” of the transit message. If the current shardchain splits into two shardchains before the message is forwarded further, it is the shardchain containing the intermediate owner that inherits this transit message. + +Alternatively, we might go on computing the next-hop addresses only to find out that the destination address already belongs to the current shardchain. In that case, the message will be processed (by a transaction) inside this shardchain instead of being forwarded further. + +### 2.1.12. Neighboring shardchains + +Two shards in a shard configuration—or the two corresponding shardchains—are said to be **neighbors**, or neighboring shardchains, if one of them contains a next-hop address for at least one combination of allowed source and destination addresses, while the other contains the transit address for the same combination. In other words, two shardchains are neighbors if a message can be forwarded directly from one of them into the other via Hypercube Routing. + +The masterchain is also included in this definition, as if it were the only shardchain of the workchain with `workchain_id = −1`. In this respect, it is a neighbor of all the other shardchains. + +### 2.1.13. Any shard is a neighbor of itself + +Notice that a shardchain is always considered a neighbor of itself. This may seem redundant, because we always repeat the next-hop computation described in [2.1.5](#2-1-5-computation-of-the-next-hop-address-for-hypercube-routing) until we obtain a next-hop address outside the current shardchain (cf. [2.1.11](#2-1-11-internal-routing)). However, there are at least two reasons for such an arrangement: + +* Some messages have the source and the destination address inside the same shardchain, at least when the message is created. However, if such a message is not processed immediately in the same block where it has been created, it must be added to the outbound message queue of its shardchain, and be imported as an inbound message (with an entry in the `InMsgDescr`) in one of the subsequent blocks of the same shardchain.[¹⁷](#footnote-17) +* Alternatively, the next-hop address may originally be in some other shardchain that later gets merged with the current shardchain, so that the next hop becomes inside the same shardchain. Then the message will have to be imported from the outbound message queue of the merged shardchain, and forwarded or processed accordingly to its next-hop address, even though they reside now inside the same shardchain. + +### 2.1.14. Hypercube Routing and the ISP + +Ultimately, the Infinite Sharding Paradigm (ISP) applies here: a shardchain should be considered a provisional union of accountchains, grouped together solely to minimize the block generation and transmission overhead. + +The forwarding of a message runs through several intermediate accountchains, some of which can happen to lie in the same shard. In this case, once a message reaches an accountchain lying in this shard, it is immediately (“internally”) routed inside that shard until the last accountchain lying in the same shard is reached (cf. [2.1.11](#2-1-11-internal-routing)). Then the message is enqueued in the output queue of that last accountchain.[¹⁸](#footnote-18) + +### 2.1.15. Representation of transit and next-hop addresses + +Notice that the transit and next-hop addresses differ from the source address only in the `workchain_id` and in the first (most significant) 64 bits of the account address. Therefore, they may be represented by 96-bit strings. Furthermore, their `workchain_id` usually coincides with the `workchain_id` of either the source address or the destination address; a couple of bits may be used to indicate this situation, thus further reducing the space required to represent the transit and next-hop addresses. + +In fact, the required storage may be reduced even further by observing that the specific **hypercube routing algorithm** described in [2.1.5](#2-1-5-computation-of-the-next-hop-address-for-hypercube-routing) always generates intermediate (i.e., transit and next-hop) addresses that coincide with the destination address in their first `k` bits, and with the source address in their remaining bits. + +Therefore, one might use just the values `0 ≤ k_tr, k_nh ≤ 96` to fully specify the transit and next-hop addresses. One might also notice that `k′ := k_nh` turns out to be a fixed function of `k := k_tr` (for instance, `k′ = k + n/2 = k + 4` for `k ≥ 32`), and therefore include only one 7-bit value of `k` in the serialization. + +Such optimizations have the obvious disadvantage that they rely too much on the specific routing algorithm used, which can be changed in the future, so they are used in [3.1.15](#3-1-15-enveloped-messages) with a provision to specify more general intermediate addresses if necessary. + +### 2.1.16. Message envelopes + +The transit and next-hop addresses of a forwarded message are not included in the message itself, but are kept in a special **message envelope**, which is a cell (or a cell slice) containing the transit and next-hop addresses with the above optimizations, some other information relevant for forwarding and processing, and a reference to a cell containing the unmodified original message. + +In this way, a message can easily be “extracted” from its original envelope (e.g., the one present in the `InMsgDescr`) and be put into another envelope (e.g., before being included into the `OutMsgQueue`). + +In the representation of a block as a tree, or rather a DAG, of cells, the two different envelopes will contain references to a shared cell with the original message. If the message is large, this arrangement avoids the need to keep more than one copy of the message in the block. + +--- + +## 2.2 Hypercube Routing protocol + +This section exposes the details of the hypercube routing protocol employed by the TON Blockchain to achieve guaranteed delivery of messages between smart contracts residing in arbitrary shardchains. For the purposes of this document, we will refer to the variant of hypercube routing employed by the TON Blockchain as Hypercube Routing (HR). + +### 2.2.1. Message uniqueness +Before continuing, let us observe that any (internal) message is unique. Recall that a message contains its full source address along with its logical creation time, and all outbound messages created by the same smart contract have strictly increasing logical creation times (cf. [1.4.6](#1-4-6-logical-time-in-the-ton-blockchain)); therefore, the combination of the full source address and the logical creation time uniquely defines the message. Since we assume the chosen hash function `sha256` to be collision resistant, a message is uniquely determined by its hash, so we can identify two messages if we know that their hashes coincide. + +This does not extend to external messages “from nowhere”, which have no source addresses. Special care must be taken to prevent replay attacks related to such messages, especially by designers of user wallet smart contracts. One possible solution is to include a sequence number in the body of such messages, and keep the count of external messages already processed inside the smart-contract persistent data, refusing to process an external message if its sequence number differs from this count. + +### 2.2.2. Identifying messages with equal hashes +The TON Blockchain assumes that two messages with the same hashes coincide, and treats either of them as a redundant copy of the other. As explained above in [2.2.1](#2-2-1-message-uniqueness), this does not lead to any unexpected effects for internal messages. However, if one sends two coinciding “messages from nowhere” to a smart contract, it may happen that only one of them will be delivered—or both. If their action is not supposed to be idempotent (i.e., if processing the message twice has a different effect from processing it once), some provisions should be made to distinguish the two messages, for instance by including a sequence number in them. + +In particular, the `InMsgDescr` and `OutMsgDescr` use the (unenveloped) message hash as a key, tacitly assuming that distinct messages have distinct hashes. In this way, one can trace the path and the fate of a message across different shardchains by looking up the message hash in the `InMsgDescr` and `OutMsgDescr` of different blocks. + +### 2.2.3. The structure of OutMsgQueue +Recall that the outbound messages — both those created inside the shardchain, and transit messages previously imported from a neighboring shardchain to be relayed to the next-hop shardchain — are accumulated in the `OutMsgQueue`, which is part of the state of the shardchain (cf. [1.2.7](#1-2-7-outbound-message-queue-of-a-shardchain)). In contrast with `InMsgDescr` and `OutMsgDescr`, the key in `OutMsgQueue` is not the message hash, but its next-hop address — or at least its first 96 bits — concatenated with the message hash. + +Furthermore, the `OutMsgQueue` is not just a dictionary (hashmap), mapping its keys into (enveloped) messages. Rather, it is a **min-augmented dictionary** with respect to the logical creation time, meaning that each node of the Patricia tree representing `OutMsgQueue` has an additional value (in this case, an unsigned 64-bit integer), and that this augmentation value in each fork node is set to be equal to the minimum of the augmentation values of its children. The augmentation value of a leaf equals the logical creation time of the message contained in that leaf; it need not be stored explicitly. + +### 2.2.4. Inspecting the OutMsgQueue of a neighbor +Such a structure for the `OutMsgQueue` enables the validators of a neighboring shardchain to inspect it to find its part (Patricia subtree) relevant to them (i.e., consisting of messages with the next-hop address belonging to the neighboring shard in question — or having the next-hop address with a given binary prefix), as well as quickly compute the “oldest” (i.e., with the minimum logical creation time) message in that part. + +Furthermore, the shard validators do not even need to track the total state of all their neighboring shardchains — they only need to keep and update a copy of their `OutMsgQueue`, or even of its subtree related to them. + +### 2.2.5. Logical time monotonicity:: importing the oldest message from the neighbors +The first fundamental local condition of message forwarding, called (message import) (logical time) monotonicity condition, may be summarized as follows: + +> While importing messages into the `InMsgDescr` of a shardchain block from the `OutMsgQueues` of its neighboring shardchains, the validators must import the messages in the increasing order of their logical time; in the case of a tie, the message with the smaller hash is imported first. + +More precisely, each shardchain block contains the hash of a masterchain block (assumed to be “the latest” masterchain block at the time of the shardchain block’s creation), which in turn contains the hashes of the most recent shardchain blocks. In this way, each shardchain block indirectly “knows” the most recent state of all other shardchains, and especially its neighboring shardchains, including their `OutMsgQueues`.[¹⁹](#footnote-19) + +Now an alternative equivalent formulation of the monotonicity condition is as follows: + +> If a message is imported into the `InMsgDescr` of the new block, its logical creation time cannot be greater than that of any message left unimported in the `OutMsgQueue` of the most recent state of any of the neighboring shardchains. + +It is this form of the monotonicity condition that appears in the local consistency conditions of the TON Blockchain blocks and is enforced by the validators. + +### 2.2.6. Witnesses to violations of the message import logical time monotonicity condition +Notice that if this condition is not fulfilled, a small Merkle proof witnessing its failure may be constructed. Such a proof will contain: + +- A path in the `OutMsgQueue` of a neighbor from the root to a certain message `m` with small logical creation time. +- A path in the `InMsgDescr` of the block under consideration showing that the key equal to `Hash(m)` is absent in `InMsgDescr` (i.e., that `m` has not been included in the current block). +- A proof that `m` has not been included in a preceding block of the same shardchain, using the block header information containing the smallest and the largest logical time of all messages imported into the block (cf. [2.3.4](#2-3-4-checking-whether-a-message-has-already-been-delivered-to-its-final-destination)–[2.3.7](#2-3-7-checking-whether-an-hr-message-has-already-been-delivered-via-ihr-to-its-final-destination) for more information). +- A path in `InMsgDescr` to another included message `m′`, such that either `Lt(m′) > Lt(m)`, or `Lt(m′) = Lt(m)` and `Hash(m′) > Hash(m)`. + +### 2.2.7. Deleting a message from OutMsgQueue +A message must be deleted from `OutMsgQueue` sooner or later; otherwise, the storage used by `OutMsgQueue` would grow to infinity. To this end, several “garbage collection rules” are introduced. They allow the deletion of a message from `OutMsgQueue` during the evaluation of a block only if an explicit special “delivery record” is present in the `OutMsgDescr` of that block. This record contains either a reference to the neighboring shardchain block that has included the message into its `InMsgDescr` (the hash of the block is sufficient, but collated material for the block may contain the relevant Merkle proof), or a Merkle proof of the fact that the message has been delivered to its final destination via Instant Hypercube Routing. + +### 2.2.8. Guaranteed message delivery via Hypercube Routing +In this way, a message cannot be deleted from the outbound message queue unless it has been either relayed to its next-hop shardchain or delivered to its final destination (cf. [2.2.7](#2-2-7-deleting-a-message-from-outmsgqueue)). Meanwhile, the message import monotonicity condition (cf. [2.2.5](#2-2-5-logical-time-monotonicity%3A%3A-importing-the-oldest-message-from-the-neighbors)) ensures that any message will sooner or later be relayed into the next shardchain, taking into account other conditions which require the validators to use at least half of the block’s space or gas limits for importing inbound internal messages (otherwise the validators might choose to create empty blocks or import only external messages even in the presence of non-empty outbound message queues at their neighbors). + +### 2.2.9. Message processing order +When several imported messages are processed by transactions inside a block, the message processing order conditions ensure that older messages are processed first. More precisely, if a block contains two transactions `t` and `t′` of the same account, which process inbound messages `m` and `m′`, respectively, and `Lt(m) < Lt(m′)`, then we must have `Lt(t) < Lt(t′)`. + +### 2.2.10. FIFO guarantees of Hypercube Routing + +The message processing order conditions (cf. [2.2.9](#2-2-9-message-processing-order)), along with the message import monotonicity conditions (cf. [2.2.5](#2-2-5-logical-time-monotonicity%3A%3A-importing-the-oldest-message-from-the-neighbors)), imply the FIFO guarantees for Hypercube Routing. Namely, if a smart contract $ξ$ creates two messages $m$ and $m'$ with the same destination $η$, and $m'$ is generated later than $m$ (meaning that $m \prec m'$, hence $Lt(m) < Lt(m')$), then $m$ will be processed by $η$ before $m'$. This is so because both messages will follow the same routing steps on the path from $ξ$ to $η$ (the Hypercube Routing algorithm described in [2.1.5](#2-1-5-computation-of-the-next-hop-address-for-hypercube-routing) is deterministic), and in all outbound queues and inbound message descriptions $m'$ will appear “after” $m$. [²⁰](#footnote-20) + +If message m′ can be delivered to B via Instant Hypercube Routing, this is not necessarily true anymore. Therefore, a simple way of ensuring FIFO message delivery discipline between a pair of smart contracts consists in setting a special bit in the message header preventing its delivery via IHR. + +### 2.2.11. Delivery uniqueness guarantees of Hypercube Routing +Notice that the message import monotonicity conditions also imply the uniqueness of the delivery of any message via Hypercube Routing — i.e., that it cannot be imported and processed by the destination smart contract more than once. We will see later in §2.3 that enforcing delivery uniqueness when both Hypercube Routing and Instant Hypercube Routing are active is more complicated. + +### 2.2.12. An overview of Hypercube Routing + +Let us summarize all routing steps performed to deliver an internal message `m` created by source account `ξ₀` to destination account `η`. +We denote by `ξₖ₊₁ := NextHop(ξₖ, η)`, `k = 0, 1, 2, …` the intermediate addresses dictated by HR for forwarding the message `m` to its final destination `η`. +Let `Sₖ` be the shard containing `ξₖ`. + +* **[Birth]** — Message `m` with destination `η` is created by a transaction `t` belonging to an account `ξ₀` residing in some shardchain `S₀`. The logical creation time `Lt(m)` is fixed at this point and included into the message `m`. + +* **[ImmediateProcessing?]** — If the destination `η` resides in the same shardchain `S₀`, the message may be processed in the same block it was generated in. In this case, `m` is included into `OutMsgDescr` with a flag indicating it has been processed in this very block and need not be forwarded further. Another copy of `m` is included into `InMsgDescr`, along with the usual data describing the processing of inbound messages. (Notice that `m` is not included into the `OutMsgQueue` of `S₀`.) + +* **[InitialInternalRouting]** — If `m` either has a destination outside `S₀`, or is not processed in the same block where it was generated, the internal routing procedure described in [2.1.11](#2-1-11-internal-routing) is applied, until an index `k` is found such that `ξₖ` lies in `S₀`, but `ξₖ₊₁ = NextHop(ξₖ, η)` does not (i.e., `Sₖ = S₀`, but `Sₖ₊₁ ≠ S₀`). Alternatively, this process stops if `ξₖ = η` or `ξₖ` coincides with `η` in its first 96 bits. + +* **[OutboundQueuing]** — The message `m` is included into `OutMsgDescr` (with the key equal to its hash), with an envelope containing its transit address `ξₖ` and next-hop address `ξₖ₊₁` as explained in [2.1.16](#2-1-6-notation-for-the-next-hop-address) and [2.1.15](#2-1-15-representation-of-transit-and-next-hop-addresses). + The same enveloped message is also included in the `OutMsgQueue` of the state of `Sₖ`, with the key equal to the concatenation of the first 96 bits of its next-hop address `ξₖ₊₁` (which may be equal to `η` if `η` belongs to `Sₖ`) and the message hash `Hash(m)`. + +* **[QueueWait]** — Message `m` waits in the `OutMsgQueue` of shardchain `Sₖ` to be forwarded further. In the meantime, shardchain `Sₖ` may split or merge with other shardchains; in that case, the new shard `S′ₖ` containing the transit address `ξₖ` inherits `m` in its `OutMsgQueue`. + +* **[ImportInbound]** — At some point in the future, the validators for the shardchain `Sₖ₊₁` containing the next-hop address `ξₖ₊₁` scan the `OutMsgQueue` in the state of shardchain `Sₖ` and decide to import message `m` in keeping with the monotonicity condition (cf. [2.2.5](#2-2-5-logical-time-monotonicity%3A%3A-importing-the-oldest-message-from-the-neighbors)) and other conditions. + A new block for shardchain `Sₖ₊₁` is generated, with an enveloped copy of `m` included in its `InMsgDescr`. The entry in `InMsgDescr` contains also the reason for importing `m` into this block, with a hash of the most recent block of shardchain `S′ₖ`, and the previous next-hop and transit addresses `ξₖ` and `ξₖ₊₁`, so that the corresponding entry in the `OutMsgQueue` of `S′ₖ` can be easily located. + +* **[Confirmation]** — This entry in the `InMsgDescr` of `Sₖ₊₁` also serves as a confirmation for `S′ₖ`. + In a later block of `S′ₖ`, message `m` must be removed from the `OutMsgQueue` of `S′ₖ`; this modification is reflected in a special entry in the `OutMsgDescr` of the block of `S′ₖ` that performs this state modification. + +* **[Forwarding?]** — If the final destination `η` of `m` does not reside in `Sₖ₊₁`, the message is forwarded. + Hypercube Routing is applied until some `ξₗ`, `l > k`, and `ξₗ₊₁ = NextHop(ξₗ, η)` are obtained, such that `ξₗ` lies in `Sₖ₊₁`, but `ξₗ₊₁` does not (cf. [2.1.11](#2-1-11-internal-routing)). + After that, a newly-enveloped copy of `m` with transit address set to `ξₗ` and next-hop address `ξₗ₊₁` is included into both the `OutMsgDescr` of the current block of `Sₖ₊₁` and the `OutMsgQueue` of the new state of `Sₖ₊₁`. + The entry of `m` in `InMsgDescr` contains a flag indicating that the message has been forwarded; the entry in `OutMsgDescr` contains the newly-enveloped message and a flag indicating that this is a forwarded message. + Then all the steps starting from [OutboundQueuing]** are repeated, for `l` instead of `k`. + +* **[Processing?]** — If the final destination `η` of `m` resides in `Sₖ₊₁`, then the block of `Sₖ₊₁` that imported the message must process it by a transaction `t` included in the same block. + In this case, `InMsgDescr` contains a reference to `t` by its logical time `Lt(t)`, and a flag indicating that the message has been processed. + +The above message routing algorithm does not take into account some further modifications required to implement **Instant Hypercube Routing (IHR)**. For instance, a message may be discarded after being imported (listed in `InMsgDescr`) into its final or intermediate shardchain block, because a proof of delivery via IHR to the final destination is presented. +In this case, such a proof must be included into `InMsgDescr` to explain why the message was not forwarded further or processed. + +--- + +## 2.3 Instant Hypercube Routing and combined delivery guarantees + +This section describes the Instant Hypercube Routing protocol, normally applied by TON Blockchain in parallel to the previously discussed Hypercube Routing protocol to achieve faster message delivery. However, when both Hypercube Routing and Instant Hypercube Routing are applied to the same message in parallel, achieving delivery and unique delivery guarantees is more complicated. This topic is also discussed in this section. + +### 2.3.1. An overview of Instant Hypercube Routing +Let us explain the major steps applied when the Instant Hypercube Routing (IHR) mechanism is applied to a message. (Notice that normally both the usual HR and IHR work in parallel for the same message; some provisions must be taken to guarantee the uniqueness of delivery of any message.) + +Consider the routing and delivery of the same message `m` with source `ξ` and destination `η` as discussed in [2.2.12](#2-2-12-an-overview-of-hypercube-routing): + +- **[NetworkSend]** — After the validators of `S₀` have agreed on and signed the block containing the creating transaction `t` for `m`, and observed that the destination `η` of `m` does not reside inside `S₀`, they may send a datagram (encrypted network message), containing the message `m` along with a Merkle proof of its inclusion into the `OutMsgDescr` of the block just generated, to the validator group of the shardchain `T` currently owning the destination `η`. +- **[NetworkReceive]** — If the validators of shardchain `T` receive such a message, they check its validity starting from the most recent masterchain block and the shardchain block hashes listed in it, including the most recent “canonical” block of shardchain `S₀` as well. If the message is invalid, they silently discard it. If that block of shardchain `S₀` has a larger sequence number than the one listed in the most recent masterchain block, they may either discard it or postpone the verification until the next masterchain block appears. +- **[InclusionConditions]** — The validators check inclusion conditions for message `m`. In particular, they must check that this message has not been delivered before, and that the `OutMsgQueues` of the neighbors do not have unprocessed outbound messages with destinations in `T` with smaller logical creation times than `Lt(m)`. +- **[Deliver]** — The validators deliver and process the message, by including it into the `InMsgDescr` of the current shardchain block along with a bit indicating that it is an IHR message, the Merkle proof of its inclusion into the `OutMsgDescr` of the original block, and the logical time of the transaction `t′` processing this inbound message into the currently generated block. +- **[Confirm]** — Finally, the validators send encrypted datagrams to all the validator groups of the intermediate shardchains on the path from `ξ` to `η`, containing a Merkle proof of the inclusion of message `m` into the `InMsgDescr` of its final destination. The validators of an intermediate shardchain may use this proof to discard the copy of message `m` travelling by the rules of HR, by importing the message into their `InMsgDescr` along with the Merkle proof of final delivery and setting a flag indicating that the message has been discarded. + +The overall procedure is even simpler than that for Hypercube Routing. Notice, however, that IHR comes with no delivery or FIFO guarantees: the network datagram may be lost in transit, or the validators of the destination shardchain may decide not to act on it, or they may discard it due to buffer overflow. This is the reason why IHR is used as a complement to HR, and not as a replacement. + +### 2.3.2. Overall eventual delivery guarantees +Notice that the combination of HR and IHR guarantees the ultimate delivery of any internal message to its final destination. Indeed, the HR by itself is guaranteed to deliver any message eventually, and the HR for message `m` can be cancelled at an intermediate stage only by a Merkle proof of delivery of `m` to its final destination (via IHR). + +### 2.3.3. Overall unique delivery guarantees +However, the uniqueness of message delivery for the combination of HR and IHR is more difficult to achieve. In particular, one must check the following conditions, and, if necessary, be able to provide short Merkle proofs that they do or don’t hold: +- When a message `m` is imported into its next intermediate shardchain block via HR, we must check that `m` has not already been imported via HR. +- When `m` is imported and processed in its final destination shardchain, we must check that `m` has not already been processed. If it has, there are three subcases: + – If `m` is being considered for import via HR, and it has already been imported via HR, it must not be imported at all. + – If `m` is being considered for import via HR, and it has already been imported via IHR (but not HR), then it must be imported and immediately discarded (without being processed by a transaction). This is necessary to remove `m` from the `OutMsgQueue` of its previous intermediate shardchain. + – If `m` is being considered for import via IHR, and it has already been imported via either IHR or HR, it must not be imported at all. + +### 2.3.4. Checking whether a message has already been delivered to its final destination +Consider the following general algorithm for checking whether a message `m` has already been delivered to its final destination `η`: + +One can simply scan the last several blocks belonging to the shardchain containing the destination address, starting from the latest block and working backwards through the previous block references. (If there are two previous blocks—i.e., if a shardchain merge event occurred at some point—one would follow the chain containing the destination address.) The `InMsgDescr` of each of these blocks can be checked for an entry with key `Hash(m)`. If such an entry is found, the message `m` has already been delivered, and we can easily construct a Merkle proof of this fact. If we do not find such an entry before arriving at a block `B` with `Lt⁺(B) < Lt(m)`, implying that `m` could not be delivered in `B` or any of its predecessors, then the message `m` definitely has not been delivered yet. + +The obvious disadvantage of this algorithm is that, if message `m` is very old (and most likely delivered a long time ago), meaning that it has a small value of `Lt(m)`, then a large number of blocks will need to be scanned before yielding an answer. Furthermore, if the answer is negative, the size of the Merkle proof of this fact will increase linearly with the number of blocks scanned. + +### 2.3.5. Checking whether an IHR message has already been delivered to its final destination +To check whether an IHR message `m` has already been delivered to its destination shardchain, we can apply the general algorithm described above (cf. [2.3.4](#2-3-4-checking-whether-a-message-has-already-been-delivered-to-its-final-destination)), modified to inspect only the last `c` blocks for some small constant `c` (say, `c = 8`). If no conclusion can be reached after inspecting these blocks, then the validators for the destination shardchain may simply discard the IHR message instead of spending more resources on this check. + +### 2.3.6. Checking whether an HR message has already been delivered via HR to its final destination or an intermediate shardchain + +To check whether an HR-received message `m` (or rather, a message `m` being considered for import via HR) has already been imported via HR, we can use the following algorithm: + +Let `ξₖ` be the transit address of `m` (belonging to a neighboring shardchain `Sₖ`) and `ξₖ₊₁` be its next-hop address (belonging to the shardchain under consideration). Since we are considering the inclusion of `m`, `m` must be present in the `OutMsgQueue` of the most recent state of shardchain `Sₖ`, with `ξₖ` and `ξₖ₊₁` indicated in its envelope. + +In particular: + +* (a) the message has been included into `OutMsgQueue`, and we may even know when, because the entry in `OutMsgQueue` sometimes contains the logical time of the block where it has been added, and +* (b) it has not yet been removed from `OutMsgQueue`. + +Now, the validators of the neighboring shardchain are required to remove a message from `OutMsgQueue` as soon as they observe that the message (with transit and next-hop addresses `ξₖ` and `ξₖ₊₁` in its envelope) has been imported into the `InMsgDescr` of the message’s next-hop shardchain. Therefore, (b) implies that the message could have been imported into the `InMsgDescr` of a preceding block only if this preceding block is very new (i.e., not yet known to the most recent neighboring shardchain block). + +Therefore, only a very limited number of preceding blocks (typically one or two, at most) need to be scanned by the algorithm described in [2.3.4](#2-3-4-checking-whether-a-message-has-already-been-delivered-to-its-final-destination) to conclude that the message has not yet been imported.[²¹](#footnote-21) + +In fact, if this check is performed by the validators or collators for the current shardchain themselves, it can be optimized by keeping in memory the `InMsgDescr`s of the several latest blocks. + +### 2.3.7. Checking whether an HR message has already been delivered via IHR to its final destination + +Finally, to check whether an HR message has already been delivered to its final destination via IHR, one can use the general algorithm described in [2.3.4](#2-3-4-checking-whether-a-message-has-already-been-delivered-to-its-final-destination). + +In contrast with [2.3.5](#2-3-5-checking-whether-an-ihr-message-has-already-been-delivered-to-its-final-destination), we cannot abort the verification process after scanning a fixed number of the latest blocks in the destination shardchain, because HR messages cannot be dropped without a reason. + +Instead, we indirectly bound the number of blocks to be inspected by forbidding the inclusion of an IHR message `m` into a block `B` of its destination shardchain if there are already more than, say, `c = 8` blocks `B′` in the destination shardchain with `Lt⁺(B′) ≥ Lt(m)`. + +Such a condition effectively restricts the time interval after the creation of message `m` in which it could have been delivered via IHR, so that only a small number of blocks of the destination shardchain (at most `c`) will need to be inspected. + +Notice that this condition nicely aligns with the modified algorithm described in [2.3.5](#2-3-5-checking-whether-an-ihr-message-has-already-been-delivered-to-its-final-destination), effectively forbidding the validators from importing the newly-received IHR message if more than `c = 8` steps are needed to check that it had not been imported already. + +--- + +# 3 Messages, message descriptors, and queues + +This chapter presents the internal layout of individual messages, message descriptors (such as `InMsgDescr` or `OutMsgDescr`), and message queues (such as `OutMsgQueue`). Enveloped messages (cf. [2.1.16](#2-1-16-message-envelopes)) are also discussed here. + +Notice that most general conventions related to messages must be obeyed by all shardchains, even if they do not belong to the basic shardchain; otherwise, messaging and interaction between different workchains would not be possible. It is the interpretation of the message contents and the processing of messages, usually by some transactions, that differs between workchains. + +## 3.1 Address, currency, and message layout + +This chapter begins with some general definitions, followed by the precise layout of addresses used for serializing source and destination addresses in a message. + +### 3.1.1. Some standard definitions +For the reader’s convenience, we reproduce here several general TL-B definitions.[²²](#footnote-22) These definitions are used below in the discussion of address and message layout, but otherwise are not related to the TON Blockchain. + +```c +unit$_ = Unit; +true$_ = True; +// EMPTY False; +bool_false$0 = Bool; +bool_true$1 = Bool; +nothing$0 {X:Type} = Maybe X; +just$1 {X:Type} value:X = Maybe X; +left$0 {X:Type} {Y:Type} value:X = Either X Y; +right$1 {X:Type} {Y:Type} value:Y = Either X Y; +pair$_ {X:Type} {Y:Type} first:X second:Y = Both X Y; +bit$_ _:(## 1) = Bit; +``` + +### 3.1.2. TL-B scheme for addresses + +The serialization of source and destination addresses is defined by the following TL-B scheme: + +```c +addr_none$00 = MsgAddressExt; +addr_extern$01 len:(## 8) external_address:(len * Bit) + = MsgAddressExt; +anycast_info$_ depth:(## 5) rewrite_pfx:(depth * Bit) = Anycast; +addr_std$10 anycast:(Maybe Anycast) + workchain_id:int8 address:uint256 = MsgAddressInt; +addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) + workchain_id:int32 address:(addr_len * Bit) = MsgAddressInt; +_ MsgAddressInt = MsgAddress; +_ MsgAddressExt = MsgAddress; +``` + +The two last lines define type `MsgAddress` to be the internal union of types `MsgAddressInt` and `MsgAddressExt` (not to be confused with their external union `Either MsgAddressInt MsgAddressExt` as defined in [3.1.1](#3-1-1-some-standard-definitions)), as if the preceding four lines had been repeated with the right-hand side replaced by `MsgAddress`. + +In this way, type `MsgAddress` has four constructors, and types `MsgAddressInt` and `MsgAddressExt` are both subtypes of `MsgAddress`. + +### 3.1.3. External addresses + +The first two constructors, `addr_none` and `addr_extern`, are used for source addresses of “messages from nowhere” (inbound external messages), and for destination addresses of “messages to nowhere” (outbound external messages). The `addr_extern` constructor defines an “external address”, which is ignored by the TON Blockchain software altogether (which treats `addr_extern` as a longer variant of `addr_none`), but may be used by external software for its own purposes. + +For example, a special external service may inspect the destination address of all outbound external messages found in all blocks of the TON Blockchain, and, if a special magic number is present in the `external_address` field, parse the remainder as an IP address and UDP port or a (TON Network) ADNL address, and send a datagram with a copy of the message to the network address thus obtained. + +### 3.1.4. Internal addresses + +The two remaining constructors, `addr_std` and `addr_var`, represent internal addresses. The first of them, `addr_std`, represents a signed 8-bit `workchain_id` (sufficient for the masterchain and for the basic workchain) and a 256-bit internal address in the selected workchain. + +The second of them, `addr_var`, represents addresses in workchains with a “large” `workchain_id`, or internal addresses of length not equal to 256. + +Both constructors have an optional `anycast` value, absent by default, which enables “address rewriting” when present. [²³](#footnote-23) + +The validators must use `addr_std` instead of `addr_var` whenever possible, but must be ready to accept `addr_var` in inbound messages. The `addr_var` constructor is intended for future extensions. + +Notice that `workchain_id` must be a valid workchain identifier enabled in the current masterchain configuration, and the length of the internal address must be in the range allowed for the indicated workchain. For example, one cannot use `workchain_id = 0` (basic workchain) or `workchain_id = −1` (masterchain) with addresses that are not exactly 256 bits long. + +### 3.1.5. Representing Gram currency amounts + +Amounts of Grams are expressed with the aid of two types representing variable-length unsigned or signed integers, plus a type `Grams` explicitly dedicated to representing non-negative amounts of nanograms, as follows: + +```c +var_uint$_ {n:#} len:(#< n) value:(uint (len * 8)) += VarUInteger n; +var_int$_ {n:#} len:(#< n) value:(int (len * 8)) += VarInteger n; +nanograms$_ amount:(VarUInteger 16) = Grams; +``` + +If one wants to represent `x` nanograms, one selects an integer `ℓ < 16` such that `x < 2⁸ˡ`, and serializes first `ℓ` as an unsigned 4-bit integer, then `x` itself as an unsigned `8ℓ`-bit integer. Notice that four zero bits represent a zero amount of Grams. + +Recall (cf. [3, A](#ref-3)) that the original total supply of Grams is fixed at five billion (i.e., `5·10¹⁸ < 2⁶³` nanograms), and is expected to grow very slowly. Therefore, all the amounts of Grams encountered in practice will fit in unsigned or even signed 64-bit integers. Validators may use the 64-bit integer representation of Grams in their internal computations; however, serialization of such values in the blockchain is another matter. + +### 3.1.6. Representing collections of arbitrary currencies + +Recall that the TON Blockchain allows its users to define arbitrary cryptocurrencies or tokens apart from the Gram, provided some conditions are met. Such additional cryptocurrencies are identified by 32-bit `currency_id`s. The list of defined additional cryptocurrencies is a part of the blockchain configuration, stored in the masterchain. + +When some amounts of one or several such cryptocurrencies need to be represented, a dictionary (cf. [4, 3.3](#ref-4)) with 32-bit `currency_id`s as keys and `VarUInteger 32` values is used: + +```c +extra_currencies$_ dict:(HashmapE 32 (VarUInteger 32)) += ExtraCurrencyCollection; +currencies$_ grams:Grams other:ExtraCurrencyCollection += CurrencyCollection; +``` + +The value attached to an internal message is represented by a value of the `CurrencyCollection` type, which may describe a certain (non-negative) amount of (nano)grams as well as some additional currencies, if needed. Notice that if no additional currencies are required, `other` reduces to just one zero bit. + +### 3.1.7. Message layout + +A message consists of its header followed by its body, or payload. The body is essentially arbitrary, to be interpreted by the destination smart contract. The message header is standard and is organized as follows: + +```c +int_msg_info$0 ihr_disabled:Bool bounce:Bool +src:MsgAddressInt dest:MsgAddressInt +value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams +created_lt:uint64 created_at:uint32 = CommonMsgInfo; + +ext_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt +import_fee:Grams = CommonMsgInfo; + +ext_out_msg_info$11 src:MsgAddressInt dest:MsgAddressExt +created_lt:uint64 created_at:uint32 = CommonMsgInfo; + +tick_tock$_ tick:Bool tock:Bool = TickTock; + +_ split_depth:(Maybe (## 5)) special:(Maybe TickTock) +code:(Maybe ^Cell) data:(Maybe ^Cell) +library:(Maybe ^Cell) = StateInit; + +message$_ {X:Type} info:CommonMsgInfo +init:(Maybe (Either StateInit ^StateInit)) +body:(Either X ^X) = Message X; +``` + +The meaning of this scheme is as follows. + +Type `Message X` describes a message with the body (or payload) of type `X`. Its serialization starts with `info` of type `CommonMsgInfo`, which comes in three flavors: for internal messages, inbound external messages, and outbound external messages, respectively. All of them have a source address `src` and destination address `dest`, which are external or internal according to the chosen constructor. Apart from that, an internal message may bear some value in Grams and other defined currencies (cf. [3.1.6](#3-1-6-representing-collections-of-arbitrary-currencies)), and all messages generated inside the TON Blockchain have a logical creation time `created_lt` (cf. [1.4.6](#1-4-6-logical-time-in-the-ton-blockchain)) and creation unixtime `created_at`, both automatically set by the generating transaction. The creation unixtime equals the creation unixtime of the block containing the generating transaction. + +### 3.1.8. Forwarding and IHR fees. Total value of an internal message + +Internal messages define an `ihr_fee` in Grams, which is subtracted from the value attached to the message and awarded to the validators of the destination shardchain if they include the message by the IHR mechanism. The `fwd_fee` is the original total forwarding fee paid for using the HR mechanism; it is automatically computed from some configuration parameters and the size of the message at the time the message is generated. + +Notice that the total value carried by a newly created internal outbound message equals the sum of `value`, `ihr_fee`, and `fwd_fee`. This sum is deducted from the balance of the source account. Among the components, only `value` is always credited to the destination account on message delivery. The `fwd_fee` is collected by the validators on the HR path from the source to the destination, and the `ihr_fee` is either collected by the validators of the destination shardchain (if the message is delivered via IHR), or credited to the destination account. + +### 3.1.9. Code and data portions contained in a message + +Apart from the common message information stored in `info`, a message can contain portions of the destination smart contract’s code and data. This feature is used, for instance, in the so-called constructor messages (cf. [1.7.3](#1-7-3-initializing-smart-contracts-by-constructor-messages)), which are simply internal or inbound external messages with `code` and possibly `data` fields defined in their `init` portions. If the hash of these fields is correct, and the destination smart contract has no code or data, the values from the message are used instead.²⁴ + +### 3.1.10. Using code and data for other purposes + +Workchains other than the masterchain and the basic workchain are free to use the trees of cells referred to in the `code`, `data`, and `library` fields for their own purposes. The messaging system itself makes no assumptions about their contents; they become relevant only when a message is processed by a transaction. + +### 3.1.11. Absence of an explicit gas price and gas limit + +Notice that messages do not have an explicit gas price and gas limit. Instead, the gas price is set globally by the validators for each workchain (it is a special configurable parameter), and the gas limit for each transaction has also a default value, which is a configurable parameter; the smart contract itself may lower the gas limit during its execution if so desired. + +For internal messages, the initial gas limit cannot exceed the Gram value of the message divided by the current gas price. For inbound external messages, the initial gas limit is very small, and the true gas limit is set by the receiving smart contract itself, when it accepts the inbound message by the corresponding TVM primitive. + +### 3.1.12. Deserialization of a message payload + +The payload, or body, of a message is deserialized by the receiving smart contract when executed by TVM. The messaging system itself makes no assumptions about the internal format of the payload. However, it makes sense to describe the serialization of supported inbound messages by TL or TL-B schemes with 32-bit constructor tags, so that the developers of other smart contracts will know the interface supported by a specific smart contract. + +A message is always serialized inside the blockchain as the last field in a cell. Therefore, the blockchain software may assume that whatever bits and references left unparsed after parsing the fields of a `Message` preceding `body` belong to the payload `body : X`, without knowing anything about the serialization of the type `X`.²⁴ + +### 3.1.13. Messages with empty payloads + +The payload of a message may happen to be an empty cell slice, having no data bits and no references. By convention, such messages are used for simple value transfers. The receiving smart contract is normally expected to process such messages quietly and to terminate successfully (with a zero exit code), although some smart contracts may perform non-trivial actions even when receiving a message with empty payload. For example, a smart contract may check the resulting balance, and, if it becomes sufficient for a previously postponed action, trigger this action. Alternatively, the smart contract might want to remember in its persistent storage the amount received and the corresponding sender, in order, for instance, to distribute some tokens later to each sender proportionally to the funds transferred. + +Notice that even if a smart contract makes no special provisions for messages with empty payloads and throws an exception while processing such messages, the received value (minus the gas payment) will still be added to the balance of the smart contract. + +### 3.1.14. Message source address and logical creation time determine its generating block + +Notice that the source address and the logical creation time of an internal or an outbound external message uniquely determine the block in which the message has been generated. Indeed, the source address determines the source shardchain, and the blocks of this shardchain are assigned non-intersecting logical time intervals, so only one of them may contain the indicated logical creation time. This is the reason why no explicit mention of the generating block is needed in messages. + +### 3.1.15. Enveloped messages + +Message envelopes are used for attaching routing information, such as the current (transit) address and the next-hop address, to inbound, transit, and outbound messages (cf. [2.1.16](#2-1-16-message-envelopes)). The message itself is kept in a separate cell and referred to from the message envelope by a cell reference. + +```c +interm_addr_regular$0 use_src_bits:(#<= 96) += IntermediateAddress; +interm_addr_simple$10 workchain_id:int8 addr_pfx:(64 * Bit) += IntermediateAddress; +interm_addr_ext$11 workchain_id:int32 addr_pfx:(64 * Bit) += IntermediateAddress; + +msg_envelope cur_addr:IntermediateAddress +next_addr:IntermediateAddress fwd_fee_remaining:Grams +msg:^(Message Any) = MsgEnvelope; +``` + +The `IntermediateAddress` type is used to describe the intermediate addresses of a message—that is, its current (or transit) address `cur_addr`, and its next-hop address `next_addr`. The first constructor `interm_addr_regular` represents the intermediate address using the optimization described in [2.1.15](#2-1-15-representation-of-transit-and-next-hop-addresses), by storing the number of the first bits of the intermediate address that are the same as in the source address; the two other explicitly store the workchain identifier and the first 64 bits of the address inside that workchain (the remaining bits can be taken from the source address). The `fwd_fee_remaining` field is used to explicitly represent the maximum amount of message forwarding fees that can be deducted from the message value during the remaining HR steps; it cannot exceed the value of `fwd_fee` indicated in the message itself. + +--- + +## 3.2 Inbound message descriptors + +This section discusses `InMsgDescr`, the structure containing a description of all inbound messages imported into a block.[²⁵](#footnote-25) + +### 3.2.1. Types and sources of inbound messages +Each inbound message mentioned in `InMsgDescr` is described by a value of type InMsg (an “inbound message descriptor”), which specifies the source of the message, the reason for its being imported into this block, and some information about its “fate”—its processing by a transaction or forwarding inside the block. + +Inbound messages may be classified as follows: + +- **Inbound external messages** — Need no additional reason for being imported into the block, but must be immediately processed by a transaction in the same block. +- **Internal IHR messages with destination addresses in this block** — The reason for their being imported into the block includes a Merkle proof of their generation (i.e., their inclusion in OutMsgDescr of their original block). Such a message must be immediately delivered to its final destination and processed by a transaction. +- **Internal messages with destinations in this block** — The reason for their inclusion is their presence in `OutMsgQueue` of the most recent state of a neighboring shardchain,[²⁶](#footnote-26) or their presence in `OutMsgDescr` of this very block. This neighboring shardchain is completely determined by the transit address indicated in the forwarded message envelope, which is replicated in InMsg as well. The “fate” of this message is again described by a reference to the processing transaction inside the current block. +- **Immediately routed internal messages** — Essentially a subclass of the previous class of messages. In this case, the imported message is one of the outbound messages generated in this very block. +- **Transit internal messages** — Have the same reason for inclusion as the previous class of messages. However, they are not processed inside the block, but internally forwarded into `OutMsgDescr` and `OutMsgQueue`. This fact, along with a reference to the new envelope of the transit message, must be registered in `InMsg`. +- **Discarded internal messages with destinations in this block** — An internal message with a destination in this block may be imported and immediately discarded instead of being processed by a transaction if it has already been received and processed via IHR in a preceding block of this shardchain. In this case, a reference to the previous processing transaction must be provided. +- **Discarded transit internal messages** — Similarly, a transit message may be discarded immediately after import if it has already been delivered via IHR to its final destination. In this case, a Merkle proof of its processing in the final block (as an IHR message) is required. + +### 3.2.2. Descriptor of an inbound message +Each inbound message is described by an instance of the InMsg type, which has six constructors corresponding to the cases listed above in [3.2.1](#3-2-1-types-and-sources-of-inbound-messages): + +```c +msg_import_ext$000 msg:^(Message Any) transaction:^Transaction += InMsg; + +msg_import_ihr$010 msg:^(Message Any) transaction:^Transaction +ihr_fee:Grams proof_created:^Cell = InMsg; + +msg_import_imm$011 in_msg:^MsgEnvelope +transaction:^Transaction fwd_fee:Grams = InMsg; + +msg_import_fin$100 in_msg:^MsgEnvelope +transaction:^Transaction fwd_fee:Grams = InMsg; + +msg_import_tr$101 in_msg:^MsgEnvelope out_msg:^MsgEnvelope +transit_fee:Grams = InMsg; + +msg_discard_fin$110 in_msg:^MsgEnvelope transaction_id:uint64 +fwd_fee:Grams = InMsg; + +msg_discard_tr$111 in_msg:^MsgEnvelope transaction_id:uint64 +fwd_fee:Grams proof_delivered:^Cell = InMsg; +``` + +Notice that the processing transaction is referred to in the first four constructors directly by a cell reference to Transaction, even though the logical time of the transaction `transaction_lt:uint64` would suffice for this purpose. Internal consistency conditions ensure that the transaction referred to does belong to the destination smart contract indicated in the message, and that the inbound message processed by that transaction is indeed the one being described in this InMsg instance. + +Furthermore, notice that `msg_import_imm` could be distinguished from `msg_import_fin` by observing that it is the only case when the logical creation time of the message being processed is greater than or equal to the (minimal) logical time of the block importing the message. + +### 3.2.3. Collecting forwarding and transit fees from imported messages + +The InMsg structure is also used to indicate the forwarding and transit fees collected from inbound messages. The fee itself is indicated in `ihr_fee`, `fwd_fee`, or `transit_fee` fields; it is absent only in inbound external messages, which use other mechanisms to reward the validators for importing them. The fees must satisfy the following internal consistency conditions: + +* For external messages (`msg_import_ext`), there is no forwarding fee. +* For IHR-imported internal messages (`msg_import_ihr`), the fee equals `ihr_fee`, which must coincide with the `ihr_fee` value indicated in the message itself. Notice that `fwd_fee` or `fwd_fee_remaining` are never collected from IHR-imported messages. +* For internal messages delivered to their destination (`msg_import_fin` and `msg_import_imm`), the fee equals the `fwd_fee_remaining` of the enveloped inbound message `in_msg`. Note that it cannot exceed the `fwd_fee` value indicated in the message itself. +* For transit messages (`msg_import_tr`), the fee equals the difference between the `fwd_fee_remaining` values indicated in the `in_msg` and `out_msg` envelopes. +* For discarded messages, the fee also equals the `fwd_fee_remaining` indicated in `in_msg`. + +### 3.2.4. Imported value of an inbound message + +Each imported message imports some value—a certain amount of one or more cryptocurrencies—into the block. This imported value is computed as follows: + +* An external message imports no value. +* An IHR-imported message imports its value plus its `ihr_fee`. +* A delivered or transit internal message imports its value plus its `ihr_fee` plus the value of `fwd_fee_remaining` of its `in_msg` envelope. +* A discarded message imports the `fwd_fee_remaining` of its `in_msg` envelope. + +Notice that the forwarding and transit fees collected from an imported message do not exceed its imported value. + +### 3.2.5. Augmented hashmaps, or dictionaries + +Before continuing, let us discuss the serialization of augmented hashmaps, or dictionaries. + +Augmented hashmaps are key-value storage structures with `n`-bit keys and values of some type `X`, similar to the ordinary hashmaps described in [4, 3.3](#ref-4). However, each intermediate node of the Patricia tree representing an augmented hashmap is augmented by a value of type `Y`. + +These augmentation values must satisfy certain aggregation conditions. Typically, `Y` is an integer type, and the aggregation condition is that the augmentation value of a fork must equal the sum of the augmentation values of its two children. In general, a fork evaluation function `S : Y × Y → Y` or `S : Y → Y → Y` is used instead of the sum. The augmentation value of a leaf is usually computed from the value stored in that leaf by means of a leaf evaluation function `L : X → Y`. The augmentation value of a leaf may be stored explicitly in the leaf along with the value; however, in most cases there is no need for this, because the leaf evaluation function `L` is very simple. + +### 3.2.6. Serialization of augmented hashmaps + +The serialization of augmented hashmaps with `n`-bit keys, values of type `X`, and augmentation values of type `Y` is given by the following TL-B scheme, which is an extension of the one provided in [4, 3.3.3](#ref-4): + +```tlb +ahm_edge#_ {n:#} {X:Type} {Y:Type} {l:#} {m:#} +label:(HmLabel ~l n) {n = (~m) + l} +node:(HashmapAugNode m X Y) = HashmapAug n X Y; + +ahmn_leaf#_ {X:Type} {Y:Type} extra:Y value:X += HashmapAugNode 0 X Y; + +ahmn_fork#_ {n:#} {X:Type} {Y:Type} +left:^(HashmapAug n X Y) right:^(HashmapAug n X Y) extra:Y += HashmapAugNode (n + 1) X Y; + +ahme_empty$0 {n:#} {X:Type} {Y:Type} extra:Y += HashmapAugE n X Y; + +ahme_root$1 {n:#} {X:Type} {Y:Type} root:^(HashmapAug n X Y) +extra:Y = HashmapAugE n X Y; +``` + +### 3.2.7. Augmentation of InMsgDescr + +The collection of inbound message descriptors is augmented by a vector of two currency values, representing the imported value and the forwarding and transit fees collected from a message or a collection of messages: + +```tlb +import_fees$_ fees_collected:Grams +value_imported:CurrencyCollection = ImportFees; +``` + +### 3.2.8. Structure of InMsgDescr + +Now the itself is defined as an augmented hashmap, with 256-bit keys (equal to the representation hashes of imported messages), values of type InMsg (cf. [3.2.2](#3-2-2-descriptor-of-an-inbound-message)), and augmentation values of type ImportFees (cf. [3.2.7](#3-2-7-augmentation-of-inmsgdescr)): + +```math +_ (HashmapAugE 256 InMsg ImportFees) = InMsgDescr; +``` + +This TL-B notation uses an anonymous constructor `_` to define `InMsgDescr` as a synonym for another type. + +### 3.2.9. Aggregation rules for InMsgDescr + +The fork evaluation and leaf evaluation functions (cf. [3.2.5](#3-2-5-augmented-hashmaps%2C-or-dictionaries)) are not included explicitly in the above notation, because the dependent types of TL-B are not expressive enough for this purpose. In words, the fork evaluation function is just the componentwise addition of two ImportFees instances, and the leaf evaluation function is defined by the rules listed in [3.2.3](#3-2-3-collecting-forwarding-and-transit-fees-from-imported-messages) and [3.2.4](#3-2-4-imported-value-of-an-inbound-message). In this way, the root of the Patricia tree representing an instance of InMsgDescr contains an ImportFees instance with the total value imported by all inbound messages, and with the total forwarding fees collected from them. + +## 3.3 Outbound message queue and descriptors + +This section discusses `OutMsgDescr`, the structure representing all outbound messages of a block, along with their envelopes and brief descriptions of the reasons for including them into `OutMsgDescr`. This structure also describes all modifications of `OutMsgQueue`, which is a part of the shardchain state. + +### 3.3.1. Types of outbound messages + +Outbound messages may be classified as follows: + +* **External outbound messages, or “messages to nowhere”** — Generated by a transaction inside this block. The reason for including such a message into `OutMsgDescr` is simply a reference to its generating transaction. +* **Immediately processed internal outbound messages** — Generated and processed in this very block, and not included into `OutMsgQueue`. The reason for including such a message is a reference to its generating transaction, and its “fate” is described by a reference to the corresponding entry in InMsgDescr. +* **Ordinary (internal) outbound messages** — Generated in this block and included into `OutMsgQueue`. +* **Transit (internal) outbound messages** — Imported into the `InMsgDescr` of the same block and routed via HR until a next-hop address outside the current shard is obtained. + +### 3.3.2. Message dequeueing records + +Apart from the above types of outbound messages, `OutMsgDescr` can contain special “message dequeueing records”, which indicate that a message has been removed from the `OutMsgQueue` in this block. The reason for this removal is indicated in the message deletion record; it consists of a reference to the enveloped message being deleted, and of the logical time of the neighboring shardchain block that has this enveloped message in its `InMsgDescr`. + +Notice that on some occasions a message may be imported from the `OutMsgQueue` of the current shardchain, internally routed (cf. [2.1.11](#2-1-11-internal-routing)), and then included into OutMsgDescr and OutMsgQueue again with a different envelope.[²⁷](#footnote-27) In this case, a variant of the transit outbound message description is used, which doubles as a message dequeueing record. + +### 3.3.3. Descriptor of an outbound message + +Each outbound message is described by an instance of OutMsg: + +```c +msg_export_ext$000 msg:^(Message Any) +transaction:^Transaction = OutMsg; + +msg_export_imm$010 out_msg:^MsgEnvelope +transaction:^Transaction reimport:^InMsg = OutMsg; + +msg_export_new$001 out_msg:^MsgEnvelope +transaction:^Transaction = OutMsg; + +msg_export_tr$011 out_msg:^MsgEnvelope +imported:^InMsg = OutMsg; + +msg_export_deq$110 out_msg:^MsgEnvelope +import_block_lt:uint64 = OutMsg; + +msg_export_tr_req$111 out_msg:^MsgEnvelope +imported:^InMsg = OutMsg; +``` + +The last two descriptions have the effect of removing (dequeueing) the message from OutMsgQueue instead of inserting it. The last one re-inserts the message into OutMsgQueue with a new envelope after performing the internal routing (cf. [2.1.11](#2-1-11-internal-routing)). + +### 3.3.4. Exported value of an outbound message + +Each outbound message described by an `OutMsg` exports some value—a certain amount of one or more cryptocurrencies—from the block. This exported value is computed as follows: + +* An external outbound message exports no value. +* An internal message, generated in this block, exports its value plus its `ihr_fee` plus its `fwd_fee`. Notice that `fwd_fee` must be equal to the `fwd_fee_remaining` indicated in the `out_msg` envelope. +* A transit message exports its value plus its `ihr_fee` plus the value of `fwd_fee_remaining` of its `out_msg` envelope. +* The same holds for `msg_export_tr_req`, the constructor of `OutMsg` used for re-inserted dequeued messages. +* A message dequeueing record (`msg_export_deq`; cf. [3.3.2](#3-3-2-message-dequeueing-records)) exports no value. + +### 3.3.5. Structure of OutMsgDescr + +The `OutMsgDescr` itself is simply an augmented hashmap (cf. [3.2.5](#3-2-5-augmented-hashmaps%2C-or-dictionaries), with 256-bit keys (equal to the representation hash of the message), values of type `OutMsg`, and augmentation values of type `CurrencyCollection`: + +```math +_ (HashmapAugE 256 OutMsg CurrencyCollection) = OutMsgDescr; +``` + +The augmentation is the exported value of the corresponding message, aggregated by means of the sum, and computed at the leaves as explained in [3.3.4](#3-3-4-exported-value-of-an-outbound-message). In this way, the total exported value appears near the root of the Patricia tree representing `OutMsgDescr`. + +The most important consistency condition for `OutMsgDescr` is that its entry with key `k` must be an `OutMsg` describing a message `m` with representation hash ``Hash♭(m) = k``. + +### 3.3.6. Structure of OutMsgQueue + +Recall (cf. [1.2.7](#1-2-7-outbound-message-queue-of-a-shardchain)) that `OutMsgQueue` is a part of the blockchain state, not of a block. Therefore, a block contains only hash references to its initial and final state, and its newly-created cells. + +The structure of `OutMsgQueue` is simple: it is just an augmented hashmap with 352-bit keys and values of type OutMsg: + +```math +_ (HashmapAugE 352 OutMsg uint64) = OutMsgQueue; +``` + +The key used for an outbound message `m` is the concatenation of its 32-bit next-hop `workchain_id`, the first 64 bits of the next-hop address inside that workchain, and the representation hash `Hash♭(m)` of the message `m` itself. + +The augmentation is by the logical creation time `Lt(m)` of message `m` at the leaves, and by the minimum of the augmentation values of the children at the forks. + +The most important consistency condition for `OutMsgQueue` is that the value at key `k` must indeed contain an enveloped message with the expected next-hop address and representation hash. + +### 3.3.7. Consistency conditions for OutMsg + +Several internal consistency conditions are imposed on `OutMsg` instances present in `OutMsgDescr`. They include the following: + +* Each of the first three constructors of outbound message descriptions includes a reference to the generating transaction. This transaction must belong to the source account of the message, it must contain a reference to the specified message as one of its outbound messages, and it must be recoverable by looking it up by its `account_id` and `transaction_id`. +* `msg_export_tr` and `msg_export_tr_req` must refer to an InMsg instance describing the same message (in a different original envelope). +* If one of the first four constructors is used, the message must be absent in the initial `OutMsgQueue` of the block; otherwise, it must be present. +* If `msg_export_deq` is used, the message must be absent in the final `OutMsgQueue` of the block; otherwise, it must be present. +* If a message is not mentioned in `OutMsgDescr`, it must be the same in the initial and final `OutMsgQueues` of the block. + +--- +# 4 Accounts and transactions + +This chapter discusses the layout of accounts (or smart contracts) and their state in the TON Blockchain. It also considers transactions, which are the only way to modify the state of an account, and to process inbound messages and generate new outbound messages. + +## 4.1 Accounts and their states + +Recall that a smart contract and an account are the same thing in the context of the TON Blockchain, and that these terms can be used interchangeably, at least as long as only small (or “usual”) smart contracts are considered. A large smart contract may employ several accounts lying in different shardchains of the same workchain for load balancing purposes. + +An account is identified by its full address, and is completely described by its state. In other words, there is nothing else in an account apart from its address and state. + +### 4.1.1. Account addresses + +In general, an account is completely identified by its full address, consisting of a 32-bit `workchain_id`, and the (usually 256-bit) internal address or account identifier `account_id` inside the chosen workchain. In the basic workchain (`workchain_id = 0`) and in the masterchain (`workchain_id = −1`) the internal address is always 256-bit. In these workchains,[²⁸](#footnote-28) `account_id` cannot be chosen arbitrarily, but must be equal to the hash of the initial code and data of the smart contract; otherwise, it will be impossible to initialize the account with the intended code and data (cf. [1.7.3](#1-7-3-initializing-smart-contracts-by-constructor-messages)), and to do anything with the accumulated funds in the account balance. + +### 4.1.2. Zero account + +By convention, the zero account or account with zero address accumulates the processing, forwarding, and transit fees, as well as any other payments collected by the validators of the masterchain or a workchain. Furthermore, the zero account is a “large smart contract”, meaning that each shardchain has its instance of the zero account, with the most significant bits of the address adjusted to lie in the shard. Any funds transferred to the zero account, intentionally or by accident, are effectively a gift for the validators. For example, a smart contract might destroy itself by sending all its funds to the zero account. + +### 4.1.3. Small and large smart contracts + +By default, smart contracts are “small”, meaning that they have one account address belonging to exactly one shardchain at any given moment of time. However, one can create a “large smart contract of splitting depth d”, meaning that up to 2ᵈ instances of the smart contract may be created, with the first d bits of the original address of the smart contract replaced by arbitrary bit sequences.[²⁹](#footnote-29) One can send messages to such smart contracts using internal anycast addresses with `anycast` set to d (cf. [3.1.2](#3-1-2-tl-b-scheme-for-addresses)). Furthermore, the instances of the large smart contract are allowed to use this anycast address as the source address of their generated messages. + +An instance of a large smart contract is an account with non-zero maximal splitting depth d. + + +### 4.1.4. The three kinds of accounts + +There are three kinds of accounts: + +* **Uninitialized** — The account only has a balance; its code and data have not yet been initialized. +* **Active** — The account’s code and data have been initialized as well. +* **Frozen** — The account’s code and data have been replaced by a hash, but the balance is still stored explicitly. The balance of a frozen account may effectively become negative, reflecting due storage payments. + +### 4.1.5. Storage profile of an account + +The storage profile of an account is a data structure describing the amount of persistent blockchain state storage used by that account. It describes the total amount of cells, data bits, and internal and external cell references used. + +```c +storage_used$_ cells:(VarUInteger 7) bits:(VarUInteger 7) +ext_refs:(VarUInteger 7) int_refs:(VarUInteger 7) +public_cells:(VarUInteger 7) = StorageUsed; +``` + +The same type `StorageUsed` may represent the storage profile of a message, as required, for instance, to compute fwd\_fee, the total forwarding fee for Hypercube Routing. The storage profile of an account has some additional fields indicating the last time when the storage fees were exacted: + +```c +storage_info$_ used:StorageUsed last_paid:uint32 +due_payment:(Maybe Grams) = StorageInfo; +``` + +The `last_paid` field contains either the unixtime of the most recent storage payment collected (usually this is the unixtime of the most recent transaction), or the unixtime when the account was created (again, by a transaction). The `due_payment` field, if present, accumulates the storage payments that could not be exacted from the balance of the account, represented by a strictly positive amount of nanograms; it can be present only for uninitialized or frozen accounts that have a balance of zero Grams (but may have non-zero balances in other cryptocurrencies). When `due_payment` becomes larger than the value of a configurable parameter of the blockchain, the account is destroyed altogether, and its balance, if any, is transferred to the zero account. + +### 4.1.6. Account description + +The state of an account is represented by an instance of type `Account`, described by the following TL-B scheme:[³⁰](#footnote-30) + +```c +account_none$0 = Account; +account$1 addr:MsgAddressInt storage_stat:StorageInfo +storage:AccountStorage = Account; + +account_storage$_ last_trans_lt:uint64 +balance:CurrencyCollection state:AccountState += AccountStorage; + +account_uninit$00 = AccountState; +account_active$1 _:StateInit = AccountState; +account_frozen$01 state_hash:uint256 = AccountState; + +acc_state_uninit$00 = AccountStatus; +acc_state_frozen$01 = AccountStatus; +acc_state_active$10 = AccountStatus; +acc_state_nonexist$11 = AccountStatus; + +tick_tock$_ tick:Bool tock:Bool = TickTock; +_ split_depth:(Maybe (## 5)) special:(Maybe TickTock) +code:(Maybe ^Cell) data:(Maybe ^Cell) +library:(Maybe ^Cell) = StateInit; +``` + +Notice that `account_frozen` contains the representation hash of an instance of `StateInit`, instead of that instance itself, which would otherwise be contained in an `account_active`; `account_uninit` is similar to `account_frozen`, but it does not contain an explicit `state_hash`, because it is assumed to be equal to the internal address of the account (`account_id`), already present in the `addr` field. The `split_depth` field is present and non-zero only in instances of large smart contracts. The `special` field may be present only in the masterchain—and within the masterchain, only in some fundamental smart contracts required for the whole system to function. + +The storage statistics kept in `storage_stat` reflect the total storage usage of cell slice storage. In particular, the bits and cells used to store the balance are also reflected in `storage_stat`. + +When a non-existent account needs to be represented, the `account_none` constructor is used. + +### 4.1.7. Account state as a message from an account to its future self + +Notice that the account state is very similar to a message sent from an account to its future self participating in the next transaction, for the following reasons: + +* The account state does not change between two consecutive transactions of the same account, so it is completely similar in this respect to a message sent from the earlier transaction to the later one. +* When a transaction is processed, its inputs are an inbound message and the previous account state; its outputs are outbound messages generated and the next account state. If we treat the state as a special kind of message, we see that every transaction has exactly two inputs (the account state and an inbound message) and at least one output. +* Both a message and the account state can carry code and data in an instance of `StateInit`, and some value in their balance. +* An account is initialized by a constructor message, which essentially carries the future state and balance of the account. +* On some occasions messages are converted into account states, and vice versa. For instance, when a shardchain merge event occurs, and two accounts that are instances of the same large contract need to be merged, one of them is converted into a message sent to the other one (cf. [4.2.11](#4-2-11-merge-transactions)). Similarly, when a shardchain split event occurs, and an instance of a large smart contract needs to be split into two, this is achieved by a special transaction that creates the new instance by means of a constructor message sent from the previously existing instance to the new one (cf. [4.2.10](#4-2-10-split-transactions)). +* One may say that a message is involved in transferring some information across space (between different shardchains, or at least accountchains), while an account state transfers information across time (from the past to the future of the same account). + +### 4.1.8. Differences between messages and account states + +Of course, there are important differences, too. For example: + +* The account state is transferred only “in time” (for a shardchain block to its successor), but never “in space” (from one shardchain to another). As a consequence, this transfer is done implicitly, without creating complete copies of the account state anywhere in the blockchain. +* Storage payments collected by the validators for keeping the account state usually are considerably smaller than message forwarding fees for the same amount of data. +* When an inbound message is delivered to an account, it is the code from the account that is invoked, not the code from the message. + +### 4.1.9. The combined state of all accounts in a shard + +The split part of the shardchain state (cf. [1.2.1](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state) and [1.2.2](#1-2-2-split-and-non-split-part-of-the-shardchain-block-and-state)) is given by + +```math +_ (HashmapAugE 256 Account CurrencyCollection) = ShardAccounts; +``` + +This is simply a dictionary with 256-bit `account_ids` as keys and corresponding account states as values, sum-augmented by the balances of the accounts. In this way the sum of balances of all accounts in a shardchain is computed, so that one can easily check the total amount of cryptocurrency “stored” in a shard. + +Internal consistency conditions ensure that the address of an account referred to by key `k` in SmartAccounts is indeed equal to `k`. An additional internal consistency condition requires that all keys `k` begin with the shard prefix `s`. + +### 4.1.10. Account owner and interface descriptions + +One may want to include some optional information in a controlled account. For example, an individual user or a company may want to add a text description field to their wallet account, with the user’s or company’s name or address (or their hash, if the information should not be made publicly available). Alternatively, a smart contract may offer a machine-readable or human-readable description of its supported methods and their intended application, which might be used by advanced wallet applications to construct drop-down menus and forms helping a human user to create valid messages to be sent to that smart contract. + +One way of including such information is to reserve, say, the second reference in the data cell of the state of an account for a dictionary with 64-bit keys (corresponding to some identifiers of the standard types of extra data one might want to store) and corresponding values. Then a blockchain explorer would be able to extract the required value, along with a Merkle proof if necessary. + +A better way of doing this is by defining some get methods in the smart contract. + +### 4.1.11. Get methods of a smart contract + +Get methods are executed by a stand-alone instance of TVM with the account’s code and data loaded into it. The required parameters are passed on the stack (say, a magic number indicating the field to be fetched or the specific get method to be invoked), and the results are returned on the TVM stack as well (say, a cell slice containing the serialization of a string with the account owner’s name). + +As a bonus, get methods may be used to get answers to more sophisticated queries than just fetching a constant object. For instance, TON DNS registry smart contracts provide get methods to look up a doa domain string in the registry and return the corresponding record, if found. + +By convention, get methods use large negative 32-bit or 64-bit indices or magic numbers, and internal functions of a smart contract use consecutive positive indices, to be used in TVM’s `CALLDICT` instruction. The `main()` function of a smart contract, used to process inbound messages in ordinary transactions, always has index zero. + +--- + +## 4.2 Transactions +According to the Infinite Sharding Paradigm and the actor model, the three +principal components of the TON Blockchain are accounts (along with their +states), messages, and transactions. Previous sections have already discussed +the first two; this section considers transactions. + +In contrast with messages, which have essentially the same headers throughout all workchains of the TON Blockchain, and accounts, which have at least +some common parts (the address and the balance), our discussion of transactions is necessarily limited to the masterchain and the basic workchain. +Other workchains may define completely different kinds of transactions. + + +### 4.2.1. Logical time of a transaction + +Each transaction `t` has a logical time interval `Lt•(t) = [Lt⁻(t), Lt⁺(t))` assigned to it (cf. [1.4.6](#1-4-6-logical-time-in-the-ton-blockchain) and [1.4.3](#1-4-3-logical-time-intervals)). + +By convention, a transaction `t` generating `n` outbound messages `m₁, ..., mₙ` is assigned a logical time interval of length `n + 1`, so that: + +```math +Lt⁺(t) = Lt⁻(t) + n + 1 (16) +``` + +We also set `Lt(t) := Lt⁻(t)`, and assign the logical creation time of message `mᵢ`, where `1 ≤ i ≤ n`, by: + +```math +Lt(mᵢ) = Lt⁻(mᵢ) := Lt⁻(t) + i +Lt⁺(mᵢ) := Lt⁻(mᵢ) + 1 (17) +``` + +In this way, each generated outbound message is assigned its own unit interval inside the logical time interval `Lt•(t)` of transaction `t`. + +### 4.2.2. Logical time uniquely identifies transactions and outbound messages of an account + +Recall that the conditions imposed on logical time imply that: + +```math +Lt⁻(t) ≥ Lt⁺(t′) +``` + +for any preceding transaction `t′` of the same account `ξ`, and that: + +```math +Lt⁻(t) > Lt(m) +``` + +if `m` is the inbound message processed by transaction `t`. + +In this way, the logical time intervals of transactions of the same account do not intersect each other, and as a consequence, the logical time intervals of all outbound messages generated by an account do not intersect each other either. In other words, all `Lt(m)` are different when `m` runs through all outbound messages of the same account `ξ`. + +In this way, `Lt(t)` and `Lt(m)`, when combined with an account identifier `ξ`, uniquely determine a transaction `t` or an outbound message `m` of that account. Furthermore, if one has an ordered list of all transactions of an account along with their logical times, it is easy to find the transaction that generated a given outbound message `m`, simply by looking up the transaction `t` with logical time `Lt(t)` nearest to `Lt(m)` from below. + + +### 4.2.3. Generic components of a transaction. + +Each transaction t contains or indirectly refers to the following data: + +* The account ξ to which the transaction belongs. +* The logical time `Lt(t)` of the transaction. +* One or zero inbound messages m processed by the transaction. +* The number of generated outbound messages `n ≥ 0`. +* The outbound messages `m₁, ..., mₙ`. +* The initial state of account ξ (including its balance). +* The final state of account ξ (including its balance). +* The total fees collected by the validators. +* The detailed description of the transaction containing all or some data + needed to validate it, including the kind of the transaction (cf. [4.2.4](#4-2-4-kinds-of-transactions)) + and some of the intermediate steps performed. + +Of these components, all but the very last one are quite general and might appear in other workchains as well. + +### 4.2.4. Kinds of transactions. + +There are different kinds of transactions allowed in the masterchain and the shardchains. **Ordinary transactions** consist +in the delivery of one inbound message to an account, and its processing by +that account’s code; this is the most common kind of transaction. Additionally, there are several kinds of exotic transactions. + +Altogether, there are six kinds of transactions: + +* **Ordinary transactions** — Belong to an account ξ. They process exactly + one inbound message m (described in `InMsgDescr` of the encompassing + block) with destination ξ, compute the new state of the account, and + generate several outbound messages (registered in `OutMsgDescr`) with + source ξ. +* **Storage transactions** — Can be inserted by validators at their discretion. + They do not process any inbound message and do not invoke any + code. Their only effect is to collect storage payments from an account, + affecting its storage statistics and its balance. If the resulting Gram + balance of the account becomes less than a certain amount, the account + may be frozen and its code and data replaced by their combined hash. +* **Tick transactions** — Automatically invoked for certain special accounts + (smart contracts) in the masterchain that have the tick flag set in + their state, as the very first transactions in every masterchain block. + They have no inbound message, but may generate outbound messages + and change the account state. For instance, validator elections are + performed by tick transactions of special smart contracts in the masterchain. +* **Tock transactions** — Similarly automatically invoked as the very last + transactions in every masterchain block for certain special accounts. +* **Split transactions** — Invoked as the last transactions of shardchain + blocks immediately preceding a shardchain split event. They are triggered + automatically for instances of large smart contracts that need to + produce a new instance after splitting. +* **Merge transactions** — Similarly invoked as the first transactions of + shardchain blocks immediately after a shardchain merge event, if an + instance of a large smart contract needs to be merged with another + instance of the same smart contract. + +Notice that out of these six kinds of transactions, only four can occur in the +masterchain, and another subset of four can occur in the basic workchain. + +### 4.2.5. Phases of an ordinary transaction. + +An ordinary transaction +is performed in several phases, which may be thought of as several “subtransactions” +tightly bound into one: + +* **Storage phase** — Collects due storage payments for the account state + (including smart-contract code and data, if present) up to the present + time. The smart contract may be frozen as a result. If the smart + contract did not exist before, the storage phase is absent. +* **Credit phase** — The account is credited with the value of the inbound + message received. +* **Computing phase** — The code of the smart contract is invoked inside + an instance of TVM with adequate parameters, including a copy of the + inbound message and of the persistent data, and terminates with an exit + code, the new persistent data, and an action list (which includes, for + instance, outbound messages to be sent). The processing phase may + lead to the creation of a new account (uninitialized or active), or to + the activation of a previously uninitialized or frozen account. The gas + payment, equal to the product of the gas price and the gas consumed, + is exacted from the account balance. +* **Action phase** — If the smart contract has terminated successfully (with + exit code 0 or 1), the actions from the list are performed. If it is + impossible to perform all of them—for example, because of insufficient + funds to transfer with an outbound message—then the transaction is + aborted and the account state is rolled back. The transaction is also + aborted if the smart contract did not terminate successfully, or if it was + not possible to invoke the smart contract at all because it is uninitialized + or frozen. +* **Bounce phase** — If the transaction has been aborted, and the inbound + message has its bounce flag set, then it is “bounced” by automatically + generating an outbound message (with the bounce flag clear) to its + original sender. Almost all value of the original inbound message (minus + gas payments and forwarding fees) is transferred to the generated + message, which otherwise has an empty body. + +### 4.2.6. Bouncing inbound messages to non-existent accounts. + +Notice +that if an inbound message with its bounce flag set is sent to a previously +non-existent account, and the transaction is aborted (for instance, because +there is no code and data with the correct hash in the inbound message, so +the virtual machine could not be invoked at all), then the account is not created even as an uninitialized account, since it would have zero balance and no code and data anyways.[³¹](#footnote-31) + +### 4.2.7. Processing of an inbound message is split between computing and action phases. + +Notice that the processing of an inbound message is in fact split into two phases: the computing phase and the action phase. During the computing phase, the virtual machine is invoked and the necessary computations are performed, but no actions outside the virtual machine are taken. In other words, the execution of a smart contract in `TVM` has no side effects; there is no way for a smart contract to interact with the blockchain directly during its execution. Instead, `TVM` primitives such as `SENDMSG` simply store the required action (e.g., the outbound message to be sent) into the action list being gradually accumulated in `TVM` control register `c5`. The actions themselves are postponed until the action phase, during which the user smart contract is not invoked at all. + +### 4.2.8. Reasons for splitting the processing into computation and action phases. + +Some reasons for such an arrangement are: + +* It is simpler to abort the transaction if the smart contract eventually terminates with an exit code other than `0` or `1`. +* The rules for processing output actions may be changed without modifying the virtual machine. (For instance, new output actions may be introduced.) +* The virtual machine itself may be modified or even replaced by another one (for instance, in a new workchain) without changing the rules for processing output actions. +* The execution of the smart contract inside the virtual machine is completely isolated from the blockchain and is a pure computation. As a consequence, this execution may be virtualized inside the virtual machine itself by means of `TVM`’s `RUNVM` primitive, a useful feature for validator smart contracts and for smart contracts controlling payment channels and other sidechains. Additionally, the virtual machine may be emulated inside itself or a stripped-down version of itself, a useful feature for validating the execution of smart contracts inside `TVM`.[³²](#footnote-32) + +### 4.2.9. Storage, tick, and tock transactions. + +Storage transactions are very similar to a stand-alone storage phase of an ordinary transaction. Tick and tock transactions are similar to ordinary transactions without credit and bounce phases, because there is no inbound message. + +### 4.2.10. Split transactions. + +Split transactions in fact consist of two transactions. If an account ξ needs to be split into two accounts ξ and ξ′: + +* First a split prepare transaction, similar to a tock transaction (but in a shardchain instead of the masterchain), is issued for account ξ. It must be the last transaction for ξ in a shardchain block. The output of the processing stage of a split prepare transaction consists not only of the new state of account ξ, but also of the new state of account ξ′, represented by a constructor message to ξ′ (cf. [4.1.7](#4-1-7-account-state-as-a-message-from-an-account-to-its-future-self)). +* Then a split install transaction is added for account ξ′, with a reference to the corresponding split prepare transaction. The split install transaction must be the only transaction for a previously non-existent account ξ′ in the block. It effectively sets the state of ξ′ as defined by the split prepare transaction. + +### 4.2.11. Merge transactions. + +Merge transactions also consist of two transactions each. If an account ξ′ needs to be merged into account ξ: + +* First a merge prepare transaction is issued for ξ′, which converts all of its persistent state and balance into a special constructor message with destination ξ (cf. [4.1.7](#4-1-7-account-state-as-a-message-from-an-account-to-its-future-self)). +* Then a merge install transaction for ξ, referring to the corresponding merge prepare transaction, processes that constructor message. The merge install transaction is similar to a tick transaction in that it must be the first transaction for ξ in a block, but it is located in a shardchain block, not in the masterchain, and it has a special inbound message. + +### 4.2.12. Serialization of a general transaction. + +Any transaction contains the fields listed in [4.2.3](#4-2-3-generic-components-of-a-transaction). As a consequence, there are some common +components in all transactions: + +```c +transaction$_ account_addr:uint256 lt:uint64 outmsg_cnt:uint15 +orig_status:AccountStatus end_status:AccountStatus +in_msg:(Maybe ^(Message Any)) +out_msgs:(HashmapE 15 ^(Message Any)) +total_fees:Grams state_update:^(MERKLE_UPDATE Account) +description:^TransactionDescr = Transaction; + +!merkle_update#02 {X:Type} old_hash:uint256 new_hash:uint256 +old:^X new:^X = MERKLE_UPDATE X; +``` + +The exclamation mark in the TL-B declaration of a merkle\_update indicates +special processing required for such values. In particular, they must be kept +in a separate cell, which must be marked as exotic by a bit in its header +(cf. [4, 3.1](#ref-4)). + +A full explanation of the serialization of TransactionDescr, which describes one transaction according to its kind listed in [4.2.4](#4-2-4-kinds-of-transactions), can be found +in [4.3](#4-3-transaction-descriptions). + +### 4.2.13. Representation of outbound messages generated by a transaction. + +The outbound messages generated by a transaction `t` are kept in a dictionary `out_msgs` with 15-bit keys equal to `0, 1, … , n − 1`, where `n = outmsg_cnt` is the number of generated outbound messages. + +Message `mᵢ₊₁` with index `0 ≤ i < n` must have: + +```math +Lt(mᵢ₊₁) = Lt(t) + i + 1 +```` + +and + +```math +Lt(t) = Lt⁻(t) +``` + +is explicitly stored in the `lt` field. + +### 4.2.14. Consistency conditions for transactions. + +The common serialization of the fields present in a Transaction, independent of its type and +description, enables us to impose several “external” consistency conditions +on any transaction. The most important of them involves the value flow inside the transaction: the sum of all inputs (the import value of the inbound +message plus the original balance of the account) must equal the sum of all +outputs (the resulting balance of the account, plus the sum of the export +values of all outbound messages, plus all storage, processing, and forwarding +fees collected by the validators). + +In this way, a surface inspection of a transaction, which processes an inbound message with an import value of 1 Gram +received by an account with an initial balance of 10 Grams, generating an +outbound message with an export value of 100 Grams in the process, will +reveal its invalidity even before checking all the details of the TVM execution. + +Other consistency conditions may slightly depend on the description of +the transaction. For instance, the inbound message processed by an ordinary +transaction must be registered in the `InMsgDescr` of the encompassing block, +and the corresponding record must contain a reference to this transaction. +Similarly, all outbound messages generated by all transactions (with the exception of one special message generated by a split prepare or merge prepare +transaction) must be registered in `OutMsgDescr`. + +### 4.2.15. Collection of all transactions of an account. + +All transactions in +a block belonging to the same account ξ are collected into an “accountchain +block” AccountBlock, which essentially is a dictionary transactions with +64-bit keys, each equal to the logical time of the corresponding transaction: + +```c +acc_trans$_ account_addr:uint256 +transactions:(HashmapAug 64 ^Transaction Grams) +state_update:^(MERKLE_UPDATE Account) += AccountBlock; +``` + +The transactions dictionary is sum-augmented by a Grams value, which +aggregates the total fees collected from these transactions. + +In addition to this dictionary, an AccountBlock contains a Merkle update +(cf. [4, 3.1](#ref-4)) of the total state of the account. If an account did not exist +before the block, its state is represented by an account\_none. + +### 4.2.16. Consistency conditions for AccountBlocks. + +There are several +general consistency conditions imposed on an AccountBlock. In particular: + +* The transaction appearing as a value in the augmented transactions + dictionary must have its `lt` value equal to its key. +* All transactions must belong to an account whose address `account_addr` + is indicated in the AccountBlock. +* If t and t′ are two transactions with `Lt(t)` < `Lt(t′)`, and their keys are + consecutive in transactions, meaning that there is no transaction t″ + with `Lt(t)` < `Lt(t″)` < `Lt(t′)`, then the final state of t must correspond + to the initial state of t′ (their hashes as explicitly indicated in the Merkle + updates must be equal). +* If t is the transaction with minimal `Lt(t)`, its initial state must coincide + with the initial state as indicated in `state_update` of the AccountBlock. +* If t is the transaction with maximal `Lt(t)`, its final state must coincide + with the final state as indicated in `state_update` of the AccountBlock. +* The list of transactions must be non-empty. + +These conditions simply express the fact that the state of an account may +change only as the result of performing a transaction. + +### 4.2.17. Collection of all transactions in a block. + +All transactions in a +block are represented by (cf. [1.2.1](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state)): + +```math +_ (HashmapAugE 256 AccountBlock Grams) = ShardAccountBlocks; +``` + +### 4.2.18. Consistency conditions for the collection of all transactions. + +Again, consistency conditions are imposed on this structure, requiring that +the value at key ξ be an AccountBlock with address equal to ξ. Further +consistency conditions relate this structure with the initial and final states +of the shardchain indicated in the block, requiring that: + +* If ShardAccountBlock has no key ξ, then the state of account ξ in the + initial and in the final state of the block must coincide (or it must be + absent from both). +* If ξ is present in ShardAccountBlock, its initial and final states as indicated in AccountBlock must match those indicated in the initial and + final states of the shardchain block, expressed by instances of ShardAccounts (cf. [4.1.9](#4-1-9-the-combined-state-of-all-accounts-in-a-shard)). + +These conditions express that the shardchain state is indeed composed out +of the states of separate accountchains. + +## 4.3 Transaction descriptions + +This section presents the specific TL-B schemes for transaction descriptions +according to the classification provided in [4.2.4](#4-2-4-kinds-of-transactions). + +### 4.3.1. Reasons for omitting data from a transaction description. + +A transaction description for a blockchain featuring a Turing-complete virtual +machine for smart-contract execution is necessarily incomplete. Indeed, a +truly complete description would contain all the intermediate states of the +virtual machine after each instruction is executed, something that cannot fit +into a blockchain block of a reasonable size. Therefore, the description of +such a transaction is likely to contain only the total number of steps and the +hashes of the initial and final states of the virtual machine. The validation of +such a transaction will necessarily involve the execution of the smart contract +to reproduce all the intermediate steps and the final result. + +If we compress the sequence of all intermediate steps of the virtual machine into just the hashes of the initial and final states, then no transaction +details at all need to be included: a validator able to check the execution of +the virtual machine by itself would also be able to check all the other actions +of the transaction starting from its initial data without these details. + +### 4.3.2. Reasons for including data into a transaction description. + +The above considerations notwithstanding, there are still several reasons to +introduce some details in the transaction description: + +* We want to impose external consistency conditions on the transaction, + so that at least the validity of the value flow inside the transaction + and the validity of inbound and outbound messages can be quickly + checked without invoking the virtual machine (cf. [4.2.14](#4-2-14-consistency-conditions-for-transactions)). This at least + guarantees the invariance of the total amount of each cryptocurrency + in the blockchain, even if it does not guarantee the correctness of its + distribution. +* We want to be able to trace principal state changes of an account (such + as its being created, activated, or frozen) by inspecting the data stored + in the transaction description, without figuring out the missing details + of the transaction. This simplifies the verification of the consistency + conditions between the accountchain and shardchain states in a block. +* Finally, certain information—such as the total steps of the virtual + machine, the hashes of its initial and final states, the total gas consumed, + and the exit code—might considerably simplify the debugging + and implementation of the TON Blockchain software. (This information + would help a human programmer understand what has happened + in a particular blockchain block.) + +On the other hand, we want to minimize the size of each transaction, because we want to maximize the number of transactions that can fit into each +(bounded-size) block. Therefore, all information not required for one of the +above reasons is omitted. + +### 4.3.3. Description of a storage phase. + +The storage phase is present in +several kinds of transactions, so a common representation for this phase is +used: + +```c +tr_phase_storage$_ storage_fees_collected:Grams +storage_fees_due:(Maybe Grams) +status_change:AccStatusChange += TrStoragePhase; + +acst_unchanged$0 = AccStatusChange; // x -> x +acst_frozen$10 = AccStatusChange; // init -> frozen +acst_deleted$11 = AccStatusChange; // frozen -> deleted +``` + +### 4.3.4. Description of a credit phase. + +The credit phase can result in the +collection of some due payments: + +```c +tr_phase_credit$_ due_fees_collected:(Maybe Grams) +credit:CurrencyCollection = TrCreditPhase; +``` + +The sum of `due_fees_collected` and `credit` must equal the value of the message received, plus its `ihr_fee` if the message has not been received via IHR (otherwise the `ihr_fee` is awarded to the validators). + +### 4.3.5. Description of a computing phase. + +The computing phase consists +in invoking TVM with correct inputs. On some occasions, TVM cannot be +invoked at all (e.g., if the account is absent, not initialized, or frozen, and the +inbound message being processed has no code or data fields or these fields +have an incorrect hash); this is reflected by corresponding constructors. + +```c +tr_phase_compute_skipped$0 reason:ComputeSkipReason += TrComputePhase; + +tr_phase_compute_vm$1 success:Bool msg_state_used:Bool +account_activated:Bool gas_fees:Grams +_:^[ gas_used:(VarUInteger 7) + gas_limit:(VarUInteger 7) gas_credit:(Maybe (VarUInteger 3)) + mode:int8 exit_code:int32 exit_arg:(Maybe int32) + vm_steps:uint32 + vm_init_state_hash:uint256 vm_final_state_hash:uint256 ] += TrComputePhase; + +cskip_no_state$00 = ComputeSkipReason; +cskip_bad_state$01 = ComputeSkipReason; +cskip_no_gas$10 = ComputeSkipReason; +``` + +The TL-B construct `_:^[...]` describes a reference to a cell containing the fields listed inside the square brackets. In this way, several fields can be moved from a cell containing a large record into a separate subcell. + +### 4.3.6. Skipped computing phase. + +If the computing phase has been +skipped, possible reasons include: + +* The absence of funds to buy gas. +* The absence of a state (i.e., smart-contract code and data) in both the + account (non-existing, uninitialized, or frozen) and the message. +* An invalid state passed in the message (i.e., the state’s hash differs + from the expected value) to a frozen or uninitialized account. + +### 4.3.7. Valid computing phase. + +If there is no reason to skip the computing phase, TVM is invoked and the results of the computation are logged. +Possible parameters are as follows: + +* The `success` flag is set if and only if `exit_code` is either 0 or 1. +* The `msg_state_used` parameter reflects whether the state passed in the message has been used. If it is set, the `account_activated` flag reflects whether this has resulted in the activation of a previously frozen, uninitialized or non-existent account. +* The `gas_fees` parameter reflects the total gas fees collected by the validators for executing this transaction. It must be equal to the product of `gas_used` and `gas_price` from the current block header. +* The `gas_limit` parameter reflects the gas limit for this instance of TVM. It equals the lesser of either the Grams credited in the credit phase from the value of the inbound message divided by the current gas price, or the global per-transaction gas limit. The `gas_credit` parameter may be non-zero only for external inbound messages. It is the lesser of either the amount of gas that can be paid from the account balance or the maximum gas credit. +* The `exit_code` and `exit_args` parameters represent the status values returned by TVM. +* The `vm_init_state_hash` and `vm_final_state_hash` parameters are the representation hashes of the original and resulting states of TVM, and `vm_steps` is the total number of steps performed by TVM (usually equal to two plus the number of instructions executed, including implicit `RET`s).[³³](#footnote-33) + +### 4.3.8. Description of the action phase. + +The action phase occurs after a valid computation phase. It attempts to perform the actions stored by TVM during the computing phase into the action list. It may fail, because the action list may turn out to be too long, contain invalid actions, or contain actions that cannot be completed (for instance, because of insufficient funds to create an outbound message with the required value). + +```c +tr_phase_action$_ success:Bool valid:Bool no_funds:Bool +status_change:AccStatusChange +total_fwd_fees:(Maybe Grams) total_action_fees:(Maybe Grams) +result_code:int32 result_arg:(Maybe int32) tot_actions:int16 +spec_actions:int16 msgs_created:int16 +action_list_hash:uint256 tot_msg_size:StorageUsed += TrActionPhase; +``` + +### 4.3.9. Description of the bounce phase. + +```c +tr_phase_bounce_negfunds$00 = TrBouncePhase; +tr_phase_bounce_nofunds$01 msg_size:StorageUsed +req_fwd_fees:Grams = TrBouncePhase; +tr_phase_bounce_ok$1 msg_size:StorageUsed +msg_fees:Grams fwd_fees:Grams = TrBouncePhase; +``` + +### 4.3.10. Description of an ordinary transaction. + +```c +trans_ord$0000 storage_ph:(Maybe TrStoragePhase) +credit_ph:(Maybe TrCreditPhase) +compute_ph:TrComputePhase action:(Maybe ^TrActionPhase) +aborted:Bool bounce:(Maybe TrBouncePhase) +destroyed:Bool += TransactionDescr; +``` + +Several consistency conditions are imposed on this structure: + +* action is absent if and only if the computing phase was unsuccessful. +* The aborted flag is set either if there is no action phase or if the action phase was unsuccessful. +* The bounce phase occurs only if the aborted flag is set and the inbound message was bounceable. + +### 4.3.11. Description of a storage transaction. + +A storage transaction consists just of one stand-alone storage phase: + +```c +trans_storage$0001 storage_ph:TrStoragePhase += TransactionDescr; +``` + +### 4.3.12. Description of tick and tock transactions. + +Tick and tock transactions are similar to ordinary transactions without an inbound message, so there are no credit or bounce phases: + +```c +trans_tick_tock$001 is_tock:Bool storage:TrStoragePhase +compute_ph:TrComputePhase action:(Maybe ^TrActionPhase) +aborted:Bool destroyed:Bool = TransactionDescr; +``` + +### 4.3.13. Split prepare and install transactions. + +A split prepare transaction is similar to a tock transaction in a masterchain, but it must generate exactly one special constructor message; otherwise, the action phase is +aborted. + +```c +split_merge_info$_ cur_shard_pfx_len:(## 6) +acc_split_depth:(## 6) this_addr:uint256 sibling_addr:uint256 += SplitMergeInfo; + +trans_split_prepare$0100 split_info:SplitMergeInfo +compute_ph:TrComputePhase action:(Maybe ^TrActionPhase) +aborted:Bool destroyed:Bool += TransactionDescr; + +trans_split_install$0101 split_info:SplitMergeInfo +prepare_transaction:^Transaction +installed:Bool = TransactionDescr; +``` + +Notice that the split install transaction for the new sibling account ξ′ refers to +its corresponding split prepare transaction of the previously existing account +ξ. + +### 4.3.14. Merge prepare and install transactions. + +A merge prepare transaction converts the state and balance of an account into a message, and a +subsequent merge install transaction processes this state: + +```c +trans_merge_prepare$0110 split_info:SplitMergeInfo +storage_ph:TrStoragePhase aborted:Bool += TransactionDescr; + +trans_merge_install$0111 split_info:SplitMergeInfo +prepare_transaction:^Transaction +credit_ph:(Maybe TrCreditPhase) +compute_ph:TrComputePhase action:(Maybe ^TrActionPhase) +aborted:Bool destroyed:Bool += TransactionDescr; +``` + +# 4.4 Invoking smart contracts in TVM + +This section describes the exact parameters with which `TVM` is invoked during the computing phase of ordinary and other transactions. + +### 4.4.1. Smart-contract code + +The code of a smart contract is normally a part of the account’s persistent state, at least if the account is active (cf. [4.1.6](#4-1-6-account-description)). However, a frozen or uninitialized (or non-existent) account has no persistent state, with the possible exception of the account’s balance and the hash of its intended state (equal to the account address for uninitialized accounts). In this case, the code must be supplied in the `init` field of the inbound message being processed by the transaction (cf. [3.1.7](#3-1-7-message-layout)). + +### 4.4.2. Smart-contract persistent data + +The persistent data of a smart contract is kept alongside its code, and remarks similar to those made above in [4.4.1](#4-4-1-smart-contract-code) apply. In this respect, the code and persistent data of a smart contract are just two parts of its persistent state, which differ only in the way they are treated by `TVM` during smart-contract execution. + +### 4.4.3. Smart-contract library environment + +The library environment of a smart contract is a hashmap mapping 256-bit cell (representation) hashes into the corresponding cells themselves. When an external cell reference is accessed during the execution of a smart contract, the cell referred to is looked up in the library environment and the external cell reference is transparently replaced by the cell found. + +The library environment for an invocation of a smart contract is computed as follows: + +1. The global library environment for the workchain in question is taken from the current state of the masterchain.[³⁴](#footnote-34) +2. Next, it is augmented by the local library environment of the smart contract, stored in the `library` field of the smart contract’s state. Only 256-bit keys equal to the hashes of the corresponding value cells are taken into account. If a key is present in both the global and local library **environment**, the local environment takes precedence while merging the two library environments. +3. Finally, the message library stored in the `library` field of the `init` field of the inbound message is similarly taken into account. Notice, however, that if the account is frozen or uninitialized, the `library` field of the message is part of the suggested state of the account, and is used instead of the local library environment in the previous step. The message library has lower precedence than both the local and the global library environments. + +### 4.4.4. The initial state of TVM + +A new instance of `TVM` is initialized prior to the execution of a smart contract as follows: + +* The original `cc` (current continuation) is initialized using the cell slice created from the cell `code`, containing the code of the smart contract computed as described in [4.4.1](#4-4-1-smart-contract-code). + The `cp` (`TVM` codepage) is set to zero. If the smart contract wants to use another `TVM` codepage `x`, it must switch to it by using `SETCODEPAGE x` as the first instruction of its code. +* Control register `c0` (return continuation) is initialized by extraordinary continuation `ec_quit` with parameter `0`. When executed, this continuation leads to a termination of `TVM` with exit code `0`. +* Control register `c1` (alternative return continuation) is initialized by extraordinary continuation `ec_quit` with parameter `1`. When invoked, it leads to a termination of `TVM` with exit code `1`. (Notice that terminating with exit code `0` or `1` is considered a successful termination.) +* Control register `c2` (exception handler) is initialized by extraordinary continuation `ec_quit_exc`. When invoked, it takes the top integer from the stack (equal to the exception number) and terminates `TVM` with exit code equal to that integer. In this way, by default all exceptions terminate the smart-contract execution with exit code equal to the exception number. +* Control register `c3` (code dictionary) is initialized by the cell with the smart-contract code, similarly to the initial current continuation (`cc`). +* Control register `c4` (root of persistent data) is initialized by the persistent data of the smart contract.[³⁵](#footnote-35) +* Control register `c5` (root of actions) is initialized by an empty cell. The “output action” primitives of `TVM`, such as `SENDMSG`, use `c5` to accumulate the list of actions (e.g., outbound messages) to be performed upon successful termination of the smart contract (cf. [4.2.7](#4-2-7-processing-of-an-inbound-message-is-split-between-computing-and-action-phases) and [4.2.8](#4-2-8-reasons-for-splitting-the-processing-into-computation-and-action-phases)). +* Control register `c7` (root of temporary data) is initialized by a singleton `Tuple`, the only component of which is a `Tuple` containing an instance of `SmartContractInfo` with smart contract balance and other useful information (cf. [4.4.10](#4-4-10-smart-contract-information)). The smart contract may replace the temporary data, especially all components of the `Tuple` at `c7` but the first one, with whatever other temporary data it may require. However, the original content of the `SmartContractInfo` at the first component of the `Tuple` held in `c7` is inspected and sometimes modified by `SENDMSG` `TVM` primitives and other “output action” primitives of `TVM`. +* The gas limits `gas = (gₘ, gₗ, g𝚌, gᵣ)` are initialized as follows: + - The maximal gas limit `gₘ` is set to the lesser of either the total Gram balance of the smart contract (after the credit phase — i.e., combined with the value of the inbound message) divided by the current gas price, or the per-execution global gas limit.[³⁶](#footnote-36) + + - The current gas limit `gₗ` is set to the lesser of either the Gram value of the inbound message divided by the gas price, or the global per-execution gas limit. In this way, always `gₗ ≤ gₘ`. For inbound external messages `gₗ = 0`, since they cannot carry any value. + + - The gas credit `g𝚌` is set to zero for inbound internal messages, and to the lesser of either `gₘ` or a fixed small value (the default `external_message_gas_credit`, a configurable parameter) for inbound external messages. + + - Finally, the remaining gas limit `gᵣ` is automatically initialized by `gₗ + g𝚌`. + + +### 4.4.5. The initial stack of TVM for processing an internal message + +After `TVM` is initialized as described in [4.4.4](#4-4-4-the-initial-state-of-tvm), its stack is initialized by pushing the arguments to the `main()` function of the smart contract as follows: + +* The Gram balance `b` of the smart contract (after crediting the value of the inbound message) is passed as an `Integer` amount of nanograms. +* The Gram balance `bₘ` of inbound message `m` is passed as an `Integer`amount of nanograms. +* The inbound message `m` is passed as a cell, which contains a serialized value of type `Message X`, where `X` is the type of the message body. The body `m₍b₎ : X` of the inbound message, equal to the value of field `body` of `m`, is passed as a cell slice. +* Finally, the function selector `s`, an `Integer` normally equal to zero, is pushed into the stack. + +After that, the code of the smart contract, equal to its initial value of `c3`, is executed. It selects the correct function according to `s`, which is expected to process the remaining arguments to the function and terminate afterwards. + +### 4.4.6. Processing an inbound external message + +An inbound external message is processed similarly to [4.4.4](#4-4-4-the-initial-state-of-tvm) and [4.4.5](#4-4-5-the-initial-stack-of-tvm-for-processing-an-internal-message), with the following modifications: + +* The function selector `s` is set to `−1`, not to `0`. +* The Gram balance `bₘ` of the inbound message is always 0. +* The initial current gas limit `gₗ` is always 0. However, the initial gas credit `g𝚌 > 0`. + +The smart contract must terminate with `g𝚌 = 0` or `gᵣ ≥ g𝚌`; otherwise, the transaction and the block containing it are invalid. Validators or collators suggesting a block candidate must never include transactions processing inbound external messages that are invalid. + +### 4.4.7. Processing tick and tock transactions + +The `TVM` stack for processing tick and tock transactions (cf. [4.2.4](#4-2-4-kinds-of-transactions)) is initialized by pushing the following values: + +* The Gram balance `b` of the current account in nanograms (an `Integer`). +* The 256-bit address `ξ` of the current account inside the masterchain, represented by an unsigned `Integer`. +* An integer equal to `0` for tick transactions and to `−1` for tock transactions. +* The function selector `s`, equal to `−2`. + +### 4.4.8. Processing split prepare transactions + +For processing split prepare transactions (cf. [4.3.13](#4-3-13-split-prepare-and-install-transactions)), the `TVM` stack is initialized by pushing the following values: + +* The Gram balance `b` of the current account. +* A `Slice` containing `SplitMergeInfo` (cf. [4.3.13](#4-3-13-split-prepare-and-install-transactions)). +* The 256-bit address `ξ` of the current account. +* The 256-bit address `˜ξ` of the sibling account. +* An integer `0 ≤ d ≤ 63`, equal to the position of the only bit in which `ξ` and `˜ξ` differ. +* The function selector `s`, equal to `−3`. + +### 4.4.9. Processing merge install transactions + +For processing merge install transactions (cf. [4.3.14](#4-3-14-merge-prepare-and-install-transactions)), the `TVM` stack is initialized by pushing the following values: + +* The Gram balance `b` of the current account (already combined with the Gram balance of the sibling account). +* The Gram balance `b′` of the sibling account, taken from the inbound message `m`. +* The message `m` from the sibling account, automatically generated by a merge prepare transaction. Its `init` field contains the final state `S˜` of the sibling account. +* The state `S˜` of the sibling account, represented by a `StateInit` (cf. [3.1.7](#3-1-7-message-layout)). +* A `Slice` containing `SplitMergeInfo` (cf. [4.3.13](#4-3-13-split-prepare-and-install-transactions)). +* The 256-bit address `ξ` of the current account. +* The 256-bit address `˜ξ` of the sibling account. +* An integer `0 ≤ d ≤ 63`, equal to the position of the only bit in which `ξ` and `˜ξ` differ. +* The function selector `s`, equal to `−4`. + +### 4.4.10. Smart-contract information + +The smart-contract information structure `SmartContractInfo`, passed in the first component of the `Tuple` contained in control register `c7`, is also a `Tuple` containing the following data: + +```c +[ magic:0x076ef1ea actions:Integer msgs_sent:Integer + unixtime:Integer block_lt:Integer trans_lt:Integer + rand_seed:Integer balance_remaining:[Integer (Maybe Cell)] + myself:MsgAddressInt global_config:(Maybe Cell) +] = SmartContractInfo; +``` + +In other words, the first component of this tuple is an `Integer` `magic` always equal to `0x076ef1ea`, the second component is an `Integer` `actions`, originally initialized by zero, but incremented by one whenever an output action is installed by a non-RAW output action primitive of the `TVM`, and so on. The remaining balance is represented by a pair, i.e., a two-component `Tuple`: the first component is the nanogram balance, and the second component is a dictionary with 32-bit keys representing all other currencies, if any (cf. [3.1.6](#3-1-6-representing-collections-of-arbitrary-currencies)). The `rand_seed` field (an unsigned 256-bit integer) here is initialized deterministically starting from the `rand_seed` of the block, the account address, the hash of the inbound message being processed (if any), and the transaction logical time `trans_lt`. + +### 4.4.11. Serialization of output actions + +The output actions of a smart contract are accumulated in a linked list stored in control register `c5`. The list of output actions is serialized as a value of type `OutList n`, where `n` is the length of the list: + +```c +out_list_empty$_ = OutList 0; +out_list$_ {n:#} prev:^(OutList n) action:OutAction + = OutList (n + 1); +action_send_msg#0ec3c86d out_msg:^(Message Any) = OutAction; +action_set_code#ad4de08e new_code:^Cell = OutAction; +``` + +--- + +# 5 Block layout + +This chapter presents the block layout used by the TON Blockchain, combining the data structures described separately in previous chapters to produce a complete description of a shardchain block. In addition to the TL-B schemes that define the representation of a shardchain block by a tree of cells, this chapter describes exact serialization formats for the resulting bags (collections) of cells, which are necessary to represent a shardchain block as a file. Masterchain blocks are similar to shardchain blocks, but have some additional fields. The necessary modifications are discussed separately in 5.2. + +## 5.1 Shardchain block layout + +This section lists the data structures that must be contained in a shardchain block and in the shardchain state, and concludes by presenting a formal TL-B scheme for a shardchain block. + +### 5.1.1. Components of the shardchain state. + +The shardchain state consists of: + +* `ShardAccounts`, the split part of the shardchain state (cf. [1.2.2](#1-2-2-split-and-non-split-part-of-the-shardchain-block-and-state)) containing the state of all accounts assigned to this shard (cf. [4.1.9](#4-3-9-description-of-the-bounce-phase)). +* `OutMsgQueue`, the output message queue of the shardchain (cf. [3.3.6](#3-3-6-structure-of-outmsgqueue)). +* `SharedLibraries`, the description of all shared libraries of the shardchain (for now, non-empty only in the masterchain). +* The logical time and the unixtime of the last modification of the state. +* The total balance of the shard. +* A hash reference to the most recent masterchain block, indirectly describing the state of the masterchain and, through it, the state of all other shardchains of the TON Blockchain (cf. 1.5.2). + +### 5.1.2. Components of a shardchain block. + +A shardchain block must contain: + +* A list of validator signatures (cf. [1.2.6](#1-2-6-validator-signatures%2C-signed-and-unsigned-blocks)), which is external with respect to all other contents of the block. +* `BlockHeader`, containing general information about the block (cf. [1.2.5](#1-2-5-block-header)) +* Hash references to the immediately preceding block or blocks of the same shardchain, and to the most recent masterchain block. +* `InMsgDescr` and `OutMsgDescr`, the inbound and outbound message descriptors (cf. [3.2.8](#3-2-8-structure-of-inmsgdescr) and [3.3.5](#3-3-5-structure-of-outmsgdescr)).. +* `ShardAccountBlocks`, the collection of all transactions processed in the block (cf. [4.2.17](##4-2-17-collection-of-all-transactions-in-a-block)) along with all updates of the states of the accounts assigned to the shard. This is the split part of the shardchain block (cf. 1.2.2). +* The value flow, describing the total value imported from the preceding blocks of the same shardchain and from inbound messages, the total value exported by outbound message, the total fees collected by validators, and the total value remaining in the shard. +* A Merkle update (cf. [4, 3.1](#ref-4)) of the shardchain state. Such a Merkle update contains the hashes of the initial and final shardchain states with respect to the block, along with all new cells of the final state that have been created while processing the block.[³⁷](#footnote-37) + +### 5.1.3. Common parts of the block layout for all workchains. + +Recall that different workchains may define their own rules for processing messages, other types of transactions, other components of the state, and other ways to serialize all this data. However, some components of the block and its state must be common for all workchains in order to maintain the interoperability between different workchains. Such common components include: + +* `OutMsgQueue`, the outbound message queue of a shardchain, which is scanned by neighboring shardchains for messages addressed to them. +* The outer structure of `InMsgDescr` as a hashmap with 256-bit keys equal to the hashes of the imported messages. (The inbound message descriptors themselves need not have the same structure.) +* Some fields in the block header identifying the shardchain and the block, along with the paths from the block header to the other information indicated in this list. +* The value flow information. + +### 5.1.4. TL-B scheme for the shardchain state. + +The shardchain state (cf. [1.2.1](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state) and [5.1.1](#5-1-1-components-of-the-shardchain-state)) is serialized according to the following TL-B scheme: + +```c +ext_blk_ref$_ start_lt:uint64 end_lt:uint64 +seq_no:uint32 hash:uint256 = ExtBlkRef; +master_info$_ master:ExtBlkRef = BlkMasterInfo; +shard_ident$00 shard_pfx_bits:(## 6) +workchain_id:int32 shard_prefix:uint64 = ShardIdent; +shard_state shard_id:ShardIdent +out_msg_queue:OutMsgQueue +total_balance:CurrencyCollection +total_validator_fees:CurrencyCollection +accounts:ShardAccounts +libraries:(HashmapE 256 LibDescr) +master_ref:(Maybe BlkMasterInfo) +custom:(Maybe ^McStateExtra) += ShardState; +``` + +The field `custom` is usually present only in the masterchain and contains all the masterchain-specific data. However, other workchains may use the same cell reference to refer to their specific state data. + +### 5.1.5. Shared libraries description. + +Shared libraries currently can be present only in masterchain blocks. They are described by an instance of `HashmapE(256, LibDescr)`, where the 256-bit key is the representation hash of the library, and `LibDescr` describes one library: + +```c +shared_lib_descr$00 lib:^Cell publishers:(Hashmap 256 True) += LibDescr; +``` + +Here `publishers` is a hashmap with keys equal to the addresses of all accounts that have published the corresponding shared library. The sharedlibrary is preserved as long as at least one account keeps it in its published libraries collection. + +### 5.1.6. TL-B scheme for an unsigned shardchain block. + +The precise format of an unsigned (cf. [1.2.6](#1-2-6-validator-signatures%2C-signed-and-unsigned-blocks)) shardchain block is given by the following TL-B scheme: + +```c +block_info version:uint32 +not_master:(## 1) +after_merge:(## 1) before_split:(## 1) flags:(## 13) +seq_no:# vert_seq_no:# +shard:ShardIdent gen_utime:uint32 +start_lt:uint64 end_lt:uint64 +master_ref:not_master?^BlkMasterInfo +prev_ref:seq_no?^(BlkPrevInfo after_merge) +prev_vert_ref:vert_seq_no?^(BlkPrevInfo 0) += BlockInfo; +prev_blk_info#_ {merged:#} prev:ExtBlkRef +prev_alt:merged?ExtBlkRef = BlkPrevInfo merged; +unsigned_block info:^BlockInfo value_flow:^ValueFlow +state_update:^(MERKLE_UPDATE ShardState) +extra:^BlockExtra = Block; +block_extra in_msg_descr:^InMsgDescr +out_msg_descr:^OutMsgDescr +account_blocks:ShardAccountBlocks +rand_seed:uint256 +custom:(Maybe ^McBlockExtra) = BlockExtra; +``` + +The field `custom` is usually present only in the masterchain and contains all the masterchain-specific data. However, other workchains may use the same cell reference to refer to their specific block data. + +### 5.1.7. Description of total value flow through a block. + +The total value flow through a block is serialized according to the following TL-B scheme: + +```tlb +value_flow _:^[ from_prev_blk:CurrencyCollection +to_next_blk:CurrencyCollection +imported:CurrencyCollection +exported:CurrencyCollection ] +fees_collected:CurrencyCollection +_:^[ +fees_imported:CurrencyCollection +created:CurrencyCollection +minted:CurrencyCollection +] = ValueFlow; +``` + +Recall that `_:^[ . . . ]` is a TL-B construction indicating that a group of fields has been moved into a separate cell. The last three fields may be non-zero only in masterchain blocks. + +### 5.1.8. Signed shardchain block. + +A signed shardchain block is just an unsigned block augmented by a collection of validator signatures: + +```c +ed25519_signature#5 R:uint256 s:uint256 = CryptoSignature; +signed_block block:^Block blk_serialize_hash:uint256 +signatures:(HashmapE 64 CryptoSignature) += SignedBlock; +``` + +The serialization hash `blk_serialize_hash` of the unsigned block `block` is essentially a hash of a specific serialization of the block into an octet string (cf. 5.3.12 for a more detailed explanation). The signatures collected in `signatures` are Ed25519-signatures (cf. A.3) made with a validator’s private keys of the sha256 of the concatenation of the 256-bit representation hash of the block `block` and of its 256-bit serialization hash `blk_serialize_hash`. + +The 64-bit keys in dictionary `signatures` represent the first 64 bits of the public keys of the corresponding validators. + +### 5.1.9. Serialization of a signed block. + +The overall procedure of serializing and signing a block may be described as follows: + +1. An unsigned block **B** is generated, transformed into a complete bag of cells (cf. [5.3.2](#5-3-4-assigning-indices-to-the-cells-from-a-bag-of-cells)), and serialized into an octet string `Sᵦ`. +2. Validators sign the 256-bit combined hash + +``` math +Hᴮ := sha256( Hash∞(B) . Hashᴹ(Sᵦ) ) (18) +``` + + of the representation hash of **B** and of the Merkle hash of its serialization **Sᵦ**. +3. A signed shardchain block **B̃** is generated from **B** and these validator signatures as described above (cf. [5.1.8](#5-1-8-signed-shardchain-block)). +4. This signed block **B̃** is transformed into an incomplete bag of cells, which contains only the validator signatures, but the unsigned block itself is absent from this bag of cells, being its only absent cell. +5. This incomplete bag of cells is serialized, and its serialization is prepended to the previously constructed serialization of the unsigned block. The result is the serialization of the signed block into an octet string. It may be propagated by network or stored into a disk file. + +## 5.2 Masterchain block layout + +Masterchain blocks are very similar to shardchain blocks of the basic workchain. This section lists some of the modifications needed to obtain the description of a masterchain block from the description of a shardchain block given in 5.1. + +### 5.2.1. Additional components present in the masterchain state. + +In addition to the components listed in [5.1.1](#5-1-1-components-of-the-shardchain-state), the masterchain state must contain: + +* `ShardHashes` — Describes the current shard configuration, and contains the hashes of the latest blocks of the corresponding shardchains. +* `ShardFees` — Describes the total fees collected by the validators of each shardchain. +* `ShardSplitMerge` — Describes future shard split/merge events. It is serialized as a part of `ShardHashes`. +* `ConfigParams` — Describes the values of all configurable parameters of the TON Blockchain. + +### 5.2.2. Additional components present in masterchain blocks. + +In addition to the components listed in 5.1.2, each masterchain block must contain: + +* `ShardHashes` — Describes the current shard configuration, and contains the hashes of the latest blocks of the corresponding shardchains. (Notice that this component is also present in the masterchain state.) + +### 5.2.3. Description of `ShardHashes`. + +`ShardHashes` is represented by a dictionary with 32-bit `workchain_id`s as keys, and “shard binary trees”, represented by TL-B type `BinTree ShardDescr`, as values. Each leaf of this shard binary tree contains a value of type `ShardDescr`, which describes a single shard by indicating the sequence number `seq_no`, the logical time `lt`, and the hash `hash` of the latest (signed) block of the corresponding shardchain. + +```c +bt_leaf$0 {X:Type} leaf:X = BinTree X; +bt_fork$1 {X:Type} left:^(BinTree X) right:^(BinTree X) += BinTree X; +fsm_none$0 = FutureSplitMerge; +fsm_split$10 mc_seqno:uint32 = FutureSplitMerge; +fsm_merge$11 mc_seqno:uint32 = FutureSplitMerge; +shard_descr$_ seq_no:uint32 lt:uint64 hash:uint256 +split_merge_at:FutureSplitMerge = ShardDescr; +_ (HashmapE 32 ^(BinTree ShardDescr)) = ShardHashes; +``` + +Fields `mc_seqno` of `fsm_split` and `fsm_merge` are used to signal future shard merge or split events. Shardchain blocks referring to masterchain blocks with sequence numbers up to, but not including, the one indicated in `mc_seqno` are generated in the usual way. Once the indicated sequence number is reached, a shard merge or split event must occur. + +Notice that the masterchain itself is omitted from `ShardHashes` (i.e., 32-bit index −1 is absent from this dictionary). + +### 5.2.4. Description of `ShardFees`. + +`ShardFees` is a masterchain structure used to reflect the total fees collected so far by the validators of a shardchain. The total fees reflected in this structure are accumulated in the masterchain by crediting them to a special account, whose address is a configurable parameter. Typically this account is the smart contract that computes and distributes the rewards to all validators. + +```c +bta_leaf$0 {X:Type} {Y:Type} leaf:X extra:Y = BinTreeAug X Y; +bta_fork$1 {X:Type} {Y:Type} left:^(BinTreeAug X Y) +right:^(BinTreeAug X Y) extra:Y = BinTreeAug X Y; +_ (HashmapAugE 32 ^(BinTreeAug True CurrencyCollection) +CurrencyCollection) = ShardFees; +``` + +The structure of `ShardFees` is similar to that of `ShardHashes` (cf. [5.2.3](#5-2-3-description-of-shardhashes)), but the dictionary and binary trees involved are augmented by currency values, equal to the `total_validator_fees` values of the final states of the corresponding shardchain blocks. The value aggregated at the root of `ShardFees` is added together with the `total_validator_fees` of the masterchain state, yielding the total TON Blockchain validator fees. The increase of the value aggregated at the root of `ShardFees` from the initial to the final state of a masterchain block is reflected in the `fees_imported` in the value flow of that masterchain block. + +### 5.2.5. Description of `ConfigParams`. + +Recall that the configurable parameters or the configuration dictionary is a dictionary `config` with 32-bit keys kept inside the first cell reference of the persistent data of the configuration smart contract γ (cf. [1.6](#1-6-configurable-parameters-and-smart-contracts)). The address γ of the configuration smart contract and a copy of the configuration dictionary are duplicated in fields `config_addr` and `config` of a `ConfigParams` structure, explicitly included into masterchain state to facilitate access to the current values of the configurable parameters (cf. [1.6.3](#1-6-3-quick-access-through-the-header-of-masterchain-blocks)): + +```c +_ config_addr:uint256 config:^(Hashmap 32 ^Cell) += ConfigParams; +``` + +### 5.2.6. Masterchain state data. + +The data specific to the masterchain state is collected into `McStateExtra`, already mentioned in [5.1.4](#5-1-4-tl-b-scheme-for-the-shardchain-state): + +```c +masterchain_state_extra#cc1f +shard_hashes:ShardHashes +shard_fees:ShardFees +config:ConfigParams += McStateExtra; +``` + +### 5.2.7. Masterchain block data. + +Similarly, the data specific to the masterchain blocks is collected into `McBlockExtra`: + +```c +masterchain_block_extra#cc9f +shard_hashes:ShardHashes += McBlockExtra; +``` + +## 5.3 Serialization of a bag of cells + +The description provided in the previous section defines the way a shardchain block is represented as a tree of cells. However, this tree of cells needs to be serialized into a file, suitable for disk storage or network transfer. This section discusses the standard ways of serializing a tree, a DAG, or a bag of cells into an octet string. + +### 5.3.1. Transforming a tree of cells into a bag of cells. + +Recall that values of arbitrary (dependent) algebraic data types are represented in the TON Blockchain by trees of cells. Such a tree of cells is transformed into a directed acyclic graph, or DAG, of cells, by identifying identical cells in the tree. + +After that, we might replace each of the references of each cell by the 32-byte representation hash of the cell referred to and obtain a bag of cells. By convention, the root of the original tree of cells is a marked element of the resulting bag of cells, so that anybody receiving this bag of cells and knowing the marked element can reconstruct the original DAG of cells, hence also the original tree of cells. + +### 5.3.2. Complete bags of cells. + +Let us say that a bag of cells is complete if it contains all cells referred to by any of its cells. In other words, a complete bag of cells does not have any “unresolved” hash references to cells outside that bag of cells. In most cases, we need to serialize only complete bags of cells. + +### 5.3.3. Internal references inside a bag of cells. + +Let us say that a reference of a cell **c** belonging to a bag of cells **B** is internal (with respect to **B**) if the cell **cᵢ** referred to by this reference belongs to **B** as well. Otherwise, the reference is called external. A bag of cells is complete if and only if all references of its constituent cells are internal. + +### 5.3.4. Assigning indices to the cells from a bag of cells. + +Let `c₀`, …, `cₙ₋₁` be the `n` distinct cells belonging to a bag of cells `B`. We can list these cells in some order, and then assign indices from `0` to `n − 1`, so that cell `cᵢ` gets index `i`. Some options for ordering cells are: + +* Order cells by their representation hash. Then `Hash(cᵢ) < Hash(cⱼ)` whenever `i < j`. +* Topological order: if cell `cᵢ` refers to cell `cⱼ`, then `i < j`. In general, there is more than one topological order for the same bag of cells. There are two standard ways for constructing topological orders: + + * Depth-first order: apply a depth-first search to the directed acyclic graph of cells starting from its root (i.e., marked cell), and list cells in the order they are visited. + * Breadth-first order: same as above, but applying a breadth-first search. + +Notice that the topological order always assigns index 0 to the root cell of a bag of cells constructed from a tree of cells. In most cases, we opt to use a topological order, or the depth-first order if we want to be more specific. + +If cells are listed in a topological order, then the verification that there are no cyclic references in a bag of cells is immediate. On the other hand, ordering cells by their representation hash simplifies the verification that there are no duplicates in a serialized bag of cells. + +### 5.3.5. Outline of serialization process. + +The serialization process of a bag of cells **B** consisting of **n** cells can be outlined as follows: + +1. List the cells from **B** in a topological order: **c₀**, **c₁**, …, **cₙ₋₁**. Then **c₀** is the root cell of **B**. +2. Choose an integer **s**, such that `n ≤ 2ˢ`. Represent each cell **cᵢ** by an integral number of octets in the standard way (cf. [1.1.3](#1-1-3-the-layout-of-a-single-cell) or [4, 3.1.4](#ref-4)), but using unsigned big-endian **s**-bit integer **j** instead of hash `Hash(cⱼ)` to represent internal references to cell **cⱼ** (cf. [5.3.6](#5-3-6-serialization-of-one-cell-from-a-bag-of-cells)below). +3. Concatenate the representations of cells **cᵢ** thus obtained in the increasing order of **i**. +4. Optionally, an index can be constructed that consists of **n + 1** **t**-bit integer entries **L₀**, …, **Lₙ**, where **Lᵢ** is the total length (in octets) of the representations of cells **cⱼ** with `j ≤ i`, and integer `t ≥ 0` is chosen so that `Lₙ ≤ 2ᵗ`. +5. The serialization of the bag of cells now consists of a magic number indicating the precise format of the serialization, followed by integers `s ≥ 0`, `t ≥ 0`, `n ≤ 2ˢ`, an optional index consisting of `⌈(n+1)t/8⌉` octets, and **Lₙ** octets with the cell representations. +6. An optional CRC32 may be appended to the serialization for integrity verification purposes. + +If an index is included, any cell **cᵢ** in the serialized bag of cells may be easily accessed by its index **i** without deserializing all other cells, or even without loading the entire serialized bag of cells in memory. + +### 5.3.6. Serialization of one cell from a bag of cells. + +More precisely, each individual cell `c = cᵢ` is serialized as follows, provided `s` is a multiple of eight (usually `s = 8, 16, 24, or 32`): + +1. Two descriptor bytes `d₁` and `d₂` are computed similarly to [4, 3.1.4](#ref-4) by setting `d₁ = r + 8s + 16h + 32l` and `d₂ = ⌊b/8⌋ + ⌈b/8⌉`, where: + + * `0 ≤ r ≤ 4` is the number of cell references present in cell `c`; if `c` is absent from the bag of cells being serialized and is represented by its hashes only, then `r = 7`.[³⁸](#footnote-38) + * `0 ≤ b ≤ 1023` is the number of data bits in cell `c`. + * `0 ≤ l ≤ 3` is the level of cell `c` (cf. [4, 3.1.3](#ref-4)). + * `s = 1` for exotic cells and `s = 0` for ordinary cells. + * `h = 1` if the cell’s hashes are explicitly included into the serialization; otherwise, `h = 0`. (When `r = 7`, we must always have `h = 1`.) + + For absent cells (i.e., external references), only `d₁` is present, always equal to `23 + 32l`. + +2. Two bytes `d₁` and `d₂` (if `r < 7`) or one byte `d₁` (if `r = 7`) begin the serialization of cell `c`. + +3. If `h = 1`, the serialization is continued by `l + 1` 32-byte higher hashes of `c` (cf. [4, 3.1.6](#ref-4)): `Hash₁(c)`, …, `Hash_{l+1}(c) = Hash∞(c)`. + +4. After that, `⌈b/8⌉` data bytes are serialized, by splitting `b` data bits into 8-bit groups and interpreting each group as a big-endian integer in the range `0 ... 255`. If `b` is not divisible by 8, then the data bits are first augmented by one binary `1` and up to six binary `0`, so as to make the number of data bits divisible by eight.[³⁹](#footnote-39) + +5. Finally, `r` cell references to cells `c_{j₁}`, …, `c_{jᵣ}` are encoded by means of `r` `s`-bit big-endian integers `j₁`, …, `jᵣ`.[⁴⁰](#footnote-40) + +### 5.3.7. A classification of serialization schemes for bags of cells. + +A serialization scheme for a bag of cells must specify the following parameters: + +* The 4-byte magic number prepended to the serialization. +* The number of bits **s** used to represent cell indices. Usually **s** is a multiple of eight (e.g., 8, 16, 24, or 32). +* The number of bits **t** used to represent offsets of cell serializations (cf. [5.3.5](#5-3-5-outline-of-serialization-process)). Usually **t** is also a multiple of eight. +* A flag indicating whether an index with offsets **L₀**, …, **Lₙ** of cell serializations is present. This flag may be combined with **t** by setting `t = 0` when the index is absent. +* A flag indicating whether the CRC32-C of the whole serialization is appended to it for integrity verification purposes. + +### 5.3.8. Fields present in the serialization of a bag of cells. + +In addition to the values listed in [5.3.7](#5-3-7-a-classification-of-serialization-schemes-for-bags-of-cells), fixed by the choice of a serialization scheme for bags of cells, the serialization of a specific bag of cells must specify the following parameters: + +* The total number of cells `n` present in the serialization. +* The number of “root cells” `k ≤ n` present in the serialization. The root cells themselves are `c₀`, …, `c_{k−1}`. All other cells present in the bag of cells are expected to be reachable by chains of references starting from the root cells. +* The number of “absent cells” `l ≤ n − k`, which represent cells that are actually absent from this bag of cells, but are referred to from it. The absent cells themselves are represented by `c_{n−l}`, …, `c_{n−1}`, and only these cells may (and also must) have `r = 7`. Complete bags of cells have `l = 0`. +* The total length in bytes `Lₙ` of the serialization of all cells. If the index is present, `Lₙ` might not be stored explicitly since it can be recovered as the last entry of the index. + +### 5.3.9. TL-B scheme for serializing bags of cells. + +Several TL-B constructors can be used to serialize bags of cells into octet (i.e., 8-bit byte) sequences. The only one that is currently used to serialize new bags of cell is + +```c +serialized_boc#b5ee9c72 has_idx:(## 1) has_crc32c:(## 1) +has_cache_bits:(## 1) flags:(## 2) { flags = 0 } +size:(## 3) { size <= 4 } +off_bytes:(## 8) { off_bytes <= 8 } +cells:(##(size * 8)) +roots:(##(size * 8)) { roots >= 1 } +absent:(##(size * 8)) { roots + absent <= cells } +tot_cells_size:(##(off_bytes * 8)) +root_list:(roots * ##(size * 8)) +index:has_idx?(cells * ##(off_bytes * 8)) +cell_data:(tot_cells_size * [ uint8 ]) +crc32c:has_crc32c?uint32 += BagOfCells; +``` + +Field `cells` is **n**, `roots` is **k**, `absent` is **l**, and `tot_cells_size` is **Lₙ** (the total size of the serialization of all cells in bytes). If an index is present, parameters **s/8** and **t/8** are serialized separately as `size` and `off_bytes`, respectively, and the flag `has_idx` is set. The index itself is contained in `index`, present only if `has_idx` is set. The field `root_list` contains the (zero-based) indices of the root nodes of the bag of cells + +Two older constructors are still supported in the bag-of-cells deserialization functions: + +```c +serialized_boc_idx#68ff65f3 size:(## 8) { size <= 4 } +off_bytes:(## 8) { off_bytes <= 8 } +cells:(##(size * 8)) +roots:(##(size * 8)) { roots = 1 } +absent:(##(size * 8)) { roots + absent <= cells } +tot_cells_size:(##(off_bytes * 8)) +index:(cells * ##(off_bytes * 8)) +cell_data:(tot_cells_size * [ uint8 ]) += BagOfCells; + +serialized_boc_idx_crc32c#acc3a728 size:(## 8) { size <= 4 } +off_bytes:(## 8) { off_bytes <= 8 } +cells:(##(size * 8)) +roots:(##(size * 8)) { roots = 1 } +absent:(##(size * 8)) { roots + absent <= cells } +tot_cells_size:(##(off_bytes * 8)) +index:(cells * ##(off_bytes * 8)) +cell_data:(tot_cells_size * [ uint8 ]) +crc32c:uint32 = BagOfCells; +``` + +### 5.3.10. Storing compiled TVM code in files. + +Notice that the above procedure for serializing bags of cells may be used to serialize compiled smart contracts and other TVM code. One must define a TL-B constructor similar to the following: + +```c +compiled_smart_contract +compiled_at:uint32 code:^Cell data:^Cell +description:(Maybe ^TinyString) +_:^[ source_file:(Maybe ^TinyString) +compiler_version:(Maybe ^TinyString) ] += CompiledSmartContract; +tiny_string#_ len:(#<= 126) str:(len * [ uint8 ]) = TinyString; +``` + +Then a compiled smart contract may be represented by a value of type `CompiledSmartContract`, transformed into a tree of cells and then into a bag of cells, and then serialized using one of the constructors listed in 5.3.9. The resulting octet string may be then written into a file with suffix `.tvc` (“TVM smart contract”), and this file may be used to distribute the compiled smart contract, download it into a wallet application for deploying into the TON Blockchain, and so on. + +### 5.3.11. Merkle hashes for an octet string + +On some occasions, we must define a Merkle hash `Hashₘ(s)` of an arbitrary octet string `s` of length `|s|`. +We do this as follows: + +* If `|s| ≤ 256` octets, then the Merkle hash of `s` is just its `sha256`: + +```math +Hashₘ(s) := sha256(s) if |s| ≤ 256 (19) +``` + +* If `|s| > 256`, let `n = 2ᵏ` be the largest power of two less than `|s|` + (i.e., `k := ⌊log₂(|s| − 1)⌋`, `n := 2ᵏ`). + If `s′` is the prefix of `s` of length `n`, and `s′′` is the suffix of `s` of length `|s| − n`, so that `s = s′.s′′`, we define: + +```math +Hashₘ(s) := sha256( int64(|s|) . Hashₘ(s′) . Hashₘ(s′′) ) (20) +``` + +In other words, we concatenate the 64-bit big-endian representation of `|s|` and the recursively computed Merkle hashes of `s′` and `s′′`, and compute `sha256` of the resulting string. + +One can check that + +```math +Hashₘ(s) = Hashₘ(t) +``` + +for octet strings `s` and `t` of length less than `2⁶⁴ − 2⁵⁶` implies `s = t`, unless a hash collision for `sha256` has been found. + + +### 5.3.12. The serialization hash of a block. + +The construction of [5.3.11](#5-3-11-merkle-hashes-for-an-octet-string) is applied in particular to the serialization of the bag of cells representing an unsigned shardchain or masterchain block. The validators sign not only the representation hash of the unsigned block, but also the “serialization hash” of the unsigned block, defined as `HashM` of the serialization of the unsigned block. In this way, the validators certify that this octet string is indeed a serialization of the corresponding block. + +--- + +# A Elliptic curve cryptography + +This appendix contains a formal description of the elliptic curve cryptography currently used in TON, particularly in the TON Blockchain and the TON Network. + +TON uses two forms of elliptic curve cryptography: Ed25519 is used for cryptographic Schnorr signatures, while Curve25519 is used for asymmetric cryptography. These curves are used in the standard way (as defined in the original articles [1](#ref-1) and [2](#ref-2) by D. Bernstein and RFCs 7748 and 8032); however, some serialization details specific to TON must be explained. One unique adaptation of these curves for TON is that TON supports automatic conversion of Ed25519 keys into Curve25519 keys, so that the same keys can be used for signatures and for asymmetric cryptography. + +## A.1 Elliptic curves + +Some general facts on elliptic curves over finite fields, relevant for elliptic curve cryptography, are collected in this section. + +### A.1.1. Finite fields. + +We consider elliptic curves over finite fields. For the purposes of the Curve25519 and Ed25519 algorithms, we will be mostly concerned with elliptic curves over the finite prime field `k := F_p` of residues modulo `p`, where `p = 2^255 − 19` is a prime number, and over finite extensions `F_q` of `F_p`, especially the quadratic extension `F_p^2`.[⁴¹](#footnote-41) + +### A.1.1. Finite fields + +We consider elliptic curves over finite fields. For the purposes of the Curve25519 and Ed25519 algorithms, we will be mostly concerned with elliptic curves over the finite prime field `k := Fₚ` of residues modulo `p`, where `p = 2²⁵⁵ − 19` is a prime number, and over finite extensions `F_q` of `Fₚ`, especially the quadratic extension `Fₚ₂`.[⁴¹](#footnote-41) + +### A.1.2. Elliptic curves + +An *elliptic curve* `E = (E, O)` over a field `k` is a geometrically integral smooth projective curve `E/k` of genus `g = 1`, along with a marked `k`-rational point `O ∈ E(k)`. + +It is well-known that an elliptic curve `E` over a field `k` can be represented in (generalized) Weierstrass form: + +```math +y² + a₁xy + a₃y = x³ + a₂x² + a₄x + a₆ (21) +``` + +for some `a₁, …, a₆ ∈ k`. + +### A.1.3. Weierstrass form in homogeneous coordinates + +In homogeneous coordinates `[X : Y : Z]`, (21) corresponds to + +```math +Y²Z + a₁XYZ + a₃YZ² = X³ + a₂X²Z + a₄XZ² + a₆Z³ (22) +``` + +When `Z ≠ 0`, we can set `x := X/Z`, `y := Y/Z`, and obtain a solution `(x, y)` of ([21](#a-1-2-elliptic-curves)) (i.e., a finite point of `E`). + +On the other hand, the only solution (up to proportionality) of (22) with `Z = 0` is `[0 : 1 : 0]`; this is the point at infinity `O`. + + +### A.1.4. Standard Weierstrass form + +When the characteristic `char k` of field `k` is `≠ 2, 3`, the Weierstrass form of ([21](#a-1-2-elliptic-curves)) or ([22](#a-1-3-weierstrass-form-in-homogeneous-coordinates)) can be simplified with the aid of linear transformations +`y′ := y + a₁x/2 + a₃/2`, `x′ := x + a₂/3`, thus making `a₁ = a₃ = a₂ = 0` and obtaining + +```math +y² = x³ + a₄x + a₆ (23) +``` + +and + +```math +Y²Z = X³ + a₄XZ² + a₆Z³ (24) +``` + +Such an equation defines an elliptic curve if and only if the cubic polynomial `P(x) := x³ + a₄x + a₆` has no multiple roots, i.e., if the discriminant + +```math +D := −4a₄³ − 27a₆² +``` + +is non-zero. + + +### A.1.5. Addition of points on elliptic curve *E* + +Let `K` be a field extension of field `k`, and let `E = (E, O)` be any elliptic curve in Weierstrass form defined over `k`. Then any line `l ⊂ ℙ²_K` intersects the elliptic curve `E_(K)` (which is the base change of curve `E` to field `K`, i.e., the curve defined by the same equations over a larger field `K`) at exactly three points `P, Q, R`, considered with multiplicities. + +We define the **addition of points** on elliptic curve `E` (or rather the addition of its `K`-valued points `E(K)`) by requiring that: + +```math +P + Q + R = O \quad \text{whenever } \{P, Q, R\} = l ∩ E \text{ for some line } l ⊂ ℙ²_K. + +\quad(25) +``` + +It is well-known that this requirement defines a unique commutative law + +```math +[+] : E ×_k E → E +``` + +on the points of the elliptic curve `E`, having `O` as its neutral element. + +When elliptic curve `E` is represented by its Weierstrass form ([21](#a-1-2-elliptic-curves)), one can write explicit formulas expressing the coordinates `x_(P+Q), y_(P+Q)` of the sum `P + Q` of two `K`-valued points `P, Q ∈ E(K)` of elliptic curve `E` as rational functions of the coordinates `x_P, y_P, x_Q, y_Q ∈ K` of points `P` and `Q` and of the coefficients `aᵢ ∈ k` of [(21)](#21). + + +### A.1.6. Power maps + +Since `E(K)` is an abelian group, one can define **multiples** or **powers** `[n]X` for any point `X ∈ E(K)` and any integer `n ∈ ℤ`. + +* If `n = 0`, then `[0]X = O`. +* If `n > 0`, then `[n]X = [n−1]X + X`. +* If `n < 0`, then `[n]X = −[−n]X`. + +The map `[n] = [n]_E : E → E` for `n ≠ 0` is an **isogeny**, meaning that it is a non-constant homomorphism for the group law of `E`: + +```math +[n](P + Q) = [n]P + [n]Q \quad \text{for any } P, Q ∈ E(K) \text{ and } n ∈ ℤ. \tag{26} +``` + +In particular, `[−1]_E : E → E, P ↦ −P`, is an involutive automorphism of elliptic curve `E`. If `E` is in Weierstrass form, `[−1]_E` maps `(x, y) ↦ (x, −y)`, and two points `P, Q ∈ E(ℱ_q)` have equal `x`-coordinates if and only if `Q = ±P`. + +### A.1.7. The order of the group of rational points of *E* + +Let `E` be an elliptic curve defined over a finite base field `k`, and let `K = ℱ_q` be a finite extension of `k`. Then `E(ℱ_q)` is a finite abelian group. + +By a well-known result of Hasse, the order `n` of this group is not too distant from `q`: + +```math +n = |E(ℱ_q)| = q − t + 1, \quad \text{where } t² ≤ 4q, \; \text{i.e., } |t| ≤ 2√q. \tag{27} +``` + +We will be mostly interested in the case `K = k = ℱ_p`, with `q = p` a prime number. + + +### A.1.8. Cyclic subgroups of large prime order. + +Elliptic curve cryptography is usually performed using elliptic curves that admit a (necessarily cyclic) subgroup `C ⊂ E(𝔽_q)` of prime order `ℓ`. Equivalently, a rational point `G ∈ E(𝔽_q)` of prime order `ℓ` may be given; then `C` can be recovered as the cyclic subgroup `⟨G⟩` generated by `G`. In order to verify that a point `G ∈ E(𝔽_q)` generates a cyclic group of prime order `ℓ`, one can check that `G ≠ O`, but `[ℓ]G = O`. + +By the Legendre theorem, `ℓ` is necessarily a divisor of the order `n = |E(𝔽_q)|` of the finite abelian group `E(𝔽_q)`: + +```math +n = |E(\mathbb{F}_q)| = c \ell \quad \text{for some integer } c \ge 1 \quad (28) +``` + +The integer `c` is called the cofactor; one usually wants the cofactor to be as small as possible, so as to make `ℓ = n/c` as large as possible. Recall that `n` always has the same order of magnitude as `q` by ([27](#a-1-7-the-order-of-the-group-of-rational-points-of-e)), so it cannot be changed much by varying `E` once `q` is fixed. + + +### A.1.9. Data for elliptic curve cryptography. + +In order to define specific elliptic curve cryptography, one must fix a finite base field `𝔽_q` (if `q = p` is a prime, it is sufficient to fix prime `p`), an elliptic curve `E/𝔽_q` (usually represented by the coefficients of its Weierstrass form (23) or (21)), the base point `O` (which usually is the point at infinity of an elliptic curve written in Weierstrass form), and the generator `G ∈ E(𝔽_q)` (usually determined by its coordinates `(x, y)` with respect to the equation of the elliptic curve) of a cyclic subgroup of large prime order `ℓ`. Prime number `ℓ` and the cofactor `c` are usually also part of the elliptic cryptography data. + +### A.1.10. Main operations of elliptic curve cryptography. + +Elliptic curve cryptography usually deals with a fixed cyclic subgroup `C` of a large prime order `ℓ` inside the group of points of an elliptic curve `E` over a finite field `𝔽_q`. A generator `G` of `C` is usually fixed. It is usually assumed that, given a point `X` of `C`, one cannot find its “discrete logarithm base `G`” (i.e., a residue `n` modulo `ℓ` such that `X = [n]G`) faster than in `O(√ℓ)` operations. + +The most important operations used in elliptic curve cryptography are the addition of points from `C ⊂ E(𝔽_q)` and the computation of their powers, or multiples. + +### A.1.11. Private and public keys for elliptic curve cryptography. + +Usually a private key for elliptic curve cryptography described by the data listed in [A.1.9](#a-1-9-data-for-elliptic-curve-cryptography) is a “random” integer `0 < a < ℓ`, called the secret exponent, and the corresponding public key is the point `A := [a]G` (or just its x-coordinate `x_A`), suitably serialized. + +### A.1.12. Montgomery curves. + +Elliptic curves with the specific Weierstrass equation + +```math +y^2 = x^3 + A x^2 + x \quad \text{where } A = 4a - 2 \text{ for some } a \in k,\ a \ne 0,\ a \ne 1 \quad (29) +``` + +are called Montgomery curves. They have the convenient property that + +```math +x_{P+Q}\, x_{P-Q} \ \text{can be expressed as a simple rational function of}\ x_P \ \text{and}\ x_Q: \\ +x_{P+Q}\, x_{P-Q} \ = \ \left(\frac{x_P x_Q - A}{x_P - x_Q}\right)^2 \quad (30) +``` + +This means that `x_(P+Q)` can be computed provided `x_(P−Q)`, `x_P`, and `x_Q` are known. + +In particular, if `x_P`, `x_[n]P`, and `x_[(n+1)P]` are known, then `x_[(2n)P]`, `x_[(2n+1)P]`, and `x_[(2n+2)P]` can be computed. + +Using the binary representation of `0 < n < 2ˢ`, one can compute + +```math +x_[⌊n / 2^(s−i)⌋ P], \quad x_[(⌊n / 2^(s−i)⌋ + 1)P] \quad \text{for } i = 0, 1, ..., s, +``` + +thus obtaining `x_[nP]`. + +This algorithm for quickly computing `x_[nP]` starting from `x_P` on Montgomery curves is called the **Montgomery ladder**. Hence, we see the importance of Montgomery curves for elliptic curve cryptography. + +--- + +## A.2 Curve25519 cryptography + +This section describes the well-known Curve25519 cryptography proposed by Daniel Bernstein [1](#ref-1) and its usage in TON. + +### A.2.1. Curve25519 + +Curve25519 is defined as the Montgomery curve: + +```math +y^2 = x^3 + A x^2 + x \quad \text{over } \mathbb{F}_p, +``` + +where + +```math +p = 2^{255} - 19, \quad A = 486662. \tag{31} +``` + +The order of this curve is `8ℓ`, where `ℓ` is a prime number, and `c = 8` is the **cofactor**. + +The cyclic subgroup of order `ℓ` is generated by a point `G` with + +```math +x_G = 9 +``` + +(this determines `G` up to the sign of `y_G`, which is unimportant). + +The order of the quadratic twist + +```math +2y^2 = x^3 + A x^2 + x +``` + +of Curve25519 is `4ℓ′` for another prime number `ℓ′`.[⁴²](#footnote-42) + + +### A.2.2. Parameters of Curve25519 + +The parameters of Curve25519 are as follows: + +* **Base field**: Prime finite field `𝔽_p` for + + ```math + p = 2^{255} - 19 + ``` + +* **Equation**: + + ```math + y^2 = x^3 + A x^2 + x, \quad A = 486662 + ``` + +* **Base point G**: Characterized by + + ```math + x_G = 9 + ``` + + (nine is the smallest positive integer x-coordinate of a generator of the subgroup of large prime order of `E(𝔽_p)`). + +* **Order of `E(𝔽_p)`**: + + ```math + |E(\mathbb{F}_p)| = p - t + 1 = 8ℓ + ``` + + where + + ```math + ℓ = 2^{252} + 27742317777372353535851937790883648493 \tag{32} + ``` + + is prime. + +* **Order of the quadratic twist `Ē(𝔽_p)`**, where `Ē` is the quadratic twist of `E`: + + ```math + |\tilde{E}(\mathbb{F}_p)| = p + t + 1 = 2p + 2 - 8ℓ = 4ℓ′ \tag{33} + ``` + + where + + ```math + ℓ′ = 2^{253} - 55484635554744707071703875581767296995 \tag{34} + ``` + + is prime. + + + +### A.2.3. Private and public keys for standard Curve25519 cryptography +A private key for Curve25519 cryptography is usually defined as a secret exponent *a*, while the corresponding public key is `xₐ`, the *x*-coordinate of point + +```math +A := [a]G +``` + +This is usually sufficient for performing ECDH (elliptic curve Diffie–Hellman key exchange) and asymmetric elliptic curve cryptography, as follows: + +If a party wants to send a message *M* to another party, which has public key `xₐ` (and private key *a*), the following computations are performed. A one-time random secret exponent *b* is generated, and + +```math +x_b := x[b]G +``` + +and + +```math +x[b]A +``` + +are computed using a Montgomery ladder. After that, the message *M* is encrypted by a symmetric cypher such as AES using the 256-bit “shared secret” + +```math +S := x[b]A +``` + +as a key, and 256-bit integer (“one-time public key”) `x_b` is prepended to the encrypted message. Once the party with public key `xₐ` receives this message, it can compute + +```math +x[a]B +``` + +starting from `x_b` (transmitted with the encrypted message) and the private key *a*. Since + +```math +x[a]B = x[ab]G = x[b]A = S +``` + +the receiving party recovers the shared secret *S* and is able to decrypt the remainder of the message. + +## A.2.4. Public and private keys for TON Curve25519 cryptography + +TON uses another form for public and private keys of Curve25519 cryptography, borrowed from Ed25519 cryptography. + +A private key for TON Curve25519 cryptography is just a random 256-bit string *k*. It is used by computing `SHA512(k)`, taking the first 256 bits of the result, interpreting them as a little-endian 256-bit integer *a*, clearing bits 0, 1, 2, and 255 of *a*, and setting bit 254 so as to obtain a value + +```math +2^{254} \leq a < 2^{255} +``` + +divisible by eight. The value *a* thus obtained is the *secret exponent* corresponding to *k*; meanwhile, the remaining 256 bits of `SHA512(k)` constitute the *secret salt* `k''`. + +The public key corresponding to *k*—or to the secret exponent *a*—is just the *x*-coordinate `xₐ` of the point + +```math +A := [a]G +``` + +Once *a* and `xₐ` are computed, they are used in exactly the same way as in [A.2.3](#a-2-3-private-and-public-keys-for-standard-curve25519-cryptography). In particular, if `xₐ` needs to be serialized, it is serialized into 32 octets as an unsigned little-endian 256-bit integer. + + +### A.2.5. Curve25519 is used in the TON Network. + +Notice that the asymmetric Curve25519 cryptography described in [A.2.4](#a-2-4-public-and-private-keys-for-ton-curve25519-cryptography) is extensively used by the TON Network, especially the ADNL (Abstract Datagram Network Layer) protocol. However, TON Blockchain needs elliptic curve cryptography mostly for signatures. For this purpose, Ed25519 signatures described in the next section are used. + +--- + +# A.3 Ed25519 cryptography + +Ed25519 cryptography is extensively used for fast cryptographic signatures by both the TON Blockchain and the TON Network. This section describes the variant of Ed25519 cryptography used by TON. An important difference from the standard approaches (as defined by D. Bernstein et al. in [2](#ref-2)) is that TON provides automatic conversion of private and public Ed25519 keys into Curve25519 keys, so that the same keys could be used both for encrypting/decrypting and for signing messages. + +## A.3.1. Twisted Edwards curves + +A *twisted Edwards curve* `Eₐ,𝑑` with parameters `a ≠ 0` and `d ≠ 0`, `a` over a field `k` is given by equation + +```math +E_{a,d} : ax^2 + y^2 = 1 + dx^2 y^2 \quad \text{over } k +\tag{36} +``` + +If `a = 1`, this equation defines an (untwisted) Edwards curve. Point `O(0,1)` is usually chosen as the marked point of `Eₐ,𝑑`. + + +## A.3.2. Twisted Edwards curves are birationally equivalent to Montgomery curves + +A twisted Edwards curve `Eₐ,𝑑` is birationally equivalent to a Montgomery elliptic curve + +```math +M_A : v^2 = u^3 + Au^2 + u +\tag{37} +``` + +where + +```math +A = \frac{2(a+d)}{(a-d)} \quad \text{and} \quad d/a = \frac{A-2}{A+2}. +``` + +The birational equivalence + +```math +\varphi : E_{a,d} \longrightarrow M_A +``` + +and its inverse `φ⁻¹` are given by + +```math +\varphi : (x,y) \mapsto \left( \frac{1+y}{1-y}, \; \frac{c(1+y)}{x(1-y)} \right) +\tag{38} +``` + +and + +```math +\varphi^{-1} : (u,v) \mapsto \left( \frac{cu}{v}, \; \frac{u-1}{u+1} \right) +\tag{39} +``` + +where + +```math +c = \sqrt{\frac{A+2}{a}} +\tag{40} +``` + +Notice that `φ` transforms the marked point `O(0,1)` of `Eₐ,𝑑` into the marked point of `M_A` (i.e., its point at infinity). + + +## A.3.3. Addition of points on a twisted Edwards curve + +Since `Eₐ,𝑑` is birationally equivalent to an elliptic curve `M_A`, the addition of points on `M_A` can be transferred to `Eₐ,𝑑` by setting + +```math +P + Q := \varphi^{-1}(\varphi(P) + \varphi(Q)) \quad \text{for any } P, Q \in E_{a,d}(k). +\tag{41} +``` + +Notice that the marked point `O(0,1)` is the neutral element with respect to this addition, and that + +```math +-(x_P, y_P) = (-x_P, y_P). +``` + +## A.3.4. Formulas for adding points on a twisted Edwards curve + +The coordinates `x_{P+Q}` and `y_{P+Q}` admit simple expressions as rational functions of `x_P, y_P, x_Q, y_Q`: + +```math +x_{P+Q} = \frac{x_P y_Q + x_Q y_P}{1 + d x_P x_Q y_P y_Q} +\tag{42} +``` + +```math +y_{P+Q} = \frac{y_P y_Q - a x_P x_Q}{1 - d x_P x_Q y_P y_Q} +\tag{43} +``` + +These expressions can be efficiently computed, especially if `a = -1`. This is the reason twisted Edwards curves are important for fast elliptic curve cryptography. + + +## A.3.5. Ed25519 twisted Edwards curve + +Ed25519 is the twisted Edwards curve `E_{-1,d}` over `Fₚ`, where + +```math +p = 2^{255} - 19 +``` + +is the same prime number as that used for Curve25519, and + +```math +d = -\frac{(A-2)}{(A+2)} = -121665/121666, +``` + +where `A = 486662` is the same as in equation (31): + +```math +-x^2 + y^2 = 1 - \frac{121665}{121666} x^2 y^2 +\quad \text{for } x,y \in F_p, \; p = 2^{255} - 19. +\tag{44} +``` + +In this way, Ed25519-curve `E_{-1,d}` is birationally equivalent to Curve25519 (31), and one can use `E_{-1,d}` and formulas ([42](#a-3-4-formulas-for-adding-points-on-a-twisted-edwards-curve))–([43](#a-3-4-formulas-for-adding-points-on-a-twisted-edwards-curve)) for point addition on either Ed25519 or Curve25519, using ([38](#a-3-2-twisted-edwards-curves-are-birationally-equivalent-to-montgomery-curves)) and ([39](#a-3-2-twisted-edwards-curves-are-birationally-equivalent-to-montgomery-curves)]) to convert points on Ed25519 into corresponding points on Curve25519, and vice versa. + + +### A.3.6. Generator of Ed25519 + +The generator of Ed25519 is the point `G′` with `y(G′) = 4/5` and `0 ≤ x(G′) < p` even. According to ([38](#a-3-2-twisted-edwards-curves-are-birationally-equivalent-to-montgomery-curves)), it corresponds to the point `(u,v)` of Curve25519 with + +```math +u = \frac{1+4/5}{1-4/5} = 9 +``` + +(i.e., to the generator `G` of Curve25519 chosen in [A.2.2](#a-2-2-public-and-private-keys-for-ton-curve25519-cryptography)). In particular, + +```math +G = \varphi(G′), +``` + +`G′` generates a cyclic subgroup of the same large prime order `ℓ` given in (32), and for any integer `a`, + +```math +\varphi([a]G′) = [a]G . +\tag{45} +``` + +In this way, we can perform computations with Curve25519 and its generator `G`, or with Ed25519 and generator `G′`, and obtain essentially the same results. + + +### A.3.7. Standard representation of points on Ed25519 + +A point `P(x,y)` on Ed25519 may be represented by its two coordinates `xₚ` and `yₚ`, residues modulo + +```math +p = 2^{255} - 19. +``` + +In their turn, both these coordinates may be represented by unsigned 255- or 256-bit integers + +```math +0 ≤ xₚ, yₚ < p < 2^{255}. +``` + +However, a more compact representation of `P` by one little-endian unsigned 256-bit integer `Ṕ` is commonly used (and is used by TON as well). Namely, the 255 lower-order bits of `Ṕ` contain `yₚ`, + +```math +0 ≤ yₚ < p < 2^{255}, +``` + +and bit 255 is used to store `xₚ mod 2`, the lower-order bit of `xₚ`. Since `yₚ` always determines `xₚ` up to sign (i.e., up to replacing `xₚ` with `p − xₚ`), `xₚ` and `p − xₚ` can always be distinguished by their lower-order bit, `p` being odd. + +If it is sufficient to know `±P` up to sign, one can ignore `xₚ mod 2` and consider only the little-endian 255-bit integer `yₚ`, setting the bit 255 arbitrarily, ignoring its previously defined value, or clearing it. + +## A.3.8. Private key for Ed25519 + +A *private key* for Ed25519 is just an arbitrary 256-bit string `k`. A *secret exponent* `a` and *secret salt* `k″` are derived from `k` by first computing `SHA512(k)`, and then taking the first 256 bits of this `SHA512` as the little-endian representation of `a` (but with bits 255, 2, 1, and 0 cleared, and bit 254 set); the last 256 bits of `SHA512(k)` then constitute `k″`. + +This is essentially the same procedure as described in [A.2.4](#a-2-4-public-and-private-keys-for-ton-curve25519-cryptography), but with Curve25519 replaced by the birationally equivalent curve Ed25519. (In fact, it is the other way around: this procedure is standard for Ed25519-based elliptic curve cryptography, and TON extends the procedure to Curve25519.) + + +## A.3.9. Public key for Ed25519 + +A *public key* corresponding to a private key `k` for Ed25519 is the standard representation (cf. [A.3.7](#a-3-7-standard-representation-of-points-on-ed25519)) of the point + +```math +A = [a]G′, +``` + +where `a` is the secret exponent (cf. [A.3.8](#a-3-8-private-key-for-ed25519)) defined by the private key `k`. + + +### A.3.10. Cryptographic Ed25519-signatures + +If a message (octet string) *M* needs to be signed by a private key `k` defining secret exponent `a` and secret salt `k″`, the following computations are performed: + +* `r := SHA512(k″‖M)`, interpreted as a little-endian 512-bit integer. Here `s‖t` denotes the concatenation of octet strings `s` and `t`. +* `R := [r]G′` is a point on Ed25519. +* `Ṙ` is the standard representation (cf. [A.3.7](#a-3-7-standard-representation-of-points-on-ed25519)) of point `R` as a 32-octet string. +* `s := r + a · SHA512(Ṙ‖Ã‖M) mod ℓ`, encoded as a little-endian 256-bit integer. Here `Ã` is the standard representation of point `A = [a]G′`, the public key corresponding to `k`. + +The (Schnorr) signature is a 64-octet string `(Ṙ,s)`, consisting of the standard representation of the point `R` and of the 256-bit integer `s`. + + +### A.3.11. Checking Ed25519-signatures + +In order to verify signature `(Ṙ,s)` of a message *M*, supposedly made by the owner of the private key `k` corresponding to a known public key `A`, the following steps are performed: + +* Points `[s]G′` and `R + [SHA512(Ṙ‖Ã‖M)]A` of Ed25519 are computed. +* If these two points coincide, the signature is correct. + +--- + + +## References + +
+[1] Daniel J. Bernstein, *Curve25519: New Diffie–Hellman Speed Records* (2006), in: M. Yung, Ye. Dodis, A. Kiayas et al., **Public Key Cryptography**, Lecture Notes in Computer Science 3958, pp. 207–228. Available at: [https://cr.yp.to/ecdh/curve25519-20060209.pdf](https://cr.yp.to/ecdh/curve25519-20060209.pdf). + + +[2] Daniel J. Bernstein, Niels Duif, Tanja Lange et al., *High-speed high-security signatures* (2012), **Journal of Cryptographic Engineering** 2(2), pp. 77–89. Available at: [https://ed25519.cr.yp.to/ed25519-20110926.pdf](https://ed25519.cr.yp.to/ed25519-20110926.pdf). + + +[3] N. Durov, *Telegram Open Network*, 2017. + + +[4] N. Durov, *Telegram Open Network Virtual Machine*, 2018. + + +## Footnotes + + **1.** As of August 2018, this document does not include a detailed description of serialized invalidity proofs, because they are likely to change significantly during the development of the validator software. Only the general design principles for consistency conditions and serialized invalidity proofs are discussed. [Back ↑](#introduction) + + **2.** This is not included in the present version of this document, but will be provided in a separate appendix to a future revision. [Back ↑](#introduction) + + **3** Completely identical cells are often identified in memory and in disk storage; this is the reason why trees of cells are transparently transformed into DAGs of cells. From this perspective, a DAG is just a storage optimization of the underlying tree of cells, irrelevant for most considerations. [Back ↑](#1-1-1-tvm-cells) + + **4** Cf. [4.3.3–4](#ref-4), where an example is given and explained, pending a more complete reference. [Back ↑](#1-1-1-tvm-cells) + + **5.** If there are no transactions related to an account, the corresponding virtual block is empty and is omitted in the shardchain block. [Back ↑](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state) + + **6.** Recall that TON Blockchain supports dynamic sharding, so the shard configuration may change from block to block because of shard merge and split events. Therefore, we cannot simply say that each shardchain corresponds to a fixed set of accountchains. [Back ↑](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state) + + **7.** This condition applies if there is exactly one immediate antecessor (i.e., if a shardchain merge event did not occur immediately before the block in question); otherwise, this condition becomes more convoluted. [Back ↑](#1-2-3-interaction-with-other-blocks-and-the-outside-world-global-and-local-consistency-conditions) + + **8.** This example is a bit simplified since it does not take into account the presence of transit messages in `InMsgDescr`, which are not processed by any explicit transaction. [Back ↑](#1-3-8-example-consistency-condition-for-inmsgdescr) + + **9.** It is interesting to note that this part of the work can be done almost automatically. [Back ↑](#1-3-12-witnesses-of-the-invalidity-of-a-block) + + **10** In order to express this condition correctly in the presence of dynamic sharding, one should fix some account ξ, and consider the latest blocks `S` and `S′` of the shardchains containing ξ in the shard configurations of both `B` and `B′`, since the shards containing ξ might be different in `B` and `B′`. [Back ↑](#1-5-1-total-state-defined-by-a-masterchain-block) + +**11** Value-bearing messages with the bounce flag set will not be accepted by an uninitialized account, but will be “bounced” back. [Back ↑](#1-7-2-transferring-cryptocurrency-to-uninitialized-accounts) + +**12** “Messages to nowhere” may have some special fields in their body indicating their destination outside the TON Blockchain—for instance, an account in some other blockchain, or an IP address and port—which may be interpreted by the third-party software appropriately. Such fields are ignored by the TON Blockchain. [Back ↑](#2-1-3-external-messages-with-no-source-or-destination-address) + +**13** The problem of bypassing possible validator censorship—which could happen, for instance, if all validators conspire not to include external messages sent to accounts belonging to some set of blacklisted accounts—is dealt with separately elsewhere. The main idea is that the validators may be forced to promise to include a message with a known hash in a future block, without knowing anything about the identity of the sender or the receiver; they will have to keep this promise afterwards when the message itself with pre-agreed hash is presented. [Back ↑](#2-1-3-external-messages-with-no-source-or-destination-address) + +**14** However, the internal routing process described in [2.1.11](#2-1-11-internal-routing) is applied immediately after that, which may further modify the transit address. [Back ↑](#2-1-4-transit-and-next-hop-addresses) + +**15** When the addresses involved are of different lengths (e.g., because they belong to different workchains), one should consider only the first 96 bits of the addresses in the above formula. [Back ↑](l#2-1-8-hamming-optimality-of-the-next-hop-address-algorithm) + +**16** Instead of Hamming optimality, we might have considered the equivalent property of Kademlia optimality, written for the Kademlia (or weighted `L1`) distance as given by `‖ξ − η‖ₖ := ∑ᵢ 2⁻ᶦ |ξᵢ − ηᵢ|` instead of the Hamming distance. [Back ↑](l#2-1-8-hamming-optimality-of-the-next-hop-address-algorithm) + + **17** Notice that the next-hop and internal-routing computations are still applied to such messages, since the current shardchain may be split before the message is processed. In this case, the new sub-shardchain containing the destination address will inherit the message. [Back ↑](#2-1-13-any-shard-is-a-neighbor-of-itself) + + **18** We may define the (virtual) output queue of an account(chain) as the subset of the `OutMsgQueue` of the shard currently containing that account that consists of messages with transit addresses equal to the address of the account. [Back ↑](#2-1-14-hypercube-routing-and-the-isp) + + **19** In particular, if the hash of a recent block of a neighboring shardchain is not yet reflected in the latest masterchain block, its modifications to `OutMsgQueue` must not be taken into account. [Back ↑](#2-2-5-logical-time-monotonicity%3A%3A-importing-the-oldest-message-from-the-neighbors) + + **20** This statement is not as trivial as it seems at first, because some of the shardchains involved may split or merge during the routing. A correct proof may be obtained by adopting the ISP perspective to HR as explained in [2.1.14](#2-1-14-hypercube-routing-and-the-isp) and observing that m′ will always be behind m, either in terms of the intermediate accountchain reached or, if they happen to be in the same accountchain, in terms of logical creation time. A crucial observation is that “at any given moment of time” (logically; a more precise description would be “in the total state obtained after processing any causally closed subset F of blocks”), the intermediate accountchains belonging to the same shard are contiguous on the path from ξ to η (i.e., cannot have accountchains belonging to some other shard in between). This is a “convexity property” (cf. [2.1.10](#2-1-10-fifo-guarantees-of-hypercube-routing)) of the Hypercube Routing algorithm described in [2.1.5](#2-1-5-computation-of-the-next-hop-address-for-hypercube-routing). [Back ↑](#2-2-10-fifo-guarantees-of-hypercube-routing) + + **21** One must not only look up the key `Hash(m)` in the `InMsgDescr` of these blocks, but also check the intermediate addresses in the envelope of the corresponding entry, if found. [Back ↑](#2-3-6-checking-whether-an-hr-message-has-already-been-delivered-via-hr-to-its-final-destination-or-an-intermediate-shardchain) + +**22** A description of an older version of TL may be found at [https://core.telegram.org/mtproto/TL](https://core.telegram.org/mtproto/TL). Alternatively, an informal introduction to TL-B schemes may be found in [4, 3.3.4](#ref-4). [Back ↑](#3-1-1-some-standard-definitions) + + **23** Address rewriting is a feature used to implement “anycast addresses” employed by the so-called large or global smart contracts (cf. [[3](#ref-3), 2.3.18]), which can have instances in several shardchains. When address rewriting is enabled, a message may be routed to and processed by a smart contract with an address coinciding with the destination address up to the first `d` bits, where `d ≤ 32` is the “splitting depth” indicated in `anycast.depth` (cf. [2.1.7](#2-1-7-internal-routing)). Otherwise, the addresses must match exactly. [Back ↑](#3-1-4-internal-addresses) + + **24** The information from the `init` field of an inbound message is used either when the receiving account is uninitialized or frozen with the hash of `StateInit` equal to the one expected by the account, or when the receiving account is active and its code or data is an external hash reference matching the hash received in the `StateInit` of the message. [Back ↑](#3-1-12-deserialization-of-a-message-payload) + + **25** Strictly speaking, `InMsgDescr` is the type of this structure; we deliberately use the same notation to describe the only instance of this type in a block. [Back ↑](#3-2-inbound-message-descriptors) + + **26** Recall that a shardchain is considered a neighbor of itself. [Back ↑](#3-2-1-types-and-sources-of-inbound-messages) + + **27** This situation is rare and occurs only after shardchain merge events. Normally the messages imported from the `OutMsgQueue` of the same shardchain have destinations inside this shardchain, and are processed accordingly instead of being re-queued. [Back ↑](#3-3-2-message-dequeueing-records) + + **28** For simplicity, we sometimes treat the masterchain as just another workchain with `workchain_id = −1`. [Back ↑](#4-1-1-account-addresses) + + **29** In fact, up to the first d bits are replaced in such a way that each shard contains at most one instance. [Back ↑](#4-1-3-small-and-large-smart-contracts) + + **30** This scheme uses anonymous constructors and anonymous fields, both represented by an underscore `_`. [Back ↑](#4-1-6-account-description) + +**31** `MERKLE_UPDATE` and exotic cells. A `MERKLE_UPDATE` is a special TL-B constructor whose cell is marked exotic. It carries `old_hash` and `new_hash` (representation hashes of the subtree before/after the update) and may include old/new by reference. Verifiers can validate updates using these hashes with Merkle proofs even if full bodies aren’t inlined. [Back ↑](#4-2-6-bouncing-inbound-messages-to-non-existent-accounts) + +**32** TL-B `_` and `^` syntax. `_` denotes an anonymous field/constructor; `^` means “store under a reference”. Thus the pattern `_:^[ ... ]` means: put the bracketed fields into a separate subcell and store a reference to it instead of inlining. [Back ↑](#4-2-8-reasons-for-splitting-the-processing-into-computation-and-action-phases) + +**33** Notice that this record does not represent a change in the state of the account, because the transaction may still be aborted during the action phase. In that case, the new persistent data indirectly referenced by `vm_final_state_hash` will be discarded. [Back ↑](#4-3-7-valid-computing-phase) + +**34** The most common way of creating shared libraries for TVM is to publish a reference to the root cell of the library in the masterchain. [Back ↑](#4-4-3-smart-contract-library-environment) + +**35** The persistent data of the smart contract need not be loaded in its entirety for this to occur. Instead the root is loaded, and TVM may load other cells by their references from the root only when they are accessed, thus providing a form of virtual memory. [Back ↑](#4-4-4-the-initial-state-of-tvm) + +**36** Both the global gas limit and the gas price are configurable parameters determined by the current state of the masterchain. [Back ↑](#4-4-4-the-initial-state-of-tvm) + + **37** Arithmetic modulo *p* for a modulus *p* near a power of two can be implemented very efficiently. On the other hand, residues modulo 2²⁵⁵ − 19 can be represented by 255-bit integers. This is the reason this particular value of *p* has been chosen by D. Bernstein. [Back ↑](#5-1-2-components-of-a-shardchain-block) + +**38** Notice that these “absent cells” are different from the library reference and external reference cells, which are kinds of exotic cells (cf. [4, 3.1.7](#ref-4)). Absent cells, by contrast, are introduced only for the purpose of serializing incomplete bags of cells, and can never be processed by TVM. [Back ↑](#5-3-6-serialization-of-one-cell-from-a-bag-of-cells) + +**39** Notice that exotic cells (with `s = 1`) always have `b ≥ 8`, with the cell type encoded in the first eight data bits (cf. [4, 3.1.7](#ref-4)). [Back ↑](#5-3-6-serialization-of-one-cell-from-a-bag-of-cells) + +**40** If the bag of cells is not complete, some of these cell references may refer to cells `c′` absent from the bag of cells. In that case, special “absent cells” with `r = 7` are included into the bag of cells and are assigned some indices `j`. These indices are then used to represent references to absent cells. [Back ↑](#5-3-6-serialization-of-one-cell-from-a-bag-of-cells) + +**41** Arithmetic modulo **p** for a modulus **p** near a power of two can be implemented very efficiently. On the other hand, residues modulo **2²⁵⁵ − 19** can be represented by 255-bit integers. This is the reason this particular value of **p** has been chosen by D. Bernstein. [Back ↑](#a-1-1-finite-fields) + + **42** Actually, D. Bernstein chose `A = 486662` because it is the smallest positive integer `A ≡ 2 (mod 4)` such that both the corresponding Montgomery curve ([31](#a-2-1-curve25519)) over `F_p` for `p = 2^255 − 19` and the quadratic twist of this curve have small cofactors. Such an arrangement avoids the necessity to check whether an x-coordinate `x_P ∈ F_p` of a point `P` defines a point `(x_P, y_P) ∈ F_{p^2}` lying on the Montgomery curve itself or on its quadratic twist. [Back ↑](#a2-curve25519-cryptography) \ No newline at end of file From ce96ab35741b0e8366a1f03653b5ba438e8b7c8e Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Fri, 19 Sep 2025 16:09:13 +0100 Subject: [PATCH 16/18] add vale fixes --- .vale/config/vocabularies/Custom/accept.txt | 26 +++- .vale/config/vocabularies/Mintlify/accept.txt | 8 +- ton/tvm.mdx | 123 +++++++++--------- 3 files changed, 90 insertions(+), 67 deletions(-) diff --git a/.vale/config/vocabularies/Custom/accept.txt b/.vale/config/vocabularies/Custom/accept.txt index dcac5cb6..73e0d20e 100644 --- a/.vale/config/vocabularies/Custom/accept.txt +++ b/.vale/config/vocabularies/Custom/accept.txt @@ -14,6 +14,7 @@ Bounceable CEXes CEXs Codepage +Codepages Codespaces Coinbase Cryptobot @@ -262,6 +263,7 @@ shardchains accountchain accountchains bitstrings +bitstring anycast nanograms unixtime @@ -288,4 +290,26 @@ virtualized sidechains sharedlibrary subtransactions -deserialized \ No newline at end of file +deserialize +deserialized +callee +subdictionaries +subdictionary +bitcode +NOPs +indeterministic +arith +CPUs +variadic +nullary +arity +Brujn +deserialisation +prefetch +trie +Serializable +subslices +savelists +multibyte +subexpressions +subcolumn \ No newline at end of file diff --git a/.vale/config/vocabularies/Mintlify/accept.txt b/.vale/config/vocabularies/Mintlify/accept.txt index c1b9b01c..4fb9fe6a 100644 --- a/.vale/config/vocabularies/Mintlify/accept.txt +++ b/.vale/config/vocabularies/Mintlify/accept.txt @@ -61,6 +61,7 @@ undefined struct bool thes +asin cors csrf @@ -116,6 +117,7 @@ uri url ux ui +ato nodejs npm @@ -258,6 +260,7 @@ str tmp val vars +alls todo href @@ -282,4 +285,7 @@ constructivized subinterval cofactors unenveloped -subcases \ No newline at end of file +subcases +frequences +Upgradability +rethrow \ No newline at end of file diff --git a/ton/tvm.mdx b/ton/tvm.mdx index a229a477..0c6377d0 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -696,19 +696,25 @@ The serialization of a hashmap into a tree of cells (or, more generally, into a ```c bit#_ _:(## 1) = Bit; + hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n) -{n = (~m) + l} node:(HashmapNode m X) = Hashmap n X; + {n = (~m) + l} node:(HashmapNode m X) = Hashmap n X; + hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X; hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X) -right:^(Hashmap n X) = HashmapNode (n + 1) X; + right:^(Hashmap n X) = HashmapNode (n + 1) X; + hml_short$0 {m:#} {n:#} len:(Unary ~n) -s:(n * Bit) = HmLabel ~n m; + s:(n * Bit) = HmLabel ~n m; hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m; hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m; + unary_zero$0 = Unary ~0; unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1); + hme_empty$0 {n:#} {X:Type} = HashmapE n X; hme_root$1 {n:#} {X:Type} root:^(Hashmap n X) = HashmapE n X; + true#_ = True; _ {n:#} _:(Hashmap n True) = BitstringSet n; ``` @@ -1473,7 +1479,7 @@ The list of all instructions available in codepage zero, along with their encodi # A Instructions and opcodes This appendix lists all instructions available in the (experimental) codepage zero of TVM, as explained in [5.3](#5-3-instruction-encoding-in-codepage-zero). -We list the instructions in lexicographical opcode order. However, the opcode space is distributed in such way as to make all instructions in each category (e.g., arithmetic primitives) have neighboring opcodes. So we first list a number of stack manipulation primitives, then constant primitives, arithmetic primitives, comparison primitives, cell primitives, continuation primitives, dictionary primitives, and finally application-specific primitives. +We list the instructions in lexicographical opcode order. However, the opcode space is distributed in such way as to make all instructions in each category (e.g., arithmetic primitives) have neighbouring opcodes. So we first list a number of stack manipulation primitives, then constant primitives, arithmetic primitives, comparison primitives, cell primitives, continuation primitives, dictionary primitives, and finally application-specific primitives. We use hexadecimal notation (cf. [1.0](#1-0-notation-for-bitstrings)) for bitstrings. Stack registers `s(i)` usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, 8-bit, or variable length. @@ -2283,7 +2289,7 @@ All these primitives first check whether there is enough space in the Builder, a 0 ≤l≤256. * `D704` — `LDIXQ (s l– x s′ −1 or s 0)`, quiet version of LDIX: loads a - signed l-bit integer from ssimilarly to LDIX, but returns a success flag, + signed l-bit integer from similarly to LDIX, but returns a success flag, equal to−1 on success or to 0 on failure (if s does not have l bits), instead of throwing a cell underflow exception. @@ -2359,9 +2365,10 @@ All these primitives first check whether there is enough space in the Builder, a * `D727` — `SDBEGINSXQ (ss′ – s′′ −1 or s0)`, a quiet version of SDBEGINSX. -* `D72A_xsss` — `SDBEGINS(s– s′′)`, checks whether sbegins with constant - bitstring sss of length 8x+ 3 (with continuation bit assumed), where - 0 ≤x≤127, and removes sss from s on success. +* `D72A_xsss` — `SDBEGINS(s – s′′)`, checks whether `s` begins with constant +bitstring `sss` of length $8x + 3$ (with continuation bit assumed), where +$0 \leq x \leq 127$, and removes `sss` from `s` on success. + * `D72802` — `SDBEGINS ‘0’ (s– s′′)`, checks whether s begins with a binary zero. @@ -2392,35 +2399,34 @@ All these primitives first check whether there is enough space in the Builder, a * `D737` — `SPLITQ (s l r– s′ s′′ −1 or s 0)`, a quiet version of SPLIT. * `D739` — `XCTOS (c– s ?),` transforms an ordinary or exotic cell into a - Slice, asifitwereanordinarycell. Aflagisreturnedindicatingwhether - c is exotic. If that be the case, its type can later be deserialized from - the first eight bits of s. + Slice, as if it were an ordinary cell. A flag is returned indicating whether + `c` is exotic. If that be the case, its type can later be deserialized from + the first eight bits of `s`. -* `D73A` — `XLOAD (c– c′)`, loads an exotic cell c and returns an ordinary +* `D73A` — `XLOAD (c– c′)`, loads an exotic cell `c` and returns an ordinary cell c′. If c is already ordinary, does nothing. If c cannot be loaded, throws an exception. -* `D73B` — `XLOADQ (c– c′ −1 or c 0)`, loads an exotic cell c as XLOAD, but +* `D73B` — `XLOADQ (c– c′ −1 or c 0)`, loads an exotic cell `c` as XLOAD, but returns 0 on failure. -* `D741` — `SCHKBITS (sl– )`, checks whether there are at least ldata bits +* `D741` — `SCHKBITS (sl– )`, checks whether there are at least `l` data bits in Slice s. If this is not the case, throws a cell deserialisation (i.e., cell underflow) exception. -* `D742` — `SCHKREFS (sr–)`, checkswhetherthereareatleastrreferences - in Slice s. +* `D742` — `SCHKREFS (sr–)`, checks whether there are at least `r` references +in Slice `s`. -* `D743` — `SCHKBITREFS (s l r – )`, checks whether there are at least l - data bits and r references in Slice s. +* `D743` — `SCHKBITREFS (s l r – )`, checks whether there are at least `l` + data bits and `r` references in Slice s. -* `D745` — `SCHKBITSQ (s l– ?),` checks whether there are at least l data +* `D745` — `SCHKBITSQ (s l– ?),` checks whether there are at least `l` data bits in Slice s. -* `D746` — `SCHKREFSQ (sr– ?),` checks whether there are at least r refer- - ences in Slice s. +* `D746` — `SCHKREFSQ (sr– ?),` checks whether there are at least `r` references in Slice s. -* `D747` — `SCHKBITREFSQ (s l r– ?),` checks whether there are at least l - data bits and r references in Slice s. +* `D747` — `SCHKBITREFSQ (s l r– ?),` checks whether there are at least `l` + data bits and `r` references in Slice `s`. * `D748` — `PLDREFVAR (s n– c)`, returns the n-th cell reference of Slice s for 0 ≤n≤3. @@ -2479,22 +2485,22 @@ All these primitives first check whether there is enough space in the Builder, a * `D75F` — `PLDULE8Q (s– x−1 or 0)`, quietly preloads a little-endian unsigned 64-bit integer. -* `D760` — `LDZEROES (s– n s′)`, returns the count n of leading zero bits +* `D760` — `LDZEROES (s– n s′)`, returns the count `n` of leading zero bits in s, and removes these bits from s. -* `D761` — `LDONES (s– ns′)`, returns the count nof leading one bits in s, +* `D761` — `LDONES (s– ns′)`, returns the count `n` of leading one bits in s, and removes these bits from s. * `D762` — `LDSAME (s x– n s′)`, returns the count n of leading bits equal - to 0 ≤x≤1 in s, and removes these bits from s. + to 0 ≤x≤1 in s, and removes these bits from `s`. * `D764` — `SDEPTH (s– x)`, returns the depth of Slice s. If s has no references, then x= 0; otherwise xis one plus the maximum of depths of cells referred to from s. * `D765` — `CDEPTH (c– x)`, returns the depth of Cell c. If c has no - references, then x= 0; otherwise xis one plus the maximum of depths - of cells referred to from c. If cis a Null instead of a Cell, returns zero. + references, then x= 0; otherwise `x` is one plus the maximum of depths + of cells referred to from c. If `c` is a Null instead of a Cell, returns zero. --- @@ -2745,8 +2751,7 @@ Most of the loop primitives listed below are implemented with the aid of extraor * `F2FF` — `TRY (c c′ – )`, sets `c2` to `c′`, first saving the old value of `c2` both into the savelist of `c′` and into the savelist of the current continuation, which is stored into `c.c0` and `c′.c0`. Then runs `c` similarly to `EXECUTE`. - If `c` does not throw any exceptions, the original value of `c2` is automati- - cally restored on return from `c`. If an exception occurs, the execution is + If `c` does not throw any exceptions, the original value of `c2` is automatically restored on return from `c`. If an exception occurs, the execution is transferred to `c′`, but the original value of `c2` is restored in the process, so that `c′` can re-throw the exception by `THROWANY` if it cannot handle it by itself. @@ -2767,13 +2772,11 @@ TVM’s dictionary support is discussed at length in [3.3](#3-3-hashmaps%2C-or-d Dictionaries admit two different representations as TVM stack values: * A Slice `s` with a serialization of a TL-B value of type `HashmapE(n, X)`. -In other words, `s` consists either of one bit equal to zero (if the dic- -tionary is empty), or of one bit equal to one and a reference to a Cell +In other words, `s` consists either of one bit equal to zero (if the dictionary is empty), or of one bit equal to one and a reference to a Cell containing the root of the binary tree, i.e., a serialized value of type `Hashmap(n, X)`. -* A “maybe Cell” `cˀ`, i.e., a value that is either a Cell (containing a seri- - alized value of type `Hashmap(n, X)` as before) or a Null (corresponding +* A “maybe Cell” `cˀ`, i.e., a value that is either a Cell (containing a serialized value of type `Hashmap(n, X)` as before) or a Null (corresponding to an empty dictionary). When a “maybe Cell” `cˀ` is used to represent a dictionary, we usually denote it by `D` in the stack notation. @@ -2794,7 +2797,7 @@ Opcodes starting with `F4` and `F5` are reserved for dictionary operations. Builder `b`. It is actually a synonym for `STSLICE`. * `F400` — `STDICT or STOPTREF (D b– b′)`, stores dictionary `D` into Builder - `b`, returing the resulting Builder `b′`. In other words, if `D` is a cell, + `b`, returning the resulting Builder `b′`. In other words, if `D` is a cell, performs `STONE` and `STREF`; if `D` is `Null`, performs `NIP` and `STZERO`; otherwise throws a type checking exception. @@ -2905,8 +2908,7 @@ The mnemonics of the following dictionary primitives are constructed in a system * `F427`— `DICTUREPLACEREF (c i D n– D′ −1 or D 0)`. * `F42A`— `DICTREPLACEGET (x k D n– D′ y−1 or D 0)`, a Replace - counterpart of `DICTSETGET`: on success, also returns the old value asso- - ciated with the key in question. + counterpart of `DICTSETGET`: on success, also returns the old value associated with the key in question. * `F42B`— `DICTREPLACEGETREF (c k D n– D′ c′ −1 or D 0)`. @@ -2962,7 +2964,7 @@ Slices.) The net effect is roughly equivalent to converting b into a Slice by * `F462`— `DICTDELGET (k D n– D′ x−1 or D 0)`, deletes n-bit key, represented by a Slice k, from dictionary D. If the key is present, - returns the modified dictionary D′, the original value xassociated with + returns the modified dictionary D′, the original value `x` associated with the key k (represented by a Slice), and the success flag−1. Otherwise, returns the original dictionary D and 0. @@ -2985,18 +2987,16 @@ Slices.) The net effect is roughly equivalent to converting b into a Slice by ### A.10.7. “Maybe reference” dictionary operations. The following operations assume that a dictionary is used to store values `cˀ` of type Cellˀ -(“Maybe Cell”), which can be used in particular to store dictionaries as val- -ues in other dictionaries. The representation is as follows: if `cˀ` is a Cell, it +(“Maybe Cell”), which can be used in particular to store dictionaries as values in other dictionaries. The representation is as follows: if `cˀ` is a Cell, it is stored as a value with no data bits and exactly one reference to this Cell. If cˀ is Null, then the corresponding key must be absent from the dictionary altogether. * `F469`— `DICTGETOPTREF (k D n– cˀ)`, a variant of `DICTGETREF` that - returns Null instead of the value cˀ if the key k is absent from dictio- - nary D. + returns Null instead of the value cˀ if the key k is absent from dictionary D. * `F46A`— `DICTIGETOPTREF (i D n– cˀ)`, similar to `DICTGETOPTREF`, but - with the key given by signed n-bit Integer i. If the key iis out of range, + with the key given by signed n-bit Integer i. If the key `i` is out of range, also returns Null. * `F46B`— `DICTUGETOPTREF (i D n– cˀ)`, similar to `DICTGETOPTREF`, but @@ -3009,11 +3009,11 @@ altogether. returns Null instead). * `F46E`— `DICTISETGETOPTREF (cˀ i D n– D′ ˜cˀ)`, similar to primitive - `DICTSETGETOPTREF`, but using signed n-bit Integer ias a key. If idoes + `DICTSETGETOPTREF`, but using signed n-bit Integer `i` as a key. If `i` does not fit into n bits, throws a range checking exception. * `F46F`— `DICTUSETGETOPTREF (cˀ i D n– D′ ˜cˀ)`, similar to primitive - DICTSETGETOPTREF, but using unsigned n-bit Integer i as a key. + DICTSETGETOPTREF, but using unsigned n-bit Integer `i` as a key. ### A.10.8. Prefix code dictionary operations. @@ -3049,8 +3049,7 @@ as well. equal to k. * `F478`— `DICTIGETNEXT (iDn– x′i′ −1 or 0)`, similar to `DICTGETNEXT`, - but interprets all keys in dictionary D as big-endian signed n-bit in- - tegers, and computes the minimal key i′ that is larger than Integer i + but interprets all keys in dictionary D as big-endian signed n-bit integers, and computes the minimal key i′ that is larger than Integer i (which does not necessarily fit into n bits). * `F479`— `DICTIGETNEXTEQ (i D n– x′ i′ −1 or 0)`. @@ -3107,7 +3106,7 @@ as well. * `F48F`— `DICTUMAXREF (D n– c i−1 or 0)`. * `F492`— `DICTREMMIN (D n– D′xk−1 or D 0)`, computes the minimal - key k(represented by a Slice with ndata bits) in dictionary D, removes + key k(represented by a Slice with `n` data bits) in dictionary D, removes k from the dictionary, and returns k along with the associated value x and the modified dictionary D′. @@ -3115,7 +3114,7 @@ as well. but returns the only reference in the value as a Cell c. * `F494`— `DICTIREMMIN (D n– D′ x i−1 or D 0)`, somewhat similar - to DICTREMMIN, but computes the minimal key iunder the assumption + to DICTREMMIN, but computes the minimal key `i` under the assumption that all keys are big-endian signed n-bit integers. Notice that the key and value returned may differ from those computed by `DICTREMMIN` and `DICTUREMMIN`. @@ -3191,8 +3190,7 @@ as well. ### A.10.12. SubDict dictionary operations -* `F4B1` — `SUBDICTGET (k l D n – D′)`, constructs a subdictionary con- - sisting of all keys beginning with prefix `k` (represented by a `Slice`, the +* `F4B1` — `SUBDICTGET (k l D n – D′)`, constructs a subdictionary consisting of all keys beginning with prefix `k` (represented by a `Slice`, the first `0 ≤ l ≤ n ≤ 1023` data bits of which are used as a key) of length `l` in dictionary `D` of type `HashmapE(n, X)` with `n`-bit keys. On success, returns the new subdictionary of the same type `HashmapE(n, X)` as a @@ -3232,7 +3230,7 @@ specific primitives are in fact TON Blockchain-specific. Most of the primitives listed below use 16-bit opcodes. * `F800` — `ACCEPT`, sets current gas limit `gl` to its maximal allowed value - `gm`, and resets the gas credit `gc` to zero (cf. `1.4`), decreasing the value + `gm`, and resets the gas credit `gc` to zero (cf. [1.4](#1-4-total-state-of-tvm-scccg)), decreasing the value of `gr` by `gc` in the process. In other words, the current smart contract agrees to buy some gas to finish the current transaction. This action is required to process external messages, which bring no value (hence @@ -3257,8 +3255,7 @@ Most of the primitives listed below use 16-bit opcodes. * `F806–F80E` — Reserved for gas-related primitives. -* `F80F` — `COMMIT ( – )`, commits the current state of registers `c4` (“persis- - tentdata”) and `c5` (“actions”) so that the current execution is considered +* `F80F` — `COMMIT ( – )`, commits the current state of registers `c4` (“persistent data”) and `c5` (“actions”) so that the current execution is considered “successful” with the saved values even if an exception is thrown later. @@ -3286,8 +3283,7 @@ Most of the primitives listed below use 16-bit opcodes. of two 32-byte strings: the first with the big-endian representation of the old seed `r`, and the second with the big-endian representation of `x`. -* `F810–F81F` — Reserved for pseudo-random number generator primi- - tives. +* `F810–F81F` — Reserved for pseudo-random number generator primitives. ### A.11.4. Configuration primitives. @@ -3312,8 +3308,7 @@ Most of the primitives listed below use 16-bit opcodes. 256-bit `Integer`. Equivalent to `GETPARAM 6`. * `F827` — `BALANCE ( – t)`, returns the remaining balance of the smart - contract as a `Tuple` consisting of an `Integer` (the remaining Gram bal- - ance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys + contract as a `Tuple` consisting of an `Integer` (the remaining Gram balance in nanograms) and a `Maybe Cell` (a dictionary with 32-bit keys representing the balance of “extra currencies”). Equivalent to `GETPARAM 7`. Note that RAW primitives such as `SENDRAWMSG` do not update this field. @@ -3325,15 +3320,13 @@ Most of the primitives listed below use 16-bit opcodes. * `F829` — `CONFIGROOT ( – D)`, returns the `Maybe Cell D` with the current global configuration dictionary. Equivalent to `GETPARAM 9`. -* `F830` — `CONFIGDICT ( – D 32)`, returns the global configuration dic- - tionary along with its key length `(32)`. Equivalent to `CONFIGROOT; PUSHINT 32`. +* `F830` — `CONFIGDICT ( – D 32)`, returns the global configuration dictionary along with its key length `(32)`. Equivalent to `CONFIGROOT; PUSHINT 32`. * `F832` — `CONFIGPARAM (i – c −1 or 0)`, returns the value of the global configuration parameter with integer index `i` as a `Cell c`, and a flag to indicate success. Equivalent to `CONFIGDICT; DICTIGETREF`. -* `F833` — `CONFIGOPTPARAM (i – cˀ)`, returns the value of the global config- - uration parameter with integer index `i` as a `Maybe Cell cˀ`. Equivalent +* `F833` — `CONFIGOPTPARAM (i – cˀ)`, returns the value of the global configuration parameter with integer index `i` as a `Maybe Cell cˀ`. Equivalent to `CONFIGDICT; DICTIGETOPTREF`. * `F820–F83F` — Reserved for configuration primitives. @@ -3380,10 +3373,10 @@ Most of the primitives listed below use 16-bit opcodes. second hashing occurring inside CHKSIGNS. * `F911`— `CHKSIGNS (d s k– ? )`, checks whether s is a valid Ed25519- - signature of the data portion of Slice dusing public key k, similarly to - CHKSIGNU. If the bit length of Slice d is not divisible by eight, throws + signature of the data portion of Slice `d` using public key `k`, similarly to + CHKSIGNU. If the bit length of Slice `d` is not divisible by eight, throws a cell underflow exception. The verification of Ed25519 signatures is - the standard one, with sha256 used to reduce dto the 256-bit number + the standard one, with sha256 used to reduce `d` to the 256-bit number that is actually signed. * `F912–F93F` — Reserved for hashing and cryptography primitives. From 1d33ee42607f890c0bf79215a72d3f130d0b5bc3 Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Fri, 19 Sep 2025 16:24:11 +0100 Subject: [PATCH 17/18] vale fixes --- .vale/config/vocabularies/Custom/accept.txt | 6 +++++- .vale/config/vocabularies/Mintlify/accept.txt | 6 +++++- ton/tvm.mdx | 7 +++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.vale/config/vocabularies/Custom/accept.txt b/.vale/config/vocabularies/Custom/accept.txt index 7ee9735d..2b258afe 100644 --- a/.vale/config/vocabularies/Custom/accept.txt +++ b/.vale/config/vocabularies/Custom/accept.txt @@ -360,4 +360,8 @@ virtualized sidechains sharedlibrary subtransactions -deserialized \ No newline at end of file +deserialized +deserializes +ident +substring +subcolumn \ No newline at end of file diff --git a/.vale/config/vocabularies/Mintlify/accept.txt b/.vale/config/vocabularies/Mintlify/accept.txt index 68339951..0c587426 100644 --- a/.vale/config/vocabularies/Mintlify/accept.txt +++ b/.vale/config/vocabularies/Mintlify/accept.txt @@ -14,6 +14,8 @@ Lorem ipsum impsum amet +aor +orin const myName @@ -305,4 +307,6 @@ constructivized subinterval cofactors unenveloped -subcases \ No newline at end of file +subcases +rethrow +neighboring \ No newline at end of file diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 0c6377d0..2c3883f1 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -1479,7 +1479,7 @@ The list of all instructions available in codepage zero, along with their encodi # A Instructions and opcodes This appendix lists all instructions available in the (experimental) codepage zero of TVM, as explained in [5.3](#5-3-instruction-encoding-in-codepage-zero). -We list the instructions in lexicographical opcode order. However, the opcode space is distributed in such way as to make all instructions in each category (e.g., arithmetic primitives) have neighbouring opcodes. So we first list a number of stack manipulation primitives, then constant primitives, arithmetic primitives, comparison primitives, cell primitives, continuation primitives, dictionary primitives, and finally application-specific primitives. +We list the instructions in lexicographical opcode order. However, the opcode space is distributed in such way as to make all instructions in each category (e.g., arithmetic primitives) have neighboring opcodes. So we first list a number of stack manipulation primitives, then constant primitives, arithmetic primitives, comparison primitives, cell primitives, continuation primitives, dictionary primitives, and finally application-specific primitives. We use hexadecimal notation (cf. [1.0](#1-0-notation-for-bitstrings)) for bitstrings. Stack registers `s(i)` usually have `0 ≤ i ≤ 15`, and `i` is encoded in a 4-bit field (or, on a few rare occasions, in an 8-bit field). Other immediate parameters are usually 4-bit, 8-bit, or variable length. @@ -2256,8 +2256,7 @@ All these primitives first check whether there is enough space in the Builder, a ### A.7.2. Cell deserialization primitives * `D0` — `CTOS (c– s)`, converts a Cell into a Slice. Notice that c must - be either an ordinary cell, or an exotic cell (cf. [3.1.2](#3-1-2-ordinary-and-exotic-cells)) which is au- - tomatically loaded to yield an ordinary cell c′, converted into a Slice + be either an ordinary cell, or an exotic cell (cf. [3.1.2](#3-1-2-ordinary-and-exotic-cells)) which is automatically loaded to yield an ordinary cell c′, converted into a Slice afterwards. * `D1` — `ENDS (s – )`, removes a Slice s from the stack, and throws an @@ -2358,7 +2357,7 @@ All these primitives first check whether there is enough space in the Builder, a from offset 0 ≤l ≤1023, thus extracting a bit substring out of the data of s. -* `D726` — `SDBEGINSX (ss′ – s′′)`, checks whether sbegins with (the data +* `D726` — `SDBEGINSX (ss′ – s′′)`, checks whether `s` begins with (the data bits of) s′, and removes s′ from s on success. On failure throws a cell deserialization exception. Primitive SDPFXREV can be considered a quiet version of SDBEGINSX. From 7018e924d2a0d4c0cfb4817d822f9f17e6badfcf Mon Sep 17 00:00:00 2001 From: Favour Kelvin Date: Fri, 19 Sep 2025 16:27:17 +0100 Subject: [PATCH 18/18] update valke fixes on repeated word --- ton/tvm.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ton/tvm.mdx b/ton/tvm.mdx index 2c3883f1..adcd7125 100644 --- a/ton/tvm.mdx +++ b/ton/tvm.mdx @@ -217,7 +217,7 @@ If `y` is zero, then all of the expected results are replaced by `NaN`s, and (us The implementation of division in TVM somewhat differs from most other implementations with regards to rounding. By default, these primitives round to `−∞`, meaning that `q = ⌊x/y⌋`, and `r` has the same sign as `y`. (Most conventional implementations of division use “rounding to zero” instead, meaning that `r` has the same sign as `x`.) -Apart from this “floor rounding”, two other rounding modes are available, called **ceiling rounding** (with `q = ⌈x/y⌉`, and `r` and `y` having opposite signs) and **nearest rounding** (with `q = ⌊x/y + 1/2⌋` and `|r| ≤ |y|/2`). +Apart from this “floor rounding”, two other rounding modes are available, called **ceiling rounding** (with `q = ⌈x/y⌉`, & `r` and `y` having opposite signs) and **nearest rounding** (with `q = ⌊x/y + 1/2⌋` and `|r| ≤ |y|/2`). These rounding modes are selected by using other division primitives, with letters `C` and `R` appended to their mnemonics. For example, `DIVMODR` computes both the quotient and the remainder using rounding to the nearest integer.

C>k!S(wlAT3u&(xZi#PMivrr#v3mvohiUqy) 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