-
Notifications
You must be signed in to change notification settings - Fork 2
/
en_tvm.tex
3197 lines (2708 loc) · 370 KB
/
en_tvm.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[12pt,oneside]{article}
\usepackage[T1]{fontenc}
%\usepackage{euler}
\usepackage{amssymb, amsmath, amsfonts, stmaryrd}
\usepackage[mathscr]{euscript}
\usepackage{mathrsfs}
\usepackage{theorem}
\usepackage[english]{babel}
\usepackage{bm}
\usepackage[all]{xy}
\usepackage{array}
\usepackage{multirow}
%\usepackage{chngcntr}
%\CompileMatrices
\usepackage[bookmarks=false,pdfauthor={Nikolai Durov},pdftitle={Telegram Open Network Virtual Machine}]{hyperref}
\usepackage{fancyhdr}
\usepackage{caption}
%
\setlength{\headheight}{15.2pt}
\pagestyle{fancy}
\renewcommand{\headrulewidth}{0.5pt}
%
\def\makepoint#1{\medbreak\noindent{\bf #1.\ }}
\def\zeropoint{\setcounter{subsection}{-1}}
\def\zerosubpoint{\setcounter{subsubsection}{-1}}
\def\nxpoint{\refstepcounter{subsection}%
\smallbreak\makepoint{\thesubsection}}
\def\nxsubpoint{\refstepcounter{subsubsection}%
\smallbreak\makepoint{\thesubsubsection}}
\def\nxsubsubpoint{\refstepcounter{paragraph}%
\makepoint{\paragraph}}
%\setcounter{secnumdepth}{4}
%\counterwithin{paragraph}{subsubsection}
\def\refpoint#1{{\rm\textbf{\ref{#1}}}}
\let\ptref=\refpoint
\def\embt(#1.){\textbf{#1.}}
\def\embtx(#1){\textbf{#1}}
\def\emb#1{\textbf{#1.}}
\long\def\nodo#1{}
%
%\def\markbothsame#1{\markboth{#1}{#1}}
\fancyhf{}
\fancyfoot[C]{\thepage}
\def\markbothsame#1{\fancyhead[C]{#1}}
\def\mysection#1{\section{#1}\fancyhead[C]{\textsc{Chapter \textbf{\thesection.} #1}}}
\def\mysubsection#1{\subsection{#1}\fancyhead[C]{\small{\textsc{\textrm{\thesubsection.} #1}}}}
\def\myappendix#1{\section{#1}\fancyhead[C]{\textsc{Appendix \textbf{\thesection.} #1}}}
%
\let\tp=\textit
\let\vr=\textit
\def\workchainid{\vr{workchain\_id\/}}
\def\shardpfx{\vr{shard\_prefix}}
\def\accountid{\vr{account\_id\/}}
\def\currencyid{\vr{currency\_id\/}}
\def\uint{\tp{uint}}
\def\opsc#1{\operatorname{\textsc{#1}}}
\def\blkseqno{\opsc{blk-seqno}}
\def\blkprev{\opsc{blk-prev}}
\def\blkhash{\opsc{blk-hash}}
\def\Hash{\opsc{Hash}}
\def\Sha{\opsc{sha256}}
\def\CellRepr{\opsc{CellRepr}}
\def\Lvl{\opsc{Lvl}}
\def\height{\opsc{height}}
\def\len{\opsc{len}}
\def\leaf{\opsc{Leaf}}
\def\node{\opsc{Node}}
\def\root{\opsc{Root}}
\def\emptyroot{\opsc{EmptyRoot}}
\def\code{\opsc{code}}
\def\Ping{\opsc{Ping}}
\def\Store{\opsc{Store}}
\def\FindNode{\opsc{Find\_Node}}
\def\FindValue{\opsc{Find\_Value}}
\def\Bytes{\tp{Bytes}}
\def\Transaction{\tp{Transaction}}
\def\Account{\tp{Account}}
\def\State{\tp{State}}
\def\Maybe{\opsc{Maybe}}
\def\List{\opsc{List}}
\def\Block{\tp{Block}}
\def\Blockchain{\tp{Blockchain}}
\def\isValidBc{\tp{isValidBc}}
\def\evtrans{\vr{ev\_trans}}
\def\evblock{\vr{ev\_block}}
\def\Hashmap{\tp{Hashmap}}
\def\HashmapE{\tp{HashmapE}}
\def\Type{\tp{Type}}
\def\nat{\tp{nat\/}}
\def\hget{\vr{hget\/}}
\def\bbB{{\mathbb{B}}}
\def\st#1{{\mathbf{#1}}}
\def\sgn{\operatorname{sgn}}
\def\caret{\^{}}
%
\hfuzz=0.8pt
\title{Telegram Open Network Virtual Machine}
\author{Nikolai Durov}
\begin{document}
%\pagestyle{myheadings}
\maketitle
\begin{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.
\end{abstract}
\section*{Introduction}
\markbothsame{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:
\begin{itemize}
\item 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.
\item It must strive to attain high ``(virtual) machine code'' density, so that the code of a typical smart contract occupies as little persistent block\-chain storage as possible.
\item 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.\footnote{For example, there are no floating-point arithmetic operations (which could be efficiently implemented using hardware-supported {\em 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.}
\end{itemize}
The design of TVM is guided by these requirements. While this document describes a preliminary and experimental version of TVM,\footnote{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.} 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.
\clearpage
\tableofcontents
\clearpage
\mysection{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.
\zeropoint\mysubsection{Notation for bitstrings}\label{p:bitstring.hex}
The following notation is used for bit strings (or {\em bitstrings\/})---i.e., finite strings consisting of binary digits (bits), \texttt{0} and \texttt{1}---throughout this document.
\nxsubpoint\emb{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 \texttt{0}--\texttt{9}, \texttt{A}--\texttt{F} in the usual manner: $\texttt{0}_{16}\leftrightarrow\texttt{0000}$, $\texttt{1}_{16}\leftrightarrow\texttt{0001}$, \dots, $\texttt{F}_{16}\leftrightarrow\texttt{1111}$. The resulting hexadecimal string is our equivalent representation for the original binary string.
\nxsubpoint\emb{Bitstrings of lengths not divisible by four}
If the length of a binary string is not divisible by four, we augment it by one \texttt{1} and several (maybe zero) \texttt{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'' \texttt{\_} 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 \texttt{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, \texttt{8A} corresponds to binary string \texttt{10001010}, while \texttt{8A\_} and \texttt{8A0\_} both correspond to \texttt{100010}. An empty bitstring may be represented by either `', `\texttt{8\_}', `\texttt{0\_}', `\texttt{\_}', or `\texttt{00\_}'.
\nxsubpoint\label{sp:hex.bitst}\emb{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 \texttt{\_} at the end) is the hexadecimal representation of a bitstring. In such cases, we either prepend \texttt{x} to the resulting string (e.g., \texttt{x8A}), or prepend \texttt{x\{} and append \texttt{\}} (e.g., \texttt{x\{2D9\_\}}, which is \texttt{00101101100}). This should not be confused with hexadecimal numbers, usually prepended by \texttt{0x} (e.g., \texttt{0x2D9} or \texttt{0x2d9}, which is the integer 729).
\nxsubpoint\emb{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\ldots255$, 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\ldots255$. If the length of the bitstring is not a multiple of eight, the bitstring is augmented by a binary \texttt{1} and up to seven binary \texttt{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, \texttt{00101101100} corresponds to the sequence of two octets $(\texttt{0x2d}, \texttt{0x90})$ (hexadecimal), or $(45,144)$ (decimal), along with a completion tag bit equal to \texttt{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 $\texttt{0x80}=128$.
\mysubsection{TVM is a stack machine}\label{p:tvm.stack}
First of all, {\em 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) {\em stack}, at least from the ``low-level'' (TVM) perspective.\footnote{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.}
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) \texttt{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.
\nxsubpoint\label{sp:tvm.val}\emb{TVM values}
The entities that can be stored in the TVM stack will be called {\em TVM values}, or simply {\em values\/} for brevity. They belong to one of several predefined {\em 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 {\em primitives}) only accept values of predefined types.
For example, the integer addition primitive \texttt{ADD} accepts only two integer values, and returns one integer value as a result. One cannot supply \texttt{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.
\nxsubpoint\emb{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.
\nxsubpoint\label{sp:val.types}\emb{Preliminary list of value types}
A preliminary list of value types supported by TVM is as follows:
\begin{itemize}
\item {\em Integer\/} --- Signed 257-bit integers, representing integer numbers in the range $-2^{256}\ldots2^{256}-1$, as well as a special ``not-a-number'' value \texttt{NaN}.
\item {\em Cell\/} --- A {\em 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.~\cite[2.5.14]{TON}).
\item {\em Tuple\/} --- An ordered collection of up to 255 components, having arbitrary value types, possibly distinct. May be used to represent non-persistent values of arbitrary algebraic data types.
\item {\em Null\/} --- A type with exactly one value~$\bot$, used for representing empty lists, empty branches of binary trees, absence of return value in some situations, and so on.
\item {\em Slice\/} --- A {\em TVM cell slice}, or {\em 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.
\item {\em Builder\/} --- A {\em TVM cell builder}, or {\em 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).
\item {\em 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.
\end{itemize}
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 {\em Integer\/} might become 513-bit {\em LongInteger\/}, with originally defined arithmetic primitives failing if either of the arguments or the result does not fit into the original subtype {\em 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.~\ptref{sp:old.op.change}).
\mysubsection{Categories of TVM instructions}
TVM {\em instructions}, also called {\em primitives\/} and sometimes {\em (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.~\ptref{sp:val.types}) they work on. The most important of these categories are:
\begin{itemize}
\item {\em 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.
\item {\em Tuple (manipulation) primitives\/} --- Construct, modify, and decompose {\em Tuple\/}s. Similarly to the stack primitives, they are polymorphic.
\item {\em Constant\/} or {\em 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.
\item {\em Arithmetic primitives\/} --- Perform the usual integer arithmetic operations on values of type {\em Integer}.
\item {\em Cell (manipulation) primitives\/} --- Create new cells and store data in them ({\em cell creation primitives}) or read data from previously created cells ({\em 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 {\em Builder}, while cell parsing primitives work with {\em Slice\/}s.
\item {\em Continuation\/} and {\em control flow primitives\/} --- Create and modify {\em Continuation\/}s, as well as execute existing {\em Continuation\/}s in different ways, including conditional and repeated execution.
\item {\em Custom\/} or {\em 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.
\end{itemize}
\mysubsection{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 {\em control registers}, denoted by \texttt{c0} to \texttt{c15}, or $\texttt{c}(0)$ to $\texttt{c}(15)$. The original version of TVM makes use of only some of these registers; the rest may be supported later.
\nxsubpoint\emb{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.
\nxsubpoint\label{sp:cr.list}\emb{List of control registers}
The original version of TVM defines and uses the following control registers:
\begin{itemize}
\item \texttt{c0} --- Contains the {\em next continuation} or {\em return continuation} (similar to the subroutine return address in conventional designs). This value must be a {\em Continuation}.
\item \texttt{c1} --- Contains the {\em alternative (return) continuation}; this value must be a {\em Continuation}. It is used in some (experimental) control flow primitives, allowing TVM to define and call ``subroutines with two exit points''.
\item \texttt{c2} --- Contains the {\em exception handler}. This value is a {\em Continuation}, invoked whenever an exception is triggered.
\item \texttt{c3} --- Contains the {\em current dictionary}, essentially a hashmap containing the code of all functions used in the program. For reasons explained later in~\ptref{p:func.rec.dict}, this value is also a {\em Continuation}, not a {\em Cell\/} as one might expect.
\item \texttt{c4} --- Contains the {\em root of persistent data}, or simply the {\em data}. This value is a {\em Cell}. When the code of a smart contract is invoked, \texttt{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 \texttt{c4} before returning.
\item \texttt{c5} --- Contains the {\em output actions}. It is also a {\em Cell\/} initialized by a reference to an empty cell, but its final value is considered one of the smart contract outputs. For instance, the {\tt SENDMSG} primitive, specific for the TON Blockchain, simply inserts the message into a list stored in the output actions.
\item \texttt{c7} --- Contains the {\em root of temporary data}. It is a {\em Tuple}, initialized by a reference to an empty {\em Tuple\/} before invoking the smart contract and discarded after its termination.\footnote{In the TON Blockchain context, \texttt{c7} is initialized with a singleton {\em Tuple}, the only component of which is a {\em Tuple\/} containing blockchain-specific data. The smart contract is free to modify \texttt{c7} to store its temporary data provided the first component of this {\em Tuple\/} remains intact.}
\end{itemize}
More control registers may be defined in the future for specific TON Block\-chain or high-level programming language purposes, if necessary.
\mysubsection{Total state of TVM (SCCCG)}\label{p:tvm.state}
The total state of TVM consists of the following components:
\begin{itemize}
\item {\em Stack} (cf.~\ptref{p:tvm.stack}) --- Contains zero or more {\em values\/} (cf.~\ptref{sp:tvm.val}), each belonging to one of {\em value types} listed in~\ptref{sp:val.types}.
\item {\em Control registers \texttt{c0}--\texttt{c15}} --- Contain some specific values as described in \ptref{sp:cr.list}. (Only seven control registers are used in the current version.)
\item {\em Current continuation \texttt{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 (\texttt{ip}) in other architectures.
\item {\em Current codepage \texttt{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.
\item {\em Gas limits \texttt{gas}} --- Contains four signed 64-bit integers: the current gas limit $g_l$, the maximal gas limit $g_m$, the remaining gas $g_r$, and the gas credit $g_c$. Always $0\leq g_l\leq g_m$, $g_c\geq0$, and $g_r\leq g_l+g_c$; $g_c$ is usually initialized by zero, $g_r$ is initialized by $g_l+g_c$ and gradually decreases as the TVM runs. When $g_r$ becomes negative or if the final value of $g_r$ is less than $g_c$, an {\em out of gas\/} exception is triggered.
\end{itemize}
Notice that there is no ``return stack'' containing the return addresses of all previously called but unfinished functions. Instead, only control register \texttt{c0} is used. The reason for this will be explained later in~\ptref{sp:call.sw}.
Also notice that there are no general-purpose registers, because TVM is a stack machine (cf.~\ptref{p:tvm.stack}). 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 {\em total\/} state of TVM.\footnote{Strictly speaking, there is also the current {\em library context}, which consists of a dictionary with 256-bit keys and cell values, used to load library reference cells of~\ptref{sp:exotic.cell.types}.}
\mysubsection{Integer arithmetic}
All arithmetic primitives of TVM operate on several arguments of type {\em Integer}, taken from the top of the stack, and return their results, of the same type, into the stack. Recall that {\em Integer\/} represents all integer values in the range $-2^{256}\leq x<2^{256}$, and additionally contains a special value \texttt{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 \texttt{NaN}---then this result or all of the results are replaced by a \texttt{NaN}, and (by default) an integer overflow exception is generated. However, special ``quiet'' versions of arithmetic operations will simply produce \texttt{NaN}s and keep going. If these \texttt{NaN}s end up being used in a ``non-quiet'' arithmetic operation, or in a non-arithmetic operation, an integer overflow exception will occur.
\nxsubpoint\label{sp:int.no.autoconv}\emb{Absence of automatic conversion of integers}
Notice that TVM {\em 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 \texttt{MUL}, rather than two (\texttt{MUL} for unsigned multiplication and \texttt{IMUL} for signed multiplication) as occurs, for example, in the popular x86 architecture.
\nxsubpoint\emb{Automatic overflow checks}
Notice that all TVM arithmetic primitives perform overflow checks of the results. If a result does not fit into the {\em Integer} type, it is replaced by a \texttt{NaN}, and (usually) an exception occurs. In particular, the result is {\em not\/} automatically reduced modulo $2^{256}$ or $2^{257}$, as is common for most hardware machine code architectures.
\nxsubpoint\emb{Custom overflow checks}
In addition to automatic overflow checks, TVM includes custom overflow checks, performed by primitives \texttt{FITS}~$n$ and \texttt{UFITS}~$n$, where $1\leq n\leq256$. These primitives check whether the value on (the top of) the stack is an integer $x$ in the range $-2^{n-1}\leq x<2^{n-1}$ or $0\leq x<2^n$, respectively, and replace the value with a \texttt{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 \texttt{FITS} or \texttt{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.
\nxsubpoint\emb{Reduction modulo $2^n$}
TVM also has a primitive \texttt{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$.
\nxsubpoint\emb{{\em Integer\/} is 257-bit, not 256-bit}
One can understand now why TVM's {\em 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.~\ptref{sp:int.no.autoconv}).
\nxsubpoint\label{sp:div.round}\emb{Division and rounding}
The most important division primitives are \texttt{DIV}, \texttt{MOD}, and \texttt{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 \texttt{NaN}s, and (usually) an integer overflow exception is generated.
The implementation of division in TVM somewhat differs from most other implementations with regards to rounding. By default, these primitives round to $-\infty$, meaning that $q=\lfloor x/y\rfloor$, 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=\lceil x/y\rceil$, and $r$ and $y$ having opposite signs) and ``nearest rounding'' (with $q=\lfloor x/y+1/2\rfloor$ and $|r|\leq|y|/2$). These rounding modes are selected by using other division primitives, with letters \texttt{C} and \texttt{R} appended to their mnemonics. For example, \texttt{DIVMODR} computes both the quotient and the remainder using rounding to the nearest integer.
\nxsubpoint\emb{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, \texttt{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 {\em Integer}, either two \texttt{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.
\clearpage
\mysection{The stack}
This chapter contains a general discussion and comparison of register and stack machines, expanded further in Appendix~\ptref{app:code.density}, and describes the two main classes of stack manipulation primitives employed by TVM: the {\em basic\/} and the {\em 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~\ptref{p:eff.stack.manip}.
\mysubsection{Stack calling conventions}\label{p:stack.conv}
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.
\nxsubpoint\emb{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 \texttt{s0} or $\texttt{s}(0)$ the value at the top of the stack, by \texttt{s1} or $\texttt{s}(1)$ the value immediately under it, and so on. The total number of values in the stack is called its {\em depth}. If the depth of the stack is $n$, then $\texttt{s}(0)$, $\texttt{s}(1)$, \dots, $\texttt{s}(n-1)$ are well-defined, while $\texttt{s}(n)$ and all subsequent $\texttt{s}(i)$ with $i>n$ are not. Any attempt to use $\texttt{s}(i)$ with $i\geq 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.
\nxsubpoint\emb{Pushing and popping values}
When a value $x$ is {\em pushed\/} into a stack of depth $n$, it becomes the new \texttt{s0}; at the same time, the old \texttt{s0} becomes the new \texttt{s1}, the old \texttt{s1}---the new \texttt{s2}, and so on. The depth of the resulting stack is $n+1$.
Similarly, when a value $x$ is {\em popped\/} from a stack of depth $n\geq1$, it is the old value of \texttt{s0} (i.e., the old value at the top of the stack). After this, it is removed from the stack, and the old \texttt{s1} becomes the new \texttt{s0} (the new value at the top of the stack), the old \texttt{s2} becomes the new \texttt{s1}, and so on. The depth of the resulting stack is $n-1$.
If originally $n=0$, then the stack is {\em empty}, and a value cannot be popped from it. If a primitive attempts to pop a value from an empty stack, a {\em stack underflow\/} exception occurs.
\nxsubpoint\emb{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 \texttt{r0}, \texttt{r1}, and so on, or by $\texttt{r}(0)$, $\texttt{r}(1)$, \ldots, $\texttt{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.
\nxsubpoint\emb{The top-of-stack register \texttt{s0} vs.\ the accumulator register \texttt{r0}}
Some register machine architectures require one of the arguments for most arithmetic and logical operations to reside in a special register called the {\em accumulator}. In our comparison, we will assume that the accumulator is the general-purpose register \texttt{r0}; otherwise we could simply renumber the registers. In this respect, the accumulator is somewhat similar to the top-of-stack ``register'' \texttt{s0} of a stack machine, because virtually all operations of a stack machine both use \texttt{s0} as one of their arguments and return their result as \texttt{s0}.
\nxsubpoint\emb{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\leq n$ function arguments are passed in registers, and that these registers are $\texttt{r0}$, $\texttt{r1}$, \dots, $\texttt{r}(m-1)$, in that order (if some other registers are used, we can simply renumber them).\footnote{Our inclusion of $\texttt{r0}$ here creates a minor conflict with our assumption that the accumulator register, if present, is also \texttt{r0}; for simplicity, we will resolve this problem by assuming that the first argument to a function is passed in the accumulator.}
\nxsubpoint\label{sp:func.arg.ord}\emb{Order of function arguments}
If a function or primitive requires $m$ arguments $x_1$, \dots, $x_m$, they are pushed by the caller into the stack in the same order, starting from $x_1$. Therefore, when the function or primitive is invoked, its first argument $x_1$ is in $\texttt{s}(m-1)$, its second argument $x_2$ is in $\texttt{s}(m-2)$, and so on. The last argument $x_m$ is in $\texttt{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 \texttt{scanf} and \texttt{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.
\nxsubpoint\label{sp:reg.op.arg}\emb{Arguments to arithmetic primitives on register machines}
On a stack machine, built-in arithmetic primitives (such as \texttt{ADD} or \texttt{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 \texttt{SUB}, thus requires two arguments, $\texttt{r}(i)$ and $\texttt{r}(j)$, with $i$ and $j$ specified by the instruction. A register $\texttt{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:
\begin{itemize}
\item {Three-address form} --- Allows the programmer to arbitrarily choose not only the two source registers $\texttt{r}(i)$ and $\texttt{r}(j)$, but also a separate destination register $\texttt{r}(k)$. This form is common for most RISC processors, and for the XMM and AVX SIMD instruction sets in the x86-64 architecture.
\item {Two-address form} --- Uses one of the two operand registers (usually $\texttt{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).
\item {One-address form} --- Always takes one of the arguments from the accumulator \texttt{r0}, and stores the result in \texttt{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).
\end{itemize}
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.\footnote{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.}
\nxsubpoint\emb{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'' \texttt{s0}.
This is in complete accordance with Forth calling conventions, but differs slightly from Pascal and C calling conventions, where the accumulator register \texttt{r0} is normally used for the return value.
\nxsubpoint\emb{Returning several values}
Some functions might want to return several values $y_1$, \dots, $y_k$, 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 $y_1$.
For example, the ``divide with remainder'' primitive \texttt{DIVMOD} needs to return two values, the quotient $q$ and the remainder $r$. Therefore, \texttt{DIVMOD} pushes $q$ and $r$ into the stack, in that order, so that the quotient is available thereafter at \texttt{s1} and the remainder at \texttt{s0}. The net effect of \texttt{DIVMOD} is to divide the original value of \texttt{s1} by the original value of \texttt{s0}, and return the quotient in \texttt{s1} and the remainder in \texttt{s0}. In this particular case the depth of the stack and the values of all other ``stack registers'' remain unchanged, because \texttt{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.~\ptref{sp:func.arg.ord}) 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 $y_1$, \dots, $y_k$, and then push their total number $k$ as an integer. The caller would then determine the total number of returned values by inspecting \texttt{s0}.)
In this respect TVM, again, faithfully observes Forth calling conventions.
\nxsubpoint\label{sp:stack.notat}\emb{Stack notation}
When a stack of depth $n$ contains values $z_1$, \dots, $z_n$, in that order, with $z_1$ the deepest element and $z_n$ the top of the stack, the contents of the stack are often represented by a list $z_1$ $z_2$ \dots $z_n$, 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 {\em stack notation}. For example, the action of the division primitive \texttt{DIV} can be described by $S$ $x$ $y$ -- $S$ $\lfloor x/y\rfloor$, where $S$ is any list of values. This is usually abbreviated as $x$ $y$ -- $\lfloor x/y\rfloor$, tacitly assuming that all other values deeper in the stack remain intact.
Alternatively, one can describe \texttt{DIV} as a primitive that runs on a stack $S'$ of depth $n\geq2$, divides \texttt{s1} by \texttt{s0}, and returns the floor-rounded quotient as \texttt{s0} of the new stack $S''$ of depth $n-1$. The new value of $\texttt{s}(i)$ equals the old value of $\texttt{s}(i+1)$ for $1\leq i<n-1$. These descriptions are equivalent, but saying that \texttt{DIV} transforms $x$ $y$ into $\lfloor x/y\rfloor$, or \dots $x$ $y$ into \dots $\lfloor x/y\rfloor$, is more concise.
The stack notation is extensively used throughout Appendix~\ptref{app:opcodes}, where all currently defined TVM primitives are listed.
\nxsubpoint\emb{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.~\ptref{sp:callx.num.args}). 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.
\mysubsection{Stack manipulation primitives}\label{p:stack.manip}
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~\ptref{app:code.density}.
\nxsubpoint\label{sp:stack.basic}
\emb{Basic stack manipulation primitives}
The most important stack manipulation primitives used by TVM are the following:
\begin{itemize}
\item {\em Top-of-stack exchange operation\/}: \texttt{XCHG s0,s$(i)$} or \texttt{XCHG s$(i)$} --- Exchanges values of \texttt{s0} and $\texttt{s}(i)$. When $i=1$, operation \texttt{XCHG s1} is traditionally denoted by \texttt{SWAP}. When $i=0$, this is a \texttt{NOP} (an operation that does nothing, at least if the stack is non-empty).
\item {\em Arbitrary exchange operation\/}: \texttt{XCHG s$(i)$,s$(j)$} --- Exchanges values of $\texttt{s}(i)$ and $\texttt{s}(j)$. Notice that this operation is not strictly necessary, because it can be simulated by three top-of-stack exchanges: \texttt{XCHG s$(i)$}; \texttt{XCHG s$(j)$}; \texttt{XCHG s$(i)$}. However, it is useful to have arbitrary exchanges as primitives, because they are required quite often.
\item {\em Push operation\/}: \texttt{PUSH s$(i)$} --- Pushes a copy of the (old) value of \texttt{s}$(i)$ into the stack. Traditionally, \texttt{PUSH s0} is also denoted by \texttt{DUP} (it duplicates the value at the top of the stack), and \texttt{PUSH s1} by \texttt{OVER}.
\item {\em Pop operation\/}: \texttt{POP $s(i)$} --- Removes the top-of-stack value and puts it into the (new) \texttt{s}$(i-1)$, or the old $\texttt{s}(i)$. Traditionally, \texttt{POP s0} is also denoted by \texttt{DROP} (it simply drops the top-of-stack value), and \texttt{POP s1} by \texttt{NIP}.
\end{itemize}
Some other ``unsystematic'' stack manipulation operations might be also defined (e.g., \texttt{ROT}, with stack notation $a$ $b$ $c$ -- $b$ $c$ $a$). While such operations are defined in stack languages like Forth (where \texttt{DUP}, \texttt{DROP}, \texttt{OVER}, \texttt{NIP} and \texttt{SWAP} are also present), they are not strictly necessary because the {\em basic stack manipulation primitives\/} listed above suffice to rearrange stack registers to allow any arithmetic primitives and user-defined functions to be invoked correctly.
\nxsubpoint\label{sp:basic.stack.suff}\emb{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 $\texttt{s}(i)$, $\texttt{s}(j)$, and $\texttt{s}(k)$. In this circumstance, the compiler (or programmer) might issue operation \texttt{PUSH s$(i)$} (if a copy of $x$ is needed after the call to this primitive) or \texttt{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 \texttt{PUSH s$(j')$} or \texttt{XCHG s$(j')$}, where $j'=j$ or $j+1$, to put $y$ into the new top of the stack.\footnote{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 \texttt{SWAP} before \texttt{XCHG s$(j')$}, or replace the previous operation \texttt{XCHG s$(i)$} with \texttt{XCHG s1, s$(i)$}, so that $x$ is exchanged with $\texttt{s1}$ from the beginning.}
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 $\texttt{s2}$, $\texttt{s1}$, and $\texttt{s0}$, using a sequence of push and exchange operations (cf.~\ptref{sp:mnem.comp.stk} and~\ptref{sp:sem.comp.stk} 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 $\texttt{s0}$, this is achieved either by an \texttt{XCHG s$(i)$} or a \texttt{POP s$(i)$} (in most cases, a \texttt{DROP}) operation.\footnote{Notice that the most common \texttt{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.}
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.
\nxsubpoint\label{sp:stack.comp}\emb{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:
\begin{itemize}
\item \texttt{XCHG2 s$(i)$,s$(j)$} --- Equivalent to \texttt{XCHG s1,s$(i)$}; \texttt{XCHG s$(j)$}.
\item \texttt{PUSH2 s$(i)$,s$(j)$} --- Equivalent to \texttt{PUSH s$(i)$}; \texttt{PUSH s$(j+1)$}.
\item \texttt{XCPU s$(i)$,s$(j)$} --- Equivalent to \texttt{XCHG s$(i)$}; \texttt{PUSH s$(j)$}.
\item \texttt{PUXC s$(i)$,s$(j)$} --- Equivalent to \texttt{PUSH s$(i)$}; \texttt{SWAP}; \texttt{XCHG s$(j+1)$}. When $j\neq i$ and $j\neq0$, it is also equivalent to \texttt{XCHG s$(j)$}; \texttt{PUSH s$(i)$}; \texttt{SWAP}.
\item \texttt{XCHG3 s$(i)$,s$(j)$,s$(k)$} --- Equivalent to \texttt{XCHG s2,s$(i)$}; \texttt{XCHG s1,s$(j)$}; \texttt{XCHG s$(k)$}.
\item \texttt{PUSH3 s$(i)$,s$(j)$,s$(k)$} --- Equivalent to \texttt{PUSH s$(i)$}; \texttt{PUSH s$(j+1)$}; \texttt{PUSH s$(k+2)$}.
\end{itemize}
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, \texttt{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 \texttt{PUXC}, \texttt{XCHG3}, and \texttt{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~\ptref{sp:reg.op.arg}, 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.~\ptref{sect:sample.nonleaf} for a more detailed discussion with examples).
\nxsubpoint\label{sp:mnem.comp.stk}\emb{Mnemonics of compound stack operations}
The mnemonics of compound stack operations, some examples of which have been provided in~\ptref{sp:stack.comp}, are created as follows.
The $\gamma\geq2$ formal arguments \texttt{s$(i_1)$}, \dots, \texttt{s$(i_\gamma)$} to such an operation $O$ represent the values in the original stack that will end up in \texttt{s$(\gamma-1)$}, \dots, \texttt{s0} after the execution of this compound operation, at least if all $i_\nu$, $1\leq\nu\leq\gamma$, are distinct and at least $\gamma$. The mnemonic itself of the operation $O$ is a sequence of $\gamma$ two-letter strings \texttt{PU} and \texttt{XC}, with \texttt{PU} meaning that the corresponding argument is to be PUshed (i.e., a copy is to be created), and \texttt{XC} meaning that the value is to be eXChanged (i.e., no other copy of the original value is created). Sequences of several \texttt{PU} or \texttt{XC} strings may be abbreviated to one \texttt{PU} or \texttt{XC} followed by the number of copies. (For instance, we write \texttt{PUXC2PU} instead of \texttt{PUXCXCPU}.)
As an exception, if a mnemonic would consist of only \texttt{PU} or only \texttt{XC} strings, so that the compound operation is equivalent to a sequence of $m$ PUSHes or eXCHanGes, the notation \texttt{PUSH}$m$ or \texttt{XCHG}$m$ is used instead of \texttt{PU$m$} or \texttt{XC$m$}.
\nxsubpoint\label{sp:sem.comp.stk}\emb{Semantics of compound stack operations}
Each compound $\gamma$-ary operation $O$ \texttt{s$(i_1)$},\dots,\texttt{s$(i_\gamma)$} is translated into an equivalent sequence of basic stack operations by induction in $\gamma$ as follows:
\begin{itemize}
\item As a base of induction, if $\gamma=0$, the only nullary compound stack operation corresponds to an empty sequence of basic stack operations.
\item Equivalently, we might begin the induction from $\gamma=1$. Then \texttt{PU s$(i)$} corresponds to the sequence consisting of one basic operation \texttt{PUSH s$(i)$}, and \texttt{XC s$(i)$} corresponds to the one-element sequence consisting of \texttt{XCHG s$(i)$}.
\item For $\gamma\geq1$ (or for $\gamma\geq2$, if we use $\gamma=1$ as induction base), there are two subcases:
\begin{enumerate}
\item $O \texttt{s}(i_1),\ldots,\texttt{s}(i_\gamma)$, with $O=\texttt{XC}O'$, where $O'$ is a compound operation of arity $\gamma-1$ (i.e., the mnemonic of $O'$ consists of $\gamma-1$ strings \texttt{XC} and \texttt{PU}). Let $\alpha$ be the total quantity of \texttt{PU}shes in $O$, and $\beta$ be that of e\texttt{XC}hanges, so that $\alpha+\beta=\gamma$. Then the original operation is translated into \texttt{XCHG s$(\beta-1)$,s$(i_1)$}, followed by the translation of $O' \texttt{s}(i_2),\ldots,\texttt{s}(i_\gamma)$, defined by the induction hypothesis.
\item $O \texttt{s}(i_1),\ldots,\texttt{s}(i_\gamma)$, with $O=\texttt{PU}O'$, where $O'$ is a compound operation of arity $\gamma-1$. Then the original operation is translated into \texttt{PUSH s$(i_1)$}; \texttt{XCHG s$(\beta)$}, followed by the translation of $O' \texttt{s}(i_2+1),\ldots,\texttt{s}(i_\gamma+1)$, defined by the induction hypothesis.\footnote{An alternative, arguably better, translation of $\texttt{PU}O' \texttt{s}(i_1),\ldots,\texttt{s}(i_\gamma)$ consists of the translation of $O' \texttt{s}(i_2),\ldots,\texttt{s}(i_\gamma)$, followed by \texttt{PUSH s$(i_1+\alpha-1)$}; \texttt{XCHG s$(\gamma-1)$}.}
\end{enumerate}
\end{itemize}
\nxsubpoint\label{sp:stack.prim.poly}
\emb{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, \texttt{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).
\mysubsection{Efficiency of stack manipulation primitives}\label{p:eff.stack.manip}
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).
\nxsubpoint\emb{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 \texttt{SWAP} instruction only needs to interchange the references at \texttt{s0} and \texttt{s1}, not the actual objects they refer to.
\nxsubpoint\label{sp:cow}\emb{Efficient implementation of \texttt{DUP} and \texttt{PUSH} instructions using copy-on-write}
Furthermore, a \texttt{DUP} (or, more generally, \texttt{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).
\nxsubpoint\emb{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 \texttt{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.
\nxsubpoint\label{sp:no.refs}\emb{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.
\nxsubpoint\label{sp:no.cyclic}\emb{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 $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. 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.
\clearpage
\mysection{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.
\mysubsection{Generalities on cells}
This section presents a classification and general descriptions of cell types.
\nxsubpoint\emb{TVM memory and persistent storage consist of cells}
Recall that the TVM memory and persistent storage consist of {\em (TVM) cells}. Each cell contains up to 1023 bits of data and up to four references to other cells.\footnote{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.} Circular references are forbidden and cannot be created by means of TVM (cf.~\ptref{sp:no.cyclic}). In this way, all cells kept in TVM memory and persistent storage constitute a directed acyclic graph (DAG).
\nxsubpoint\label{sp:exotic.cells}\emb{Ordinary and exotic cells}
Apart from the data and references, a cell has a {\em cell type}, encoded by an integer $-1$\dots$255$. A cell of type $-1$ is called {\em ordinary}; such cells do not require any special processing. Cells of other types are called {\em exotic}, and may be {\em loaded}---automatically replaced by other cells when an attempt to deserialize them (i.e., to convert them into a {\em Slice\/} by a {\tt 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.
\nxsubpoint\label{sp:cell.level}\emb{The level of a cell}
Every cell $c$ has another attribute $\Lvl(c)$ called its {\em (de Brujn) level}, which currently takes integer values in the range 0\dots3. The level of an ordinary cell is always equal to the maximum of the levels of all its children $c_i$:
\begin{equation}
\Lvl(c)=\max_{1\leq i\leq r}\Lvl(c_i)\quad,
\end{equation}
for an ordinary cell $c$ containing $r$ references to cells $c_1$, \dots, $c_r$. If $r=0$, $\Lvl(c)=0$. Exotic cells may have different rules for setting their level.
A cell's level affects the number of {\em higher hashes\/} it has. More precisely, a level $l$ cell has $l$ higher hashes $\Hash_1(c)$, \dots, $\Hash_l(c)$ in addition to its representation hash $\Hash(c)=\Hash_\infty(c)$. Cells of non-zero level appear inside {\em Merkle proofs\/} and {\em Merkle updates}, after some branches of the tree of cells representing a value of an abstract data type are pruned.
\nxsubpoint\label{sp:std.cell.repr}\emb{Standard cell representation}
When a cell needs to be transferred by a network protocol or stored in a disk file, it must be {\em serialized}. The standard representation $\CellRepr(c)=\CellRepr_\infty(c)$ of a cell $c$ as an octet (byte) sequence is constructed as follows:
\begin{enumerate}
\item Two descriptor bytes $d_1$ and $d_2$ are serialized first. Byte $d_1$ equals $r+8s+32l$, where $0\leq r\leq 4$ is the quantity of cell references contained in the cell, $0\leq l\leq 3$ is the level of the cell, and $0\leq s\leq 1$ is $1$ for exotic cells and $0$ for ordinary cells. Byte $d_2$ equals $\lfloor b/8\rfloor+\lceil b/8\rceil$, where $0\leq b\leq 1023$ is the quantity of data bits in~$c$.
\item Then the data bits are serialized as $\lceil b/8\rceil$ 8-bit octets (bytes). If $b$ is not a multiple of eight, a binary \texttt{1} and up to six binary \texttt{0}s are appended to the data bits. After that, the data is split into $\lceil b/8\rceil$ eight-bit groups, and each group is interpreted as an unsigned big-endian integer $0\dots 255$ and stored into an octet.
\item Finally, each of the $r$ cell references is represented by 32 bytes containing the 256-bit {\em representation hash\/} $\Hash(c_i)$, explained below in~\ptref{sp:repr.hash}, of the cell $c_i$ referred to.
\end{enumerate}
In this way, $2+\lceil b/8\rceil+32r$ bytes of $\CellRepr(c)$ are obtained.
\nxsubpoint\label{sp:repr.hash}\emb{The representation hash of a cell}
The 256-bit {\em representation hash\/} or simply {\em hash\/} $\Hash(c)$ of a cell~$c$ is recursively defined as the $\Sha$ of the standard representation of the cell~$c$:
\begin{equation}
\Hash(c):=\Sha\bigl(\CellRepr(c)\bigr)
\end{equation}
Notice that cyclic cell references are not allowed and cannot be created by means of the TVM (cf.~\ptref{sp:no.cyclic}), so this recursion always ends, and the representation hash of any cell is well-defined.
\nxsubpoint\emb{The higher hashes of a cell}
Recall that a cell $c$ of level $l$ has $l$ higher hashes $\Hash_i(c)$, $1\leq i\leq l$, as well. Exotic cells have their own rules for computing their higher hashes. Higher hashes $\Hash_i(c)$ of an ordinary cell~$c$ are computed similarly to its representation hash, but using the higher hashes $\Hash_i(c_j)$ of its children $c_j$ instead of their representation hashes $\Hash(c_j)$. By convention, we set $\Hash_\infty(c):=\Hash(c)$, and $\Hash_i(c):=\Hash_\infty(c)=\Hash(c)$ for all $i>l$.\footnote{From a theoretical perspective, we might say that a cell $c$ has an infinite sequence of hashes $\bigl(\Hash_i(c)\bigr)_{i\geq1}$, which eventually stabilizes: $\Hash_i(c)\to\Hash_\infty(c)$. Then the level $l$ is simply the largest index~$i$, such that $\Hash_i(c)\neq\Hash_\infty(c)$.}
\nxsubpoint\label{sp:exotic.cell.types}\emb{Types of exotic cells}
TVM currently supports the following cell types:
\begin{itemize}
\item Type $-1$: {\em Ordinary cell} --- Contains up to 1023 bits of data and up to four cell references.
\item Type 1: {\em Pruned branch cell~$c$} --- May have any level $1\leq l\leq 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 $\Hash_1(c)$, \dots, $\Hash_l(c)$. The level $l$ of a pruned branch cell may be called its {\em 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.
\item Type 2: {\em 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 {\em library context}.
\item Type 3: {\em Merkle proof cell $c$} --- Has exactly one reference $c_1$ and level $0\leq l\leq 3$, which must be one less than the level of its only child $c_1$:
\begin{equation}
\Lvl(c)=\max(\Lvl(c_1)-1,0)
\end{equation}
The $8+256$ data bits of a Merkle proof cell contain its 8-bit type integer 3, followed by $\Hash_1(c_1)$ (assumed to be equal to $\Hash(c_1)$ if $\Lvl(c_1)=0$). The higher hashes $\Hash_i(c)$ of $c$ are computed similarly to the higher hashes of an ordinary cell, but with $\Hash_{i+1}(c_1)$ used instead of $\Hash_i(c_1)$. When loaded, a Merkle proof cell is replaced by $c_1$.
\item Type 4: {\em Merkle update cell $c$} --- Has two children $c_1$ and $c_2$. Its level $0\leq l\leq 3$ is given by
\begin{equation}
\Lvl(c)=\max(\Lvl(c_1)-1,\Lvl(c_2)-1,0)
\end{equation}
A Merkle update behaves like a Merkle proof for both $c_1$ and $c_2$, and contains $8+256+256$ data bits with $\Hash_1(c_1)$ and $\Hash_1(c_2)$. However, an extra requirement is that {\em all pruned branch cells $c'$ that are descendants of $c_2$ and are bound by $c$ must also be descendants of $c_1$.}\footnote{A pruned branch cell $c'$ of level $l$ is {\em 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$.} When a Merkle update cell is loaded, it is replaced by $c_2$.
\end{itemize}
\nxsubpoint\label{sp:data.boc}\emb{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.~\ptref{sp:cow}) 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.
\nxsubpoint\label{sp:code.boc}\emb{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.~\ptref{sp:ord.cont.exec} and~\ptref{p:instr.encode}), in sections discussing control flow instructions, continuations, and TVM instruction encoding.
\nxsubpoint\emb{``Everything is a bag of cells'' paradigm}
As described in \cite[2.5.14]{TON}, 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.~\ptref{sp:data.boc}) and code (cf.~\ptref{sp:code.boc}) 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.)
\mysubsection{Data manipulation instructions and cells}\label{p:cell.manip}
The next large group of TVM instructions consists of {\em data manipulation instructions}, also known as {\em cell manipulation instructions\/} or simply {\em cell instructions}. They correspond to memory access instructions of other architectures.
\nxsubpoint\emb{Classes of cell manipulation instructions}
The TVM cell instructions are naturally subdivided into two principal classes:
\begin{itemize}
\item {\em Cell creation instructions\/} or {\em serialization instructions}, used to construct new cells from values previously kept in the stack and previously constructed cells.
\item {\em Cell parsing instructions\/} or {\em deserialization instructions}, used to extract data previously stored into cells by cell creation instructions.
\end{itemize}
Additionally, there are {\em exotic cell instructions\/} used to create and inspect exotic cells (cf.~\ptref{sp:exotic.cells}), which in particular are used to represent pruned branches of Merkle proofs and Merkle proofs themselves.
\nxsubpoint\label{sp:builder.slice.val}\emb{{\em Builder\/} and {\em Slice\/} values}
Cell creation instructions usually work with {\em Builder\/} values, which can be kept only in the stack (cf.~\ptref{sp:val.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 {\em 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.
\nxsubpoint\emb{{\em Builder\/} and {\em Slice\/} values exist only as stack values}
Notice that {\em Builder\/} and {\em 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 {\em Cell\/} objects than {\em Builder\/} or {\em Slice\/} objects in a TVM environment, but, somewhat paradoxically, a TVM program sees {\em Builder\/} and {\em Slice\/} objects in its stack more often than {\em Cell\/}s. In fact, a TVM program does not have much use for {\em Cell\/} values, because they are immutable and opaque; all cell manipulation primitives require that a {\em Cell\/} value be transformed into either a {\em Builder\/} or a {\em Slice\/} first, before it can be modified or inspected.
\nxsubpoint\emb{TVM has no separate {\em Bitstring\/} value type}
Notice that TVM offers no separate bitstring value type. Instead, bitstrings are represented by {\em Slice\/}s that happen to have no references at all, but can still contain up to 1023 data bits.
\nxsubpoint\label{sp:cells.of.bits}
\emb{Cells and cell primitives are bit-oriented, not byte-oriented}
An important point is that {\em TVM regards data kept in cells as sequences (strings, streams) of (up to 1023) bits, not of bytes}. In other words, TVM is a {\em 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.
\nxsubpoint\label{sp:cc.taxonomy}
\emb{Taxonomy of cell creation (serialization) primitives}
Cell creation primitives usually accept a {\em 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 {\em 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:
\begin{itemize}
\item Which is the type of values being serialized?
\item How many bits are used for serialization? If this is a variable number, does it come from the stack, or from the instruction itself?
\item 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?
\item What happens if there is insufficient space left in the {\em Builder}? Is an exception generated, or is a zero success flag returned along with the unmodified original {\em Builder}?
\end{itemize}
The mnemonics of cell serialization primitives usually begin with \texttt{ST}. Subsequent letters describe the following attributes:
\begin{itemize}
\item The type of values being serialized and the serialization format (e.g., \texttt{I} for signed integers, \texttt{U} for unsigned integers).
\item The source of the field width in bits to be used (e.g., \texttt{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).
\item 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 \texttt{Q} letter in their mnemonics).
\end{itemize}
This classification scheme is used to create a more complete taxonomy of cell serialization primitives, which can be found in~\ptref{sp:prim.ser}.
\nxsubpoint\emb{Integer serialization primitives}
Integer serialization primitives can be classified according to the above taxonomy as well. For example:
\begin{itemize}
\item There are signed and unsigned (big-endian) integer serialization primitives.
\item The size $n$ of the bit field to be used ($1\leq n\leq 257$ for signed integers, $0\leq n\leq 256$ for unsigned integers) can either come from the top of stack or be embedded into the instruction itself.
\item If the integer $x$ to be serialized is not in the range $-2^{n-1}\leq x<2^{n-1}$ (for signed integer serialization) or $0\leq x<2^n$ (for unsigned integer serialization), a range check exception is usually generated, and if $n$ bits cannot be stored into the provided {\em Builder}, a cell overflow exception is generated.
\item Quiet versions of serialization instructions do not throw exceptions; instead, they push \texttt{-1} on top of the resulting {\em Builder} upon success, or return the original {\em Builder} with \texttt{0} on top of it to indicate failure.
\end{itemize}
Integer serialization instructions have mnemonics like \texttt{STU 20} (``store an unsigned 20-bit integer value'') or \texttt{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~\ptref{sp:prim.ser}.
\nxsubpoint\emb{Integers in cells are big-endian by default}
Notice that the default order of bits in {\em Integer\/}s serialized into {\em Cell\/}s is {\em big-endian}, not little-endian.\footnote{Negative numbers are represented using two's complement. For instance, integer $-17$ is serialized by instruction {\tt STI 8} into bitstring {\tt xEF}.} In this respect {\em TVM is a big-endian machine}. However, this affects only the serialization of integers inside cells. The internal representation of the {\em Integer\/} value type is implementation-dependent and irrelevant for the operation of TVM. Besides, there are some special primitives such as {\tt 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.
\nxsubpoint\emb{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 {\em Builder\/}s (which are also concatenated); and cell references (\texttt{STREF}).
\nxsubpoint\emb{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 {\em Builder\/} and push it into the stack (\texttt{NEWC}), or transform a {\em Builder} into a {\em Cell} (\texttt{ENDC}), thus finishing the cell creation process. An \texttt{ENDC} can be combined with a \texttt{STREF} into a single instruction \texttt{ENDCST}, which finishes the creation of a cell and immediately stores a reference to it in an ``outer'' {\em Builder}. There are also primitives that obtain the quantity of data bits or references already stored in a {\em Builder}, and check how many data bits or references can be stored.
\nxsubpoint\label{sp:cd.taxonomy}\emb{Taxonomy of cell deserialisation primitives}
Cell parsing, or deserialization, primitives can be classified as described in~\ptref{sp:cc.taxonomy}, with the following modifications:
\begin{itemize}
\item They work with {\em Slice\/}s (representing the remainder of the cell being parsed) instead of {\em Builder\/}s.
\item They return deserialized values instead of accepting them as arguments.
\item They may come in two flavors, depending on whether they remove the deserialized portion from the {\em Slice\/} supplied (``fetch operations'') or leave it unmodified (``prefetch operations'').
\item Their mnemonics usually begin with \texttt{LD} (or \texttt{PLD} for prefetch operations) instead of \texttt{ST}.
\end{itemize}
For example, an unsigned big-endian 20-bit integer previously serialized into a cell by a \texttt{STU 20} instruction is likely to be deserialized later by a matching \texttt{LDU 20} instruction.
Again, more detailed information about these instructions is provided in~\ptref{sp:prim.deser}.
\nxsubpoint\emb{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 {\em Cell\/} into a {\em Slice\/} (\texttt{CTOS}), so that its deserialisation might begin; or check whether a {\em Slice\/} is empty, and generate an exception if it is not (\texttt{ENDS}); or deserialize a cell reference and immediately convert it into a {\em Slice\/} (\texttt{LDREFTOS}, equivalent to two instructions \texttt{LDREF} and \texttt{CTOS}).
\nxsubpoint\label{sp:mod.val.cell}\emb{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.~\ptref{sp:no.refs} and \ptref{sp:no.cyclic}), so our example can only be accomplished with a series of operations as follows:
\begin{enumerate}
\item Deserialize the original cell into three {\em Integer\/}s $x$, $y$, $z$ in the stack (e.g., by \texttt{CTOS; LDI 29; LDI 29; LDI 29; ENDS}).
\item Increase $y$ by one (e.g., by \texttt{SWAP; INC; SWAP}).
\item Finally, serialize the resulting {\em Integer\/}s into a new cell (e.g., by \texttt{XCHG s2; NEWC; STI 29; STI 29; STI 29; ENDC}).
\end{enumerate}
\nxsubpoint\emb{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 {\tt c4}, it simply needs to rewrite control register {\tt 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.~\ptref{sp:mod.val.cell}.)
\mysubsection{Hashmaps, or dictionaries}\label{p:hashmaps}
{\em Hashmaps\/}, or {\em dictionaries}, are a specific data structure represented by a tree of cells. Essentially, a hashmap represents a map from {\em keys}, which are bitstrings of either fixed or variable length, into {\em 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.
\nxsubpoint\emb{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 {\em keys}) for some fixed $0\leq n\leq 1023$ into {\em 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).
\nxsubpoint\label{sp:hm.patricia}\emb{Hashmaps as Patricia trees}
The abstract representation of a hashmap in TVM is a {\em Patricia tree}, or a {\em 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.
\nxsubpoint\label{sp:hm.tlb}\emb{Serialization of hashmaps}
The serialization of a hashmap into a tree of cells (or, more generally, into a {\em Slice\/}) is defined by the following TL-B scheme:\footnote{A description of an older version of TL may be found at~\url{https://core.telegram.org/mtproto/TL}.}
\begin{verbatim}
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;
\end{verbatim}
\nxsubpoint\label{sp:tlb.brief}\emb{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 {\em type}, either simple (such as {\tt Bit} or {\tt True}) or parametrized (such as {\tt 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 {\tt Hashmap $n$ $X$}, or other types, such as $X$ in {\tt 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 {\em constructor}, such as {\tt hm\_edge} or {\tt hml\_long}, immediately followed by an optional {\em constructor tag}, such as {\tt \#\_} or {\tt \$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 \ptref{p:bitstring.hex}. 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 {\tt \#\_} or {\tt \$\_}. 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 {\em field definitions}. Each field definition is of the form ${\textit{ident}}:{\textit{type-expr}}$, where ${\textit{ident}}\/$ is an identifier with the name of the field\footnote{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.} (replaced by an underscore for anonymous fields), and {\textit{type-expr}} is the field's type. The type provided here is a {\em type expression}, which may include simple types or parametrized types with suitable parameters. {\em 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 {\em 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.\footnote{This is the ``linear negation'' operation $(-)^\perp$ of linear logic, hence our notation \texttt{\~}.}
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 (\texttt{\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 \texttt{\caret$X$} means ``the type of references to cells containing values of type $X$''.
Parametrized type \texttt{\#<= $p$} with $p:\texttt{\#}$ (this notation means ``$p$ of type \texttt{\#}'', i.e., a natural number) denotes the subtype of the natural numbers type $\#$, consisting of integers $0\ldots p$; it is serialized into $\lceil\log_2(p+1)\rceil$ bits as an unsigned big-endian integer. Type \texttt{\#} by itself is serialized as an unsigned 32-bit integer. Parametrized type \texttt{\#\# $b$} with $b:\texttt{\#<=}31$ is equivalent to \texttt{\#<= $2^b-1$} (i.e., it is an unsigned $b$-bit integer).
\nxsubpoint\emb{Application to the serialization of hashmaps} Let us explain the net result of applying the general rules described in \ptref{sp:tlb.brief} to the TL-B scheme presented in \ptref{sp:hm.tlb}.
Suppose we wish to serialize a value of type $\HashmapE$ $n$ $X$ for some integer $0\leq n\leq 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.~\ptref{sp:hm.patricia})).
First of all, if our dictionary is empty, it is serialized into a single binary {\tt 0}, which is the tag of nullary constructor {\tt hme\_empty}. Otherwise, its serialization consists of a binary {\tt 1} (the tag of {\tt 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 {\tt hm\_edge} constructor, which instructs us to serialize first the label {\tt 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 {\tt HmLabel $l^\perp$ $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\leq l\leq n$, becomes known from the serialization of the label. (This special serialization method is described separately in~\ptref{sp:hm.label.ser}.)
The label must be followed by the serialization of a {\tt node} of type {\em Hashmap\-Node $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 {\tt HashmapNode $0$ $X$} is given by the {\tt 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 {\tt value} of type $X$ and is serialized accordingly.
On the other hand, if $m>0$, a value of type {\tt HashmapNode $m$ $X$} corresponds to a fork (i.e., an intermediate node) in the Patricia tree, and is given by the {\tt hmn\_fork} constructor. Its serialization consists of {\tt left} and {\tt right}, two references to cells containing values of type {\tt 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 {\tt 0} or a binary {\tt 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 {\tt Hashmap $m-1$ $X$}.
\nxsubpoint\label{sp:hm.label.ser}\emb{Serialization of labels}
There are several ways to serialize a label of length at most $n$, if its exact length is $l\leq 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 {\tt hml\_short}, {\tt hml\_long}, and {\tt hml\_same} of type {\tt HmLabel $l^\perp$ $n$}:
\begin{itemize}
\item {\tt hml\_short} --- Describes a way to serialize ``short'' labels, of small length $l\leq n$. Such a serialization consists of a binary {\tt 0} (the constructor tag of {\tt hml\_short}), followed by $l$ binary {\tt 1}s and one binary {\tt 0} (the unary representation of the length $l$), followed by $l$ bits comprising the label itself.
\item {\tt hml\_long} --- Describes a way to serialize ``long'' labels, of arbitrary length $l\leq n$. Such a serialization consists of a binary {\tt 10} (the constructor tag of {\tt hml\_long}), followed by the big-endian binary representation of the length $0\leq l\leq n$ in $\lceil\log_2(n+1)\rceil$ bits, followed by $l$ bits comprising the label itself.
\item {\tt hml\_same} --- Describes a way to serialize ``long'' labels, consisting of $l$ repetitions of the same bit $v$. Such a serialization consists of {\tt 11} (the constructor tag of {\tt hml\_same}), followed by the bit $v$, followed by the length $l$ stored in $\lceil\log_2(n+1)\rceil$ bits as before.
\end{itemize}
Each label can always be serialized in at least two different fashions, using {\tt hml\_short} or {\tt 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).
\nxsubpoint\emb{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:
\begin{verbatim}
0000000000001101 => 0000000010101001
0000000000010001 => 0000000100100001
0000000011101111 => 1101111100100001
\end{verbatim}
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^8$. 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 {\tt HashmapE 16 (\#\# 16)} may be written in human-readable form as:
\begin{verbatim}
(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)))))
\end{verbatim}
The serialization of this data structure into a tree of cells consists of six cells with the following binary data contained in them:
\begin{verbatim}
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
\end{verbatim}
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~\ptref{p:bitstring.hex}, using indentation to reflect the tree-of-cells structure:
\begin{verbatim}
C_
C8
62_
A68054C_
A08090C_
BEFDF21
\end{verbatim}
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.
\nxsubpoint\emb{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$:
\begin{itemize}
\item The simplest case is when $X=\texttt{\caret} 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.
\item Another simple case is when the serialization of any value of type $X$ always consists of $0\leq b\leq 1023$ data bits and $0\leq r\leq 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$.)
\item A more sophisticated case can be described by four integers $1\leq b_0,b_1\leq 1023$, $0\leq r_0,r_1\leq 4$, with $b_i$ and $r_i$ used when the first bit of the serialization equals~$i$. When $b_0=b_1$ and $r_0=r_1$, this case reduces to the previous one.
\item Finally, the most general description of the serialization of a type~$X$ is given by a {\em splitting function\/} ${\textit split}_X$ for~$X$, which accepts one {\em Slice\/} parameter $s$, and returns two {\em 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.
\end{itemize}
\nxsubpoint\emb{A simplifying assumption on the serialization of~$X$}
One may notice that values of type $X$ always occupy the remaining part of an {\tt hm\_edge}/{\tt 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 {\tt hm\_edge}/{\tt hme\_leaf} cell after deserializing its {\tt 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.
\nxsubpoint\label{sp:dict.ops}\emb{Basic dictionary operations}
Let us present a classification of basic operations with dictionaries (i.e., values $D$ of type $\HashmapE$ $n$ $X$):
\begin{itemize}
\item $\textsc{Get}(D,k)$ --- Given $D:\HashmapE(n,X)$ and a key $k:n\cdot{\tt bit}$, returns the corresponding value $D[k]:X^?$ kept in~$D$.
\item $\textsc{Set}(D,k,x)$ --- Given $D:\HashmapE(n,X)$, a key $k:n\cdot{\tt bit}$, and a value $x:X$, sets $D'[k]$ to $x$ in a copy $D'$ of~$D$, and returns the resulting dictionary $D'$ (cf.~\ptref{sp:no.refs}).
\item $\textsc{Add}(D,k,x)$ --- Similar to {\sc Set}, but adds the key-value pair $(k,x)$ to $D$ only if key $k$ is absent in~$D$.
\item $\textsc{Replace}(D,k,x)$ --- Similar to {\sc Set}, but changes $D'[k]$ to $x$ only if key $k$ is already present in~$D$.
\item {\sc GetSet}, {\sc GetAdd}, {\sc GetReplace} --- Similar to \textsc{Set}, \textsc{Add}, and \textsc{Replace}, respectively, but returns the old value of $D[k]$ as well.
\item $\textsc{Delete}(D,k)$ --- Deletes key $k$ from dictionary $D$, and returns the resulting dictionary~$D'$.
\item $\textsc{GetMin}(D)$, $\textsc{GetMax}(D)$ --- Gets the minimal or maximal key~$k$ from dictionary~$D$, along with the associated value $x:X$.
\item $\textsc{RemoveMin}(D)$, $\textsc{RemoveMax}(D)$ --- Similar to \textsc{GetMin} and \textsc{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.
\item $\textsc{GetNext}(D,k)$ --- Computes the minimal key $k'>k$ (or $k'\geq k$ in a variant) and returns it along with the corresponding value $x':X$. May be used to iterate over all elements of~$D$.
\item $\textsc{GetPrev}(D,k)$ --- Computes the maximal key $k'<k$ (or $k'\leq k$ in a variant) and returns it along with the corresponding value $x':X$.
\item $\textsc{Empty}(n)$ --- Creates an empty dictionary $D:\HashmapE(n,X)$.
\item $\textsc{IsEmpty}(D)$ --- Checks whether a dictionary is empty.
\item $\textsc{Create}(n,\{(k_i,x_i)\})$ --- Given $n$, creates a dictionary from a list ${(k_i,x_i)}$ of key-value pairs passed in stack.
\item $\textsc{GetSubdict}(D,l,k_0)$ --- Given $D:\HashmapE(n,X)$ and some $l$-bit string $k_0:l\cdot{\tt bit}$ for $0\leq l\leq n$, returns subdictionary $D'=D/k_0$ of $D$, consisting of keys beginning with~$k_0$. The result $D'$ may be of either type $\HashmapE(n,X)$ or type $\HashmapE(n-l,X)$.
\item $\textsc{ReplaceSubdict}(D,l,k_0,D')$ --- Given $D:\HashmapE(n,X)$, $0\leq l\leq n$, $k_0:l\cdot{\tt bit}$, and $D':\HashmapE(n-l,X)$, replaces with $D'$ the subdictionary $D/k_0$ of $D$ consisting of keys beginning with $k_0$, and returns the resulting dictionary $D'':\HashmapE(n,X)$. Some variants of $\textsc{ReplaceSubdict}$ may also return the old value of the subdictionary $D/k_0$ in question.
\item $\textsc{DeleteSubdict}(D,l,k_0)$ --- Equivalent to $\textsc{ReplaceSubdict}$ with $D'$ being an empty dictionary.
\item $\textsc{Split}(D)$ --- Given $D:\HashmapE(n,X)$, returns $D_0:=D/0$ and $D_1:=D/1:\HashmapE(n-1,X)$, the two subdictionaries of $D$ consisting of all keys beginning with $0$ and $1$, respectively.
\item $\textsc{Merge}(D_0,D_1)$ --- Given $D_0$ and $D_1:\HashmapE(n-1,X)$, computes $D:\HashmapE(n,X)$, such that $D/0=D_0$ and $D/1=D_1$.
\item $\textsc{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.\footnote{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.}
\item $\textsc{ForeachRev}(D,f)$ --- Similar to {\sc Foreach}, but processes all key-value pairs in reverse order.
\item $\textsc{TreeReduce}(D,o,f,g)$ --- Given $D:\HashmapE(n,X)$, a value $o:X$, and two functions $f:X\to Y$ and $g:Y\times Y\to 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.\footnote{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.}
\end{itemize}
\nxsubpoint\label{sp:dict.prim.taxonomy}\emb{Taxonomy of dictionary primitives}
The dictionary primitives, described in detail in~\ptref{p:prim.dict}, can be classified according to the following categories:
\begin{itemize}
\item Which dictionary operation (cf.~\ptref{sp:dict.ops}) do they perform?
\item Are they specialized for the case $X=\texttt{\caret} Y$? If so, do they represent values of type~$Y$ by {\em Cell\/}s or by {\em Slice\/}s? (Generic versions always represent values of type $X$ as {\em Slice\/}s.)
\item Are the dictionaries themselves passed and returned as {\em Cell\/}s or as {\em Slice\/}s? (Most primitives represent dictionaries as {\em Slice\/}s.)
\item Is the key length $n$ fixed inside the primitive, or is it passed in the stack?
\item Are the keys represented by {\em Slice\/}s, or by signed or unsigned {\em Integer\/}s?
\end{itemize}
In addition, TVM includes special serialization/deserialization primitives, such as {\tt STDICT}, {\tt LDDICT}, and {\tt 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.
\mysubsection{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 \ptref{p:hashmaps} above).
\nxsubpoint\emb{Serialization of dictionaries with variable-length keys}
The serialization of a {\em VarHashmap\/} into a tree of cells (or, more generally, into a {\em Slice\/}) is defined by a TL-B scheme, similar to that described in \ptref{sp:hm.tlb}:
\begin{verbatim}
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;
\end{verbatim}
\nxsubpoint\label{sp:pfx.dict.tlb}\emb{Serialization of prefix codes}
One special case of a dictionary with variable-length keys is that of a {\em 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:
\begin{verbatim}
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;
\end{verbatim}
\clearpage
\mysection{Control flow, continuations, and exceptions}
This chapter describes {\em 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).
\mysubsection{Continuations and subroutines}\label{p:cont.subr}
Recall (cf.\ptref{sp:val.types}) that {\em Continuation\/} values represent ``execution tokens'' that can be executed later---for example, by \texttt{EXECUTE}=\texttt{CALLX} (``execute'' or ``call indirect'') or \texttt{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.
\nxsubpoint\label{sp:ord.cont}\emb{Ordinary continuations}
The most common kind of continuations are the {\em ordinary continuations}, containing the following data:
\begin{itemize}
\item A {\em Slice\/} \texttt{code} (cf.~\ptref{sp:val.types} and \ptref{sp:builder.slice.val}), containing (the remainder of) the TVM code to be executed.
\item A (possibly empty) {\em Stack\/} \texttt{stack}, containing the original contents of the stack for the code to be executed.
\item A (possibly empty) list \texttt{save} of pairs $(\texttt{c}(i),v_i)$ (also called ``savelist''), containing the values of control registers to be restored before the execution of the code.
\item A 16-bit integer value \texttt{cp}, selecting the TVM codepage used to interpret the TVM code from \texttt{code}.
\item An optional non-negative integer \texttt{nargs}, indicating the number of arguments expected by the continuation.
\end{itemize}
\nxsubpoint\emb{Simple ordinary continuations}
In most cases, the ordinary continuations are the simplest ones, having empty \texttt{stack} and \texttt{save}. They consist essentially of a reference \texttt{code} to (the remainder of) the code to be executed, and of the codepage \texttt{cp} to be used while decoding the instructions from this code.
\nxsubpoint\emb{Current continuation \texttt{cc}}
The ``current continuation'' \texttt{cc} is an important part of the total state of TVM, representing the code being executed right now (cf.~\ptref{p:tvm.stack}). 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 \texttt{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~\ptref{p:tvm.state}.
\nxsubpoint\label{sp:ord.cont.exec}\emb{Normal work of TVM, or the main loop}
TVM usually performs the following operations:
If the current continuation \texttt{cc} is an ordinary one, it decodes the first instruction from the {\em Slice\/} \texttt{code}, similarly to the way other cells are deserialized by TVM \texttt{LD*} primitives (cf.~\ptref{p:cell.manip} and~\ptref{sp:cd.taxonomy}): 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 {\em Slice} is then put into the \texttt{code} of the new {\tt cc}, and the decoded operation is executed on the current stack. This entire process is repeated until there are no operations left in {\tt cc.code}.
If the {\tt code} is empty (i.e., contains no bits of data and no references), or if a (rarely needed) explicit subroutine return ({\tt RET}) instruction is encountered, the current continuation is discarded, and the ``return continuation'' from control register {\tt c0} is loaded into {\tt cc} instead (this process is discussed in more detail starting in~\ptref{sp:jmp.sw}).\footnote{If there are no bits of data left in {\tt code}, but there is still exactly one reference, an implicit {\tt JMP} to the cell at that reference is performed instead of an implicit {\tt RET}.} Then the execution continues by parsing operations from the new current continuation.
\nxsubpoint\label{sp:extraord.cont}\emb{Extraordinary continuations}
In addition to the ordinary continuations considered so far (cf.~\ptref{sp:ord.cont}), TVM includes some {\em extraordinary continuations}, representing certain less common states. Examples of extraordinary continuations include:
\begin{itemize}
\item The continuation {\tt ec\_quit} with its parameter set to zero, which represents the end of the work of TVM. This continuation is the original value of {\tt c0} when TVM begins executing the code of a smart contract.
\item The continuation {\tt 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.
\end{itemize}
Execution of an extraordinary continuation by TVM depends on its specific class, and differs from the operations for ordinary continuations described in \ptref{sp:ord.cont.exec}.\footnote{Technically, TVM may simply invoke a virtual method \texttt{run()} of the continuation currently in {\tt cc}.}
\nxsubpoint\label{sp:jmp.sw}\emb{Switching to another continuation: {\tt JMP} and {\tt RET}}
The process of switching to another continuation $c$ may be performed by such instructions as \texttt{JMPX} (which takes $c$ from the stack) or \texttt{RET} (which uses {\tt c0} as $c$). This process is slightly more complex than simply setting the value of {\tt 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.)
\nxsubpoint\label{sp:jmp.sw.n}\emb{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 {\tt nargs} (number of arguments to be provided), then $n$ is computed as $n'$, equal to $c.{\tt nargs}$ minus the current depth of $c$'s stack.
Furthermore, there are special forms of \texttt{JMPX} and \texttt{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'\leq 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.
\nxsubpoint\label{sp:jmp.sw.cp}\emb{Restoring control registers from the new continuation $c$}
After the new stack is computed, the values of control registers present in $c.{\tt save}$ are restored accordingly, and the current codepage {\tt cp} is also set to $c.{\tt cp}$. Only then does TVM set \texttt{cc} equal to the new $c$ and begin its execution.\footnote{The already used savelist \texttt{cc.save} of the new {\tt cc} is emptied before the execution starts.}
\nxsubpoint\label{sp:call.sw}\emb{Subroutine calls: \texttt{CALLX} or \texttt{EXECUTE} primitives}
The execution of continuations as subroutines is slightly more complicated than switching to continuations.
Consider the \texttt{CALLX} or \texttt{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 \ptref{sp:jmp.sw} and \ptref{sp:jmp.sw.n} and setting the new control registers and codepage as described in \ptref{sp:jmp.sw.cp}, these primitives perform several additional steps:
\begin{enumerate}
\item After the top $n''$ values are removed from the current stack (cf.~\ptref{sp:jmp.sw.n}), the (usually empty) remainder is not discarded, but instead is stored in the (old) current continuation {\tt cc}.
\item The old value of the special register {\tt c0} is saved into the (previously empty) savelist {\tt cc.save}.
\item The continuation {\tt cc} thus modified is not discarded, but instead is set as the new {\tt c0}, which performs the role of ``next continuation'' or ``return continuation'' for the subroutine being called.
\item After that, the switching to $c$ continues as before. In particular, some control registers are restored from $c.{\tt save}$, potentially overwriting the value of {\tt c0} set in the previous step. (Therefore, a good optimization would be to check that $c0$ is present in $c.{\tt save}$ from the very beginning, and skip the three previous steps as useless in this case.)
\end{enumerate}
In this way, the called subroutine can return control to the caller by switching the current continuation to the return continuation saved in {\tt c0}. Nested subroutine calls work correctly because the previous value of {\tt c0} ends up saved into the new {\tt c0}'s control register savelist {\tt c0.save}, from which it is restored later.
\nxsubpoint\label{sp:callx.num.args}\emb{Determining the number of arguments passed to and/or return values accepted from a subroutine}
Similarly to {\tt JMPX} and {\tt RET}, {\tt 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 {\tt nargs} of the modified {\tt cc} continuation before storing it into the new~{\tt c0}; the new {\tt 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 {\tt CALLX} and {\tt 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.~\cite[5]{TON}).
\nxsubpoint\label{sp:call.cc}
\emb{\texttt{CALLCC}: call with current continuation}
Notice that TVM supports a form of the ``call with current continuation'' primitive. Namely, primitive {\tt CALLCC} is similar to {\tt CALLX} or {\tt JMPX} in that it takes a continuation $c$ from the stack and switches to it; however, {\tt CALLCC} does not discard the previous current continuation $c'$ (as {\tt JMPX} does) and does not write $c'$ to {\tt c0} (as {\tt CALLX} does), but rather pushes $c'$ into the (new) stack as an extra argument to $c$. The primitive {\tt JMPXDATA} does a similar thing, but pushes only the (remainder of the) code of the previous current continuation as a {\em Slice}.
\mysubsection{Control flow primitives: conditional and iterated execution}\label{p:cond.iter.exec}
\nxsubpoint\emb{Conditional execution: \texttt{IF}, \texttt{IFNOT}, \texttt{IFELSE}}
An important modification of {\tt EXECUTE} (or {\tt CALLX}) consists in its conditional forms. For example, \texttt{IF} accepts an integer $x$ and a continuation $c$, and executes $c$ (in the same way as {\tt EXECUTE} would do it) only if $x$ is non-zero; otherwise both values are simply discarded from the stack. Similarly, \texttt{IFNOT} accepts $x$ and $c$, but executes $c$ only if $x=0$. Finally, \texttt{IFELSE} accepts $x$, $c$, and $c'$, removes these values from the stack, and executes $c$ if $x\neq0$ or $c'$ if $x=0$.
\nxsubpoint\emb{Iterated execution and loops}
More sophisticated modifications of {\tt EXECUTE} include:
\begin{itemize}
\item {\tt REPEAT} --- Takes an integer $n$ and a continuation $c$, and executes $c$ $n$ times.\footnote{The implementation of {\tt 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 {\tt REPEAT}, which would be normally stored in {\tt c0} of the new {\tt cc}.)}
\item {\tt 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.
\item {\tt 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.
\end{itemize}
\nxsubpoint\label{sp:lit.cont}\emb{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 {\tt cc.code} into a cell slice, and then push it into the stack not as a {\em Slice\/} (as a {\tt PUSHSLICE} does) but as a simple ordinary {\em Continuation\/} (which has only {\tt code} and {\tt cp}).
The simplest of these primitives is {\tt 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 {\tt PUSHREFCONT}, which removes the first cell reference from the current continuation {\tt cc.code}, converts the cell referred to into a cell slice, and finally converts the cell slice into a simple continuation.
\nxsubpoint\emb{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., {\tt IFCONT} or {\tt UNTILREFCONT}) may be defined in a future revision of TVM, which combine a {\tt PUSHCONT} or {\tt PUSHREFCONT} with another primitive. If one inspects the resulting code, {\tt IFCONT} looks very much like the more customary ``conditional-branch-forward'' instruction.
\mysubsection{Operations with continuations}
\nxsubpoint\emb{Continuations are opaque}
Notice that all continuations are {\em 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.
\nxsubpoint\label{sp:op.cont}\emb{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:
\begin{itemize}
\item Push one or several values into the stack of a continuation $c$ (thus creating a partial application of a function, or a closure).
\item Set the saved value of a control register ${\tt c}(i)$ inside the savelist $c.{\tt save}$ of a continuation~$c$. If there is already a value for the control register in question, this operation silently does nothing.
\end{itemize}
\nxsubpoint\emb{Example: operations with control registers}
TVM has some primitives to set and inspect the values of control registers. The most important of them are {\tt PUSH c$(i)$} (pushes the current value of {\tt c$(i)$} into the stack) and {\tt POP c$(i)$} (sets the value of {\tt 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 {\tt POPSAVE c$(i)$}, which saves the old value of {\tt c$(i)$} (for $i>0$) into the continuation at {\tt c0} as described in~\ptref{sp:op.cont} before setting the new value.
\nxsubpoint\emb{Example: setting the number of arguments to a function in its code}
The primitive {\tt 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 {\tt 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).
\nxsubpoint\emb{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.\texttt{c0}:=c.\texttt{save}(\texttt{c0})$, and the auxiliary exit point given by $c.\texttt{c1}:=c.\texttt{save}(\texttt{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.{\tt c0}$ and $c.{\tt c1}$ defined is a {\em two-exit continuation}, or a {\em boolean circuit}, especially if the choice of the exit point depends on some internally-checked condition.
\nxsubpoint\emb{Composition of continuations}
One can {\em compose\/} two continuations $c$ and $c'$ simply by setting $c.\texttt{c0}$ or $c.\texttt{c1}$ to $c'$. This creates a new continuation denoted by $c\circ_0c'$ or $c\circ_1c'$, 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~\ptref{sp:op.cont}).
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 {\tt c0} or to {\tt c1} depending on some condition), and the one-exit continuations corresponding to the ``action nodes''.
\nxsubpoint\emb{Basic continuation composition primitives}
Two basic primitives for composing continuations are {\tt COMPOS} (also known as {\tt SETCONT c0} and {\tt BOOLAND}) and {\tt COMPOSALT} (also known as {\tt SETCONT c1} and {\tt BOOLOR}), which take $c$ and $c'$ from the stack, set $c.\texttt{c0}$ or $c.\texttt{c1}$ to $c'$, and return the resulting continuation $c''=c\circ_0c'$ or $c\circ_1c'$. All other continuation composition operations can be expressed in terms of these two primitives.
\nxsubpoint\emb{Advanced continuation composition primitives}
However, TVM can compose continuations not only taken from stack, but also taken from {\tt c0} or {\tt c1}, or from the current continuation {\tt cc}; likewise, the result may be pushed into the stack, stored into either {\tt c0} or {\tt 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, {\tt EXECUTE} can be described as ${\tt cc}\leftarrow c\circ_0\tt{cc}$, with continuation $c$ taken from the original stack. Similarly, {\tt JMPX} is ${\tt cc}\leftarrow c$, and {\tt RET} (also known as {\tt RETTRUE} in a boolean circuit context) is ${\tt cc}\leftarrow\tt{c0}$. Other interesting primitives include {\tt THENRET} ($c'\leftarrow c\circ_0{\tt c0}$) and {\tt ATEXIT} (${\tt c0}\leftarrow c\circ_0{\tt c0}$).
Finally, some ``experimental'' primitives also involve {\tt c1} and $\circ_1$. For example:
\begin{itemize}
\item {\tt RETALT} or {\tt RETFALSE} does ${\tt cc}\leftarrow{\tt c1}$.
\item Conditional versions of {\tt RET} and {\tt RETALT} may also be useful: {\tt RETBOOL} takes an integer $x$ from the stack, and performs {\tt RETTRUE} if $x\neq0$, {\tt RETFALSE} otherwise.
\item {\tt INVERT} does ${\tt c0}\leftrightarrow{\tt c1}$; if the two continuations in {\tt c0} and {\tt c1} represent the two branches we should select depending on some boolean expression, {\tt INVERT} negates this expression on the outer level.
\item {\tt INVERTCONT} does $c.{\tt c0}\leftrightarrow c.{\tt c1}$ to a continuation $c$ taken from the stack.
\item Variants of {\tt ATEXIT} include {\tt ATEXITALT} (${\tt c1}\leftarrow c\circ_1{\tt c1}$) and {\tt SETEXITALT} (${\tt c1}\leftarrow (c\circ_0{\tt c0})\circ_1{\tt c1}$).
\item {\tt BOOLEVAL} takes a continuation $c$ from the stack and does ${\tt cc}\leftarrow \bigl((c\circ_0({\tt PUSH -1}))\circ_1({\tt PUSH 0})\bigr)\circ_0{\tt 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.
\end{itemize}
\mysubsection{Continuations as objects}
\nxsubpoint\label{sp:cont.obj}\emb{Representing objects using continuations}
Object-oriented programming in Small\-talk (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 $x_1$, $x_2$, \dots, $x_n$, 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.~\ptref{sp:callx.num.args}). 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.
\nxsubpoint\emb{Serializable objects}
Another way of representing Smalltalk-style objects as continuations, or even as trees of cells, consists in using the {\tt JMPREFDATA} primitive (a variant of {\tt JMPXDATA}, cf.~\ptref{sp:call.cc}), 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 {\em Slice} into the stack. In this way, an object might be represented by a cell $\tilde o$ that contains {\tt 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 $\tilde o$ is the {\em class} of object $\tilde 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.
\nxsubpoint\emb{Unique continuations and capabilities}
It might make sense (in a future revision of TVM) to mark some continuations as {\em 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 {\em 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.~\ptref{sp:cont.obj}). 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.
\mysubsection{Exception handling}
TVM's exception handling is quite simple and consists in a transfer of control to the continuation kept in control register {\tt c2}.
\nxsubpoint\emb{Two arguments of the exception handler: exception parameter and exception number}
Every exception is characterized by two arguments: the {\em exception number\/} (an {\em Integer}) and the {\em exception parameter\/} (any value, most often a zero {\em Integer}). Exception numbers 0--31 are reserved for TVM, while all other exception numbers are available for user-defined exceptions.
\nxsubpoint\emb{Primitives for throwing an exception}
There are several special primitives used for throwing an exception. The most general of them, {\tt THROWANY}, takes two arguments, $v$ and $0\leq 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.
\nxsubpoint\emb{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.
\nxsubpoint\emb{Exception handling}
The exception handling itself consists in a control transfer to the exception handler---i.e., the continuation specified in control register {\tt c2}, with $v$ and $n$ supplied as the two arguments to this continuation, as if a {\tt JMP} to {\tt c2} had been requested with $n''=2$ arguments (cf.~\ptref{sp:jmp.sw.n} and~\ptref{sp:jmp.sw}). 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 {\tt c2} has a value for {\tt c2} in its savelist, it will be used to set up the new value of {\tt c2} before executing the exception handler. In particular, if the exception handler invokes \texttt{THROWANY}, it will re-throw the original exception with the restored value of {\tt c2}. This trick enables the exception handler to handle only some exceptions, and pass the rest to an outer exception handler.
\nxsubpoint\emb{Default exception handler}
When an instance of TVM is created, {\tt c2} contains a reference to the ``default exception handler continuation'', which is an {\tt ec\_fatal} extraordinary continuation (cf.~\ptref{sp:extraord.cont}). 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.
\nxsubpoint\emb{{\tt TRY} primitive}
A {\tt 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 {\tt c2} into the savelist of $c'$, sets {\tt c2} to $c'$, and executes $c$ just as {\tt EXECUTE} would, but additionally saving the old value of {\tt c2} into the savelist of the new {\tt c0} as well. Usually a version of the {\tt TRY} primitive with an explicit number of arguments $n''$ passed to the continuation $c$ is used.