跳到主要内容

TVM 指令

advanced level

此信息是非常底层的,对于新手来讲可能很难理解。

介绍

本文档提供了TVM指令的列表,包括它们的操作码和助记符。

信息

TVM.pdf 最初概念 TON 虚拟机(可能包含过时的信息)。

Fift 是一种基于栈的编程语言,旨在管理 TON 智能合约。Fift 汇编器是一个能够将 TVM 指令的助记符转换为它们的二进制表示形式的 Fift 库。

关于 Fift 的描述,包括介绍 Fift 汇编器,可在此处找到。

本文档为每个指令指定了对应的助记符。

请注意以下几点:

  1. Fift 是一种基于栈的语言,因此任何指令的所有参数都写在它之前(例如,5 PUSHINTs0 s4 XCHG)。
  2. 栈寄存器由 s0, s1, ..., s15 表示。其他栈寄存器(最多255个)由 i s() 表示(例如,100 s())。
  3. 控制寄存器由 c0, c1, ..., c15 表示。

Gas 价格

本文档中指定了每个指令的 gas 价格。一个指令的基本 gas 价格是 10 + b,其中 b 是指令长度(以位为单位)。某些操作有附加费用:

  1. 解析cell:将一个cell转换成一个片段的成本是 100 gas 单位,如果是在同一交易中首次加载该cell,则为 25。对于此类指令,会指定两个 gas 价格(例如,CTOS: 118/43)。
  2. cell创建500 gas 单位
  3. 抛出异常50 gas 单位。在本文档中,仅对其主要用途为抛出异常的指令指定异常费(例如,THROWIFFITS)。如果指令在某些情况下只抛出异常,则会指定两个 gas 价格(例如,FITS: 26/76)。
  4. 元组创建:每个元组元素 1 gas 单位
  5. 隐式跳转:对于一个隐式跳转,10 gas 单位;对于隐式后跳,5 gas 单位。这项费用不属于任何指令的一部分。
  6. 在continuations之间移动栈元素:每个元素 1 gas 单位,但是移动前32个元素是免费的。

快速搜索

信息

一份完整的机器可读的 TVM 指令列表可在此处获取。

随意使用下面的搜索字段来查找特定的指令:

操作码Fift 语法堆栈Gas描述
Please enter a search query
No results found

2 堆栈操作原语

这里 0 <= i,j,k <= 15 除非另有说明。

2.1 基本堆栈操作原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
00NOP-无操作。18
01SWAPx y - y x等同于 s1 XCHG018
0is[i] XCHG0交换 s0s[i]1 <= i <= 1518
10ijs[i] s[j] XCHG交换 s[i]s[j]1 <= i < j <= 1526
11iis0 [ii] s() XCHG交换 s0s[ii]0 <= ii <= 25526
1is1 s[i] XCHG交换 s1s[i]2 <= i <= 1518
2is[i] PUSH将旧的 s[i] 的一个副本推入堆栈。18
20DUPx - x x等同于 s0 PUSH18
21OVERx y - x y x等同于 s1 PUSH18
3is[i] POP将旧的 s0 值弹出到旧的 s[i] 中。等同于 s[i] XCHG0 DROP18
30DROPx -等同于 s0 POP,丢弃堆栈顶部值。18
31NIPx y - y等同于 s1 POP18

2.2 复杂堆栈操作原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
4ijks[i] s[j] s[k] XCHG3等同于 s2 s[i] XCHG s1 s[j] XCHG s[k] XCHG026
50ijs[i] s[j] XCHG2等同于 s1 s[i] XCHG s[j] XCHG026
51ijs[i] s[j] XCPU等同于 s[i] XCHG0 s[j] PUSH26
52ijs[i] s[j-1] PUXC等同于 s[i] PUSH SWAP s[j] XCHG026
53ijs[i] s[j] PUSH2等同于 s[i] PUSH s[j+1] PUSH26
540ijks[i] s[j] s[k] XCHG3_lXCHG3 的长格式。34
541ijks[i] s[j] s[k] XC2PU等同于 s[i] s[j] XCHG2 s[k] PUSH34
542ijks[i] s[j] s[k-1] XCPUXC等同于 s1 s[i] XCHG s[j] s[k-1] PUXC34
543ijks[i] s[j] s[k] XCPU2等同于 s[i] XCHG0 s[j] s[k] PUSH234
544ijks[i] s[j-1] s[k-1] PUXC2等同于 s[i] PUSH s2 XCHG0 s[j] s[k] XCHG234
545ijks[i] s[j-1] s[k-1] PUXCPU等同于 s[i] s[j-1] PUXC s[k] PUSH34
546ijks[i] s[j-1] s[k-2] PU2XC等同于 s[i] PUSH SWAP s[j] s[k-1] PUXC34
547ijks[i] s[j] s[k] PUSH3等同于 s[i] PUSH s[j+1] s[k+1] PUSH234
55ij[i+1] [j+1] BLKSWAP交换两个块 s[j+i+1] … s[j+1]s[j] … s0
0 <= i,j <= 15
等同于 [i+1] [j+1] REVERSE [j+1] 0 REVERSE [i+j+2] 0 REVERSE
26
5513ROT2
2ROT
a b c d e f - c d e f a b旋转三对堆栈最顶部的条目。26
550i[i+1] ROLL旋转顶部 i+1 个堆栈条目。
等同于 1 [i+1] BLKSWAP
26
55i0[i+1] -ROLL
[i+1] ROLLREV
以相反方向旋转顶部 i+1 个堆栈条目。
等同于 [i+1] 1 BLKSWAP
26
56ii[ii] s() PUSH将旧的 s[ii] 的一个副本推入堆栈。
0 <= ii <= 255
26
57ii[ii] s() POP将旧的 s0 值弹出到旧的 s[ii] 中。
0 <= ii <= 255
26
58ROTa b c - b c a等同于 1 2 BLKSWAPs2 s1 XCHG218
59ROTREV
-ROT
a b c - c a b等同于 2 1 BLKSWAPs2 s2 XCHG218
5ASWAP2
2SWAP
a b c d - c d a b等同于 2 2 BLKSWAPs3 s2 XCHG218
5BDROP2
2DROP
a b - 等同于两次执行 DROP18
5CDUP2
2DUP
a b - a b a b等同于 s1 s0 PUSH218
5DOVER2
2OVER
a b c d - a b c d a b等同于 s3 s2 PUSH218
5Eij[i+2] [j] REVERSE反转 s[j+i+1] … s[j] 的顺序。26
5F0i[i] BLKDROP执行 iDROP26
5Fij[i] [j] BLKPUSH执行 iPUSH s(j)
1 <= i <= 15, 0 <= j <= 15
26
60PICK
PUSHX
从堆栈弹出整数 i,然后执行 s[i] PUSH18
61ROLLX从堆栈弹出整数 i,然后执行 1 [i] BLKSWAP18
62-ROLLX
ROLLREVX
从堆栈弹出整数 i,然后执行 [i] 1 BLKSWAP18
63BLKSWX从堆栈弹出整数 ij,然后执行 [i] [j] BLKSWAP18
64REVX从堆栈弹出整数 ij,然后执行 [i] [j] REVERSE18
65DROPX从堆栈弹出整数 i,然后执行 [i] BLKDROP18
66TUCKa b - b a b等同于 SWAP OVERs1 s1 XCPU18
67XCHGX从堆栈弹出整数 i,然后执行 s[i] XCHG18
68DEPTH- depth推入当前堆栈深度。18
69CHKDEPTHi -从堆栈弹出整数 i,然后检查是否至少有 i 个元素,否则生成堆栈下溢异常。18/58
6AONLYTOPX从堆栈弹出整数 i,然后移除除顶部 i 个元素之外的所有元素。18
6BONLYX从堆栈弹出整数 i,然后仅保留底部 i 个元素。大致等同于 DEPTH SWAP SUB DROPX18
6Cij[i] [j] BLKDROP2在顶部 j 个元素下方丢弃 i 个堆栈元素。
1 <= i <= 15, 0 <= j <= 15
等同于 [i+j] 0 REVERSE [i] BLKDROP [j] 0 REVERSE
26

3 元组、列表和 Null 原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
6DNULL
PUSHNULL
- null推入类型为 Null 的唯一值。18
6EISNULLx - ?检查 x 是否为 Null,根据情况分别返回 -1018
6F0n[n] TUPLEx_1 ... x_n - t创建包含 nx_1,..., x_n 的新 Tuple t=(x_1, … ,x_n)
0 <= n <= 15
26+n
6F00NIL- t推入长度为零的唯一 Tuple t=()26
6F01SINGLEx - t创建单例 t:=(x),即长度为一的 Tuple27
6F02PAIR
CONS
x y - t创建对 t:=(x,y)28
6F03TRIPLEx y z - t创建三元组 t:=(x,y,z)29
6F1k[k] INDEXt - x返回 Tuple t 的第 k 个元素。
0 <= k <= 15
26
6F10FIRST
CAR
t - x返回 Tuple 的第一个元素。26
6F11SECOND
CDR
t - y返回 Tuple 的第二个元素。26
6F12THIRDt - z返回 Tuple 的第三个元素。26
6F2n[n] UNTUPLEt - x_1 ... x_n解包长度等于 0 <= n <= 15Tuple t=(x_1,...,x_n)
如果 t 不是 Tuple\|t\| != n,则抛出类型检查异常。
26+n
6F21UNSINGLEt - x解包单例 t=(x)27
6F22UNPAIR
UNCONS
t - x y解包对 t=(x,y)28
6F23UNTRIPLEt - x y z解包三元组 t=(x,y,z)29
6F3k[k] UNPACKFIRSTt - x_1 ... x_k解包 Tuple t 的前 0 <= k <= 15 个元素。
如果 \|t\|<k,抛出类型检查异常。
26+k
6F30CHKTUPLEt -检查 t 是否为 Tuple。如果不是,则抛出类型检查异常。26
6F4n[n] EXPLODEt - x_1 ... x_m m解包 Tuple t=(x_1,...,x_m) 并返回其长度 m,但仅当 m <= n <= 15。否则抛出类型检查异常。26+m
6F5k[k] SETINDEXt x - t'计算 Tuple t',它与 t 仅在位置 t'_{k+1} 上不同,该位置被设置为 x
0 <= k <= 15
如果 k >= \|t\|,则抛出范围检查异常。
26+\|t\|
6F50SETFIRSTt x - t'Tuple t 的第一个组件设置为 x 并返回结果 Tuple t'26+\|t\|
6F51SETSECONDt x - t'Tuple t 的第二个组件设置为 x 并返回结果 Tuple t'26+\|t\|
6F52SETTHIRDt x - t'Tuple t 的第三个组件设置为 x 并返回结果 Tuple t'26+\|t\|
6F6k[k] INDEXQt - x返回 Tuple t 的第 k 个元素,其中 0 <= k <= 15。换句话说,如果 t=(x_1,...,x_n),则返回 x_{k+1}。如果 k>=ntNull,则返回 Null 而不是 x26
6F60FIRSTQ
CARQ
t - x返回 Tuple 的第一个元素。26
6F61SECONDQ
CDRQ
t - y返回 Tuple 的第二个元素。26
6F62THIRDQt - z返回 Tuple 的第三个元素。26
6F7k[k] SETINDEXQt x - t'Tuple t 中设置第 k 个组件为 x,其中 0 <= k < 16,并返回结果 Tuple t'
如果 \|t\| <= k,首先通过将所有新组件设置为 Null 来将原始 Tuple 扩展到长度 n’=k+1。如果原始值 tNull,则将其视为空 Tuple。如果 t 既不是 Null 也不是 Tuple,抛出异常。如果 xNull\|t\| <= ktNull,则总是返回 t'=t(并且不消耗元组创建 gas)。
26+\|t’\|
6F70SETFIRSTQt x - t'Tuple t 的第一个组件设置为 x 并返回结果 元组 t'26+\|t’\|
6F71SETSECONDQt x - t'Tuple t 的第二个组件设置为 x 并返回结果 元组 t'26+\|t’\|
6F72SETTHIRDQt x - t'Tuple组 t 的第三个组件设置为 x 并返回结果 元组 t'26+\|t’\|
6F80TUPLEVARx_1 ... x_n n - t以类似于 TUPLE 的方式创建长度为 n 的新 Tuple t,但 0 <= n <= 255 从堆栈获取。26+n
6F81INDEXVARt k - x类似于 k INDEX,但 0 <= k <= 254 从堆栈获取。26
6F82UNTUPLEVARt n - x_1 ... x_n类似于 n UNTUPLE,但 0 <= n <= 255 从堆栈获取。26+n
6F83UNPACKFIRSTVARt n - x_1 ... x_n类似于 n UNPACKFIRST,但 0 <= n <= 255 从堆栈获取。26+n
6F84EXPLODEVARt n - x_1 ... x_m m类似于 n EXPLODE,但 0 <= n <= 255 从堆栈获取。26+m
6F85SETINDEXVARt x k - t'类似于 k SETINDEX,但 0 <= k <= 254 从堆栈获取。26+\|t’\|
6F86INDEXVARQt k - x类似于 n INDEXQ,但 0 <= k <= 254 从堆栈获取。26
6F87SETINDEXVARQt x k - t'类似于 k SETINDEXQ,但 0 <= k <= 254 从堆栈获取。26+\|t’\|
6F88TLENt - n返回 Tuple 的长度。26
6F89QTLENt - n or -1类似于 TLEN,但如果 t 不是 Tuple,则返回 -126
6F8AISTUPLEt - ?根据 t 是否为 Tuple,分别返回 -1026
6F8BLASTt - x返回非空 Tuple t 的最后一个元素。26
6F8CTPUSH
COMMA
t x - t'将值 x 附加到 Tuple t=(x_1,...,x_n),但仅当结果 Tuple t'=(x_1,...,x_n,x) 的长度最多为 255 时。否则抛出类型检查异常。26+\|t’\|
6F8DTPOPt - t' x从非空 Tuple t=(x_1,...,x_n) 分离最后一个元素 x=x_n,并返回结果 Tuple t'=(x_1,...,x_{n-1}) 和原始的最后一个元素 x26+\|t’\|
6FA0NULLSWAPIFx - x or null x在顶部的 Integer x 下推入一个 Null,但仅当 x!=0 时。26
6FA1NULLSWAPIFNOTx - x or null x在顶部的 Integer x 下推入一个 Null,但仅当 x=0 时。可用于在类似于 PLDUXQ 这样的静默原语后进行堆栈对齐。26
6FA2NULLROTRIFx y - x y or null x y在顶部第二个堆栈条目下推入一个 Null,但仅当顶部的 Integer y 非零时。26
6FA3NULLROTRIFNOTx y - x y or null x y在顶部第二个堆栈条目下推入一个 Null,但仅当顶部的 Integer y 为零时。可用于在类似于 LDUXQ 这样的静默原语后进行堆栈对齐。26
6FA4NULLSWAPIF2x - x or null null x在顶部的 Integer x 下推入两个 Null,但仅当 x!=0 时。
等同于 NULLSWAPIF NULLSWAPIF
26
6FA5NULLSWAPIFNOT2x - x or null null x在顶部的 Integer x 下推入两个 Null,但仅当 x=0 时。
等同于 NULLSWAPIFNOT NULLSWAPIFNOT
26
6FA6NULLROTRIF2x y - x y or null null x y在顶部第二个堆栈条目下推入两个 Null,但仅当顶部的 Integer y 非零时。
等同于 NULLROTRIF NULLROTRIF
26
6FA7NULLROTRIFNOT2x y - x y 或 null null x y仅当最顶部的 Integer y 为零时,才在顶部第二个堆栈条目下推入两个 Null
等同于两次 NULLROTRIFNOT
26
6FBij[i] [j] INDEX2t - x对于 0 <= i,j <= 3,恢复 x=(t_{i+1})_{j+1}
等同于 [i] INDEX [j] INDEX
26
6FB4CADRt - x恢复 x=(t_2)_126
6FB5CDDRt - x恢复 x=(t_2)_226
6FE_ijk[i] [j] [k] INDEX3t - x恢复 x=t_{i+1}_{j+1}_{k+1}
0 <= i,j,k <= 3
等同于 [i] [j] INDEX2 [k] INDEX
26
6FD4CADDRt - x恢复 x=t_2_2_126
6FD5CDDDRt - x恢复 x=t_2_2_226

4 常量或字面量原语

4.1 整数和布尔常量

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
7i[x] PUSHINT
[x] INT
- x将整数 x 压入栈。-5 <= x <= 10
这里的 i 等于 x 的四个低阶位 (i=x mod 16)。
18
70ZERO
FALSE
- 018
71ONE- 118
72TWO- 218
7ATEN- 1018
7FTRUE- -118
80xx[xx] PUSHINT
[xx] INT
- xx将整数 xx 压入栈。-128 <= xx <= 12726
81xxxx[xxxx] PUSHINT
[xxxx] INT
- xxxx将整数 xxxx 压入栈。-2^15 <= xx < 2^1534
82lxxx[xxx] PUSHINT
[xxx] INT
- xxx将整数 xxx 压入栈。
细节: 5位的 0 <= l <= 30 决定了有符号大端整数 xxx 的长度 n=8l+19
此指令的总长度为 l+4 字节或 n+13=8l+32 位。
23
83xx[xx+1] PUSHPOW2- 2^(xx+1)(静默地)推送 2^(xx+1),对于 0 <= xx <= 255
2^256 是一个 NaN
26
83FFPUSHNAN- NaN推送一个 NaN26
84xx[xx+1] PUSHPOW2DEC- 2^(xx+1)-1推送 2^(xx+1)-1,对于 0 <= xx <= 25526
85xx[xx+1] PUSHNEGPOW2- -2^(xx+1)推送 -2^(xx+1),对于 0 <= xx <= 25526

4.2 常量切片、continuation、cell和引用

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
88[ref] PUSHREF- c将引用 ref 推送到栈中。
细节:cc.code 的第一个引用作为 cell 推入栈(并从当前continuation中移除此引用)。
18
89[ref] PUSHREFSLICE- s类似于 PUSHREF,但将cell转换为 切片118/43
8A[ref] PUSHREFCONT- cont类似于 PUSHREFSLICE,但将cell制作成一个简单的普通 continuation118/43
8Bxsss[slice] PUSHSLICE
[slice] SLICE
- s将切片 slice 推入栈。
细节: 推送 cc.code 的 (前缀) 子切片,其由其前 8x+4 位和零个引用组成(即,基本上是一个位串),其中 0 <= x <= 15
假设有一个完成标记,意味着所有尾随零和最后一个二进制一(如果存在)都从这个位串中被移除。
如果原始位串仅由零组成,则会推入一个空切片。
22
8Crxxssss[slice] PUSHSLICE
[slice] SLICE
- s将切片 slice 推入栈。
细节: 推送 cc.code 的 (前缀) 子切片,其由其前 1 <= r+1 <= 4 个引用和最多前 8xx+1 位数据组成,其中 0 <= xx <= 31
也假设有一个完成标记。
25
8Drxxsssss[slice] PUSHSLICE
[slice] SLICE
- s将切片 slice 推入栈。
细节: 推送 cc.code 的子切片,其由 0 <= r <= 4 个引用和最多 8xx+6 位数据组成,其中 0 <= xx <= 127
假设有一个完成标记。
28
x{} PUSHSLICE
x{ABCD1234} PUSHSLICE
b{01101} PUSHSLICE
- sPUSHSLICE 的示例。
x{} 是一个空切片。x{...} 是一个十六进制字面量。b{...} 是一个二进制字面量。
关于切片字面量的更多信息在这里
注意,汇编程序可以在某些情况下(例如,如果当前continuation中没有足够的空间)将 PUSHSLICE 替换为 PUSHREFSLICE
<b x{AB12} s, b> PUSHREF
<b x{AB12} s, b> PUSHREFSLICE
- c/sPUSHREFPUSHREFSLICE 的示例。
关于在 fift 中构建cell的更多信息在这里
8F_rxxcccc[builder] PUSHCONT
[builder] CONT
- cbuilder 中推送continuation。
细节: 推送由 cc.code 的前 0 <= r <= 3 个引用和前 0 <= xx <= 127 字节制成的简单普通continuation cccc
26
9xccc[builder] PUSHCONT
[builder] CONT
- cbuilder 中推送continuation。
细节: 推送一个 x 字节的continuation,对于 0 <= x <= 15
18
<{ code }> PUSHCONT
<{ code }> CONT
CONT:<{ code }>
- c用代码 code 推送continuation。
注意,汇编程序可以在某些情况下(例如,如果当前continuation中没有足够的空间)将 PUSHCONT 替换为 PUSHREFCONT

5 算术原语

5.1 加法、减法、乘法

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
A0ADDx y - x+y18
A1SUBx y - x-y18
A2SUBRx y - y-x等同于 SWAP SUB18
A3NEGATEx - -x等同于 -1 MULCONSTZERO SUBR
注意,如果 x=-2^256 时会触发整数溢出异常。
18
A4INCx - x+1等同于 1 ADDCONST18
A5DECx - x-1等同于 -1 ADDCONST18
A6cc[cc] ADDCONST
[cc] ADDINT
[-cc] SUBCONST
[-cc] SUBINT
x - x+cc-128 <= cc <= 12726
A7cc[cc] MULCONST
[cc] MULINT
x - x*cc-128 <= cc <= 12726
A8MULx y - x*y18

5.2 除法

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
A9mscdf这是除法的通用编码,可选进行预乘和用移位替换除法或乘法。变量字段如下:
0 <= m <= 1 - 表示是否有预乘(MULDIV 及其变体),可能被左移替换。
0 <= s <= 2 - 表示乘法或除法中的哪一个被移位替换:s=0 - 无替换,s=1 - 除法被右移替换,s=2 - 乘法被左移替换(仅当 m=1 时可能)。
0 <= c <= 1 - 表示是否有移位操作符的一个字节常量参数 tt(如果 s!=0)。对于 s=0c=0。如果 c=1,则 0 <= tt <= 255,并且移位由 tt+1 位执行。如果 s!=0c=0,则移位量作为栈顶的 整数0...256 范围内提供。
1 <= d <= 3 - 表示需要哪些除法结果:1 - 仅商,2 - 仅余数,3 - 商和余数。
0 <= f <= 2 - 舍入模式:0 - 向下取整,1 - 最近整数,2 - 向上取整。
下列所有指令均为此变体。
26
A904DIVx y - qq=floor(x/y)r=x-y*q26
A905DIVRx y - q’q’=round(x/y)r’=x-y*q’26
A906DIVCx y - q''q’’=ceil(x/y)r’’=x-y*q’’26
A908MODx y - r26
A90CDIVMODx y - q r26
A90DDIVMODRx y - q' r'26
A90EDIVMODCx y - q'' r''26
A925RSHIFTRx y - round(x/2^y)26
A926RSHIFTCx y - ceil(x/2^y)34
A935tt[tt+1] RSHIFTR#x y - round(x/2^(tt+1))34
A936tt[tt+1] RSHIFTC#x y - ceil(x/2^(tt+1))34
A938tt[tt+1] MODPOW2#x - x mod 2^(tt+1)34
A98MULDIVx y z - qq=floor(x*y/z)26
A985MULDIVRx y z - q'q'=round(x*y/z)26
A98CMULDIVMODx y z - q rq=floor(x*y/z)r=x*y-z*q26
A9A4MULRSHIFTx y z - floor(x*y/2^z)0 <= z <= 25626
A9A5MULRSHIFTRx y z - round(x*y/2^z)0 <= z <= 25626
A9A6MULRSHIFTCx y z - ceil(x*y/2^z)0 <= z <= 25634
A9B4tt[tt+1] MULRSHIFT#x y - floor(x*y/2^(tt+1))34
A9B5tt[tt+1] MULRSHIFTR#x y - round(x*y/2^(tt+1))34
A9B6tt[tt+1] MULRSHIFTC#x y - ceil(x*y/2^(tt+1))26
A9C4LSHIFTDIVx y z - floor(2^z*x/y)0 <= z <= 25626
A9C5LSHIFTDIVRx y z - round(2^z*x/y)0 <= z <= 25626
A9C6LSHIFTDIVCx y z - ceil(2^z*x/y)0 <= z <= 25634
A9D4tt[tt+1] LSHIFT#DIVx y - floor(2^(tt+1)*x/y)34
A9D5tt[tt+1] LSHIFT#DIVRx y - round(2^(tt+1)*x/y)34
A9D6tt[tt+1] LSHIFT#DIVCx y - ceil(2^(tt+1)*x/y)26

5.3 移位、逻辑操作

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
AAcc[cc+1] LSHIFT#x - x*2^(cc+1)0 <= cc <= 25526
ABcc[cc+1] RSHIFT#x - floor(x/2^(cc+1))0 <= cc <= 25518
ACLSHIFTx y - x*2^y0 <= y <= 102318
ADRSHIFTx y - floor(x/2^y)0 <= y <= 102318
AEPOW2y - 2^y0 <= y <= 1023
等同于 ONE SWAP LSHIFT
18
B0ANDx y - x&y对两个有符号整数 xy 进行按位与运算,符号扩展到无限。18
B1ORx y - x\|y对两个整数进行按位或运算。18
B2XORx y - x xor y对两个整数进行按位异或运算。18
B3NOTx - ~x一个整数的按位非运算。26
B4cc[cc+1] FITSx - x检查 x 是否为 cc+1 位有符号整数,对于 0 <= cc <= 255(即 -2^cc <= x < 2^cc)。
如果不是,要么触发整数溢出异常,要么用 NaN 替换 x(静默版本)。
26/76
B400CHKBOOLx - x检查 x 是否为“布尔值”(即 0 或 -1)。26/76
B5cc[cc+1] UFITSx - x检查 x 是否为 cc+1 位无符号整数,对于 0 <= cc <= 255(即 0 <= x < 2^(cc+1))。26/76
B500CHKBITx - x检查 x 是否为二进制数字(即零或一)。26/76
B600FITSXx c - x检查 x 是否为 c 位有符号整数,对于 0 <= c <= 102326/76
B601UFITSXx c - x检查 x 是否为 c 位无符号整数,对于 0 <= c <= 102326/76
B602BITSIZEx - c计算最小的 c >= 0 使得 x 适合于 c 位有符号整数(-2^(c-1) <= c < 2^(c-1))。26
B603UBITSIZEx - c计算最小的 c >= 0 使得 x 适合于 c 位无符号整数(0 <= x < 2^c),或抛出范围检查异常。26
B608MINx y - x or y计算两个整数 xy 的最小值。26
B609MAXx y - x or y计算两个整数 xy 的最大值。26
B60AMINMAX
INTSORT2
x y - x y or y x排序两个整数。如果任一参数为 NaNs,静默版本的此操作返回两个 NaNs。26
B60BABSx - \|x\|计算整数 x 的绝对值。26

5.4 静默算术原语

静默操作在其参数之一为 NaN 或在整数溢出的情况下返回 NaN,而不是抛出异常。 静默操作如下所示带有 Q 前缀。另一种使操作变为静默的方法是在其前添加 QUIET(即可以写 QUIET ADD 而不是 QADD)。 整数比较原语的静默版本也可用(QUIET SGNQUIET LESS 等)。

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
B7A0QADDx y - x+y26
B7A1QSUBx y - x-y26
B7A2QSUBRx y - y-x26
B7A3QNEGATEx - -x26
B7A4QINCx - x+126
B7A5QDECx - x-126
B7A8QMULx y - x*y26
B7A904QDIVx y - q如果 y=0 则除法返回 NaN34
B7A905QDIVRx y - q’34
B7A906QDIVCx y - q''34
B7A908QMODx y - r34
B7A90CQDIVMODx y - q r34
B7A90DQDIVMODRx y - q' r'34
B7A90EQDIVMODCx y - q'' r''34
B7A985QMULDIVRx y z - q'34
B7A98CQMULDIVMODx y z - q r34
B7ACQLSHIFTx y - x*2^y26
B7ADQRSHIFTx y - floor(x/2^y)26
B7AEQPOW2y - 2^y26
B7B0QANDx y - x&y26
B7B1QORx y - x\|y26
B7B2QXORx y - x xor y26
B7B3QNOTx - ~x26
B7B4cc[cc+1] QFITSx - x如果 x 不是 cc+1 位有符号整数,则用 NaN 替换 x,否则保持不变。34
B7B5cc[cc+1] QUFITSx - x如果 x 不是 cc+1 位无符号整数,则用 NaN 替换 x,否则保持不变。34
B7B600QFITSXx c - x如果 x 不是 c 位有符号整数,则用 NaN 替换 x,否则保持不变。34
B7B601QUFITSXx c - x如果 x 不是 c 位无符号整数,则用 NaN 替换 x,否则保持不变。34

6 比较原语

6.1 整数比较

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
B8SGNx - sgn(x)计算整数 x 的符号:
x<0 时为 -1x=0 时为 0x>0 时为 1
18
B9LESSx y - x<yx<y,返回 -1,否则返回 018
BAEQUALx y - x=yx=y,返回 -1,否则返回 018
BBLEQx y - x<=y18
BCGREATERx y - x>y18
BDNEQx y - x!=y等同于 EQUAL NOT18
BEGEQx y - x>=y等同于 LESS NOT18
BFCMPx y - sgn(x-y)计算 x-y 的符号:
x<y 时为 -1x=y 时为 0x>y 时为 1
除非 xyNaN,否则不会发生整数溢出。
18
C0yy[yy] EQINTx - x=yyx=yy,返回 -1,否则返回 0
-2^7 <= yy < 2^7
26
C000ISZEROx - x=0检查一个整数是否为零。对应 Forth 的 0=26
C1yy[yy] LESSINT
[yy-1] LEQINT
x - x<yyx<yy,返回 -1,否则返回 0
-2^7 <= yy < 2^7
26
C100ISNEGx - x<0检查一个整数是否为负数。对应 Forth 的 0<26
C101ISNPOSx - x<=0检查一个整数是否非正。26
C2yy[yy] GTINT
[yy+1] GEQINT
x - x>yyx>yy,返回 -1,否则返回 0
-2^7 <= yy < 2^7
26
C200ISPOSx - x>0检查一个整数是否为正数。对应 Forth 的 0>26
C2FFISNNEGx - x >=0检查一个整数是否非负。26
C3yy[yy] NEQINTx - x!=yyx!=yy,返回 -1,否则返回 0
-2^7 <= yy < 2^7
26
C4ISNANx - x=NaN检查 x 是否为 NaN18
C5CHKNANx - x如果 xNaN,抛出算术溢出异常。18/68

6.2 其他比较

这些“其他比较”原语中的大多数实际上将Slice的数据部分作为位串进行比较(如果没有另外声明,忽略引用)。

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
C700SEMPTYs - ?检查切片 s 是否为空(即,不包含任何数据位和cell引用)。26
C701SDEMPTYs - ?检查切片 s 是否没有数据位。26
C702SREMPTYs - ?检查切片 s 是否没有引用。26
C703SDFIRSTs - ?检查切片 s 的第一个位是否为一。26
C704SDLEXCMPs s' - x字典序比较 ss' 的数据,根据结果返回 -1、0 或 1。26
C705SDEQs s' - ?检查 ss' 的数据部分是否一致,等同于 SDLEXCMP ISZERO26
C708SDPFXs s' - ?检查 s 是否是 s' 的前缀。26
C709SDPFXREVs s' - ?检查 s' 是否是 s 的前缀,等同于 SWAP SDPFX26
C70ASDPPFXs s' - ?检查 s 是否是 s' 的真前缀(即,一个与 s' 不同的前缀)。26
C70BSDPPFXREVs s' - ?检查 s' 是否是 s 的真前缀。26
C70CSDSFXs s' - ?检查 s 是否是 s' 的后缀。26
C70DSDSFXREVs s' - ?检查 s' 是否是 s 的后缀。26
C70ESDPSFXs s' - ?检查 s 是否是 s' 的真后缀。26
C70FSDPSFXREVs s' - ?检查 s' 是否是 s 的真后缀。26
C710SDCNTLEAD0s - n返回 s 中前导零的数量。26
C711SDCNTLEAD1s - n返回 s 中前导一的数量。26
C712SDCNTTRAIL0s - n返回 s 中末尾零的数量。26
C713SDCNTTRAIL1s - n返回 s 中末尾一的数量。26

7 Cell 原语

7.1 Cell 序列化原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
C8NEWC- b创建一个新的空 构建器18
C9ENDCb - c构建器 转换为普通的 cell518
CAcc[cc+1] STIx b - b'0 <= cc <= 255 的有符号 cc+1-位整数 x 存入 构建器 b 中,如果 x 不适合于 cc+1 位,则抛出范围检查异常。26
CBcc[cc+1] STUx b - b'将无符号的 cc+1-位整数 x 存入 构建器 b 中。在其他方面,它与 STI 类似。26
CCSTREFc b - b'cell c 的引用存入 构建器 b 中。18
CDSTBREFR
ENDCST
b b'' - b等同于 ENDC SWAP STREF518
CESTSLICEs b - b'分片 s 存入 构建器 b 中。18
CF00STIXx b l - b'0 <= l <= 257,将有符号 l-位整数 x 存入 b 中。26
CF01STUXx b l - b'0 <= l <= 256,将无符号 l-位整数 x 存入 b 中。26
CF02STIXRb x l - b'STIX 类似,但参数顺序不同。26
CF03STUXRb x l - b'STUX 类似,但参数顺序不同。26
CF04STIXQx b l - x b f or b' 0STIX 的静默版本。如果 b 中没有空间,将 b'=bf=-1
如果 x 不适合于 l 位,将 b'=bf=1
如果操作成功,b' 是新的 构建器f=0
然而,0 <= l <= 257,如果不是这样,则抛出范围检查异常。
26
CF05STUXQx b l - x b f or b' 0STUX 的静默版本。26
CF06STIXRQb x l - b x f or b' 0STIXR 的静默版本。26
CF07STUXRQb x l - b x f or b' 0STUXR 的静默版本。26
CF08cc[cc+1] STI_lx b - b'[cc+1] STI 的更长版本。34
CF09cc[cc+1] STU_lx b - b'[cc+1] STU 的更长版本。34
CF0Acc[cc+1] STIRb x - b'等同于 SWAP [cc+1] STI34
CF0Bcc[cc+1] STURb x - b'等同于 SWAP [cc+1] STU34
CF0Ccc[cc+1] STIQx b - x b f or b' 0STI 的静默版本。34
CF0Dcc[cc+1] STUQx b - x b f or b' 0STU 的静默版本。34
CF0Ecc[cc+1] STIRQb x - b x f or b' 0STIR 的静默版本。34
CF0Fcc[cc+1] STURQb x - b x f or b' 0STUR 的静默版本。34
CF10STREF_lc b - b'STREF 的更长版本。26
CF11STBREFb' b - b''等同于 SWAP STBREFR526
CF12STSLICE_ls b - b'STSLICE 的更长版本。26
CF13STBb' b - b''构建器 b' 中的所有数据附加到 构建器 b 中。26
CF14STREFRb c - b'等同于 SWAP STREF26
CF15STBREFR_lb b' - b''STBREFR 的更长编码。526
CF16STSLICERb s - b'等同于 SWAP STSLICE26
CF17STBR
BCONCAT
b b' - b''连接两个构建器。
等同于 SWAP STB
26
CF18STREFQc b - c b -1 or b' 0STREF 的静默版本。26
CF19STBREFQb' b - b' b -1 or b'' 0STBREF 的静默版本。526
CF1ASTSLICEQs b - s b -1 or b' 0STSLICE 的静默版本。26
CF1BSTBQb' b - b' b -1 or b'' 0STB 的静默版本。26
CF1CSTREFRQb c - b c -1 or b' 0STREFR 的静默版本。26
CF1DSTBREFRQb b' - b b' -1 or b'' 0STBREFR 的静默版本。526
CF1ESTSLICERQb s - b s -1 or b'' 0STSLICER 的静默版本。26
CF1FSTBRQ
BCONCATQ
b b' - b b' -1 or b'' 0STBR 的静默版本。26
CF20[ref] STREFCONSTb - b’等同于 PUSHREF STREFR26
CF21[ref] [ref] STREF2CONSTb - b’等同于 STREFCONST STREFCONST26
CF23b x - c如果 x!=0,从 构建器 b 创建一个 特殊异类 cell。
异类cell的类型必须存储在 b 的前 8 位中。
如果 x=0,它相当于 ENDC。否则,将在创建异类cell之前对 b 的数据和引用执行一些有效性检查。
526
CF28STILE4x b - b'存储一个小端有符号 32 位整数。26
CF29STULE4x b - b'存储一个小端无符号 32 位整数。26
CF2ASTILE8x b - b'存储一个小端有符号 64 位整数。26
CF2BSTULE8x b - b'存储一个小端无符号 64 位整数。26
CF30BDEPTHb - x返回 构建器 b 的深度。如果 b 中没有存储cell引用,则 x=0;否则 x 是对 b 中引用的cell的深度的最大值加 1。26
CF31BBITSb - x返回已经存储在 构建器 b 中的数据位数。26
CF32BREFSb - y返回已经存储在 b 中的cell引用数。26
CF33BBITREFSb - x y返回 b 中数据位数和cell引用数。26
CF35BREMBITSb - x'返回仍然可以存储在 b 中的数据位数。26
CF36BREMREFSb - y'返回仍然可以存储在 b 中的引用数。26
CF37BREMBITREFSb - x' y'返回仍然可以存储在 b 中的数据位数和引用数。26
CF38cc[cc+1] BCHKBITS#b -检查是否能将 cc+1 位存储到 b 中,其中 0 <= cc <= 25534/84
CF39BCHKBITSb x - 检查是否能将 x 位存储到 b 中,0 <= x <= 1023。如果 b 中没有足够空间存储 x 更多位,或者 x 不在范围 0...1023 内,则抛出异常。26/76
CF3ABCHKREFSb y - 检查是否能将 y 引用存储到 b 中,0 <= y <= 726/76
CF3BBCHKBITREFSb x y - 检查是否能将 x 位和 y 引用存储到 b 中,0 <= x <= 10230 <= y <= 726/76
CF3Ccc[cc+1] BCHKBITSQ#b - ?检查是否能将 cc+1 位存储到 b 中,其中 0 <= cc <= 25534
CF3DBCHKBITSQb x - ?检查是否能将 x 位存储到 b 中,0 <= x <= 102326
CF3EBCHKREFSQb y - ?检查是否能将 y 引用存储到 b 中,0 <= y <= 726
CF3FBCHKBITREFSQb x y - ?检查是否能将 x 位和 y 引用存储到 b 中,0 <= x <= 10230 <= y <= 726
CF40STZEROESb n - b'n 个二进制零存储到 构建器 b 中。26
CF41STONESb n - b'n 个二进制一存储到 构建器 b 中。26
CF42STSAMEb n x - b'n 个二进制 x0 <= x <= 1)存储到 构建器 b 中。26
CFC0_xysss[slice] STSLICECONSTb - b'存储一个常量子切片 sss
详情: sss0 <= x <= 3 个引用和最多 8y+2 个数据位组成,其中 0 <= y <= 7。假定有完成位。
注意,如果切片过大,汇编器可以将 STSLICECONST 替换为 PUSHSLICE STSLICER
24
CF81STZEROb - b'存储一个二进制零。24
CF83STONEb - b'存储一个二进制一。24

7.2 Cell 反序列化原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
D0CTOSc - scell 转换为 切片。请注意,c 必须是普通cell,或者是自动 加载 以产生普通cell c' 的异类cell,然后转换为 切片118/43
D1ENDSs - 从堆栈中移除 切片 s,如果不为空则抛出异常。18/68
D2cc[cc+1] LDIs - x s'切片 s 中加载(即解析)一个有符号的 cc+1-位整数 x,并返回 s 的剩余部分作为 s'26
D3cc[cc+1] LDUs - x s'切片 s 中加载一个无符号 cc+1-位整数 x26
D4LDREFs - c s's 中加载一个cell引用 c18
D5LDREFRTOSs - s' s''等效于 LDREF SWAP CTOS118/43
D6cc[cc+1] LDSLICEs - s'' s's 的接下来的 cc+1 位切割为一个独立的 切片 s''26
D700LDIXs l - x s'切片 s 中加载一个有符号的 l-位(0 <= l <= 257)整数 x,并返回 s 的剩余部分作为 s'26
D701LDUXs l - x s's 的前 l 位(0 <= l <= 256)加载一个无符号 l-位整数 x26
D702PLDIXs l - x切片 s 中预加载一个有符号 l-位整数,0 <= l <= 25726
D703PLDUXs l - xs 中预加载一个无符号 l-位整数,0 <= l <= 25626
D704LDIXQs l - x s' -1 or s 0LDIX 的静默版本:类似地从 s 中加载一个有符号 l-位整数,但在成功时返回一个成功标志位 -1,失败时(如果 s 没有 l 位)返回 0,而不是抛出cell下溢异常。26
D705LDUXQs l - x s' -1 or s 0LDUX 的静默版本。26
D706PLDIXQs l - x -1 or 0PLDIX 的静默版本。26
D707PLDUXQs l - x -1 or 0PLDUX 的静默版本。26
D708cc[cc+1] LDI_ls - x s'LDI 的更长编码。34
D709cc[cc+1] LDU_ls - x s'LDU 的更长编码。34
D70Acc[cc+1] PLDIs - x切片 s 中预加载一个有符号 cc+1-位整数。34
D70Bcc[cc+1] PLDUs - xs 中预加载一个无符号 cc+1-位整数。34
D70Ccc[cc+1] LDIQs - x s' -1 or s 0LDI 的静默版本。34
D70Dcc[cc+1] LDUQs - x s' -1 or s 0LDU 的静默版本。34
D70Ecc[cc+1] PLDIQs - x -1 or 0PLDI 的静默版本。34
D70Fcc[cc+1] PLDUQs - x -1 or 0PLDU 的静默版本。34
D714_c[32(c+1)] PLDUZs - s x切片 s 中预加载前 32(c+1) 位到无符号整数 x 中,0 <= c <= 7。如果 s 比必要的短,缺失的位假定为零。此操作旨在与 IFBITJMP 及类似指令一起使用。26
D718LDSLICEXs l - s'' s'切片 s 中加载前 0 <= l <= 1023 位到一个单独的 切片 s'' 中,返回 s 的剩余部分作为 s'26
D719PLDSLICEXs l - s''返回 s 的前 0 <= l <= 1023 位作为 s''26
D71ALDSLICEXQs l - s'' s' -1 or s 0LDSLICEX 的静默版本。26
D71BPLDSLICEXQs l - s' -1 or 0LDSLICEXQ 的静默版本。26
D71Ccc[cc+1] LDSLICE_ls - s'' s'LDSLICE 的更长编码。34
D71Dcc[cc+1] PLDSLICEs - s''返回 s 的前 0 < cc+1 <= 256 位作为 s''34
D71Ecc[cc+1] LDSLICEQs - s'' s' -1 or s 0LDSLICE 的静默版本。34
D71Fcc[cc+1] PLDSLICEQs - s'' -1 or 0PLDSLICE 的静默版本。34
D720SDCUTFIRSTs l - s'返回 s 的前 0 <= l <= 1023 位。与 PLDSLICEX 等效。26
D721SDSKIPFIRSTs l - s'返回除了 s 的前 0 <= l <= 1023 位以外的所有位。与 LDSLICEX NIP 等效。26
D722SDCUTLASTs l - s'返回 s 的后 0 <= l <= 1023 位。26
D723SDSKIPLASTs l - s'返回除了 s 的后 0 <= l <= 1023 位以外的所有位。26
D724SDSUBSTRs l l' - s'返回 s 的从偏移量 0 <= l <= 1023 开始的 0 <= l' <= 1023 位,从 s 的数据中提取出一个位子字符串。26
D726SDBEGINSXs s' - s''检查 s 是否以 s'(数据位)开始,并在成功时从 s 中移除 s'。失败抛出cell反序列化异常。原语 SDPFXREV 可以认为是 SDBEGINSX 的静默版本。26
D727SDBEGINSXQs s' - s'' -1 or s 0SDBEGINSX 的静默版本。26
D72A_xsss[slice] SDBEGINSs - s''检查 s 是否以常量位串 sss 开始,sss 的长度为 8x+3(假定有完成位),其中 0 <= x <= 127,并在成功时从 s 中移除 sss31
D72E_xsss[slice] SDBEGINSQs - s'' -1 or s 0SDBEGINS 的静默版本。31
D730SCUTFIRSTs l r - s'返回 s 的前 0 <= l <= 1023 位和前 0 <= r <= 4 个引用。26
D731SSKIPFIRSTs l r - s'返回除了 s 的前 l 位和 r 个引用以外的所有内容。26
D732SCUTLASTs l r - s'返回 s 的后 0 <= l <= 1023 个数据位和后 0 <= r <= 4 个引用。26
D733SSKIPLASTs l r - s'返回除了 s 的后 l 位和 r 个引用以外的所有内容。26
D734SUBSLICEs l r l' r' - s'在跳过 s 的前 0 <= l <= 1023 位和前 0 <= r <= 4 个引用后,返回来自 切片 s0 <= l' <= 1023 位和 0 <= r' <= 4 个引用。26
D736SPLITs l r - s' s''s 的前 0 <= l <= 1023 个数据位和前 0 <= r <= 4 个引用分割成 s',并返回 s 的剩余部分作为 s''26
D737SPLITQs l r - s' s'' -1 或 s 0SPLIT 的静默版本。26
D739c - s?将普通或异类cell转换为 切片,就好像它是一个普通cell一样。返回一个标志位,指示 c 是否是异类的。如果是这样,其类型可以稍后从 s 的前八位中反序列化。
D73Ac - c'加载异类cell c 并返回一个普通cell c'。如果 c 已经是普通的,则不执行任何操作。如果 c 无法加载,抛出异常。
D73Bc - c' -1 或 c 0加载异类cell c 并返回一个普通cell c'。如果 c 已经是普通的,则不执行任何操作。如果 c 无法加载,返回 0。
D741SCHKBITSs l - 检查 切片 s 中是否至少有 l 个数据位。如果不是这种情况,抛出cell反序列化(即cell下溢)异常。26/76
D742SCHKREFSs r - 检查 切片 s 中是否至少有 r 个引用。26/76
D743SCHKBITREFSs l r - 检查 切片 s 中是否至少有 l 个数据位和 r 个引用。26/76
D745SCHKBITSQs l - ?检查 切片 s 中是否至少有 l 个数据位。26
D746SCHKREFSQs r - ?检查 切片 s 中是否至少有 r 个引用。26
D747SCHKBITREFSQs l r - ?检查 切片 s 中是否至少有 l 个数据位和 r 个引用。26
D748PLDREFVARs n - c返回 切片 s 的第 n 个cell引用,0 <= n <= 326
D749SBITSs - l返回 切片 s 中的数据位数。26
D74ASREFSs - r返回 切片 s 中的引用数。26
D74BSBITREFSs - l r返回 s 中的数据位数和引用数。26
D74E_n[n] PLDREFIDXs - c返回 切片 s 的第 n 个cell引用,0 <= n <= 326
D74CPLDREFs - c预加载 切片 的第一个cell引用。26
D750LDILE4s - x s'加载一个小端有符号 32 位整数。26
D751LDULE4s - x s'加载一个小端无符号 32 位整数。26
D752LDILE8s - x s'加载一个小端有符号 64 位整数。26
D753LDULE8s - x s'加载一个小端无符号 64 位整数。26
D754PLDILE4s - x预加载一个小端有符号 32 位整数。26
D755PLDULE4s - x预加载一个小端无符号 32 位整数。26
D756PLDILE8s - x预加载一个小端有符号 64 位整数。26
D757PLDULE8s - x预加载一个小端无符号 64 位整数。26
D758LDILE4Qs - x s' -1 或 s 0静默加载一个小端有符号 32 位整数。26
D759LDULE4Qs - x s' -1 或 s 0静默加载一个小端无符号 32 位整数。26
D75ALDILE8Qs - x s' -1 或 s 0静默加载一个小端有符号 64 位整数。26
D75BLDULE8Qs - x s' -1 或 s 0静默加载一个小端无符号 64 位整数。26
D75CPLDILE4Qs - x -1 或 0静默预加载一个小端有符号 32 位整数。26
D75DPLDULE4Qs - x -1 或 0静默预加载一个小端无符号 32 位整数。26
D75EPLDILE8Qs - x -1 或 0静默预加载一个小端有符号 64 位整数。26
D75FPLDULE8Qs - x -1 或 0静默预加载一个小端无符号 64 位整数。26
D760LDZEROESs - n s'返回 s 中前导零位的计数 n,并从 s 中移除这些位。26
D761LDONESs - n s'返回 s 中前导一位的计数 n,并从 s 中移除这些位。26
D762LDSAMEs x - n s'返回 s 中与 0 <= x <= 1 相等的前导位的计数 n,并从 s 中移除这些位。26
D764SDEPTHs - x返回 切片 s 的深度。如果 s 没有引用,则 x=0;否则 x 是从 s 引用的cell的最大深度加 1。26
D765CDEPTHc - x返回 cell c 的深度。如果 c 没有引用,则 x=0;否则 x 是从 c 引用的cell的最大深度加 1。如果 c空(Null) 而不是 cell,返回零。26

8 Continuation 和控制流原语

8.1 无条件控制流原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
D8EXECUTE
CALLX
c - 调用执行 Continuation c18
D9JMPXc - 跳转 或 控制转移到 Continuation c
之前当前continuation cc的剩余部分被丢弃。
18
DApr[p] [r] CALLXARGSc - p 参数 调用 continuation c 并期待 r 返回值
0 <= p <= 15, 0 <= r <= 15
26
DB0p[p] -1 CALLXARGSc - 0 <= p <= 15 参数 调用 continuation c, 期望任意数量的返回值。26
DB1p[p] JMPXARGSc - 跳转 到 continuation c, 只将当前栈顶的 0 <= p <= 15 个值传递给它(当前栈的其余部分被丢弃)。26
DB2r[r] RETARGS返回c0, 携带 0 <= r <= 15 个从当前栈中取得的返回值。26
DB30RET
RETTRUE
返回 到 continuation c0。当前 continuation cc的剩余部分被丢弃。
大致相当于 c0 PUSHCTR JMPX
26
DB31RETALT
RETFALSE
返回 到 continuation c1
大致相当于 c1 PUSHCTR JMPX
26
DB32BRANCH
RETBOOL
f - 如果整数 f!=0, 执行 RETTRUE,如果 f=0,执行 RETFALSE26
DB34CALLCCc - 带当前 continuation 调用,控制权转移到 c,将旧的 cc 值推入 c 的栈中(而不是丢弃它或将其写入新的 c0中)。26
DB35JMPXDATAc - 类似于 CALLCC,但是当前 continuation 的剩余部分(旧的 cc 值)在推入 c 的栈之前被转换成一个 Slice26
DB36pr[p] [r] CALLCCARGSc - 类似于 CALLXARGS,但是将旧的 cc 值(连同最初栈顶的 0 <= p <= 15 个值)推入被调用 continuation c 的栈中,设置 cc.nargs-1 <= r <= 1434
DB38CALLXVARARGSc p r - 类似于 CALLXARGS,但从栈中取 -1 <= p,r <= 254。接下来的三个操作也从栈中取 pr,范围都是 -1...25426
DB39RETVARARGSp r - 类似于 RETARGS26
DB3AJMPXVARARGSc p r - 类似于 JMPXARGS26
DB3BCALLCCVARARGSc p r - 类似于 CALLCCARGS26
DB3C[ref] CALLREF等同于 PUSHREFCONT CALLX126/51
DB3D[ref] JMPREF等同于 PUSHREFCONT JMPX126/51
DB3E[ref] JMPREFDATA等同于 PUSHREFCONT JMPXDATA126/51
DB3FRETDATA等同于 c0 PUSHCTR JMPXDATA。这样,当前 continuation 的剩余部分被转换成一个 Slice 并返回给调用者。26

8.2 条件控制流原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
DCIFRET
IFNOT:
f - 如果整数 f 非零,则执行 RET。如果 fNaN, 抛出一个整数溢出异常。18
DDIFNOTRET
IF:
f - 如果整数 f 为零,则执行 RET18
DEIFf c - 如果整数 f 非零,执行 c(即,执行 c),否则简单地丢弃两个值。18
DEIF:<{ code }>
<{ code }>IF
f -等同于 <{ code }> CONT IF
DFIFNOTf c - 如果整数 f 为零,则执行 continuation c,否则简单地丢弃两个值。18
DFIFNOT:<{ code }>
<{ code }>IFNOT
f -等同于 <{ code }> CONT IFNOT
E0IFJMPf c - 只有当 f 非零时,跳转到 c(类似于 JMPX)。18
E0IFJMP:<{ code }>f -等同于 <{ code }> CONT IFJMP
E1IFNOTJMPf c - 只有当 f 为零时,跳转到 c(类似于 JMPX)。18
E1IFNOTJMP:<{ code }>f -等同于 <{ code }> CONT IFNOTJMP
E2IFELSEf c c' - 如果整数 f 非零,执行 c,否则执行 c'。等同于 CONDSELCHK EXECUTE18
E2IF:<{ code1 }>ELSE<{ code2 }>f -等同于 <{ code1 }> CONT <{ code2 }> CONT IFELSE
E300[ref] IFREFf - 等同于 PUSHREFCONT IF,但优化了cell引用不实际加载入一个 Slice 再转换成一个普通 Continuation 如果 f=0
这个原语的 Gas 消耗取决于 f=0 以及引用是否之前加载过。
类似的评论适用于接受 continuation 作为引用的其他原语。
26/126/51
E301[ref] IFNOTREFf - 等同于 PUSHREFCONT IFNOT26/126/51
E302[ref] IFJMPREFf - 等同于 PUSHREFCONT IFJMP26/126/51
E303[ref] IFNOTJMPREFf - 等同于 PUSHREFCONT IFNOTJMP26/126/51
E304CONDSELf x y - x 或 y如果整数 f 非零,返回 x,否则返回 y。注意 xy 上不执行类型检查;因此,它更像是一个条件栈操作。大致等同于 ROT ISZERO INC ROLLX NIP26
E305CONDSELCHKf x y - x 或 yCONDSEL 相同,但首先检查 xy 是否类型相同。26
E308IFRETALTf -如果整数 f!=0 执行 RETALT26
E309IFNOTRETALTf -如果整数 f=0 执行 RETALT26
E30D[ref] IFREFELSEf c -等同于 PUSHREFCONT SWAP IFELSE,但优化了在 f=0 时,实际上并不需要将cell引用加载进一个Slice,然后再转换成普通的 Continuation。对接下来的两个原语也适用类似的备注:只有在必要时,才将cell转换成 continuations。26/126/51
E30E[ref] IFELSEREFf c -等同于 PUSHREFCONT IFELSE26/126/51
E30F[ref] [ref] IFREFELSEREFf -等同于 PUSHREFCONT PUSHREFCONT IFELSE126/51
E39_n[n] IFBITJMPx c - x检查整数 x 中是否设置了位 0 <= n <= 31,如果是,则执行 JMPX 跳转到 continuation c。值 x 保留在栈中。26
E3B_n[n] IFNBITJMPx c - x如果整数 x 中位 0 <= n <= 31 未设置,跳转到 c26
E3D_n[ref] [n] IFBITJMPREFx - x如果整数 x 中设置了位 0 <= n <= 31,执行 JMPREF126/51
E3F_n[ref] [n] IFNBITJMPREFx - x如果整数 x 中未设置位 0 <= n <= 31,执行 JMPREF126/51

8.3 控制流原语:循环

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
E4REPEATn c - 如果整数 n 为非负数,则执行 continuation c n 次。如果 n>=2^31n<-2^31,会生成一个范围检查异常。
注意,在 c 的代码内部的 RET 作为 continue 使用,而不是 break。应使用另一种(实验性的)循环或者 RETALT(循环前与 SETEXITALT 一起使用)来从循环中 break 出去。
18
E4REPEAT:<{ code }>
<{ code }>REPEAT
n -等同于 <{ code }> CONT REPEAT
E5REPEATEND
REPEAT:
n - 类似于 REPEAT,但它应用于当前 continuation cc18
E6UNTILc - 执行 continuation c,然后从结果栈中弹出一个整数 x。如果 x 为零,执行此循环的另一次迭代。这个原语的实际实现涉及一个特殊的 continuation ec_until,其参数设置为循环体(continuation c)和原始的当前 continuation cc。然后这个特殊的 continuation 被保存到 c 的 savelist 作为 c.c0,然后执行修改后的 c。其他循环原语也类似地借助适当的特殊 continuations 实现。18
E6UNTIL:<{ code }>
<{ code }>UNTIL
-等同于 <{ code }> CONT UNTIL
E7UNTILEND
UNTIL:
-类似于 UNTIL,但在循环中执行当前 continuation cc。当满足循环退出条件时,执行 RET18
E8WHILEc' c - 执行 c' 并从结果栈中弹出一个整数 x。如果 x 为零,则退出循环并将控制权转移给原始 cc。如果 x 非零,则执行 c,然后开始新的迭代。18
E8WHILE:<{ cond }>DO<{ code }>-等同于 <{ cond }> CONT <{ code }> CONT WHILE
E9WHILEENDc' - 类似于 WHILE,但使用当前 continuation cc 作为循环体。18
EAAGAINc - 类似于 REPEAT,但无限次执行 c。一个 RET 只是开始一个无限循环的新迭代,只能通过异常或 RETALT(或显式的 JMPX)退出。18
EAAGAIN:<{ code }>
<{ code }>AGAIN
-等同于 <{ code }> CONT AGAIN
EBAGAINEND
AGAIN:
-类似于 AGAIN,但相对于当前 continuation cc 执行。18
E314REPEATBRKn c -类似于 REPEAT,但在将旧的 c1 值保存到原始 cc的 savelist 后,还将 c1 设置为原始 cc。这样,RETALT 可以用来退出循环体。26
E314REPEATBRK:<{ code }>
<{ code }>REPEATBRK
n -等同于 <{ code }> CONT REPEATBRK
E315REPEATENDBRKn -类似于 REPEATEND,但在将旧的 c1 值保存到原始 c0的 savelist 后,还将 c1 设置为原始 c0。等同于 SAMEALTSAVE REPEATEND26
E316UNTILBRKc -类似于 UNTIL,但也以与 REPEATBRK 相同的方式修改 c126
E316UNTILBRK:<{ code }>-等同于 <{ code }> CONT UNTILBRK
E317UNTILENDBRK
UNTILBRK:
-等同于 SAMEALTSAVE UNTILEND26
E318WHILEBRKc' c -类似于 WHILE,但也以与 REPEATBRK 相同的方式修改 c126
E318WHILEBRK:<{ cond }>DO<{ code }>-等同于 <{ cond }> CONT <{ code }> CONT WHILEBRK
E319WHILEENDBRKc -等同于 SAMEALTSAVE WHILEEND26
E31AAGAINBRKc -类似于 AGAIN,但也以与 REPEATBRK 相同的方式修改 c126
E31AAGAINBRK:<{ code }>-等同于 <{ code }> CONT AGAINBRK
E31BAGAINENDBRK
AGAINBRK:
-等同于 SAMEALTSAVE AGAINEND26

8.4 操作 continuation 栈

这里的 s"在 continuations 之间移动栈元素的费用。它等于结果栈的大小减去32(如果栈大小小于32,则为0)。

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
ECrn[r] [n] SETCONTARGSx_1 x_2...x_r c - c'类似于 [r] -1 SETCONTARGS,但将 c.nargs 设置为 c' 的栈的最终大小加上 n。换句话说,将 c 转换成一个闭包部分应用函数,缺少 0 <= n <= 14 个参数。26+s”
EC0n[n] SETNUMARGSc - c'设置 c.nargsn 加上 c 的当前栈的深度,其中 0 <= n <= 14。如果 c.nargs 已经设置为非负值,则不进行任何操作。26
ECrF[r] -1 SETCONTARGSx_1 x_2...x_r c - c'0 <= r <= 15 个值 x_1...x_r 推入(复制的)continuation c 的栈中,从 x_1 开始。如果 c 的栈最终深度超过了 c.nargs,将生成栈溢出异常。26+s”
ED0p[p] RETURNARGS-仅保留当前栈顶的 0 <= p <= 15 个值(类似于 ONLYTOPX),所有未使用的底部值不被丢弃,而是以与 SETCONTARGS 相同的方式保存到 continuation c0 中。26+s”
ED10RETURNVARARGSp -类似于 RETURNARGS,但从栈中取整数 0 <= p <= 25526+s”
ED11SETCONTVARARGSx_1 x_2...x_r c r n - c'类似于 SETCONTARGS,但从栈中取 0 <= r <= 255-1 <= n <= 25526+s”
ED12SETNUMVARARGSc n - c'-1 <= n <= 255
如果 n=-1,此操作不进行任何操作(c'=c)。
否则其行为类似于 [n] SETNUMARGS,但 n 是从栈中取得的。
26

8.5 创建简单的 continuations 和 闭包

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
ED1EBLESSs - cSlice s 转换为简单的普通 continuation c,其中 c.code=s,并且栈和 savelist 为空。26
ED1FBLESSVARARGSx_1...x_r s r n - c等同于 ROT BLESS ROTREV SETCONTVARARGS26+s”
EErn[r] [n] BLESSARGSx_1...x_r s - c0 <= r <= 15, -1 <= n <= 14
等同于 BLESS [r] [n] SETCONTARGS
n 的值由 4 位整数 n mod 16 内部表示。
26
EE0n[n] BLESSNUMARGSs - c也将 Slice s 转换为 Continuation c,但将 c.nargs 设置为 0 <= n <= 1426

8.6 Continuation 保存列表和控制寄存器的操作

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
ED4ic[i] PUSHCTR
c[i] PUSH
- x推送控制寄存器 c(i) 的当前值。如果当前代码页不支持该控制寄存器,或者它没有值,则触发异常。26
ED44c4 PUSHCTR
c4 PUSH
- x推送“全局数据根”cell引用,从而使访问持久智能合约数据成为可能。26
ED5ic[i] POPCTR
c[i] POP
x - 从栈中弹出一个值 x 并存储到控制寄存器 c(i) 中(如果当前代码页支持)。注意,如果控制寄存器仅接受特定类型的值,则可能发生类型检查异常。26
ED54c4 POPCTR
c4 POP
x -设置“全局数据根”cell引用,从而允许修改持久智能合约数据。26
ED6ic[i] SETCONT
c[i] SETCONTCTR
x c - c'x 存储到 continuation c 的 savelist 中作为 c(i),并返回结果 continuation c'。几乎所有与 continuations 的操作都可以用 SETCONTCTRPOPCTRPUSHCTR 来表达。26
ED7ic[i] SETRETCTRx - 等同于 c0 PUSHCTR c[i] SETCONTCTR c0 POPCTR26
ED8ic[i] SETALTCTRx - 等同于 c1 PUSHCTR c[i] SETCONTCTR c0 POPCTR26
ED9ic[i] POPSAVE
c[i] POPCTRSAVE
x -类似于 c[i] POPCTR,但还将 c[i] 的旧值保存到 continuation c0 中。
等同于(直到异常)c[i] SAVECTR c[i] POPCTR
26
EDAic[i] SAVE
c[i] SAVECTR
c(i) 的当前值保存到 continuation c0 的 savelist 中。如果 c0 的 savelist 中已存在 c[i] 的条目,则不做任何操作。等同于 c[i] PUSHCTR c[i] SETRETCTR26
EDBic[i] SAVEALT
c[i] SAVEALTCTR
类似于 c[i] SAVE,但将 c[i] 的当前值保存到 c1(而不是 c0)的 savelist 中。26
EDCic[i] SAVEBOTH
c[i] SAVEBOTHCTR
等同于 DUP c[i] SAVE c[i] SAVEALT26
EDE0PUSHCTRXi - x类似于 c[i] PUSHCTR,但 i, 0 <= i <= 255, 来自栈。
注意,这个原语是少数“异乎寻常”的原语之一,它们不像栈操作原语那样是多态的,同时参数和返回值的类型也没有良好定义,因为 x 的类型取决于 i
26
EDE1POPCTRXx i - 类似于 c[i] POPCTR,但 0 <= i <= 255 来自栈。26
EDE2SETCONTCTRXx c i - c'类似于 c[i] SETCONTCTR,但 0 <= i <= 255 来自栈。26
EDF0COMPOS
BOOLAND
c c' - c''计算组合 compose0(c, c’),它的意义为“执行 c,如果成功,执行 c'”(如果 c 是布尔电路)或简单地“执行 c,然后执行 c'”。等同于 SWAP c0 SETCONT26
EDF1COMPOSALT
BOOLOR
c c' - c''计算替代组合 compose1(c, c’),它的意义为“执行 c,如果不成功,执行 c'”(如果 c 是布尔电路)。等同于 SWAP c1 SETCONT26
EDF2COMPOSBOTHc c' - c''计算组合 compose1(compose0(c, c’), c’),它的意义为“计算布尔电路 c,然后无论 c 的结果如何,都计算 c'”。26
EDF3ATEXITc - c0 设置为 compose0(c, c0)。换句话说,c 将在退出当前子程序之前执行。26
EDF3ATEXIT:<{ code }>
<{ code }>ATEXIT
-等同于 <{ code }> CONT ATEXIT
EDF4ATEXITALTc - c1 设置为 compose1(c, c1)。换句话说,c 将在通过其替代返回路径退出当前子程序之前执行。26
EDF4ATEXITALT:<{ code }>
<{ code }>ATEXITALT
-等同于 <{ code }> CONT ATEXITALT
EDF5SETEXITALTc - c1 设置为 compose1(compose0(c, c0), c1)
这样,后续的 RETALT 将首先执行 c,然后将控制权转移给原始的 c0。例如,这可以用来从嵌套循环中退出。
26
EDF6THENRETc - c'计算 compose0(c, c0)26
EDF7THENRETALTc - c'计算 compose0(c, c1)26
EDF8INVERT-交换 c0c126
EDF9BOOLEVALc - ?执行 cc:=compose1(compose0(c, compose0(-1 PUSHINT, cc)), compose0(0 PUSHINT, cc))。如果 c 代表一个布尔电路,其最终效果是评估它,并在继续执行之前将 -10 推入栈中。26
EDFASAMEALT-c1 设置为 c0。等同于 c0 PUSHCTR c1 POPCTR26
EDFBSAMEALTSAVE-c1 设置为 c0,但首先将 c1 的旧值保存到 c0 的 savelist 中。
等同于 c1 SAVE SAMEALT
26

8.7 字典子程序调用和跳转

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F0nn[nn] CALL
[nn] CALLDICT
- nn调用 c3 中的 continuation,将整数 0 <= nn <= 255 作为参数推入其栈。
大致相当于 [nn] PUSHINT c3 PUSHCTR EXECUTE
F12_n[n] CALL
[n] CALLDICT
- n对于 0 <= n < 2^14,这是更大值的 n[n] CALL 的编码。
F16_n[n] JMP - n跳转到 c3 中的 continuation,将整数 0 <= n < 2^14 作为其参数推入。
大致相当于 n PUSHINT c3 PUSHCTR JMPX
F1A_n[n] PREPARE
[n] PREPAREDICT
- n c等同于 n PUSHINT c3 PUSHCTR,适用于 0 <= n < 2^14
这样,[n] CALL 大致等同于 [n] PREPARE EXECUTE,而 [n] JMP 大致等同于 [n] PREPARE JMPX
例如,这里可以使用 CALLXARGSCALLCC 代替 EXECUTE

9 异常产生与处理原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F22_n[n] THROW - 0 n抛出参数为零的 0 <= n <= 63 异常。
换句话说,它将控制权转移到 c2 中的continuation,将 0n 推入其堆栈,并彻底丢弃旧堆栈。
76
F26_n[n] THROWIFf - 只有当整数 f!=0 时,才抛出参数为零的 0 <= n <= 63 异常。26/76
F2A_n[n] THROWIFNOTf - 只有当整数 f=0 时,才抛出参数为零的 0 <= n <= 63 异常。26/76
F2C4_n[n] THROW- 0 nn对于 0 <= n < 2^11,是 [n] THROW 的编码,用于 n 的较大值。84
F2CC_n[n] THROWARGx - x nn抛出带有参数 x0 <= n < 2^11 异常,通过将 xn 复制到 c2 的堆栈并将控制权转移给 c284
F2D4_n[n] THROWIFf - 对于 0 <= n < 2^11,是 [n] THROWIF 的编码,用于 n 的较大值。34/84
F2DC_n[n] THROWARGIFx f - 只有当整数 f!=0 时,才抛出带有参数 x0 <= nn < 2^11 异常。34/84
F2E4_n[n] THROWIFNOTf - 对于 0 <= n < 2^11,是 [n] THROWIFNOT 的编码,用于 n 的较大值。34/84
F2EC_n[n] THROWARGIFNOTx f - 只有当整数 f=0 时,才抛出带有参数 x0 <= n < 2^11 异常。34/84
F2F0THROWANYn - 0 n抛出参数为零的 0 <= n < 2^16 异常。
大致相当于 ZERO SWAP THROWARGANY
76
F2F1THROWARGANYx n - x n抛出带有参数 x0 <= n < 2^16 异常,将控制权转移到 c2 中。
大致相当于 c2 PUSHCTR 2 JMPXARGS
76
F2F2THROWANYIFn f - 只有当 f!=0 时,才抛出参数为零的 0 <= n < 2^16 异常。26/76
F2F3THROWARGANYIFx n f - 只有当 f!=0 时,才抛出带有参数 x0 <= n<2^16 异常。26/76
F2F4THROWANYIFNOTn f - 只有当 f=0 时,才抛出参数为零的 0 <= n<2^16 异常。26/76
F2F5THROWARGANYIFNOTx n f - 只有当 f=0 时,才抛出带有参数 x0 <= n<2^16 异常。26/76
F2FFTRYc c' - 设置 c2c',首先将 c2 的旧值同时保存到 c' 的保存列表和当前continuation的保存列表中,该当前continuation存储到 c.c0c'.c0 中。然后类似于 EXECUTE 运行 c。如果 c 没有引发任何异常,从 c 返回时会自动恢复 c2 的原始值。如果发生异常,则执行权转移到 c',但在此过程中恢复了 c2 的原始值,以便 c' 可以通过 THROWANY 重新抛出异常(如果它自己无法处理)。26
F2FFTRY:<{ code1 }>CATCH<{ code2 }>-等效于 <{ code1 }> CONT <{ code2 }> CONT TRY
F3pr[p] [r] TRYARGSc c' - 类似于 TRY,但内部使用的是 [p] [r] CALLXARGS 而不是 EXECUTE
这样,顶部 0 <= p <= 15 堆栈元素以外的所有元素将保存到当前continuation的堆栈中,然后从 cc' 返回时恢复,并将 cc' 的结果堆栈的顶部 0 <= r <= 15 值作为返回值复制。
26

10 字典操作原语

大多数字典操作的燃气消耗不是固定的,它取决于给定字典的内容。

10.1 字典创建

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
6DNEWDICT - D返回一个新的空字典。
它是 PUSHNULL 的另一种助记符。
18
6EDICTEMPTYD - ?检查字典 D 是否为空,并相应地返回 -10
它是 ISNULL 的另一种助记符。
18

10.2 字典序列化与反序列化

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
CESTDICTS
``
s b - b'将以切片表示的字典 s 存储进构建器 b中。
实际上,这是 STSLICE 的同义词。
18
F400STDICT
STOPTREF
D b - b'将字典 D 存入构建器 b,返回结果 构建器 b'
换言之,如果 D 是一个cell,执行 STONESTREF;如果 DNull,执行 NIPSTZERO;否则抛出类型检查异常。
26
F401SKIPDICT
SKIPOPTREF
s - s'相当于 LDDICT NIP26
F402LDDICTSs - s' s''切片 s中加载(解析)以切片表示的字典 s',并将 s的剩余部分作为 s'' 返回。
这是所有 HashmapE(n,X) 类型字典的“分裂函数”。
26
F403PLDDICTSs - s'切片 s中预加载以切片表示的字典 s'
大致相当于 LDDICTS DROP
26
F404LDDICT
LDOPTREF
s - D s'切片 s中加载(解析)字典 D,并将 s的剩余部分作为 s' 返回。可应用于字典或任意 (^Y)? 类型的值。26
F405PLDDICT
PLDOPTREF
s - D切片 s中预加载字典 D
大致相当于 LDDICT DROP
26
F406LDDICTQs - D s' -1或 s 0LDDICT 的静默版本。26
F407PLDDICTQs - D -1或0PLDDICT 的静默版本。26

10.3 获取字典操作

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F40ADICTGETk D n - x -1或0在类型为 HashmapE(n,X) 且拥有 n-位键的字典 D 中查找键 k(由切片表示,其前 0 <= n <= 1023 数据位被用作键)。
成功时,以切片 x 的形式返回找到的值。
F40BDICTGETREFk D n - c -1或0DICTGET 类似,但在成功时对 x 应用 LDREF ENDS
此操作对于类型为 HashmapE(n,^Y) 的字典很有用。
F40CDICTIGETi D n - x -1或0DICTGET 类似,但使用带符号的(大端)n-位 整型 i 作为键。如果 i 不能放入 n 位,则返回 0。如果 iNaN,抛出整数溢出异常。
F40DDICTIGETREFi D n - c -1或0组合 DICTIGETDICTGETREF:它使用带符号的 n-位 整型 i 作为键,并在成功时返回 cell 而不是切片
F40EDICTUGETi D n - x -1或0DICTIGET 类似,但使用无符号的(大端)n-位 整型 i 作为键。
F40FDICTUGETREFi D n - c -1或0DICTIGETREF 类似,但使用一个无符号 n-位 整型i

10.4 设置/替换/添加字典操作

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F412DICTSETx k D n - D'在字典 D(同样用切片表示)中设置 n-位键 k(如 DICTGET 中用切片表示)关联的值为 x(再次是切片),并返回结果字典 D'
F413DICTSETREFc k D n - D'类似于 DICTSET,但设置的值为对cell c 的引用。
F414DICTISETx i D n - D'类似于 DICTSET,但键由(大端)有符号 n-位整数 i 表示。如果 i 不能放入 n 位,则生成范围检查异常。
F415DICTISETREFc i D n - D'类似于 DICTSETREF,但键由 DICTISET 中的有符号 n-位整数表示。
F416DICTUSETx i D n - D'类似于 DICTISET,但 i无符号 n-位整数。
F417DICTUSETREFc i D n - D'类似于 DICTISETREF,但 i 为无符号。
F41ADICTSETGETx k D n - D' y -1或 D' 0结合 DICTSETDICTGET:它将键 k 对应的值设置为 x,但也返回该键原有的旧值 y(如果存在)。
F41BDICTSETGETREFc k D n - D' c' -1或 D' 0类似于 DICTSETGETDICTSETREFDICTGETREF 的组合。
F41CDICTISETGETx i D n - D' y -1或 D' 0DICTISETGET,但 i 为有符号 n-位整数。
F41DDICTISETGETREFc i D n - D' c' -1或 D' 0DICTISETGETREF,但 i 为有符号 n-位整数。
F41EDICTUSETGETx i D n - D' y -1或 D' 0DICTISETGET,但 i 为无符号 n-位整数。
F41FDICTUSETGETREFc i D n - D' c' -1或 D' 0DICTISETGETREF,但 i 为无符号 n-位整数。
F422DICTREPLACEx k D n - D' -1或 D 0一个 替换 操作,类似于 DICTSET,但只有当键 k 已经存在于 D 中时才会将 D 中键 k 的值设置为 x
F423DICTREPLACEREFc k D n - D' -1或 D 0DICTSETREF替换 对应操作。
F424DICTIREPLACEx i D n - D' -1或 D 0DICTREPLACE,但 i 为有符号 n-位整数。
F425DICTIREPLACEREFc i D n - D' -1或 D 0DICTREPLACEREF,但 i 为有符号 n-位整数。
F426DICTUREPLACEx i D n - D' -1或 D 0DICTREPLACE,但 i 为无符号 n-位整数。
F427DICTUREPLACEREFc i D n - D' -1或 D 0DICTREPLACEREF,但 i 为无符号 n-位整数。
F42ADICTREPLACEGETx k D n - D' y -1或 D 0DICTSETGET替换 对应操作:成功时,还会返回与该键相关的旧值。
F42BDICTREPLACEGETREFc k D n - D' c' -1或 D 0DICTSETGETREF替换 对应操作。
F42CDICTIREPLACEGETx i D n - D' y -1或 D 0DICTREPLACEGET,但 i 为有符号 n-位整数。
F42DDICTIREPLACEGETREFc i D n - D' c' -1或 D 0DICTREPLACEGETREF,但 i 为有符号 n-位整数。
F42EDICTUREPLACEGETx i D n - D' y -1或 D 0DICTREPLACEGET,但 i 为无符号 n-位整数。
F42FDICTUREPLACEGETREFc i D n - D' c' -1或 D 0DICTREPLACEGETREF,但 i 为无符号 n-位整数。
F432DICTADDx k D n - D' -1或 D 0DICTSET添加 对应操作:在字典 D 中将与键 k 关联的值设置为 x,但只有当它还未在 D 中存在时。
F433DICTADDREFc k D n - D' -1或 D 0DICTSETREF添加 对应操作。
F434DICTIADDx i D n - D' -1或 D 0DICTADD,但 i 为有符号 n-位整数。
F435DICTIADDREFc i D n - D' -1或 D 0DICTADDREF,但 i 为有符号 n-位整数。
F436DICTUADDx i D n - D' -1或 D 0DICTADD,但 i 为无符号 n-位整数。
F437DICTUADDREFc i D n - D' -1或 D 0DICTADDREF,但 i 为无符号 n-位整数。
F43ADICTADDGETx k D n - D' -1或 D y 0DICTSETGET添加 对应操作:在字典 D 中将与键 k 关联的值设置为 x,但只有当键 k 还未在 D 中存在时。否则,仅返回旧值 y,不更改字典。
F43BDICTADDGETREFc k D n - D' -1或 D c' 0DICTSETGETREF添加 对应操作。
F43CDICTIADDGETx i D n - D' -1或 D y 0DICTADDGET,但 i 为有符号 n-位整数。
F43DDICTIADDGETREFc i D n - D' -1或 D c' 0DICTADDGETREF,但 i 为有符号 n-位整数。
F43EDICTUADDGETx i D n - D' -1或 D y 0DICTADDGET,但 i 为无符号 n-位整数。
F43FDICTUADDGETREFc i D n - D' -1或 D c' 0DICTADDGETREF,但 i 为无符号 n-位整数。

10.5 接受构建器的字典设置操作变体

以下操作接受新值作为构建器 b,而不是切片 x。 | xxxxxxx
操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法 | xxxxxxxxxxxxxxxxx
堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述 | xxxx
Gas | |:-|:-|:-|:-|:-| | F441 | DICTSETB | b k D n - D' | | | | F442 | DICTISETB | b i D n - D' | | | | F443 | DICTUSETB | b i D n - D' | | | | F445 | DICTSETGETB | b k D n - D' y -1或 D' 0 | | | | F446 | DICTISETGETB | b i D n - D' y -1或 D' 0 | | | | F447 | DICTUSETGETB | b i D n - D' y -1或 D' 0 | | | | F449 | DICTREPLACEB | b k D n - D' -1或 D 0 | | | | F44A | DICTIREPLACEB | b i D n - D' -1或 D 0 | | | | F44B | DICTUREPLACEB | b i D n - D' -1或 D 0 | | | | F44D | DICTREPLACEGETB | b k D n - D' y -1或 D 0 | | | | F44E | DICTIREPLACEGETB | b i D n - D' y -1或 D 0 | | | | F44F | DICTUREPLACEGETB | b i D n - D' y -1或 D 0 | | | | F451 | DICTADDB | b k D n - D' -1或 D 0 | | | | F452 | DICTIADDB | b i D n - D' -1或 D 0 | | | | F453 | DICTUADDB | b i D n - D' -1或 D 0 | | | | F455 | DICTADDGETB | b k D n - D' -1或 D y 0 | | | | F456 | DICTIADDGETB | b i D n - D' -1或 D y 0 | | | | F457 | DICTUADDGETB | b i D n - D' -1或 D y 0 | | |

10.6 删除字典操作

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F459DICTDELk D n - D' -1或 D 0从字典 D 中删除由切片 k 表示的 n-位键。如果键存在,返回修改后的字典 D' 和成功标志位 -1。否则,返回原始字典 D0
F45ADICTIDELi D n - D' ?DICTDEL 的一个版本,键由有符号的 n-位 整数 i 表示。如果 i 不能放入 n 位,简单地返回 D 0(“键未找到,字典未修改”)。
F45BDICTUDELi D n - D' ?类似于 DICTIDEL,但 i 为无符号的 n-位整数。
F462DICTDELGETk D n - D' x -1或 D 0从字典 D 中删除由切片 k 表示的 n-位键。如果键存在,返回修改后的字典 D'、与键 k 关联的原始值 x(由切片表示),和成功标志位 -1。否则,返回原始字典 D0
F463DICTDELGETREFk D n - D' c -1或 D 0类似于 DICTDELGET,但成功时对 x 应用 LDREF ENDS,以便返回的值 c 是一个cell
F464DICTIDELGETi D n - D' x -1或 D 0DICTDELGET,但 i 为有符号的 n-位整数。
F465DICTIDELGETREFi D n - D' c -1或 D 0DICTDELGETREF,但 i 为有符号的 n-位整数。
F466DICTUDELGETi D n - D' x -1或 D 0DICTDELGET,但 i 为无符号的 n-位整数。
F467DICTUDELGETREFi D n - D' c -1或 D 0DICTDELGETREF,但 i 为无符号的 n-位整数。

10.7 “可能是引用”的字典操作

以下操作假设使用字典存储类型为可能是cell(Maybe Cell)的值 c?。表示如下:如果 c? 是一个cell,它作为一个没有数据位且恰好有一个对这个cell的引用的值存储。如果 c?Null,则对应的键必须从字典中缺失。

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F469DICTGETOPTREFk D n - c^?DICTGETREF 的一个变体,如果键 k 不存在于字典 D 中,则返回 Null 而不是值 c^?
F46ADICTIGETOPTREFi D n - c^?DICTGETOPTREF 的版本,但 i 为有符号的 n-位整数。如果键 i 超出范围,也返回 Null
F46BDICTUGETOPTREFi D n - c^?DICTGETOPTREF 的版本,但 i 为无符号的 n-位整数。如果键 i 超出范围,也返回 Null
F46DDICTSETGETOPTREFc^? k D n - D' ~c^?DICTGETOPTREFDICTSETGETREF 的一个变体,将字典 D 中键 k 对应的值设置为 c^?(如果 c^?Null,则删除该键),并返回旧值 ~c^?(如果键 k 之前缺失,返回Null)。
F46EDICTISETGETOPTREFc^? i D n - D' ~c^?类似于 DICTSETGETOPTREF 的原语,但使用有符号的 n-位 整数 i 作为键。如果 i 不能放入 n 位,抛出范围检查异常。
F46FDICTUSETGETOPTREFc^? i D n - D' ~c^?类似于 DICTSETGETOPTREF 的原语,但使用无符号的 n-位 整数 i 作为键。

10.8 前缀码字典操作

构建前缀码字典的一些基本操作。 这些原语与它们非前缀码(DICTSET 等)的对应操作完全相同,不过在前缀码字典中,即使是 Set 也可能失败,因此 PFXDICTSET 也必须返回成功标志位。

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F470PFXDICTSETx k D n - D' -1或 D 0
F471PFXDICTREPLACEx k D n - D' -1或 D 0
F472PFXDICTADDx k D n - D' -1或 D 0
F473PFXDICTDELk D n - D' -1或 D 0

10.9 GetNext 和 GetPrev 操作的变体

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F474DICTGETNEXTk D n - x' k' -1或 0计算字典 D 中字典序大于 k 的最小键 k',并返回 k'(由切片表示)及其关联的值 x'(也由切片表示)。
F475DICTGETNEXTEQk D n - x' k' -1或 0类似于 DICTGETNEXT,但计算字典序大于或等于 k 的最小键 k'
F476DICTGETPREVk D n - x' k' -1或 0类似于 DICTGETNEXT,但计算字典序小于 k 的最大键 k'
F477DICTGETPREVEQk D n - x' k' -1或 0类似于 DICTGETPREV,但计算字典序小于或等于 k 的最大键 k'
F478DICTIGETNEXTi D n - x' i' -1或 0类似于 DICTGETNEXT,但将字典 D 中的所有键解释为大端有符号的 n-位整数,并计算大于整数 i 的最小键 i'i 不一定能放入 n 位)。
F479DICTIGETNEXTEQi D n - x' i' -1或 0类似于 DICTGETNEXTEQ,但将键解释为有符号的 n-位整数。
F47ADICTIGETPREVi D n - x' i' -1或 0类似于 DICTGETPREV,但将键解释为有符号的 n-位整数。
F47BDICTIGETPREVEQi D n - x' i' -1或 0类似于 DICTGETPREVEQ,但将键解释为有符号的 n-位整数。
F47CDICTUGETNEXTi D n - x' i' -1或 0类似于 DICTGETNEXT,但将字典 D 中的所有键解释为大端无符号的 n-位整数,并计算大于整数 i 的最小键 i'i 不一定能放入 n 位,也不一定是非负的)。
F47DDICTUGETNEXTEQi D n - x' i' -1或 0类似于 DICTGETNEXTEQ,但将键解释为无符号的 n-位整数。
F47EDICTUGETPREVi D n - x' i' -1或 0类似于 DICTGETPREV,但将键解释为无符号的 n-位整数。
F47FDICTUGETPREVEQi D n - x' i' -1或 0类似于 DICTGETPREVEQ,但将键解释为无符号的 n-位整数。

10.10 GetMin, GetMax, RemoveMin, RemoveMax 操作

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F482DICTMIND n - x k -1或 0计算字典 D 中的最小键 k(由拥有 n 数据位的切片表示),并返回 k 及其关联的值 x
F483DICTMINREFD n - c k -1或 0类似于 DICTMIN,但返回值中唯一的引用作为cell c
F484DICTIMIND n - x i -1或 0类似于 DICTMIN,但在假设所有键为大端有符号的 n-位整数的情况下计算最小键 i。注意,返回的键和值可能与 DICTMINDICTUMIN 计算出的不同。
F485DICTIMINREFD n - c i -1或 0类似于 DICTIMIN,但返回值中唯一的引用。
F486DICTUMIND n - x i -1或 0类似于 DICTMIN,但以无符号 n-位 整数 i 的形式返回键。
F487DICTUMINREFD n - c i -1或 0类似于 DICTUMIN,但返回值中唯一的引用。
F48ADICTMAXD n - x k -1或 0计算字典 D 中的最大键 k(由拥有 n 数据位的切片表示),并返回 k 及其关联的值 x
F48BDICTMAXREFD n - c k -1或 0类似于 DICTMAX,但返回值中唯一的引用。
F48CDICTIMAXD n - x i -1或 0类似于 DICTMAX,但在假设所有键为大端有符号的 n-位整数的情况下计算最大键 i。注意,返回的键和值可能与 DICTMAXDICTUMAX 计算出的不同。
F48DDICTIMAXREFD n - c i -1或 0类似于 DICTIMAX,但返回值中唯一的引用。
F48EDICTUMAXD n - x i -1或 0类似于 DICTMAX,但以无符号 n-位 整数 i 的形式返回键。
F48FDICTUMAXREFD n - c i -1或 0类似于 DICTUMAX,但返回值中唯一的引用。
F492DICTREMMIND n - D' x k -1或D 0计算字典 D 中的最小键 k(以n数据位的切片形式表示),从字典中移除 k,并返回 k 及其关联的值 x 和修改后的字典 D'
F493DICTREMMINREFD n - D' c k -1或D 0类似于 DICTREMMIN,但返回值中唯一的引用作为cell c
F494DICTIREMMIND n - D' x i -1或D 0类似于 DICTREMMIN,但计算最小键 i,假设所有键都是大端有符号的n-位整数。请注意,返回的键和值可能与DICTREMMINDICTUREMMIN计算的不同。
F495DICTIREMMINREFD n - D' c i -1或D 0类似于 DICTIREMMIN,但返回值中唯一的引用。
F496DICTUREMMIND n - D' x i -1或D 0类似于 DICTREMMIN,但以无符号n-位整数 i 形式返回键。
F497DICTUREMMINREFD n - D' c i -1或D 0类似于 DICTUREMMIN,但返回值中唯一的引用。
F49ADICTREMMAXD n - D' x k -1或D 0计算字典 D 中的最大键 k(以n数据位的切片形式表示),从字典中移除 k,并返回 k 及其关联的值 x 和修改后的字典 D'
F49BDICTREMMAXREFD n - D' c k -1或D 0类似于 DICTREMMAX,但返回值中唯一的引用作为cell c
F49CDICTIREMMAXD n - D' x i -1或D 0类似于 DICTREMMAX,但计算最大键 i,假设所有键都是大端有符号的n-位整数。请注意,返回的键和值可能与DICTREMMAXDICTUREMMAX计算的不同。
F49DDICTIREMMAXREFD n - D' c i -1或D 0类似于 DICTIREMMAX,但返回值中唯一的引用。
F49EDICTUREMMAXD n - D' x i -1或D 0类似于 DICTREMMAX,但以无符号n-位整数 i 形式返回键。
F49FDICTUREMMAXREFD n - D' c i -1或D 0类似于 DICTUREMMAX,但返回值中唯一的引用。

10.11 特殊的获取字典和前缀码字典操作以及常量字典

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F4A0DICTIGETJMPi D n - 类似于 DICTIGET,但在成功时将 x BLESS 成一个continuation,并随后执行对其的 JMPX。失败时不执行任何操作。这对于实现 switch/case 结构很有用。
F4A1DICTUGETJMPi D n - 类似于 DICTIGETJMP,但执行 DICTUGET 而非 DICTIGET
F4A2DICTIGETEXECi D n - 类似于 DICTIGETJMP,但使用 EXECUTE 而非 JMPX
F4A3DICTUGETEXECi D n - 类似于 DICTUGETJMP,但使用 EXECUTE 而非 JMPX
F4A6_n[ref] [n] DICTPUSHCONST - D n推送非空常量字典 D(作为Cell^?)和其键长 0 <= n <= 1023,存储为指令的一部分。字典本身是从当前continuation的剩余引用中的第一个创建的。通过这种方式,完整的 DICTPUSHCONST 指令可以通过首先序列化 xF4A4_,然后是非空字典本身(一个 1 位和一个cell引用),然后是无符号的 10 位整数 n(仿佛通过 STU 10 指令)获得。空字典可以通过 NEWDICT 原语推送。34
F4A8PFXDICTGETQs D n - s' x s'' -1或s 0在前缀码字典中查找切片 s 的唯一前缀,该字典由 Cell^? D0 <= n <= 1023 表示。如果找到,作为 s' 返回 s 的前缀,并作为切片 x 返回相应的值。s 的剩余部分作为切片 s'' 返回。如果 s 的任何前缀不是前缀码字典 D 中的键,则返回未更改的 s 和零标志位以表示失败。
F4A9PFXDICTGETs D n - s' x s''类似于 PFXDICTGET,但在失败时抛出cell反序列化失败异常。
F4AAPFXDICTGETJMPs D n - s' s''或s类似于 PFXDICTGETQ,但成功时将值 x BLESS 成一个continuation,并像执行 JMPX 一样转移控制权。失败时,返回未改变的 s 并继续执行。
F4ABPFXDICTGETEXECs D n - s' s''类似于 PFXDICTGETJMP,但执行找到的continuation而非跳转它。失败时,抛出cell反序列化异常。
F4AE_n[ref] [n] PFXDICTCONSTGETJMP
[ref] [n] PFXDICTSWITCH
s - s' s''或s[n] DICTPUSHCONSTPFXDICTGETJMP 结合起来,用于 0 <= n <= 1023
F4BCDICTIGETJMPZi D n - i或nothingDICTIGETJMP 的一个变种,在失败时返回索引 i
F4BDDICTUGETJMPZi D n - i或nothingDICTUGETJMP 的一个变种,在失败时返回索引 i
F4BEDICTIGETEXECZi D n - i或nothingDICTIGETEXEC 的一个变种,在失败时返回索引 i
F4BFDICTUGETEXECZi D n - i或nothingDICTUGETEXEC 的一个变种,在失败时返回索引 i

10.12 SubDict 字典操作

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F4B1SUBDICTGETk l D n - D'构建一个由所有以前缀 k(由一个切片表示,其前 0 <= l <= n <= 1023 个数据位用作键)为前缀的字典 D 中的键组成的子字典。这里的 D 是类型为 HashmapE(n,X) 的字典,拥有 n 位的键。成功时,返回同类型 HashmapE(n,X) 的新子字典作为一个切片 D'
F4B2SUBDICTIGETx l D n - D'SUBDICTGET 的变体,前缀由有符号的大端 l-位整数 x 表示,必须满足 l <= 257
F4B3SUBDICTUGETx l D n - D'SUBDICTGET 的变体,前缀由无符号的大端 l-位整数 x 表示,必须满足 l <= 256
F4B5SUBDICTRPGETk l D n - D'类似于 SUBDICTGET,但从新字典 D' 的所有键中移除公共前缀 k,它变为 HashmapE(n-l,X) 类型。
F4B6SUBDICTIRPGETx l D n - D'SUBDICTRPGET 的变体,前缀由有符号的大端 l-位整数 x 表示,必须满足 l <= 257
F4B7SUBDICTURPGETx l D n - D'SUBDICTRPGET 的变体,前缀由无符号的大端 l-位整数 x 表示,必须满足 l <= 256

11 应用特定原语

11.1 与 Gas 相关的原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F800ACCEPT-将当前的 Gas 限制 g_l 设置为其允许的最大值 g_m,并将 Gas 信用 g_c 重置为零,同时减少 g_r 的值 g_c
换句话说,当前的智能合约同意购买一些 Gas 以完成当前交易。此操作是处理外部消息所必需的,这些消息本身不携带价值(因而没有 Gas)。
26
F801SETGASLIMITg - 将当前的 Gas 限制 g_l 设置为 gg_m 的最小值,并将 Gas 信用 g_c 重置为零。如果到目前为止所消耗的 Gas(包括当前指令)超过了所得的 g_l 值,则在设置新的 Gas 限制之前抛出(未处理的)Gas 超限异常。请注意,带有参数 g >= 2^63-1SETGASLIMIT 等同于 ACCEPT26
F80FCOMMIT-提交寄存器 c4(“持久数据”)和 c5(“操作”)的当前状态,以便即使后来抛出异常,当前执行也被视为“成功”,并保存了这些值。26

11.2 伪随机数生成器原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F810RANDU256- x生成一个新的伪随机的无符号 256 位 整数 x。算法如下: 如果 r 是旧的随机种子值,被视为一个 32 字节的数组(通过构造一个无符号 256 位整数的大端表示),则计算其 sha512(r);这个哈希的前 32 字节被存储为新的随机种子值 r',剩下的 32 字节作为下一个随机值 x 返回。26+\|c7\|+\|c1_1\|
F811RANDy - z0...y-1(或 y...-1, 如果 y<0)范围内生成一个新的伪随机整数 z。更确切地说,生成一个无符号随机值 x,如同在 RAND256U 中;然后计算 z:=floor(x*y/2^256)
等同于 RANDU256 256 MULRSHIFT.
26+\|c7\|+\|c1_1\|
F814SETRANDx - 将随机种子设置为无符号 256 位 整数 x26+\|c7\|+\|c1_1\|
F815ADDRAND
RANDOMIZE
x - 将无符号 256 位 整数 x 混入随机种子 r 中,通过将随机种子设为两个 32 字节字符串的连结的 Sha,第一个字符串以旧种子 r 的大端表示,第二个字符串以 x 的大端表示。26

11.3 配置原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F82i[i] GETPARAM - x从提供于 c7元组 中返回第 i 个参数,对于 0 <= i <= 15。等同于 c7 PUSHCTR FIRST [i] INDEX.
如果这些内部操作之一失败,则抛出相应的类型检查或范围检查异常。
26
F823NOW - x返回当前 Unix 时间作为一个 整数。如果从 c7 开始无法恢复请求的值,则抛出类型检查或范围检查异常。
等同于 3 GETPARAM.
26
F824BLOCKLT - x返回当前区块的开始逻辑时间。
等同于 4 GETPARAM.
26
F825LTIME - x返回当前交易的逻辑时间。
等同于 5 GETPARAM.
26
F826RANDSEED - x以无符号 256 位 整数 的形式返回当前的随机种子。
等同于 6 GETPARAM.
26
F827BALANCE - t元组 形式返回智能合约剩余的余额,元组 包含一个 整数(剩余的Gram余额,以nanograms为单位)和一个 可能的cell(以 32 位键表示的“额外代币”的余额字典)。
等同于 7 GETPARAM.
请注意,如 SENDRAWMSGRAW 原语不会更新此字段。
26
F828MYADDR - s分片 形式返回当前智能合约的内部地址,包含一个 MsgAddressInt。如果必要,可以使用诸如 PARSEMSGADDRREWRITESTDADDR 之类的原语进一步解析它。
等同于 8 GETPARAM.
26
F829CONFIGROOT - D可能的cell D 形式返回当前全局配置字典。等同于 9 GETPARAM 26
F830CONFIGDICT - D 32返回全局配置字典及其键长(32)。
等同于 CONFIGROOT 32 PUSHINT.
26
F832CONFIGPARAMi - c -1 或 0cell c 的形式返回整数索引 i 的全局配置参数的值,以及指示成功的标志位。
等同于 CONFIGDICT DICTIGETREF.
F833CONFIGOPTPARAMi - c^?可能的cell c^? 的形式返回整数索引 i 的全局配置参数的值。
等同于 CONFIGDICT DICTIGETOPTREF.

11.4 全局变量原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F840GETGLOBVARk - x返回第 k 个全局变量,对于 0 <= k < 255
相当于 c7 PUSHCTR SWAP INDEXVARQ
26
F85_k[k] GETGLOB - x返回第 k 个全局变量,对于 1 <= k <= 31
相当于 c7 PUSHCTR [k] INDEXQ
26
F860SETGLOBVARx k - x 分配给第 k 个全局变量,对于 0 <= k < 255
相当于 c7 PUSHCTR ROTREV SETINDEXVARQ c7 POPCTR
26+\|c7’\|
F87_k[k] SETGLOBx - x 分配给第 k 个全局变量,对于 1 <= k <= 31
相当于 c7 PUSHCTR SWAP k SETINDEXQ c7 POPCTR
26+\|c7’\|

11.5 哈希和密码学原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F900HASHCUc - x计算 cell c 的表示哈希,并将其作为 256 位无符号整数 x 返回。用于对由cell树表示的任意实体进行签名和检查签名。26
F901HASHSUs - x计算 分片 s 的哈希,并将其作为 256 位无符号整数 x 返回。结果与如果创建了一个仅包含 s 的数据和引用的普通cell并通过 HASHCU 计算其哈希相同。526
F902SHA256Us - x分片 s 的数据位计算 Sha。如果 s 的位长度不能被八整除,抛出一个cell下溢异常。哈希值作为 256 位无符号整数 x 返回。26
F910CHKSIGNUh s k - ?使用公钥 k(也用一个 256 位无符号整数表示)检查哈希 h(通常作为某些数据的哈希,为一个 256 位无符号整数)的 Ed25519 签名 s
签名 s 必须是至少包含 512 位数据的 分片;仅使用前 512 位。结果为 -1 则签名有效,否则为 0
请注意,CHKSIGNU 相当于 ROT NEWC 256 STU ENDC ROTREV CHKSIGNS,即,相当于用第一个参数 d 设置为包含 h 的 256 位 分片CHKSIGNS。因此,如果 h 是作为某些数据的哈希计算的,这些数据会被 两次 哈希,第二次哈希发生在 CHKSIGNS 内部。
26
F911CHKSIGNSd s k - ?检查 s 是否是使用公钥 k分片 d 的数据部分的有效 Ed25519 签名,类似于 CHKSIGNU。如果 分片 d 的位长度不能被八整除,抛出一个cell下溢异常。Ed25519 签名的验证是标准的,使用 Shad 缩减为实际签名的 256 位数字。26

11.6 其他原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
F940CDATASIZEQc n - x y z -1 或 0递归计算以 cell c 为根的 dag 中不同cell x、数据位 y 和cell引用 z 的计数,有效地返回考虑等价cell标识时该 dag 使用的总存储量。xyz 的值通过该 dag 的深度优先遍历来计算,使用访问过的cell哈希表来防止已访问cell的重复访问。访问的cell总数 x 不能超过非负 整数 n;否则,在访问第 (n+1) 个cell之前计算被中断,并返回零表示失败。如果 c,则返回 x=y=z=0
F941CDATASIZEc n - x y zCDATASIZEQ 的非静默版本,失败时抛出cell溢出异常(8)。
F942SDATASIZEQs n - x y z -1 或 0类似于 CDATASIZEQ,但接受一个 分片 s 而非 cell。返回的 x 值不包括包含切片 s 本身的cell;然而,s 的数据位和cell引用在 yz 中被计算在内。
F943SDATASIZEs n - x y zSDATASIZEQ 的非静默版本,失败时抛出cell溢出异常(8)。

11.7 代币操作原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
FA00LDGRAMS
LDVARUINT16
s - x s'分片 s 中加载(反序列化)一个 GramVarUInteger 16 数量,并以 整数 x 形式返回数量及 s 的剩余部分 s'x 的预期序列化格式包括一个 4 位无符号大端整数 l,随后是 x 的一个 8l 位无符号大端表示。
其效果大致等同于 4 LDU SWAP 3 LSHIFT# LDUX
26
FA01LDVARINT16s - x s'LDVARUINT16 相似,但加载一个 有符号 整数 x
大致等同于 4 LDU SWAP 3 LSHIFT# LDIX
26
FA02STGRAMS
STVARUINT16
b x - b'将范围为 0...2^120-1 内的 整数 x 存储(序列化)到 构建器 b 中,并返回 构建器 b'的结果。x 的序列化格式包括一个 4 位无符号大端整数 l,这是满足 x<2^(8l) 的最小的 l>=0 整数,随后是 x 的一个 8l 位无符号大端表示。如果 x 不在支持的范围内,则抛出范围检查异常。26
FA03STVARINT16b x - b'类似于 STVARUINT16,但序列化一个范围为 -2^119...2^119-1有符号 整数 x26

11.8 消息和地址操作原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
FA40LDMSGADDRs - s' s''分片 s 中加载唯一有效的 MsgAddress 前缀,并将该前缀 s's 的剩余部分 s'' 作为分片返回。26
FA41LDMSGADDRQs - s' s'' -1 或 s 0LDMSGADDR 的静默版本:成功时额外推送 -1;失败时推送原始 s 和零。26
FA42PARSEMSGADDRs - t将包含有效 MsgAddress分片 s 分解为一个具有此 MsgAddress 独立字段的 元组 t。如果 s 不是有效的 MsgAddress,则抛出cell反序列化异常。26
FA43PARSEMSGADDRQs - t -1 或 0PARSEMSGADDR 的静默版本:错误时返回零而不是抛出异常。26
FA44REWRITESTDADDRs - x y解析包含有效 MsgAddressInt(通常是 msg_addr_std)的 分片 s,应用从 anycast(如果存在)到地址的相同长度前缀的重写,并以整数形式返回工作链 x 和 256 位地址 y。如果地址不是 256 位的,或者如果 s 不是有效的 MsgAddressInt 序列化,则抛出cell反序列化异常。26
FA45REWRITESTDADDRQs - x y -1 或 0原语 REWRITESTDADDR 的静默版本。26
FA46REWRITEVARADDRs - x s'REWRITESTDADDR 的变体,即使地址不是完全为 256 位长(由 msg_addr_var 表示),也返回(重写的)地址作为 分片 s26
FA47REWRITEVARADDRQs - x s' -1 或 0原语 REWRITEVARADDR 的静默版本。26

11.9 出站消息和输出操作原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
FB00SENDRAWMSGc x - 发送包含在 cell c 中的原始消息,其中应包含正确序列化的对象 Message X,唯一的例外是源地址允许有虚拟值 addr_none(将自动替换为当前智能合约地址),且 ihr_feefwd_feecreated_ltcreated_at 字段可以有任意值(在当前交易的操作阶段将被正确值重写)。整数参数 x 包含标志位。当前 x=0 用于普通消息;x=128 用于携带当前智能合约所有剩余余额的消息(而非消息最初指示的值);x=64 用于携带除初始指示的新消息值外,入站消息的所有剩余值的消息(如果未设置位 0,则此金额中扣除 gas 费用);x'=x+1 表示发送者想要单独支付转账费用;x'=x+2 表示在操作阶段处理此消息时发生的任何错误都应被忽略。最后,x'=x+32 意味着如果当前账户的最终余额为零,则必须销毁该账户。这个标志位通常与 +128 一起使用。526
FB02RAWRESERVEx y - 创建一个输出操作,该操作将从账户的剩余余额中准确预留 x nanograms(如果 y=0),最多 x nanograms(如果 y=2),或除 x nanograms外的所有nanograms(如果 y=1y=3)。这大致相当于创建一个携带 x nanograms(或 b-x nanograms,其中 b 是剩余余额)到自己的出站消息,以便后续输出操作无法花费超过剩余金额的资金。y 中的位 +2 表明,如果无法预留指定金额,外部操作不会失败;相反,将预留所有剩余余额。y 中的位 +8 表示在执行任何进一步操作之前 x:=-xy 中的位 +4 表示在执行任何其他检查和操作之前,x 会增加当前帐户(在计算阶段之前)的原始余额,包括所有额外货币。当前 x 必须是非负整数,且 y 必须在 0...15 范围内。526
FB03RAWRESERVEXx D y - 类似于 RAWRESERVE,但也接受一个代表额外代币的字典 D(由 cell 表示)。这种方式可以预留Grams以外的货币。526
FB04SETCODEc - 创建一个输出操作,该操作将此智能合约代码更改为由 cell c 给出的代码。请注意,此更改仅在当前智能合约运行成功终止后生效。526
FB06SETLIBCODEc x - 创建一个输出操作,用于修改此智能合约库的集合,通过添加或移除在 cell c 中给定代码的库。如果 x=0,若库先前存在于集合中,则实际上会被移除(如果不存在,则此操作无效)。如果 x=1,则库被作为私有库添加;如果 x=2,则库被作为公共库添加(如果当前智能合约位于主链中,则变得对所有智能合约可用);如果库之前已存在于集合中,则其公共/私有状态将根据 x 改变。另外,16 可以加到 x 上,以在失败时启用弹回交易。x 的值除了 0...2 (+16 可能) 之外都是无效的。526
FB07CHANGELIBh x - 类似于 SETLIBCODE,创建一个输出操作,但它接受库的哈希而非库代码,哈希以无符号 256 位整数 h 的形式给出。如果 x!=0 且该智能合约的库集合中不存在哈希值为 h 的库,此输出操作将失败。526

12 调试原语

FE 开头的操作码保留给调试原语使用。这些原语具有已知的固定操作长度,并且作为(多字节)NOP 操作行为。

然而,当在启用调试模式的 TVM 实例中调用时,这些原语可以产生特定输出到 TVM 实例的文本调试日志中,不影响 TVM 状态。

DEBUGDEBUGSTR 是两个调试原语,它们涵盖了所有以 FE 开头的操作码。当调试启用时,这里列出的其他原语具有其指定的效果。当调试禁用时,它们表现为 NOP

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
FEnn{nn} DEBUG-0 <= nn < 24026
FEFnssss{string} DEBUGSTR
{string} {x} DEBUGSTRI
-0 <= n < 16ssss 的长度为 n+1 字节。
{string} 是一个字符串字面量
DEBUGSTR: ssss 是给定的字符串。
DEBUGSTRI: ssss 是由一个字节的整数 0 <= x <= 255 加上给定字符串组成。
26
FE00DUMPSTK-转储堆栈(最多顶部 255 个值)并显示总堆栈深度。26
FE2is[i] DUMP-转储 s[i]26

13 代码页原语

xxxxxxx
操作码
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fift 语法
xxxxxxxxxxxxxxxxx
堆栈
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
描述
xxxx
Gas
FFnn[nn] SETCP-选择 TVM 代码页 0 <= nn < 240。如果不支持代码页,则抛出无效的操作码异常。26
FF00SETCP0-选择本文档描述的 TVM(测试)代码页零。26
FFFz[z-16] SETCP-选择 TVM 代码页 z-16,适用于 1 <= z <= 15。负代码页 -13...-1 保留用于验证其他代码页中 TVM 运行所需的限制性 TVM 版本。负代码页 -14 保留用于实验性代码页,不一定在不同 TVM 实现之间兼容,并且应在 TVM 的生产版本中禁用。26
FFF0SETCPXc - 选择通过栈顶传入的代码页 c-2^15 <= c < 2^1526

参阅