TVM 指令
此信息是非常底层的,对于新手来讲可能很难理解。
介绍
本文档提供了TVM指令的列表,包括它们的操作码和助记符。
TVM.pdf 最初概念 TON 虚拟机(可能包含过时的信息)。
Fift 是一种基于栈的编程语言,旨在管理 TON 智能合约。Fift 汇编器是一个能够将 TVM 指令的助记符转换为它们的二进制表示形式的 Fift 库。
关于 Fift 的描述,包括介绍 Fift 汇编器,可在此处找到。
本文档为每个指令指定了对应的助记符。
请注意以下几点:
- Fift 是一种基于栈的语言,因此任何指令的所有参数都写在它之前(例如,
5 PUSHINT
,s0 s4 XCHG
)。 - 栈寄存器由
s0, s1, ..., s15
表示。其他栈寄存器(最多255个)由i s()
表示(例如,100 s()
)。 - 控制寄存器由
c0, c1, ..., c15
表示。
Gas 价格
本文档中指定了每个指令的 gas 价格。一个指令的基本 gas 价格是 10 + b
,其中 b
是指令长度(以位为单位)。某些操作有附加费用:
- 解析cell:将一个cell转换成一个片段的成本是 100 gas 单位,如果是在同一交易中首次加载该cell,则为 25。对于此类指令,会指定两个 gas 价格(例如,
CTOS
:118/43
)。 - cell创建:500 gas 单位。
- 抛出异常:50 gas 单位。在本文档中,仅对其主要用途为抛出异常的指令指定异常费(例如,
THROWIF
,FITS
)。如果指令在某些情况下只抛出异常,则会指定两个 gas 价格(例如,FITS
:26/76
)。 - 元组创建:每个元组元素 1 gas 单位。
- 隐式跳转:对于一个隐式跳转,10 gas 单位;对于隐式后跳,5 gas 单位。这项费用不属于任何指令的一部分。
- 在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 |
---|---|---|---|---|
00 | NOP | - | 无操作。 | 18 |
01 | SWAP | x y - y x | 等同于 s1 XCHG0 。 | 18 |
0i | s[i] XCHG0 | 交换 s0 与 s[i] ,1 <= i <= 15 。 | 18 | |
10ij | s[i] s[j] XCHG | 交换 s[i] 与 s[j] ,1 <= i < j <= 15 。 | 26 | |
11ii | s0 [ii] s() XCHG | 交换 s0 与 s[ii] ,0 <= ii <= 255 。 | 26 | |
1i | s1 s[i] XCHG | 交换 s1 与 s[i] ,2 <= i <= 15 。 | 18 | |
2i | s[i] PUSH | 将旧的 s[i] 的一个副本推入堆栈。 | 18 | |
20 | DUP | x - x x | 等同于 s0 PUSH 。 | 18 |
21 | OVER | x y - x y x | 等同于 s1 PUSH 。 | 18 |
3i | s[i] POP | 将旧的 s0 值弹出到旧的 s[i] 中。等同于 s[i] XCHG0 DROP | 18 | |
30 | DROP | x - | 等同于 s0 POP ,丢弃堆栈顶部值。 | 18 |
31 | NIP | x y - y | 等同于 s1 POP 。 | 18 |
2.2 复杂堆栈操作原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
4ijk | s[i] s[j] s[k] XCHG3 | 等同于 s2 s[i] XCHG s1 s[j] XCHG s[k] XCHG0 。 | 26 | |
50ij | s[i] s[j] XCHG2 | 等同于 s1 s[i] XCHG s[j] XCHG0 。 | 26 | |
51ij | s[i] s[j] XCPU | 等同于 s[i] XCHG0 s[j] PUSH 。 | 26 | |
52ij | s[i] s[j-1] PUXC | 等同于 s[i] PUSH SWAP s[j] XCHG0 。 | 26 | |
53ij | s[i] s[j] PUSH2 | 等同于 s[i] PUSH s[j+1] PUSH 。 | 26 | |
540ijk | s[i] s[j] s[k] XCHG3_l | XCHG3 的长格式。 | 34 | |
541ijk | s[i] s[j] s[k] XC2PU | 等同于 s[i] s[j] XCHG2 s[k] PUSH 。 | 34 | |
542ijk | s[i] s[j] s[k-1] XCPUXC | 等同于 s1 s[i] XCHG s[j] s[k-1] PUXC 。 | 34 | |
543ijk | s[i] s[j] s[k] XCPU2 | 等同于 s[i] XCHG0 s[j] s[k] PUSH2 。 | 34 | |
544ijk | s[i] s[j-1] s[k-1] PUXC2 | 等同于 s[i] PUSH s2 XCHG0 s[j] s[k] XCHG2 。 | 34 | |
545ijk | s[i] s[j-1] s[k-1] PUXCPU | 等同于 s[i] s[j-1] PUXC s[k] PUSH 。 | 34 | |
546ijk | s[i] s[j-1] s[k-2] PU2XC | 等同于 s[i] PUSH SWAP s[j] s[k-1] PUXC 。 | 34 | |
547ijk | s[i] s[j] s[k] PUSH3 | 等同于 s[i] PUSH s[j+1] s[k+1] PUSH2 。 | 34 | |
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 | |
5513 | ROT2 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 | |
58 | ROT | a b c - b c a | 等同于 1 2 BLKSWAP 或 s2 s1 XCHG2 。 | 18 |
59 | ROTREV -ROT | a b c - c a b | 等同于 2 1 BLKSWAP 或 s2 s2 XCHG2 。 | 18 |
5A | SWAP2 2SWAP | a b c d - c d a b | 等同于 2 2 BLKSWAP 或 s3 s2 XCHG2 。 | 18 |
5B | DROP2 2DROP | a b - | 等同于两次执行 DROP 。 | 18 |
5C | DUP2 2DUP | a b - a b a b | 等同于 s1 s0 PUSH2 。 | 18 |
5D | OVER2 2OVER | a b c d - a b c d a b | 等同于 s3 s2 PUSH2 。 | 18 |
5Eij | [i+2] [j] REVERSE | 反转 s[j+i+1] … s[j] 的顺序。 | 26 | |
5F0i | [i] BLKDROP | 执行 i 次 DROP 。 | 26 | |
5Fij | [i] [j] BLKPUSH | 执行 i 次 PUSH s(j) 。1 <= i <= 15 , 0 <= j <= 15 。 | 26 | |
60 | PICK PUSHX | 从堆栈弹出整数 i ,然后执行 s[i] PUSH 。 | 18 | |
61 | ROLLX | 从堆栈弹出整数 i ,然后执行 1 [i] BLKSWAP 。 | 18 | |
62 | -ROLLX ROLLREVX | 从堆栈弹出整数 i ,然后执行 [i] 1 BLKSWAP 。 | 18 | |
63 | BLKSWX | 从堆栈弹出整数 i 、j ,然后执行 [i] [j] BLKSWAP 。 | 18 | |
64 | REVX | 从堆栈弹出整数 i 、j ,然后执行 [i] [j] REVERSE 。 | 18 | |
65 | DROPX | 从堆栈弹出整数 i ,然后执行 [i] BLKDROP 。 | 18 | |
66 | TUCK | a b - b a b | 等同于 SWAP OVER 或 s1 s1 XCPU 。 | 18 |
67 | XCHGX | 从堆栈弹出整数 i ,然后执行 s[i] XCHG 。 | 18 | |
68 | DEPTH | - depth | 推入当前堆栈深度。 | 18 |
69 | CHKDEPTH | i - | 从堆栈弹出整数 i ,然后检查是否至少有 i 个元素,否则生成堆栈下溢异常。 | 18/58 |
6A | ONLYTOPX | 从堆栈弹出整数 i ,然后移除除顶部 i 个元素之外的所有元素。 | 18 | |
6B | ONLYX | 从堆栈弹出整数 i ,然后仅保留底部 i 个元素。大致等同于 DEPTH SWAP SUB DROPX 。 | 18 | |
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 |
---|---|---|---|---|
6D | NULL PUSHNULL | - null | 推入类型为 Null 的唯一值。 | 18 |
6E | ISNULL | x - ? | 检查 x 是否为 Null,根据情况分别返回 -1 或 0 。 | 18 |
6F0n | [n] TUPLE | x_1 ... x_n - t | 创建包含 n 值 x_1 ,..., x_n 的新 Tuple t=(x_1, … ,x_n) 。0 <= n <= 15 | 26+n |
6F00 | NIL | - t | 推入长度为零的唯一 Tuple t=() 。 | 26 |
6F01 | SINGLE | x - t | 创建单例 t:=(x) ,即长度为一的 Tuple。 | 27 |
6F02 | PAIR CONS | x y - t | 创建对 t:=(x,y) 。 | 28 |
6F03 | TRIPLE | x y z - t | 创建三元组 t:=(x,y,z) 。 | 29 |
6F1k | [k] INDEX | t - x | 返回 Tuple t 的第 k 个元素。0 <= k <= 15 。 | 26 |
6F10 | FIRST CAR | t - x | 返回 Tuple 的第一个元素。 | 26 |
6F11 | SECOND CDR | t - y | 返回 Tuple 的第二个元素。 | 26 |
6F12 | THIRD | t - z | 返回 Tuple 的第三个元素。 | 26 |
6F2n | [n] UNTUPLE | t - x_1 ... x_n | 解包长度等于 0 <= n <= 15 的 Tuple t=(x_1,...,x_n) 。如果 t 不是 Tuple 或 \|t\| != n ,则抛出类型检查异常。 | 26+n |
6F21 | UNSINGLE | t - x | 解包单例 t=(x) 。 | 27 |
6F22 | UNPAIR UNCONS | t - x y | 解包对 t=(x,y) 。 | 28 |
6F23 | UNTRIPLE | t - x y z | 解包三元组 t=(x,y,z) 。 | 29 |
6F3k | [k] UNPACKFIRST | t - x_1 ... x_k | 解包 Tuple t 的前 0 <= k <= 15 个元素。如果 \|t\|<k ,抛出类型检查异常。 | 26+k |
6F30 | CHKTUPLE | t - | 检查 t 是否为 Tuple。如果不是,则抛出类型检查异常。 | 26 |
6F4n | [n] EXPLODE | t - x_1 ... x_m m | 解包 Tuple t=(x_1,...,x_m) 并返回其长度 m ,但仅当 m <= n <= 15 。否则抛出类型检查异常。 | 26+m |
6F5k | [k] SETINDEX | t x - t' | 计算 Tuple t' ,它与 t 仅在位置 t'_{k+1} 上不同,该位置被设置为 x 。0 <= k <= 15 如果 k >= \|t\| ,则抛出范围检查异常。 | 26+\|t\| |
6F50 | SETFIRST | t x - t' | 将 Tuple t 的第一个组件设置为 x 并返回结果 Tuple t' 。 | 26+\|t\| |
6F51 | SETSECOND | t x - t' | 将 Tuple t 的第二个组件设置为 x 并返回结果 Tuple t' 。 | 26+\|t\| |
6F52 | SETTHIRD | t x - t' | 将 Tuple t 的第三个组件设置为 x 并返回结果 Tuple t' 。 | 26+\|t\| |
6F6k | [k] INDEXQ | t - x | 返回 Tuple t 的第 k 个元素,其中 0 <= k <= 15 。换句话说,如果 t=(x_1,...,x_n) ,则返回 x_{k+1} 。如果 k>=n 或 t 为 Null,则返回 Null 而不是 x 。 | 26 |
6F60 | FIRSTQ CARQ | t - x | 返回 Tuple 的第一个元素。 | 26 |
6F61 | SECONDQ CDRQ | t - y | 返回 Tuple 的第二个元素。 | 26 |
6F62 | THIRDQ | t - z | 返回 Tuple 的第三个元素。 | 26 |
6F7k | [k] SETINDEXQ | t x - t' | 在 Tuple t 中设置第 k 个组件为 x ,其中 0 <= k < 16 ,并返回结果 Tuple t' 。如果 \|t\| <= k ,首先通过将所有新组件设置为 Null 来将原始 Tuple 扩展到长度 n’=k+1 。如果原始值 t 为 Null,则将其视为空 Tuple。如果 t 既不是 Null 也不是 Tuple,抛出异常。如果 x 为 Null 且 \|t\| <= k 或 t 为 Null,则总是返回 t'=t (并且不消耗元组创建 gas)。 | 26+\|t’\| |
6F70 | SETFIRSTQ | t x - t' | 将 Tuple t 的第一个组件设置为 x 并返回结果 元组 t' 。 | 26+\|t’\| |
6F71 | SETSECONDQ | t x - t' | 将 Tuple t 的第二个组件设置为 x 并返回结果 元组 t' 。 | 26+\|t’\| |
6F72 | SETTHIRDQ | t x - t' | 将 Tuple组 t 的第三个组件设置为 x 并返回结果 元组 t' 。 | 26+\|t’\| |
6F80 | TUPLEVAR | x_1 ... x_n n - t | 以类似于 TUPLE 的方式创建长度为 n 的新 Tuple t ,但 0 <= n <= 255 从堆栈获取。 | 26+n |
6F81 | INDEXVAR | t k - x | 类似于 k INDEX ,但 0 <= k <= 254 从堆栈获取。 | 26 |
6F82 | UNTUPLEVAR | t n - x_1 ... x_n | 类似于 n UNTUPLE ,但 0 <= n <= 255 从堆栈获取。 | 26+n |
6F83 | UNPACKFIRSTVAR | t n - x_1 ... x_n | 类似于 n UNPACKFIRST ,但 0 <= n <= 255 从堆栈获取。 | 26+n |
6F84 | EXPLODEVAR | t n - x_1 ... x_m m | 类似于 n EXPLODE ,但 0 <= n <= 255 从堆栈获取。 | 26+m |
6F85 | SETINDEXVAR | t x k - t' | 类似于 k SETINDEX ,但 0 <= k <= 254 从堆栈获取。 | 26+\|t’\| |
6F86 | INDEXVARQ | t k - x | 类似于 n INDEXQ ,但 0 <= k <= 254 从堆栈获取。 | 26 |
6F87 | SETINDEXVARQ | t x k - t' | 类似于 k SETINDEXQ ,但 0 <= k <= 254 从堆栈获取。 | 26+\|t’\| |
6F88 | TLEN | t - n | 返回 Tuple 的长度。 | 26 |
6F89 | QTLEN | t - n or -1 | 类似于 TLEN ,但如果 t 不是 Tuple,则返回 -1 。 | 26 |
6F8A | ISTUPLE | t - ? | 根据 t 是否为 Tuple,分别返回 -1 或 0 。 | 26 |
6F8B | LAST | t - x | 返回非空 Tuple t 的最后一个元素。 | 26 |
6F8C | TPUSH COMMA | t x - t' | 将值 x 附加到 Tuple t=(x_1,...,x_n) ,但仅当结果 Tuple t'=(x_1,...,x_n,x) 的长度最多为 255 时。否则抛出类型检查异常。 | 26+\|t’\| |
6F8D | TPOP | t - t' x | 从非空 Tuple t=(x_1,...,x_n) 分离最后一个元素 x=x_n ,并返回结果 Tuple t'=(x_1,...,x_{n-1}) 和原始的最后一个元素 x 。 | 26+\|t’\| |
6FA0 | NULLSWAPIF | x - x or null x | 在顶部的 Integer x 下推入一个 Null,但仅当 x!=0 时。 | 26 |
6FA1 | NULLSWAPIFNOT | x - x or null x | 在顶部的 Integer x 下推入一个 Null,但仅当 x=0 时。可用于在类似于 PLDUXQ 这样的静默原语后进行堆栈对齐。 | 26 |
6FA2 | NULLROTRIF | x y - x y or null x y | 在顶部第二个堆栈条目下推入一个 Null,但仅当顶部的 Integer y 非零时。 | 26 |
6FA3 | NULLROTRIFNOT | x y - x y or null x y | 在顶部第二个堆栈条目下推入一个 Null,但仅当顶部的 Integer y 为零时。可用于在类似于 LDUXQ 这样的静默原语后进行堆栈对齐。 | 26 |
6FA4 | NULLSWAPIF2 | x - x or null null x | 在顶部的 Integer x 下推入两个 Null,但仅当 x!=0 时。等同于 NULLSWAPIF NULLSWAPIF 。 | 26 |
6FA5 | NULLSWAPIFNOT2 | x - x or null null x | 在顶部的 Integer x 下推入两个 Null,但仅当 x=0 时。等同于 NULLSWAPIFNOT NULLSWAPIFNOT 。 | 26 |
6FA6 | NULLROTRIF2 | x y - x y or null null x y | 在顶部第二个堆栈条目下推入两个 Null,但仅当顶部的 Integer y 非零时。等同于 NULLROTRIF NULLROTRIF 。 | 26 |
6FA7 | NULLROTRIFNOT2 | x y - x y 或 null null x y | 仅当最顶部的 Integer y 为零时,才在顶部第二个堆栈条目下推入两个 Null。等同于两次 NULLROTRIFNOT 。 | 26 |
6FBij | [i] [j] INDEX2 | t - x | 对于 0 <= i,j <= 3 ,恢复 x=(t_{i+1})_{j+1} 。等同于 [i] INDEX [j] INDEX 。 | 26 |
6FB4 | CADR | t - x | 恢复 x=(t_2)_1 。 | 26 |
6FB5 | CDDR | t - x | 恢复 x=(t_2)_2 。 | 26 |
6FE_ijk | [i] [j] [k] INDEX3 | t - x | 恢复 x=t_{i+1}_{j+1}_{k+1} 。0 <= i,j,k <= 3 等同于 [i] [j] INDEX2 [k] INDEX 。 | 26 |
6FD4 | CADDR | t - x | 恢复 x=t_2_2_1 。 | 26 |
6FD5 | CDDDR | t - x | 恢复 x=t_2_2_2 。 | 26 |
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 |
70 | ZERO FALSE | - 0 | 18 | |
71 | ONE | - 1 | 18 | |
72 | TWO | - 2 | 18 | |
7A | TEN | - 10 | 18 | |
7F | TRUE | - -1 | 18 | |
80xx | [xx] PUSHINT [xx] INT | - xx | 将整数 xx 压入栈。-128 <= xx <= 127 。 | 26 |
81xxxx | [xxxx] PUSHINT [xxxx] INT | - xxxx | 将整数 xxxx 压入栈。-2^15 <= xx < 2^15 。 | 34 |
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 |
83FF | PUSHNAN | - NaN | 推送一个 NaN 。 | 26 |
84xx | [xx+1] PUSHPOW2DEC | - 2^(xx+1)-1 | 推送 2^(xx+1)-1 ,对于 0 <= xx <= 255 。 | 26 |
85xx | [xx+1] PUSHNEGPOW2 | - -2^(xx+1) | 推送 -2^(xx+1) ,对于 0 <= xx <= 255 。 | 26 |
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制作成一个简单的普通 continuation。 | 118/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 | - s | PUSHSLICE 的示例。x{} 是一个空切片。x{...} 是一个十六进制字面量。b{...} 是一个二进制字面量。关于切片字面量的更多信息在这里。 注意,汇编程序可以在某些情况下(例如,如果当前continuation中没有足够的空间)将 PUSHSLICE 替换为 PUSHREFSLICE 。 | ||
<b x{AB12} s, b> PUSHREF <b x{AB12} s, b> PUSHREFSLICE | - c/s | PUSHREF 和 PUSHREFSLICE 的示例。关于在 fift 中构建cell的更多信息在这里。 | ||
8F_rxxcccc | [builder] PUSHCONT [builder] CONT | - c | 从 builder 中推送continuation。细节: 推送由 cc.code 的前 0 <= r <= 3 个引用和前 0 <= xx <= 127 字节制成的简单普通continuation cccc 。 | 26 |
9xccc | [builder] PUSHCONT [builder] CONT | - c | 从 builder 中推送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 |
---|---|---|---|---|
A0 | ADD | x y - x+y | 18 | |
A1 | SUB | x y - x-y | 18 | |
A2 | SUBR | x y - y-x | 等同于 SWAP SUB 。 | 18 |
A3 | NEGATE | x - -x | 等同于 -1 MULCONST 或 ZERO SUBR 。注意,如果 x=-2^256 时会触发整数溢出异常。 | 18 |
A4 | INC | x - x+1 | 等同于 1 ADDCONST 。 | 18 |
A5 | DEC | x - x-1 | 等同于 -1 ADDCONST 。 | 18 |
A6cc | [cc] ADDCONST [cc] ADDINT [-cc] SUBCONST [-cc] SUBINT | x - x+cc | -128 <= cc <= 127 。 | 26 |
A7cc | [cc] MULCONST [cc] MULINT | x - x*cc | -128 <= cc <= 127 。 | 26 |
A8 | MUL | x y - x*y | 18 |
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=0 ,c=0 。如果 c=1 ,则 0 <= tt <= 255 ,并且移位由 tt+1 位执行。如果 s!=0 且 c=0 ,则移位量作为栈顶的 整数在 0...256 范围内提供。1 <= d <= 3 - 表示需要哪些除法结果:1 - 仅商,2 - 仅余数,3 - 商和余数。0 <= f <= 2 - 舍入模式:0 - 向下取整,1 - 最近整数,2 - 向上取整。下列所有指令均为此变体。 | 26 | ||
A904 | DIV | x y - q | q=floor(x/y) ,r=x-y*q | 26 |
A905 | DIVR | x y - q’ | q’=round(x/y) ,r’=x-y*q’ | 26 |
A906 | DIVC | x y - q'' | q’’=ceil(x/y) ,r’’=x-y*q’’ | 26 |
A908 | MOD | x y - r | 26 | |
A90C | DIVMOD | x y - q r | 26 | |
A90D | DIVMODR | x y - q' r' | 26 | |
A90E | DIVMODC | x y - q'' r'' | 26 | |
A925 | RSHIFTR | x y - round(x/2^y) | 26 | |
A926 | RSHIFTC | x 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 | |
A98 | MULDIV | x y z - q | q=floor(x*y/z) | 26 |
A985 | MULDIVR | x y z - q' | q'=round(x*y/z) | 26 |
A98C | MULDIVMOD | x y z - q r | q=floor(x*y/z) ,r=x*y-z*q | 26 |
A9A4 | MULRSHIFT | x y z - floor(x*y/2^z) | 0 <= z <= 256 | 26 |
A9A5 | MULRSHIFTR | x y z - round(x*y/2^z) | 0 <= z <= 256 | 26 |
A9A6 | MULRSHIFTC | x y z - ceil(x*y/2^z) | 0 <= z <= 256 | 34 |
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 | |
A9C4 | LSHIFTDIV | x y z - floor(2^z*x/y) | 0 <= z <= 256 | 26 |
A9C5 | LSHIFTDIVR | x y z - round(2^z*x/y) | 0 <= z <= 256 | 26 |
A9C6 | LSHIFTDIVC | x y z - ceil(2^z*x/y) | 0 <= z <= 256 | 34 |
A9D4tt | [tt+1] LSHIFT#DIV | x y - floor(2^(tt+1)*x/y) | 34 | |
A9D5tt | [tt+1] LSHIFT#DIVR | x y - round(2^(tt+1)*x/y) | 34 | |
A9D6tt | [tt+1] LSHIFT#DIVC | x 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 <= 255 | 26 |
ABcc | [cc+1] RSHIFT# | x - floor(x/2^(cc+1)) | 0 <= cc <= 255 | 18 |
AC | LSHIFT | x y - x*2^y | 0 <= y <= 1023 | 18 |
AD | RSHIFT | x y - floor(x/2^y) | 0 <= y <= 1023 | 18 |
AE | POW2 | y - 2^y | 0 <= y <= 1023 等同于 ONE SWAP LSHIFT 。 | 18 |
B0 | AND | x y - x&y | 对两个有符号整数 x 和 y 进行按位与运算,符号扩展到无限。 | 18 |
B1 | OR | x y - x\|y | 对两个整数进行按位或运算。 | 18 |
B2 | XOR | x y - x xor y | 对两个整数进行按位异或运算。 | 18 |
B3 | NOT | x - ~x | 一个整数的按位非运算。 | 26 |
B4cc | [cc+1] FITS | x - x | 检查 x 是否为 cc+1 位有符号整数,对于 0 <= cc <= 255 (即 -2^cc <= x < 2^cc )。如果不是,要么触发整数溢出异常,要么用 NaN 替换 x (静默版本)。 | 26/76 |
B400 | CHKBOOL | x - x | 检查 x 是否为“布尔值”(即 0 或 -1)。 | 26/76 |
B5cc | [cc+1] UFITS | x - x | 检查 x 是否为 cc+1 位无符号整数,对于 0 <= cc <= 255 (即 0 <= x < 2^(cc+1) )。 | 26/76 |
B500 | CHKBIT | x - x | 检查 x 是否为二进制数字(即零或一)。 | 26/76 |
B600 | FITSX | x c - x | 检查 x 是否为 c 位有符号整数,对于 0 <= c <= 1023 。 | 26/76 |
B601 | UFITSX | x c - x | 检查 x 是否为 c 位无符号整数,对于 0 <= c <= 1023 。 | 26/76 |
B602 | BITSIZE | x - c | 计算最小的 c >= 0 使得 x 适合于 c 位有符号整数(-2^(c-1) <= c < 2^(c-1) )。 | 26 |
B603 | UBITSIZE | x - c | 计算最小的 c >= 0 使得 x 适合于 c 位无符号整数(0 <= x < 2^c ),或抛出范围检查异常。 | 26 |
B608 | MIN | x y - x or y | 计算两个整数 x 和 y 的最小值。 | 26 |
B609 | MAX | x y - x or y | 计算两个整数 x 和 y 的最大值。 | 26 |
B60A | MINMAX INTSORT2 | x y - x y or y x | 排序两个整数。如果任一参数为 NaN s,静默版本的此操作返回两个 NaN s。 | 26 |
B60B | ABS | x - \|x\| | 计算整数 x 的绝对值。 | 26 |
5.4 静默算术原语
静默操作在其参数之一为 NaN
或在整数溢出的情况下返回 NaN
,而不是抛出异常。
静默操作如下所示带有 Q
前缀。另一种使操作变为静默的方法是在其前添加 QUIET
(即可以写 QUIET ADD
而不是 QADD
)。
整数比较原语的静默版本也可用(QUIET SGN
,QUIET LESS
等)。
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
B7A0 | QADD | x y - x+y | 26 | |
B7A1 | QSUB | x y - x-y | 26 | |
B7A2 | QSUBR | x y - y-x | 26 | |
B7A3 | QNEGATE | x - -x | 26 | |
B7A4 | QINC | x - x+1 | 26 | |
B7A5 | QDEC | x - x-1 | 26 | |
B7A8 | QMUL | x y - x*y | 26 | |
B7A904 | QDIV | x y - q | 如果 y=0 则除法返回 NaN 。 | 34 |
B7A905 | QDIVR | x y - q’ | 34 | |
B7A906 | QDIVC | x y - q'' | 34 | |
B7A908 | QMOD | x y - r | 34 | |
B7A90C | QDIVMOD | x y - q r | 34 | |
B7A90D | QDIVMODR | x y - q' r' | 34 | |
B7A90E | QDIVMODC | x y - q'' r'' | 34 | |
B7A985 | QMULDIVR | x y z - q' | 34 | |
B7A98C | QMULDIVMOD | x y z - q r | 34 | |
B7AC | QLSHIFT | x y - x*2^y | 26 | |
B7AD | QRSHIFT | x y - floor(x/2^y) | 26 | |
B7AE | QPOW2 | y - 2^y | 26 | |
B7B0 | QAND | x y - x&y | 26 | |
B7B1 | QOR | x y - x\|y | 26 | |
B7B2 | QXOR | x y - x xor y | 26 | |
B7B3 | QNOT | x - ~x | 26 | |
B7B4cc | [cc+1] QFITS | x - x | 如果 x 不是 cc+1 位有符号整数,则用 NaN 替换 x ,否则保持不变。 | 34 |
B7B5cc | [cc+1] QUFITS | x - x | 如果 x 不是 cc+1 位无符号整数,则用 NaN 替换 x ,否则保持不变。 | 34 |
B7B600 | QFITSX | x c - x | 如果 x 不是 c 位有符号整数,则用 NaN 替换 x ,否则保持不变。 | 34 |
B7B601 | QUFITSX | x c - x | 如果 x 不是 c 位无符号整数,则用 NaN 替换 x ,否则保持不变。 | 34 |
6 比较原语
6.1 整数比较
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
B8 | SGN | x - sgn(x) | 计算整数 x 的符号:x<0 时为 -1 ,x=0 时为 0 ,x>0 时为 1 。 | 18 |
B9 | LESS | x y - x<y | 如 x<y ,返回 -1 ,否则返回 0 。 | 18 |
BA | EQUAL | x y - x=y | 如 x=y ,返回 -1 ,否则返回 0 。 | 18 |
BB | LEQ | x y - x<=y | 18 | |
BC | GREATER | x y - x>y | 18 | |
BD | NEQ | x y - x!=y | 等同于 EQUAL NOT 。 | 18 |
BE | GEQ | x y - x>=y | 等同于 LESS NOT 。 | 18 |
BF | CMP | x y - sgn(x-y) | 计算 x-y 的符号:x<y 时为 -1 ,x=y 时为 0 ,x>y 时为 1 。除非 x 或 y 为 NaN ,否则不会发生整数溢出。 | 18 |
C0yy | [yy] EQINT | x - x=yy | 如 x=yy ,返回 -1 ,否则返回 0 。-2^7 <= yy < 2^7 。 | 26 |
C000 | ISZERO | x - x=0 | 检查一个整数是否为零。对应 Forth 的 0= 。 | 26 |
C1yy | [yy] LESSINT [yy-1] LEQINT | x - x<yy | 如 x<yy ,返回 -1 ,否则返回 0 。-2^7 <= yy < 2^7 。 | 26 |
C100 | ISNEG | x - x<0 | 检查一个整数是否为负数。对应 Forth 的 0< 。 | 26 |
C101 | ISNPOS | x - x<=0 | 检查一个整数是否非正。 | 26 |
C2yy | [yy] GTINT [yy+1] GEQINT | x - x>yy | 如 x>yy ,返回 -1 ,否则返回 0 。-2^7 <= yy < 2^7 。 | 26 |
C200 | ISPOS | x - x>0 | 检查一个整数是否为正数。对应 Forth 的 0> 。 | 26 |
C2FF | ISNNEG | x - x >=0 | 检查一个整数是否非负。 | 26 |
C3yy | [yy] NEQINT | x - x!=yy | 如 x!=yy ,返回 -1 ,否则返回 0 。-2^7 <= yy < 2^7 。 | 26 |
C4 | ISNAN | x - x=NaN | 检查 x 是否为 NaN 。 | 18 |
C5 | CHKNAN | x - x | 如果 x 为 NaN ,抛出算术溢出异常。 | 18/68 |
6.2 其他比较
这些“其他比较”原语中的大多数实际上将Slice的数据部分作为位串进行比较(如果没有另外声明,忽略引用)。
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
C700 | SEMPTY | s - ? | 检查切片 s 是否为空(即,不包含任何数据位和cell引用)。 | 26 |
C701 | SDEMPTY | s - ? | 检查切片 s 是否没有数据位。 | 26 |
C702 | SREMPTY | s - ? | 检查切片 s 是否没有引用。 | 26 |
C703 | SDFIRST | s - ? | 检查切片 s 的第一个位是否为一。 | 26 |
C704 | SDLEXCMP | s s' - x | 字典序比较 s 和 s' 的数据,根据结果返回 -1 、0 或 1。 | 26 |
C705 | SDEQ | s s' - ? | 检查 s 和 s' 的数据部分是否一致,等同于 SDLEXCMP ISZERO 。 | 26 |
C708 | SDPFX | s s' - ? | 检查 s 是否是 s' 的前缀。 | 26 |
C709 | SDPFXREV | s s' - ? | 检查 s' 是否是 s 的前缀,等同于 SWAP SDPFX 。 | 26 |
C70A | SDPPFX | s s' - ? | 检查 s 是否是 s' 的真前缀(即,一个与 s' 不同的前缀)。 | 26 |
C70B | SDPPFXREV | s s' - ? | 检查 s' 是否是 s 的真前缀。 | 26 |
C70C | SDSFX | s s' - ? | 检查 s 是否是 s' 的后缀。 | 26 |
C70D | SDSFXREV | s s' - ? | 检查 s' 是否是 s 的后缀。 | 26 |
C70E | SDPSFX | s s' - ? | 检查 s 是否是 s' 的真后缀。 | 26 |
C70F | SDPSFXREV | s s' - ? | 检查 s' 是否是 s 的真后缀。 | 26 |
C710 | SDCNTLEAD0 | s - n | 返回 s 中前导零的数量。 | 26 |
C711 | SDCNTLEAD1 | s - n | 返回 s 中前导一的数量。 | 26 |
C712 | SDCNTTRAIL0 | s - n | 返回 s 中末尾零的数量。 | 26 |
C713 | SDCNTTRAIL1 | s - n | 返回 s 中末尾一的数量。 | 26 |
7 Cell 原语
7.1 Cell 序列化原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
C8 | NEWC | - b | 创建一个新的空 构建器。 | 18 |
C9 | ENDC | b - c | 将 构建器 转换为普通的 cell。 | 518 |
CAcc | [cc+1] STI | x b - b' | 将 0 <= cc <= 255 的有符号 cc+1 -位整数 x 存入 构建器 b 中,如果 x 不适合于 cc+1 位,则抛出范围检查异常。 | 26 |
CBcc | [cc+1] STU | x b - b' | 将无符号的 cc+1 -位整数 x 存入 构建器 b 中。在其他方面,它与 STI 类似。 | 26 |
CC | STREF | c b - b' | 将 cell c 的引用存入 构建器 b 中。 | 18 |
CD | STBREFR ENDCST | b b'' - b | 等同于 ENDC SWAP STREF 。 | 518 |
CE | STSLICE | s b - b' | 将 分片 s 存入 构建器 b 中。 | 18 |
CF00 | STIX | x b l - b' | 为 0 <= l <= 257 ,将有符号 l -位整数 x 存入 b 中。 | 26 |
CF01 | STUX | x b l - b' | 为 0 <= l <= 256 ,将无符号 l -位整数 x 存入 b 中。 | 26 |
CF02 | STIXR | b x l - b' | 与 STIX 类似,但参数顺序不同。 | 26 |
CF03 | STUXR | b x l - b' | 与 STUX 类似,但参数顺序不同。 | 26 |
CF04 | STIXQ | x b l - x b f or b' 0 | STIX 的静默版本。如果 b 中没有空间,将 b'=b 和 f=-1 。如果 x 不适合于 l 位,将 b'=b 和 f=1 。如果操作成功, b' 是新的 构建器 和 f=0 。然而, 0 <= l <= 257 ,如果不是这样,则抛出范围检查异常。 | 26 |
CF05 | STUXQ | x b l - x b f or b' 0 | STUX 的静默版本。 | 26 |
CF06 | STIXRQ | b x l - b x f or b' 0 | STIXR 的静默版本。 | 26 |
CF07 | STUXRQ | b x l - b x f or b' 0 | STUXR 的静默版本。 | 26 |
CF08cc | [cc+1] STI_l | x b - b' | [cc+1] STI 的更长版本。 | 34 |
CF09cc | [cc+1] STU_l | x b - b' | [cc+1] STU 的更长版本。 | 34 |
CF0Acc | [cc+1] STIR | b x - b' | 等同于 SWAP [cc+1] STI 。 | 34 |
CF0Bcc | [cc+1] STUR | b x - b' | 等同于 SWAP [cc+1] STU 。 | 34 |
CF0Ccc | [cc+1] STIQ | x b - x b f or b' 0 | STI 的静默版本。 | 34 |
CF0Dcc | [cc+1] STUQ | x b - x b f or b' 0 | STU 的静默版本。 | 34 |
CF0Ecc | [cc+1] STIRQ | b x - b x f or b' 0 | STIR 的静默版本。 | 34 |
CF0Fcc | [cc+1] STURQ | b x - b x f or b' 0 | STUR 的静默版本。 | 34 |
CF10 | STREF_l | c b - b' | STREF 的更长版本。 | 26 |
CF11 | STBREF | b' b - b'' | 等同于 SWAP STBREFR 。 | 526 |
CF12 | STSLICE_l | s b - b' | STSLICE 的更长版本。 | 26 |
CF13 | STB | b' b - b'' | 将 构建器 b' 中的所有数据附加到 构建器 b 中。 | 26 |
CF14 | STREFR | b c - b' | 等同于 SWAP STREF 。 | 26 |
CF15 | STBREFR_l | b b' - b'' | STBREFR 的更长编码。 | 526 |
CF16 | STSLICER | b s - b' | 等同于 SWAP STSLICE 。 | 26 |
CF17 | STBR BCONCAT | b b' - b'' | 连接两个构建器。 等同于 SWAP STB 。 | 26 |
CF18 | STREFQ | c b - c b -1 or b' 0 | STREF 的静默版本。 | 26 |
CF19 | STBREFQ | b' b - b' b -1 or b'' 0 | STBREF 的静默版本。 | 526 |
CF1A | STSLICEQ | s b - s b -1 or b' 0 | STSLICE 的静默版本。 | 26 |
CF1B | STBQ | b' b - b' b -1 or b'' 0 | STB 的静默版本。 | 26 |
CF1C | STREFRQ | b c - b c -1 or b' 0 | STREFR 的静默版本。 | 26 |
CF1D | STBREFRQ | b b' - b b' -1 or b'' 0 | STBREFR 的静默版本。 | 526 |
CF1E | STSLICERQ | b s - b s -1 or b'' 0 | STSLICER 的静默版本。 | 26 |
CF1F | STBRQ BCONCATQ | b b' - b b' -1 or b'' 0 | STBR 的静默版本。 | 26 |
CF20 | [ref] STREFCONST | b - b’ | 等同于 PUSHREF STREFR 。 | 26 |
CF21 | [ref] [ref] STREF2CONST | b - b’ | 等同于 STREFCONST STREFCONST 。 | 26 |
CF23 | b x - c | 如果 x!=0 ,从 构建器 b 创建一个 特殊 或 异类 cell。异类cell的类型必须存储在 b 的前 8 位中。如果 x=0 ,它相当于 ENDC 。否则,将在创建异类cell之前对 b 的数据和引用执行一些有效性检查。 | 526 | |
CF28 | STILE4 | x b - b' | 存储一个小端有符号 32 位整数。 | 26 |
CF29 | STULE4 | x b - b' | 存储一个小端无符号 32 位整数。 | 26 |
CF2A | STILE8 | x b - b' | 存储一个小端有符号 64 位整数。 | 26 |
CF2B | STULE8 | x b - b' | 存储一个小端无符号 64 位整数。 | 26 |
CF30 | BDEPTH | b - x | 返回 构建器 b 的深度。如果 b 中没有存储cell引用,则 x=0 ;否则 x 是对 b 中引用的cell的深度的最大值加 1。 | 26 |
CF31 | BBITS | b - x | 返回已经存储在 构建器 b 中的数据位数。 | 26 |
CF32 | BREFS | b - y | 返回已经存储在 b 中的cell引用数。 | 26 |
CF33 | BBITREFS | b - x y | 返回 b 中数据位数和cell引用数。 | 26 |
CF35 | BREMBITS | b - x' | 返回仍然可以存储在 b 中的数据位数。 | 26 |
CF36 | BREMREFS | b - y' | 返回仍然可以存储在 b 中的引用数。 | 26 |
CF37 | BREMBITREFS | b - x' y' | 返回仍然可以存储在 b 中的数据位数和引用数。 | 26 |
CF38cc | [cc+1] BCHKBITS# | b - | 检查是否能将 cc+1 位存储到 b 中,其中 0 <= cc <= 255 。 | 34/84 |
CF39 | BCHKBITS | b x - | 检查是否能将 x 位存储到 b 中,0 <= x <= 1023 。如果 b 中没有足够空间存储 x 更多位,或者 x 不在范围 0...1023 内,则抛出异常。 | 26/76 |
CF3A | BCHKREFS | b y - | 检查是否能将 y 引用存储到 b 中,0 <= y <= 7 。 | 26/76 |
CF3B | BCHKBITREFS | b x y - | 检查是否能将 x 位和 y 引用存储到 b 中,0 <= x <= 1023 ,0 <= y <= 7 。 | 26/76 |
CF3Ccc | [cc+1] BCHKBITSQ# | b - ? | 检查是否能将 cc+1 位存储到 b 中,其中 0 <= cc <= 255 。 | 34 |
CF3D | BCHKBITSQ | b x - ? | 检查是否能将 x 位存储到 b 中,0 <= x <= 1023 。 | 26 |
CF3E | BCHKREFSQ | b y - ? | 检查是否能将 y 引用存储到 b 中,0 <= y <= 7 。 | 26 |
CF3F | BCHKBITREFSQ | b x y - ? | 检查是否能将 x 位和 y 引用存储到 b 中,0 <= x <= 1023 ,0 <= y <= 7 。 | 26 |
CF40 | STZEROES | b n - b' | 将 n 个二进制零存储到 构建器 b 中。 | 26 |
CF41 | STONES | b n - b' | 将 n 个二进制一存储到 构建器 b 中。 | 26 |
CF42 | STSAME | b n x - b' | 将 n 个二进制 x (0 <= x <= 1 )存储到 构建器 b 中。 | 26 |
CFC0_xysss | [slice] STSLICECONST | b - b' | 存储一个常量子切片 sss 。详情: sss 由 0 <= x <= 3 个引用和最多 8y+2 个数据位组成,其中 0 <= y <= 7 。假定有完成位。注意,如果切片过大,汇编器可以将 STSLICECONST 替换为 PUSHSLICE STSLICER 。 | 24 |
CF81 | STZERO | b - b' | 存储一个二进制零。 | 24 |
CF83 | STONE | b - b' | 存储一个二进制一。 | 24 |
7.2 Cell 反序列化原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
D0 | CTOS | c - s | 将 cell 转换为 切片。请注意,c 必须是普通cell,或者是自动 加载 以产生普通cell c' 的异类cell,然后转换为 切片。 | 118/43 |
D1 | ENDS | s - | 从堆栈中移除 切片 s ,如果不为空则抛出异常。 | 18/68 |
D2cc | [cc+1] LDI | s - x s' | 从 切片 s 中加载(即解析)一个有符号的 cc+1 -位整数 x ,并返回 s 的剩余部分作为 s' 。 | 26 |
D3cc | [cc+1] LDU | s - x s' | 从 切片 s 中加载一个无符号 cc+1 -位整数 x 。 | 26 |
D4 | LDREF | s - c s' | 从 s 中加载一个cell引用 c 。 | 18 |
D5 | LDREFRTOS | s - s' s'' | 等效于 LDREF SWAP CTOS 。 | 118/43 |
D6cc | [cc+1] LDSLICE | s - s'' s' | 将 s 的接下来的 cc+1 位切割为一个独立的 切片 s'' 。 | 26 |
D700 | LDIX | s l - x s' | 从 切片 s 中加载一个有符号的 l -位(0 <= l <= 257 )整数 x ,并返回 s 的剩余部分作为 s' 。 | 26 |
D701 | LDUX | s l - x s' | 从 s 的前 l 位(0 <= l <= 256 )加载一个无符号 l -位整数 x 。 | 26 |
D702 | PLDIX | s l - x | 从 切片 s 中预加载一个有符号 l -位整数,0 <= l <= 257 。 | 26 |
D703 | PLDUX | s l - x | 从 s 中预加载一个无符号 l -位整数,0 <= l <= 256 。 | 26 |
D704 | LDIXQ | s l - x s' -1 or s 0 | LDIX 的静默版本:类似地从 s 中加载一个有符号 l -位整数,但在成功时返回一个成功标志位 -1 ,失败时(如果 s 没有 l 位)返回 0 ,而不是抛出cell下溢异常。 | 26 |
D705 | LDUXQ | s l - x s' -1 or s 0 | LDUX 的静默版本。 | 26 |
D706 | PLDIXQ | s l - x -1 or 0 | PLDIX 的静默版本。 | 26 |
D707 | PLDUXQ | s l - x -1 or 0 | PLDUX 的静默版本。 | 26 |
D708cc | [cc+1] LDI_l | s - x s' | LDI 的更长编码。 | 34 |
D709cc | [cc+1] LDU_l | s - x s' | LDU 的更长编码。 | 34 |
D70Acc | [cc+1] PLDI | s - x | 从 切片 s 中预加载一个有符号 cc+1 -位整数。 | 34 |
D70Bcc | [cc+1] PLDU | s - x | 从 s 中预加载一个无符号 cc+1 -位整数。 | 34 |
D70Ccc | [cc+1] LDIQ | s - x s' -1 or s 0 | LDI 的静默版本。 | 34 |
D70Dcc | [cc+1] LDUQ | s - x s' -1 or s 0 | LDU 的静默版本。 | 34 |
D70Ecc | [cc+1] PLDIQ | s - x -1 or 0 | PLDI 的静默版本。 | 34 |
D70Fcc | [cc+1] PLDUQ | s - x -1 or 0 | PLDU 的静默版本。 | 34 |
D714_c | [32(c+1)] PLDUZ | s - s x | 从 切片 s 中预加载前 32(c+1) 位到无符号整数 x 中,0 <= c <= 7 。如果 s 比必要的短,缺失的位假定为零。此操作旨在与 IFBITJMP 及类似指令一起使用。 | 26 |
D718 | LDSLICEX | s l - s'' s' | 从 切片 s 中加载前 0 <= l <= 1023 位到一个单独的 切片 s'' 中,返回 s 的剩余部分作为 s' 。 | 26 |
D719 | PLDSLICEX | s l - s'' | 返回 s 的前 0 <= l <= 1023 位作为 s'' 。 | 26 |
D71A | LDSLICEXQ | s l - s'' s' -1 or s 0 | LDSLICEX 的静默版本。 | 26 |
D71B | PLDSLICEXQ | s l - s' -1 or 0 | LDSLICEXQ 的静默版本。 | 26 |
D71Ccc | [cc+1] LDSLICE_l | s - s'' s' | LDSLICE 的更长编码。 | 34 |
D71Dcc | [cc+1] PLDSLICE | s - s'' | 返回 s 的前 0 < cc+1 <= 256 位作为 s'' 。 | 34 |
D71Ecc | [cc+1] LDSLICEQ | s - s'' s' -1 or s 0 | LDSLICE 的静默版本。 | 34 |
D71Fcc | [cc+1] PLDSLICEQ | s - s'' -1 or 0 | PLDSLICE 的静默版本。 | 34 |
D720 | SDCUTFIRST | s l - s' | 返回 s 的前 0 <= l <= 1023 位。与 PLDSLICEX 等效。 | 26 |
D721 | SDSKIPFIRST | s l - s' | 返回除了 s 的前 0 <= l <= 1023 位以外的所有位。与 LDSLICEX NIP 等效。 | 26 |
D722 | SDCUTLAST | s l - s' | 返回 s 的后 0 <= l <= 1023 位。 | 26 |
D723 | SDSKIPLAST | s l - s' | 返回除了 s 的后 0 <= l <= 1023 位以外的所有位。 | 26 |
D724 | SDSUBSTR | s l l' - s' | 返回 s 的从偏移量 0 <= l <= 1023 开始的 0 <= l' <= 1023 位,从 s 的数据中提取出一个位子字符串。 | 26 |
D726 | SDBEGINSX | s s' - s'' | 检查 s 是否以 s' (数据位)开始,并在成功时从 s 中移除 s' 。失败抛出cell反序列化异常。原语 SDPFXREV 可以认为是 SDBEGINSX 的静默版本。 | 26 |
D727 | SDBEGINSXQ | s s' - s'' -1 or s 0 | SDBEGINSX 的静默版本。 | 26 |
D72A_xsss | [slice] SDBEGINS | s - s'' | 检查 s 是否以常量位串 sss 开始,sss 的长度为 8x+3 (假定有完成位),其中 0 <= x <= 127 ,并在成功时从 s 中移除 sss 。 | 31 |
D72E_xsss | [slice] SDBEGINSQ | s - s'' -1 or s 0 | SDBEGINS 的静默版本。 | 31 |
D730 | SCUTFIRST | s l r - s' | 返回 s 的前 0 <= l <= 1023 位和前 0 <= r <= 4 个引用。 | 26 |
D731 | SSKIPFIRST | s l r - s' | 返回除了 s 的前 l 位和 r 个引用以外的所有内容。 | 26 |
D732 | SCUTLAST | s l r - s' | 返回 s 的后 0 <= l <= 1023 个数据位和后 0 <= r <= 4 个引用。 | 26 |
D733 | SSKIPLAST | s l r - s' | 返回除了 s 的后 l 位和 r 个引用以外的所有内容。 | 26 |
D734 | SUBSLICE | s l r l' r' - s' | 在跳过 s 的前 0 <= l <= 1023 位和前 0 <= r <= 4 个引用后,返回来自 切片 s 的 0 <= l' <= 1023 位和 0 <= r' <= 4 个引用。 | 26 |
D736 | SPLIT | s l r - s' s'' | 将 s 的前 0 <= l <= 1023 个数据位和前 0 <= r <= 4 个引用分割成 s' ,并返回 s 的剩余部分作为 s'' 。 | 26 |
D737 | SPLITQ | s l r - s' s'' -1 或 s 0 | SPLIT 的静默版本。 | 26 |
D739 | c - s? | 将普通或异类cell转换为 切片,就好像它是一个普通cell一样。返回一个标志位,指示 c 是否是异类的。如果是这样,其类型可以稍后从 s 的前八位中反序列化。 | ||
D73A | c - c' | 加载异类cell c 并返回一个普通cell c' 。如果 c 已经是普通的,则不执行任何操作。如果 c 无法加载,抛出异常。 | ||
D73B | c - c' -1 或 c 0 | 加载异类cell c 并返回一个普通cell c' 。如果 c 已经是普通的,则不执行任何操作。如果 c 无法加载,返回 0。 | ||
D741 | SCHKBITS | s l - | 检查 切片 s 中是否至少有 l 个数据位。如果不是这种情况,抛出cell反序列化(即cell下溢)异常。 | 26/76 |
D742 | SCHKREFS | s r - | 检查 切片 s 中是否至少有 r 个引用。 | 26/76 |
D743 | SCHKBITREFS | s l r - | 检查 切片 s 中是否至少有 l 个数据位和 r 个引用。 | 26/76 |
D745 | SCHKBITSQ | s l - ? | 检查 切片 s 中是否至少有 l 个数据位。 | 26 |
D746 | SCHKREFSQ | s r - ? | 检查 切片 s 中是否至少有 r 个引用。 | 26 |
D747 | SCHKBITREFSQ | s l r - ? | 检查 切片 s 中是否至少有 l 个数据位和 r 个引用。 | 26 |
D748 | PLDREFVAR | s n - c | 返回 切片 s 的第 n 个cell引用,0 <= n <= 3 。 | 26 |
D749 | SBITS | s - l | 返回 切片 s 中的数据位数。 | 26 |
D74A | SREFS | s - r | 返回 切片 s 中的引用数。 | 26 |
D74B | SBITREFS | s - l r | 返回 s 中的数据位数和引用数。 | 26 |
D74E_n | [n] PLDREFIDX | s - c | 返回 切片 s 的第 n 个cell引用,0 <= n <= 3 。 | 26 |
D74C | PLDREF | s - c | 预加载 切片 的第一个cell引用。 | 26 |
D750 | LDILE4 | s - x s' | 加载一个小端有符号 32 位整数。 | 26 |
D751 | LDULE4 | s - x s' | 加载一个小端无符号 32 位整数。 | 26 |
D752 | LDILE8 | s - x s' | 加载一个小端有符号 64 位整数。 | 26 |
D753 | LDULE8 | s - x s' | 加载一个小端无符号 64 位整数。 | 26 |
D754 | PLDILE4 | s - x | 预加载一个小端有符号 32 位整数。 | 26 |
D755 | PLDULE4 | s - x | 预加载一个小端无符号 32 位整数。 | 26 |
D756 | PLDILE8 | s - x | 预加载一个小端有符号 64 位整数。 | 26 |
D757 | PLDULE8 | s - x | 预加载一个小端无符号 64 位整数。 | 26 |
D758 | LDILE4Q | s - x s' -1 或 s 0 | 静默加载一个小端有符号 32 位整数。 | 26 |
D759 | LDULE4Q | s - x s' -1 或 s 0 | 静默加载一个小端无符号 32 位整数。 | 26 |
D75A | LDILE8Q | s - x s' -1 或 s 0 | 静默加载一个小端有符号 64 位整数。 | 26 |
D75B | LDULE8Q | s - x s' -1 或 s 0 | 静默加载一个小端无符号 64 位整数。 | 26 |
D75C | PLDILE4Q | s - x -1 或 0 | 静默预加载一个小端有符号 32 位整数。 | 26 |
D75D | PLDULE4Q | s - x -1 或 0 | 静默预加载一个小端无符号 32 位整数。 | 26 |
D75E | PLDILE8Q | s - x -1 或 0 | 静默预加载一个小端有符号 64 位整数。 | 26 |
D75F | PLDULE8Q | s - x -1 或 0 | 静默预加载一个小端无符号 64 位整数。 | 26 |
D760 | LDZEROES | s - n s' | 返回 s 中前导零位的计数 n ,并从 s 中移除这些位。 | 26 |
D761 | LDONES | s - n s' | 返回 s 中前导一位的计数 n ,并从 s 中移除这些位。 | 26 |
D762 | LDSAME | s x - n s' | 返回 s 中与 0 <= x <= 1 相等的前导位的计数 n ,并从 s 中移除这些位。 | 26 |
D764 | SDEPTH | s - x | 返回 切片 s 的深度。如果 s 没有引用,则 x=0 ;否则 x 是从 s 引用的cell的最大深度加 1。 | 26 |
D765 | CDEPTH | c - 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 |
---|---|---|---|---|
D8 | EXECUTE CALLX | c - | 调用 或 执行 Continuation c 。 | 18 |
D9 | JMPX | c - | 跳转 或 控制转移到 Continuation c 。之前当前continuation cc 的剩余部分被丢弃。 | 18 |
DApr | [p] [r] CALLXARGS | c - | 用 p 参数 调用 continuation c 并期待 r 返回值0 <= p <= 15 , 0 <= r <= 15 | 26 |
DB0p | [p] -1 CALLXARGS | c - | 用 0 <= p <= 15 参数 调用 continuation c , 期望任意数量的返回值。 | 26 |
DB1p | [p] JMPXARGS | c - | 跳转 到 continuation c , 只将当前栈顶的 0 <= p <= 15 个值传递给它(当前栈的其余部分被丢弃)。 | 26 |
DB2r | [r] RETARGS | 返回 到 c0 , 携带 0 <= r <= 15 个从当前栈中取得的返回值。 | 26 | |
DB30 | RET RETTRUE | 返回 到 continuation c0 。当前 continuation cc 的剩余部分被丢弃。大致相当于 c0 PUSHCTR JMPX 。 | 26 | |
DB31 | RETALT RETFALSE | 返回 到 continuation c1 。大致相当于 c1 PUSHCTR JMPX 。 | 26 | |
DB32 | BRANCH RETBOOL | f - | 如果整数 f!=0 , 执行 RETTRUE ,如果 f=0 ,执行 RETFALSE 。 | 26 |
DB34 | CALLCC | c - | 带当前 continuation 调用,控制权转移到 c ,将旧的 cc 值推入 c 的栈中(而不是丢弃它或将其写入新的 c0 中)。 | 26 |
DB35 | JMPXDATA | c - | 类似于 CALLCC ,但是当前 continuation 的剩余部分(旧的 cc 值)在推入 c 的栈之前被转换成一个 Slice。 | 26 |
DB36pr | [p] [r] CALLCCARGS | c - | 类似于 CALLXARGS ,但是将旧的 cc 值(连同最初栈顶的 0 <= p <= 15 个值)推入被调用 continuation c 的栈中,设置 cc.nargs 为 -1 <= r <= 14 。 | 34 |
DB38 | CALLXVARARGS | c p r - | 类似于 CALLXARGS ,但从栈中取 -1 <= p,r <= 254 。接下来的三个操作也从栈中取 p 和 r ,范围都是 -1...254 。 | 26 |
DB39 | RETVARARGS | p r - | 类似于 RETARGS 。 | 26 |
DB3A | JMPXVARARGS | c p r - | 类似于 JMPXARGS 。 | 26 |
DB3B | CALLCCVARARGS | c p r - | 类似于 CALLCCARGS 。 | 26 |
DB3C | [ref] CALLREF | 等同于 PUSHREFCONT CALLX 。 | 126/51 | |
DB3D | [ref] JMPREF | 等同于 PUSHREFCONT JMPX 。 | 126/51 | |
DB3E | [ref] JMPREFDATA | 等同于 PUSHREFCONT JMPXDATA 。 | 126/51 | |
DB3F | RETDATA | 等同于 c0 PUSHCTR JMPXDATA 。这样,当前 continuation 的剩余部分被转换成一个 Slice 并返回给调用者。 | 26 |
8.2 条件控制流原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
DC | IFRET IFNOT: | f - | 如果整数 f 非零,则执行 RET 。如果 f 是 NaN , 抛出一个整数溢出异常。 | 18 |
DD | IFNOTRET IF: | f - | 如果整数 f 为零,则执行 RET 。 | 18 |
DE | IF | f c - | 如果整数 f 非零,执行 c (即,执行 c ),否则简单地丢弃两个值。 | 18 |
DE | IF:<{ code }> <{ code }>IF | f - | 等同于 <{ code }> CONT IF 。 | |
DF | IFNOT | f c - | 如果整数 f 为零,则执行 continuation c ,否则简单地丢弃两个值。 | 18 |
DF | IFNOT:<{ code }> <{ code }>IFNOT | f - | 等同于 <{ code }> CONT IFNOT 。 | |
E0 | IFJMP | f c - | 只有当 f 非零时,跳转到 c (类似于 JMPX )。 | 18 |
E0 | IFJMP:<{ code }> | f - | 等同于 <{ code }> CONT IFJMP 。 | |
E1 | IFNOTJMP | f c - | 只有当 f 为零时,跳转到 c (类似于 JMPX )。 | 18 |
E1 | IFNOTJMP:<{ code }> | f - | 等同于 <{ code }> CONT IFNOTJMP 。 | |
E2 | IFELSE | f c c' - | 如果整数 f 非零,执行 c ,否则执行 c' 。等同于 CONDSELCHK EXECUTE 。 | 18 |
E2 | IF:<{ code1 }>ELSE<{ code2 }> | f - | 等同于 <{ code1 }> CONT <{ code2 }> CONT IFELSE 。 | |
E300 | [ref] IFREF | f - | 等同于 PUSHREFCONT IF ,但优化了cell引用不实际加载入一个 Slice 再转换成一个普通 Continuation 如果 f=0 。这个原语的 Gas 消耗取决于 f=0 以及引用是否之前加载过。类似的评论适用于接受 continuation 作为引用的其他原语。 | 26/126/51 |
E301 | [ref] IFNOTREF | f - | 等同于 PUSHREFCONT IFNOT 。 | 26/126/51 |
E302 | [ref] IFJMPREF | f - | 等同于 PUSHREFCONT IFJMP 。 | 26/126/51 |
E303 | [ref] IFNOTJMPREF | f - | 等同于 PUSHREFCONT IFNOTJMP 。 | 26/126/51 |
E304 | CONDSEL | f x y - x 或 y | 如果整数 f 非零,返回 x ,否则返回 y 。注意 x 和 y 上不执行类型检查;因此,它更像是一个条件栈操作。大致等同于 ROT ISZERO INC ROLLX NIP 。 | 26 |
E305 | CONDSELCHK | f x y - x 或 y | 与 CONDSEL 相同,但首先检查 x 和 y 是否类型相同。 | 26 |
E308 | IFRETALT | f - | 如果整数 f!=0 执行 RETALT 。 | 26 |
E309 | IFNOTRETALT | f - | 如果整数 f=0 执行 RETALT 。 | 26 |
E30D | [ref] IFREFELSE | f c - | 等同于 PUSHREFCONT SWAP IFELSE ,但优化了在 f=0 时,实际上并不需要将cell引用加载进一个Slice,然后再转换成普通的 Continuation。对接下来的两个原语也适用类似的备注:只有在必要时,才将cell转换成 continuations。 | 26/126/51 |
E30E | [ref] IFELSEREF | f c - | 等同于 PUSHREFCONT IFELSE 。 | 26/126/51 |
E30F | [ref] [ref] IFREFELSEREF | f - | 等同于 PUSHREFCONT PUSHREFCONT IFELSE 。 | 126/51 |
E39_n | [n] IFBITJMP | x c - x | 检查整数 x 中是否设置了位 0 <= n <= 31 ,如果是,则执行 JMPX 跳转到 continuation c 。值 x 保留在栈中。 | 26 |
E3B_n | [n] IFNBITJMP | x c - x | 如果整数 x 中位 0 <= n <= 31 未设置,跳转到 c 。 | 26 |
E3D_n | [ref] [n] IFBITJMPREF | x - x | 如果整数 x 中设置了位 0 <= n <= 31 ,执行 JMPREF 。 | 126/51 |
E3F_n | [ref] [n] IFNBITJMPREF | x - x | 如果整数 x 中未设置位 0 <= n <= 31 ,执行 JMPREF 。 | 126/51 |
8.3 控制流原语:循环
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
E4 | REPEAT | n c - | 如果整数 n 为非负数,则执行 continuation c n 次。如果 n>=2^31 或 n<-2^31 ,会生成一个范围检查异常。注意,在 c 的代码内部的 RET 作为 continue 使用,而不是 break 。应使用另一种(实验性的)循环或者 RETALT (循环前与 SETEXITALT 一起使用)来从循环中 break 出去。 | 18 |
E4 | REPEAT:<{ code }> <{ code }>REPEAT | n - | 等同于 <{ code }> CONT REPEAT 。 | |
E5 | REPEATEND REPEAT: | n - | 类似于 REPEAT ,但它应用于当前 continuation cc 。 | 18 |
E6 | UNTIL | c - | 执行 continuation c ,然后从结果栈中弹出一个整数 x 。如果 x 为零,执行此循环的另一次迭代。这个原语的实际实现涉及一个特殊的 continuation ec_until ,其参数设置为循环体(continuation c )和原始的当前 continuation cc 。然后这个特殊的 continuation 被保存到 c 的 savelist 作为 c.c0 ,然后执行修改后的 c 。其他循环原语也类似地借助适当的特殊 continuations 实现。 | 18 |
E6 | UNTIL:<{ code }> <{ code }>UNTIL | - | 等同于 <{ code }> CONT UNTIL 。 | |
E7 | UNTILEND UNTIL: | - | 类似于 UNTIL ,但在循环中执行当前 continuation cc 。当满足循环退出条件时,执行 RET 。 | 18 |
E8 | WHILE | c' c - | 执行 c' 并从结果栈中弹出一个整数 x 。如果 x 为零,则退出循环并将控制权转移给原始 cc 。如果 x 非零,则执行 c ,然后开始新的迭代。 | 18 |
E8 | WHILE:<{ cond }>DO<{ code }> | - | 等同于 <{ cond }> CONT <{ code }> CONT WHILE 。 | |
E9 | WHILEEND | c' - | 类似于 WHILE ,但使用当前 continuation cc 作为循环体。 | 18 |
EA | AGAIN | c - | 类似于 REPEAT ,但无限次执行 c 。一个 RET 只是开始一个无限循环的新迭代,只能通过异常或 RETALT (或显式的 JMPX )退出。 | 18 |
EA | AGAIN:<{ code }> <{ code }>AGAIN | - | 等同于 <{ code }> CONT AGAIN 。 | |
EB | AGAINEND AGAIN: | - | 类似于 AGAIN ,但相对于当前 continuation cc 执行。 | 18 |
E314 | REPEATBRK | n c - | 类似于 REPEAT ,但在将旧的 c1 值保存到原始 cc 的 savelist 后,还将 c1 设置为原始 cc 。这样,RETALT 可以用来退出循环体。 | 26 |
E314 | REPEATBRK:<{ code }> <{ code }>REPEATBRK | n - | 等同于 <{ code }> CONT REPEATBRK 。 | |
E315 | REPEATENDBRK | n - | 类似于 REPEATEND ,但在将旧的 c1 值保存到原始 c0 的 savelist 后,还将 c1 设置为原始 c0 。等同于 SAMEALTSAVE REPEATEND 。 | 26 |
E316 | UNTILBRK | c - | 类似于 UNTIL ,但也以与 REPEATBRK 相同的方式修改 c1 。 | 26 |
E316 | UNTILBRK:<{ code }> | - | 等同于 <{ code }> CONT UNTILBRK 。 | |
E317 | UNTILENDBRK UNTILBRK: | - | 等同于 SAMEALTSAVE UNTILEND 。 | 26 |
E318 | WHILEBRK | c' c - | 类似于 WHILE ,但也以与 REPEATBRK 相同的方式修改 c1 。 | 26 |
E318 | WHILEBRK:<{ cond }>DO<{ code }> | - | 等同于 <{ cond }> CONT <{ code }> CONT WHILEBRK 。 | |
E319 | WHILEENDBRK | c - | 等同于 SAMEALTSAVE WHILEEND 。 | 26 |
E31A | AGAINBRK | c - | 类似于 AGAIN ,但也以与 REPEATBRK 相同的方式修改 c1 。 | 26 |
E31A | AGAINBRK:<{ code }> | - | 等同于 <{ code }> CONT AGAINBRK 。 | |
E31B | AGAINENDBRK AGAINBRK: | - | 等同于 SAMEALTSAVE AGAINEND 。 | 26 |
8.4 操作 continuation 栈
这里的 s"
是在 continuations 之间移动栈元素的费用。它等于结果栈的大小减去32(如果栈大小小于32,则为0)。
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
ECrn | [r] [n] SETCONTARGS | x_1 x_2...x_r c - c' | 类似于 [r] -1 SETCONTARGS ,但将 c.nargs 设置为 c' 的栈的最终大小加上 n 。换句话说,将 c 转换成一个闭包或部分应用函数,缺少 0 <= n <= 14 个参数。 | 26+s” |
EC0n | [n] SETNUMARGS | c - c' | 设置 c.nargs 为 n 加上 c 的当前栈的深度,其中 0 <= n <= 14 。如果 c.nargs 已经设置为非负值,则不进行任何操作。 | 26 |
ECrF | [r] -1 SETCONTARGS | x_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” |
ED10 | RETURNVARARGS | p - | 类似于 RETURNARGS ,但从栈中取整数 0 <= p <= 255 。 | 26+s” |
ED11 | SETCONTVARARGS | x_1 x_2...x_r c r n - c' | 类似于 SETCONTARGS ,但从栈中取 0 <= r <= 255 和 -1 <= n <= 255 。 | 26+s” |
ED12 | SETNUMVARARGS | c n - c' | -1 <= n <= 255 如果 n=-1 ,此操作不进行任何操作(c'=c )。否则其行为类似于 [n] SETNUMARGS ,但 n 是从栈中取得的。 | 26 |
8.5 创建简单的 continuations 和 闭包
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
ED1E | BLESS | s - c | 将 Slice s 转换为简单的普通 continuation c ,其中 c.code=s ,并且栈和 savelist 为空。 | 26 |
ED1F | BLESSVARARGS | x_1...x_r s r n - c | 等同于 ROT BLESS ROTREV SETCONTVARARGS 。 | 26+s” |
EErn | [r] [n] BLESSARGS | x_1...x_r s - c | 0 <= r <= 15 , -1 <= n <= 14 等同于 BLESS [r] [n] SETCONTARGS 。n 的值由 4 位整数 n mod 16 内部表示。 | 26 |
EE0n | [n] BLESSNUMARGS | s - c | 也将 Slice s 转换为 Continuation c ,但将 c.nargs 设置为 0 <= n <= 14 。 | 26 |
8.6 Continuation 保存列表和控制寄存器的操作
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
ED4i | c[i] PUSHCTR c[i] PUSH | - x | 推送控制寄存器 c(i) 的当前值。如果当前代码页不支持该控制寄存器,或者它没有值,则触发异常。 | 26 |
ED44 | c4 PUSHCTR c4 PUSH | - x | 推送“全局数据根”cell引用,从而使访问持久智能合约数据成为可能。 | 26 |
ED5i | c[i] POPCTR c[i] POP | x - | 从栈中弹出一个值 x 并存储到控制寄存器 c(i) 中(如果当前代码页支持)。注意,如果控制寄存器仅接受特定类型的值,则可能发生类型检查异常。 | 26 |
ED54 | c4 POPCTR c4 POP | x - | 设置“全局数据根”cell引用,从而允许修改持久智能合约数据。 | 26 |
ED6i | c[i] SETCONT c[i] SETCONTCTR | x c - c' | 将 x 存储到 continuation c 的 savelist 中作为 c(i) ,并返回结果 continuation c' 。几乎所有与 continuations 的操作都可以用 SETCONTCTR 、POPCTR 和 PUSHCTR 来表达。 | 26 |
ED7i | c[i] SETRETCTR | x - | 等同于 c0 PUSHCTR c[i] SETCONTCTR c0 POPCTR 。 | 26 |
ED8i | c[i] SETALTCTR | x - | 等同于 c1 PUSHCTR c[i] SETCONTCTR c0 POPCTR 。 | 26 |
ED9i | c[i] POPSAVE c[i] POPCTRSAVE | x - | 类似于 c[i] POPCTR ,但还将 c[i] 的旧值保存到 continuation c0 中。等同于(直到异常) c[i] SAVECTR c[i] POPCTR 。 | 26 |
EDAi | c[i] SAVE c[i] SAVECTR | 将 c(i) 的当前值保存到 continuation c0 的 savelist 中。如果 c0 的 savelist 中已存在 c[i] 的条目,则不做任何操作。等同于 c[i] PUSHCTR c[i] SETRETCTR 。 | 26 | |
EDBi | c[i] SAVEALT c[i] SAVEALTCTR | 类似于 c[i] SAVE ,但将 c[i] 的当前值保存到 c1 (而不是 c0 )的 savelist 中。 | 26 | |
EDCi | c[i] SAVEBOTH c[i] SAVEBOTHCTR | 等同于 DUP c[i] SAVE c[i] SAVEALT 。 | 26 | |
EDE0 | PUSHCTRX | i - x | 类似于 c[i] PUSHCTR ,但 i , 0 <= i <= 255 , 来自栈。注意,这个原语是少数“异乎寻常”的原语之一,它们不像栈操作原语那样是多态的,同时参数和返回值的类型也没有良好定义,因为 x 的类型取决于 i 。 | 26 |
EDE1 | POPCTRX | x i - | 类似于 c[i] POPCTR ,但 0 <= i <= 255 来自栈。 | 26 |
EDE2 | SETCONTCTRX | x c i - c' | 类似于 c[i] SETCONTCTR ,但 0 <= i <= 255 来自栈。 | 26 |
EDF0 | COMPOS BOOLAND | c c' - c'' | 计算组合 compose0(c, c’) ,它的意义为“执行 c ,如果成功,执行 c' ”(如果 c 是布尔电路)或简单地“执行 c ,然后执行 c' ”。等同于 SWAP c0 SETCONT 。 | 26 |
EDF1 | COMPOSALT BOOLOR | c c' - c'' | 计算替代组合 compose1(c, c’) ,它的意义为“执行 c ,如果不成功,执行 c' ”(如果 c 是布尔电路)。等同于 SWAP c1 SETCONT 。 | 26 |
EDF2 | COMPOSBOTH | c c' - c'' | 计算组合 compose1(compose0(c, c’), c’) ,它的意义为“计算布尔电路 c ,然后无论 c 的结果如何,都计算 c' ”。 | 26 |
EDF3 | ATEXIT | c - | 将 c0 设置为 compose0(c, c0) 。换句话说,c 将在退出当前子程序之前执行。 | 26 |
EDF3 | ATEXIT:<{ code }> <{ code }>ATEXIT | - | 等同于 <{ code }> CONT ATEXIT 。 | |
EDF4 | ATEXITALT | c - | 将 c1 设置为 compose1(c, c1) 。换句话说,c 将在通过其替代返回路径退出当前子程序之前执行。 | 26 |
EDF4 | ATEXITALT:<{ code }> <{ code }>ATEXITALT | - | 等同于 <{ code }> CONT ATEXITALT 。 | |
EDF5 | SETEXITALT | c - | 将 c1 设置为 compose1(compose0(c, c0), c1) ,这样,后续的 RETALT 将首先执行 c ,然后将控制权转移给原始的 c0 。例如,这可以用来从嵌套循环中退出。 | 26 |
EDF6 | THENRET | c - c' | 计算 compose0(c, c0) 。 | 26 |
EDF7 | THENRETALT | c - c' | 计算 compose0(c, c1) | 26 |
EDF8 | INVERT | - | 交换 c0 和 c1 。 | 26 |
EDF9 | BOOLEVAL | c - ? | 执行 cc:=compose1(compose0(c, compose0(-1 PUSHINT, cc)), compose0(0 PUSHINT, cc)) 。如果 c 代表一个布尔电路,其最终效果是评估它,并在继续执行之前将 -1 或 0 推入栈中。 | 26 |
EDFA | SAMEALT | - | 将 c1 设置为 c0 。等同于 c0 PUSHCTR c1 POPCTR 。 | 26 |
EDFB | SAMEALTSAVE | - | 将 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 。例如,这里可以使用 CALLXARGS 或 CALLCC 代替 EXECUTE 。 |
9 异常产生与处理原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F22_n | [n] THROW | - 0 n | 抛出参数为零的 0 <= n <= 63 异常。换句话说,它将控制权转移到 c2 中的continuation,将 0 和 n 推入其堆栈,并彻底丢弃旧堆栈。 | 76 |
F26_n | [n] THROWIF | f - | 只有当整数 f!=0 时,才抛出参数为零的 0 <= n <= 63 异常。 | 26/76 |
F2A_n | [n] THROWIFNOT | f - | 只有当整数 f=0 时,才抛出参数为零的 0 <= n <= 63 异常。 | 26/76 |
F2C4_n | [n] THROW | - 0 nn | 对于 0 <= n < 2^11 ,是 [n] THROW 的编码,用于 n 的较大值。 | 84 |
F2CC_n | [n] THROWARG | x - x nn | 抛出带有参数 x 的 0 <= n < 2^11 异常,通过将 x 和 n 复制到 c2 的堆栈并将控制权转移给 c2 。 | 84 |
F2D4_n | [n] THROWIF | f - | 对于 0 <= n < 2^11 ,是 [n] THROWIF 的编码,用于 n 的较大值。 | 34/84 |
F2DC_n | [n] THROWARGIF | x f - | 只有当整数 f!=0 时,才抛出带有参数 x 的 0 <= nn < 2^11 异常。 | 34/84 |
F2E4_n | [n] THROWIFNOT | f - | 对于 0 <= n < 2^11 ,是 [n] THROWIFNOT 的编码,用于 n 的较大值。 | 34/84 |
F2EC_n | [n] THROWARGIFNOT | x f - | 只有当整数 f=0 时,才抛出带有参数 x 的 0 <= n < 2^11 异常。 | 34/84 |
F2F0 | THROWANY | n - 0 n | 抛出参数为零的 0 <= n < 2^16 异常。大致相当于 ZERO SWAP THROWARGANY 。 | 76 |
F2F1 | THROWARGANY | x n - x n | 抛出带有参数 x 的 0 <= n < 2^16 异常,将控制权转移到 c2 中。大致相当于 c2 PUSHCTR 2 JMPXARGS 。 | 76 |
F2F2 | THROWANYIF | n f - | 只有当 f!=0 时,才抛出参数为零的 0 <= n < 2^16 异常。 | 26/76 |
F2F3 | THROWARGANYIF | x n f - | 只有当 f!=0 时,才抛出带有参数 x 的 0 <= n<2^16 异常。 | 26/76 |
F2F4 | THROWANYIFNOT | n f - | 只有当 f=0 时,才抛出参数为零的 0 <= n<2^16 异常。 | 26/76 |
F2F5 | THROWARGANYIFNOT | x n f - | 只有当 f=0 时,才抛出带有参数 x 的 0 <= n<2^16 异常。 | 26/76 |
F2FF | TRY | c c' - | 设置 c2 为 c' ,首先将 c2 的旧值同时保存到 c' 的保存列表和当前continuation的保存列表中,该当前continuation存储到 c.c0 和 c'.c0 中。然后类似于 EXECUTE 运行 c 。如果 c 没有引发任何异常,从 c 返回时会自动恢复 c2 的原始值。如果发生异常,则执行权转移到 c' ,但在此过程中恢复了 c2 的原始值,以便 c' 可以通过 THROWANY 重新抛出异常(如果它自己无法处理)。 | 26 |
F2FF | TRY:<{ code1 }>CATCH<{ code2 }> | - | 等效于 <{ code1 }> CONT <{ code2 }> CONT TRY 。 | |
F3pr | [p] [r] TRYARGS | c c' - | 类似于 TRY ,但内部使用的是 [p] [r] CALLXARGS 而不是 EXECUTE 。这样,顶部 0 <= p <= 15 堆栈元素以外的所有元素将保存到当前continuation的堆栈中,然后从 c 或 c' 返回时恢复,并将 c 或 c' 的结果堆栈的顶部 0 <= r <= 15 值作为返回值复制。 | 26 |
10 字典操作原语
大多数字典操作的燃气消耗不是固定的,它取决于给定字典的内容。
10.1 字典创建
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
6D | NEWDICT | - D | 返回一个新的空字典。 它是 PUSHNULL 的另一种助记符。 | 18 |
6E | DICTEMPTY | D - ? | 检查字典 D 是否为空,并相应地返回 -1 或 0 。它是 ISNULL 的另一种助记符。 | 18 |
10.2 字典序列化与反序列化
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
CE | STDICTS `` | s b - b' | 将以切片表示的字典 s 存储进构建器 b 中。实际上,这是 STSLICE 的同义词。 | 18 |
F400 | STDICT STOPTREF | D b - b' | 将字典 D 存入构建器 b ,返回结果 构建器 b' 。换言之,如果 D 是一个cell,执行 STONE 和 STREF ;如果 D 是 Null,执行 NIP 和 STZERO ;否则抛出类型检查异常。 | 26 |
F401 | SKIPDICT SKIPOPTREF | s - s' | 相当于 LDDICT NIP 。 | 26 |
F402 | LDDICTS | s - s' s'' | 从切片 s 中加载(解析)以切片表示的字典 s' ,并将 s 的剩余部分作为 s'' 返回。这是所有 HashmapE(n,X) 类型字典的“分裂函数”。 | 26 |
F403 | PLDDICTS | s - s' | 从切片 s 中预加载以切片表示的字典 s' 。大致相当于 LDDICTS DROP 。 | 26 |
F404 | LDDICT LDOPTREF | s - D s' | 从切片 s 中加载(解析)字典 D ,并将 s 的剩余部分作为 s' 返回。可应用于字典或任意 (^Y)? 类型的值。 | 26 |
F405 | PLDDICT PLDOPTREF | s - D | 从切片 s 中预加载字典 D 。大致相当于 LDDICT DROP 。 | 26 |
F406 | LDDICTQ | s - D s' -1或 s 0 | LDDICT 的静默版本。 | 26 |
F407 | PLDDICTQ | s - D -1或0 | PLDDICT 的静默版本。 | 26 |
10.3 获取字典操作
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F40A | DICTGET | k D n - x -1或0 | 在类型为 HashmapE(n,X) 且拥有 n -位键的字典 D 中查找键 k (由切片表示,其前 0 <= n <= 1023 数据位被用作键)。成功时,以切片 x 的形式返回找到的值。 | |
F40B | DICTGETREF | k D n - c -1或0 | 与 DICTGET 类似,但在成功时对 x 应用 LDREF ENDS 。此操作对于类型为 HashmapE(n,^Y) 的字典很有用。 | |
F40C | DICTIGET | i D n - x -1或0 | 与 DICTGET 类似,但使用带符号的(大端)n -位 整型 i 作为键。如果 i 不能放入 n 位,则返回 0 。如果 i 是 NaN ,抛出整数溢出异常。 | |
F40D | DICTIGETREF | i D n - c -1或0 | 组合 DICTIGET 与 DICTGETREF :它使用带符号的 n -位 整型 i 作为键,并在成功时返回 cell 而不是切片。 | |
F40E | DICTUGET | i D n - x -1或0 | 与 DICTIGET 类似,但使用无符号的(大端)n -位 整型 i 作为键。 | |
F40F | DICTUGETREF | i D n - c -1或0 | 与 DICTIGETREF 类似,但使用一个无符号 n -位 整型 键 i 。 |
10.4 设置/替换/添加字典操作
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F412 | DICTSET | x k D n - D' | 在字典 D (同样用切片表示)中设置 n -位键 k (如 DICTGET 中用切片表示)关联的值为 x (再次是切片),并返回结果字典 D' 。 | |
F413 | DICTSETREF | c k D n - D' | 类似于 DICTSET ,但设置的值为对cell c 的引用。 | |
F414 | DICTISET | x i D n - D' | 类似于 DICTSET ,但键由(大端)有符号 n -位整数 i 表示。如果 i 不能放入 n 位,则生成范围检查异常。 | |
F415 | DICTISETREF | c i D n - D' | 类似于 DICTSETREF ,但键由 DICTISET 中的有符号 n -位整数表示。 | |
F416 | DICTUSET | x i D n - D' | 类似于 DICTISET ,但 i 为 无符号 n -位整数。 | |
F417 | DICTUSETREF | c i D n - D' | 类似于 DICTISETREF ,但 i 为无符号。 | |
F41A | DICTSETGET | x k D n - D' y -1或 D' 0 | 结合 DICTSET 和 DICTGET :它将键 k 对应的值设置为 x ,但也返回该键原有的旧值 y (如果存在)。 | |
F41B | DICTSETGETREF | c k D n - D' c' -1或 D' 0 | 类似于 DICTSETGET 的 DICTSETREF 与 DICTGETREF 的组合。 | |
F41C | DICTISETGET | x i D n - D' y -1或 D' 0 | DICTISETGET ,但 i 为有符号 n -位整数。 | |
F41D | DICTISETGETREF | c i D n - D' c' -1或 D' 0 | DICTISETGETREF ,但 i 为有符号 n -位整数。 | |
F41E | DICTUSETGET | x i D n - D' y -1或 D' 0 | DICTISETGET ,但 i 为无符号 n -位整数。 | |
F41F | DICTUSETGETREF | c i D n - D' c' -1或 D' 0 | DICTISETGETREF ,但 i 为无符号 n -位整数。 | |
F422 | DICTREPLACE | x k D n - D' -1或 D 0 | 一个 替换 操作,类似于 DICTSET ,但只有当键 k 已经存在于 D 中时才会将 D 中键 k 的值设置为 x 。 | |
F423 | DICTREPLACEREF | c k D n - D' -1或 D 0 | DICTSETREF 的 替换 对应操作。 | |
F424 | DICTIREPLACE | x i D n - D' -1或 D 0 | DICTREPLACE ,但 i 为有符号 n -位整数。 | |
F425 | DICTIREPLACEREF | c i D n - D' -1或 D 0 | DICTREPLACEREF ,但 i 为有符号 n -位整数。 | |
F426 | DICTUREPLACE | x i D n - D' -1或 D 0 | DICTREPLACE ,但 i 为无符号 n -位整数。 | |
F427 | DICTUREPLACEREF | c i D n - D' -1或 D 0 | DICTREPLACEREF ,但 i 为无符号 n -位整数。 | |
F42A | DICTREPLACEGET | x k D n - D' y -1或 D 0 | DICTSETGET 的 替换 对应操作:成功时,还会返回与该键相关的旧值。 | |
F42B | DICTREPLACEGETREF | c k D n - D' c' -1或 D 0 | DICTSETGETREF 的 替换 对应操作。 | |
F42C | DICTIREPLACEGET | x i D n - D' y -1或 D 0 | DICTREPLACEGET ,但 i 为有符号 n -位整数。 | |
F42D | DICTIREPLACEGETREF | c i D n - D' c' -1或 D 0 | DICTREPLACEGETREF ,但 i 为有符号 n -位整数。 | |
F42E | DICTUREPLACEGET | x i D n - D' y -1或 D 0 | DICTREPLACEGET ,但 i 为无符号 n -位整数。 | |
F42F | DICTUREPLACEGETREF | c i D n - D' c' -1或 D 0 | DICTREPLACEGETREF ,但 i 为无符号 n -位整数。 | |
F432 | DICTADD | x k D n - D' -1或 D 0 | DICTSET 的 添加 对应操作:在字典 D 中将与键 k 关联的值设置为 x ,但只有当它还未在 D 中存在时。 | |
F433 | DICTADDREF | c k D n - D' -1或 D 0 | DICTSETREF 的 添加 对应操作。 | |
F434 | DICTIADD | x i D n - D' -1或 D 0 | DICTADD ,但 i 为有符号 n -位整数。 | |
F435 | DICTIADDREF | c i D n - D' -1或 D 0 | DICTADDREF ,但 i 为有符号 n -位整数。 | |
F436 | DICTUADD | x i D n - D' -1或 D 0 | DICTADD ,但 i 为无符号 n -位整数。 | |
F437 | DICTUADDREF | c i D n - D' -1或 D 0 | DICTADDREF ,但 i 为无符号 n -位整数。 | |
F43A | DICTADDGET | x k D n - D' -1或 D y 0 | DICTSETGET 的 添加 对应操作:在字典 D 中将与键 k 关联的值设置为 x ,但只有当键 k 还未在 D 中存在时。否则,仅返回旧值 y ,不更改字典。 | |
F43B | DICTADDGETREF | c k D n - D' -1或 D c' 0 | DICTSETGETREF 的 添加 对应操作。 | |
F43C | DICTIADDGET | x i D n - D' -1或 D y 0 | DICTADDGET ,但 i 为有符号 n -位整数。 | |
F43D | DICTIADDGETREF | c i D n - D' -1或 D c' 0 | DICTADDGETREF ,但 i 为有符号 n -位整数。 | |
F43E | DICTUADDGET | x i D n - D' -1或 D y 0 | DICTADDGET ,但 i 为无符号 n -位整数。 | |
F43F | DICTUADDGETREF | c i D n - D' -1或 D c' 0 | DICTADDGETREF ,但 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 |
---|---|---|---|---|
F459 | DICTDEL | k D n - D' -1或 D 0 | 从字典 D 中删除由切片 k 表示的 n -位键。如果键存在,返回修改后的字典 D' 和成功标志位 -1 。否则,返回原始字典 D 和 0 。 | |
F45A | DICTIDEL | i D n - D' ? | DICTDEL 的一个版本,键由有符号的 n -位 整数 i 表示。如果 i 不能放入 n 位,简单地返回 D 0 (“键未找到,字典未修改”)。 | |
F45B | DICTUDEL | i D n - D' ? | 类似于 DICTIDEL ,但 i 为无符号的 n -位整数。 | |
F462 | DICTDELGET | k D n - D' x -1或 D 0 | 从字典 D 中删除由切片 k 表示的 n -位键。如果键存在,返回修改后的字典 D' 、与键 k 关联的原始值 x (由切片表示),和成功标志位 -1 。否则,返回原始字典 D 和 0 。 | |
F463 | DICTDELGETREF | k D n - D' c -1或 D 0 | 类似于 DICTDELGET ,但成功时对 x 应用 LDREF ENDS ,以便返回的值 c 是一个cell。 | |
F464 | DICTIDELGET | i D n - D' x -1或 D 0 | DICTDELGET ,但 i 为有符号的 n -位整数。 | |
F465 | DICTIDELGETREF | i D n - D' c -1或 D 0 | DICTDELGETREF ,但 i 为有符号的 n -位整数。 | |
F466 | DICTUDELGET | i D n - D' x -1或 D 0 | DICTDELGET ,但 i 为无符号的 n -位整数。 | |
F467 | DICTUDELGETREF | i D n - D' c -1或 D 0 | DICTDELGETREF ,但 i 为无符号的 n -位整数。 |
10.7 “可能是引用”的字典操作
以下操作假设使用字典存储类型为可能是cell(Maybe Cell)的值 c?
。表示如下:如果 c?
是一个cell,它作为一个没有数据位且恰好有一个对这个cell的引用的值存储。如果 c?
是Null,则对应的键必须从字典中缺失。
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F469 | DICTGETOPTREF | k D n - c^? | DICTGETREF 的一个变体,如果键 k 不存在于字典 D 中,则返回 Null 而不是值 c^? 。 | |
F46A | DICTIGETOPTREF | i D n - c^? | DICTGETOPTREF 的版本,但 i 为有符号的 n -位整数。如果键 i 超出范围,也返回 Null。 | |
F46B | DICTUGETOPTREF | i D n - c^? | DICTGETOPTREF 的版本,但 i 为无符号的 n -位整数。如果键 i 超出范围,也返回 Null。 | |
F46D | DICTSETGETOPTREF | c^? k D n - D' ~c^? | DICTGETOPTREF 和 DICTSETGETREF 的一个变体,将字典 D 中键 k 对应的值设置为 c^? (如果 c^? 是Null,则删除该键),并返回旧值 ~c^? (如果键 k 之前缺失,返回Null)。 | |
F46E | DICTISETGETOPTREF | c^? i D n - D' ~c^? | 类似于 DICTSETGETOPTREF 的原语,但使用有符号的 n -位 整数 i 作为键。如果 i 不能放入 n 位,抛出范围检查异常。 | |
F46F | DICTUSETGETOPTREF | c^? i D n - D' ~c^? | 类似于 DICTSETGETOPTREF 的原语,但使用无符号的 n -位 整数 i 作为键。 |
10.8 前缀码字典操作
构建前缀码字典的一些基本操作。
这些原语与它们非前缀码(DICTSET
等)的对应操作完全相同,不过在前缀码字典中,即使是 Set 也可能失败,因此 PFXDICTSET
也必须返回成功标志位。
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F470 | PFXDICTSET | x k D n - D' -1或 D 0 | ||
F471 | PFXDICTREPLACE | x k D n - D' -1或 D 0 | ||
F472 | PFXDICTADD | x k D n - D' -1或 D 0 | ||
F473 | PFXDICTDEL | k D n - D' -1或 D 0 |
10.9 GetNext 和 GetPrev 操作的变体
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F474 | DICTGETNEXT | k D n - x' k' -1或 0 | 计算字典 D 中字典序大于 k 的最小键 k' ,并返回 k' (由切片表示)及其关联的值 x' (也由切片表示)。 | |
F475 | DICTGETNEXTEQ | k D n - x' k' -1或 0 | 类似于 DICTGETNEXT ,但计算字典序大于或等于 k 的最小键 k' 。 | |
F476 | DICTGETPREV | k D n - x' k' -1或 0 | 类似于 DICTGETNEXT ,但计算字典序小于 k 的最大键 k' 。 | |
F477 | DICTGETPREVEQ | k D n - x' k' -1或 0 | 类似于 DICTGETPREV ,但计算字典序小于或等于 k 的最大键 k' 。 | |
F478 | DICTIGETNEXT | i D n - x' i' -1或 0 | 类似于 DICTGETNEXT ,但将字典 D 中的所有键解释为大端有符号的 n -位整数,并计算大于整数 i 的最小键 i' (i 不一定能放入 n 位)。 | |
F479 | DICTIGETNEXTEQ | i D n - x' i' -1或 0 | 类似于 DICTGETNEXTEQ ,但将键解释为有符号的 n -位整数。 | |
F47A | DICTIGETPREV | i D n - x' i' -1或 0 | 类似于 DICTGETPREV ,但将键解释为有符号的 n -位整数。 | |
F47B | DICTIGETPREVEQ | i D n - x' i' -1或 0 | 类似于 DICTGETPREVEQ ,但将键解释为有符号的 n -位整数。 | |
F47C | DICTUGETNEXT | i D n - x' i' -1或 0 | 类似于 DICTGETNEXT ,但将字典 D 中的所有键解释为大端无符号的 n -位整数,并计算大于整数 i 的最小键 i' (i 不一定能放入 n 位,也不一定是非负的)。 | |
F47D | DICTUGETNEXTEQ | i D n - x' i' -1或 0 | 类似于 DICTGETNEXTEQ ,但将键解释为无符号的 n -位整数。 | |
F47E | DICTUGETPREV | i D n - x' i' -1或 0 | 类似于 DICTGETPREV ,但将键解释为无符号的 n -位整数。 | |
F47F | DICTUGETPREVEQ | i D n - x' i' -1或 0 | 类似于 DICTGETPREVEQ ,但将键解释为无符号的 n -位整数。 |
10.10 GetMin, GetMax, RemoveMin, RemoveMax 操作
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F482 | DICTMIN | D n - x k -1或 0 | 计算字典 D 中的最小键 k (由拥有 n 数据位的切片表示),并返回 k 及其关联的值 x 。 | |
F483 | DICTMINREF | D n - c k -1或 0 | 类似于 DICTMIN ,但返回值中唯一的引用作为cell c 。 | |
F484 | DICTIMIN | D n - x i -1或 0 | 类似于 DICTMIN ,但在假设所有键为大端有符号的 n -位整数的情况下计算最小键 i 。注意,返回的键和值可能与 DICTMIN 和 DICTUMIN 计算出的不同。 | |
F485 | DICTIMINREF | D n - c i -1或 0 | 类似于 DICTIMIN ,但返回值中唯一的引用。 | |
F486 | DICTUMIN | D n - x i -1或 0 | 类似于 DICTMIN ,但以无符号 n -位 整数 i 的形式返回键。 | |
F487 | DICTUMINREF | D n - c i -1或 0 | 类似于 DICTUMIN ,但返回值中唯一的引用。 | |
F48A | DICTMAX | D n - x k -1或 0 | 计算字典 D 中的最大键 k (由拥有 n 数据位的切片表示),并返回 k 及其关联的值 x 。 | |
F48B | DICTMAXREF | D n - c k -1或 0 | 类似于 DICTMAX ,但返回值中唯一的引用。 | |
F48C | DICTIMAX | D n - x i -1或 0 | 类似于 DICTMAX ,但在假设所有键为大端有符号的 n -位整数的情况下计算最大键 i 。注意,返回的键和值可能与 DICTMAX 和 DICTUMAX 计算出的不同。 | |
F48D | DICTIMAXREF | D n - c i -1或 0 | 类似于 DICTIMAX ,但返回值中唯一的引用。 | |
F48E | DICTUMAX | D n - x i -1或 0 | 类似于 DICTMAX ,但以无符号 n -位 整数 i 的形式返回键。 | |
F48F | DICTUMAXREF | D n - c i -1或 0 | 类似于 DICTUMAX ,但返回值中唯一的引用。 | |
F492 | DICTREMMIN | D n - D' x k -1或D 0 | 计算字典 D 中的最小键 k (以n数据位的切片形式表示),从字典中移除 k ,并返回 k 及其关联的值 x 和修改后的字典 D' 。 | |
F493 | DICTREMMINREF | D n - D' c k -1或D 0 | 类似于 DICTREMMIN ,但返回值中唯一的引用作为cell c 。 | |
F494 | DICTIREMMIN | D n - D' x i -1或D 0 | 类似于 DICTREMMIN ,但计算最小键 i ,假设所有键都是大端有符号的n-位整数。请注意,返回的键和值可能与DICTREMMIN 和 DICTUREMMIN 计算的不同。 | |
F495 | DICTIREMMINREF | D n - D' c i -1或D 0 | 类似于 DICTIREMMIN ,但返回值中唯一的引用。 | |
F496 | DICTUREMMIN | D n - D' x i -1或D 0 | 类似于 DICTREMMIN ,但以无符号n-位整数 i 形式返回键。 | |
F497 | DICTUREMMINREF | D n - D' c i -1或D 0 | 类似于 DICTUREMMIN ,但返回值中唯一的引用。 | |
F49A | DICTREMMAX | D n - D' x k -1或D 0 | 计算字典 D 中的最大键 k (以n数据位的切片形式表示),从字典中移除 k ,并返回 k 及其关联的值 x 和修改后的字典 D' 。 | |
F49B | DICTREMMAXREF | D n - D' c k -1或D 0 | 类似于 DICTREMMAX ,但返回值中唯一的引用作为cell c 。 | |
F49C | DICTIREMMAX | D n - D' x i -1或D 0 | 类似于 DICTREMMAX ,但计算最大键 i ,假设所有键都是大端有符号的n-位整数。请注意,返回的键和值可能与DICTREMMAX 和 DICTUREMMAX 计算的不同。 | |
F49D | DICTIREMMAXREF | D n - D' c i -1或D 0 | 类似于 DICTIREMMAX ,但返回值中唯一的引用。 | |
F49E | DICTUREMMAX | D n - D' x i -1或D 0 | 类似于 DICTREMMAX ,但以无符号n-位整数 i 形式返回键。 | |
F49F | DICTUREMMAXREF | D n - D' c i -1或D 0 | 类似于 DICTUREMMAX ,但返回值中唯一的引用。 |
10.11 特殊的获取字典和前缀码字典操作以及常量字典
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F4A0 | DICTIGETJMP | i D n - | 类似于 DICTIGET ,但在成功时将 x BLESS 成一个continuation,并随后执行对其的 JMPX 。失败时不执行任何操作。这对于实现 switch /case 结构很有用。 | |
F4A1 | DICTUGETJMP | i D n - | 类似于 DICTIGETJMP ,但执行 DICTUGET 而非 DICTIGET 。 | |
F4A2 | DICTIGETEXEC | i D n - | 类似于 DICTIGETJMP ,但使用 EXECUTE 而非 JMPX 。 | |
F4A3 | DICTUGETEXEC | i 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 |
F4A8 | PFXDICTGETQ | s D n - s' x s'' -1或s 0 | 在前缀码字典中查找切片 s 的唯一前缀,该字典由 Cell^? D 和 0 <= n <= 1023 表示。如果找到,作为 s' 返回 s 的前缀,并作为切片 x 返回相应的值。s 的剩余部分作为切片 s'' 返回。如果 s 的任何前缀不是前缀码字典 D 中的键,则返回未更改的 s 和零标志位以表示失败。 | |
F4A9 | PFXDICTGET | s D n - s' x s'' | 类似于 PFXDICTGET ,但在失败时抛出cell反序列化失败异常。 | |
F4AA | PFXDICTGETJMP | s D n - s' s''或s | 类似于 PFXDICTGETQ ,但成功时将值 x BLESS 成一个continuation,并像执行 JMPX 一样转移控制权。失败时,返回未改变的 s 并继续执行。 | |
F4AB | PFXDICTGETEXEC | s D n - s' s'' | 类似于 PFXDICTGETJMP ,但执行找到的continuation而非跳转它。失败时,抛出cell反序列化异常。 | |
F4AE_n | [ref] [n] PFXDICTCONSTGETJMP [ref] [n] PFXDICTSWITCH | s - s' s''或s | 将 [n] DICTPUSHCONST 和 PFXDICTGETJMP 结合起来,用于 0 <= n <= 1023 。 | |
F4BC | DICTIGETJMPZ | i D n - i或nothing | DICTIGETJMP 的一个变种,在失败时返回索引 i 。 | |
F4BD | DICTUGETJMPZ | i D n - i或nothing | DICTUGETJMP 的一个变种,在失败时返回索引 i 。 | |
F4BE | DICTIGETEXECZ | i D n - i或nothing | DICTIGETEXEC 的一个变种,在失败时返回索引 i 。 | |
F4BF | DICTUGETEXECZ | i D n - i或nothing | DICTUGETEXEC 的一个变种,在失败时返回索引 i 。 |
10.12 SubDict 字典操作
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F4B1 | SUBDICTGET | k l D n - D' | 构建一个由所有以前缀 k (由一个切片表示,其前 0 <= l <= n <= 1023 个数据位用作键)为前缀的字典 D 中的键组成的子字典。这里的 D 是类型为 HashmapE(n,X) 的字典,拥有 n 位的键。成功时,返回同类型 HashmapE(n,X) 的新子字典作为一个切片 D' 。 | |
F4B2 | SUBDICTIGET | x l D n - D' | SUBDICTGET 的变体,前缀由有符号的大端 l -位整数 x 表示,必须满足 l <= 257 。 | |
F4B3 | SUBDICTUGET | x l D n - D' | SUBDICTGET 的变体,前缀由无符号的大端 l -位整数 x 表示,必须满足 l <= 256 。 | |
F4B5 | SUBDICTRPGET | k l D n - D' | 类似于 SUBDICTGET ,但从新字典 D' 的所有键中移除公共前缀 k ,它变为 HashmapE(n-l,X) 类型。 | |
F4B6 | SUBDICTIRPGET | x l D n - D' | SUBDICTRPGET 的变体,前缀由有符号的大端 l -位整数 x 表示,必须满足 l <= 257 。 | |
F4B7 | SUBDICTURPGET | x l D n - D' | SUBDICTRPGET 的变体,前缀由无符号的大端 l -位整数 x 表示,必须满足 l <= 256 。 |
11 应用特定原语
11.1 与 Gas 相关的原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F800 | ACCEPT | - | 将当前的 Gas 限制 g_l 设置为其允许的最大值 g_m ,并将 Gas 信用 g_c 重置为零,同时减少 g_r 的值 g_c 。换句话说,当前的智能合约同意购买一些 Gas 以完成当前交易。此操作是处理外部消息所必需的,这些消息本身不携带价值(因而没有 Gas)。 | 26 |
F801 | SETGASLIMIT | g - | 将当前的 Gas 限制 g_l 设置为 g 与 g_m 的最小值,并将 Gas 信用 g_c 重置为零。如果到目前为止所消耗的 Gas(包括当前指令)超过了所得的 g_l 值,则在设置新的 Gas 限制之前抛出(未处理的)Gas 超限异常。请注意,带有参数 g >= 2^63-1 的 SETGASLIMIT 等同于 ACCEPT 。 | 26 |
F80F | COMMIT | - | 提交寄存器 c4 (“持久数据”)和 c5 (“操作”)的当前状态,以便即使后来抛出异常,当前执行也被视为“成功”,并保存了这些值。 | 26 |
11.2 伪随机数生成器原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F810 | RANDU256 | - x | 生成一个新的伪随机的无符号 256 位 整数 x 。算法如下: 如果 r 是旧的随机种子值,被视为一个 32 字节的数组(通过构造一个无符号 256 位整数的大端表示),则计算其 sha512(r) ;这个哈希的前 32 字节被存储为新的随机种子值 r' ,剩下的 32 字节作为下一个随机值 x 返回。 | 26+\|c7\|+\|c1_1\| |
F811 | RAND | y - z | 在 0...y-1 (或 y...-1 , 如果 y<0 )范围内生成一个新的伪随机整数 z 。更确切地说,生成一个无符号随机值 x ,如同在 RAND256U 中;然后计算 z:=floor(x*y/2^256) 。等同于 RANDU256 256 MULRSHIFT . | 26+\|c7\|+\|c1_1\| |
F814 | SETRAND | x - | 将随机种子设置为无符号 256 位 整数 x 。 | 26+\|c7\|+\|c1_1\| |
F815 | ADDRAND 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 |
F823 | NOW | - x | 返回当前 Unix 时间作为一个 整数。如果从 c7 开始无法恢复请求的值,则抛出类型检查或范围检查异常。等同于 3 GETPARAM . | 26 |
F824 | BLOCKLT | - x | 返回当前区块的开始逻辑时间。 等同于 4 GETPARAM . | 26 |
F825 | LTIME | - x | 返回当前交易的逻辑时间。 等同于 5 GETPARAM . | 26 |
F826 | RANDSEED | - x | 以无符号 256 位 整数 的形式返回当前的随机种子。 等同于 6 GETPARAM . | 26 |
F827 | BALANCE | - t | 以 元组 形式返回智能合约剩余的余额,元组 包含一个 整数(剩余的Gram余额,以nanograms为单位)和一个 可能的cell(以 32 位键表示的“额外代币”的余额字典)。 等同于 7 GETPARAM .请注意,如 SENDRAWMSG 等 RAW 原语不会更新此字段。 | 26 |
F828 | MYADDR | - s | 以 分片 形式返回当前智能合约的内部地址,包含一个 MsgAddressInt 。如果必要,可以使用诸如 PARSEMSGADDR 或 REWRITESTDADDR 之类的原语进一步解析它。等同于 8 GETPARAM . | 26 |
F829 | CONFIGROOT | - D | 以 可能的cell D 形式返回当前全局配置字典。等同于 9 GETPARAM 。 | 26 |
F830 | CONFIGDICT | - D 32 | 返回全局配置字典及其键长(32)。 等同于 CONFIGROOT 32 PUSHINT . | 26 |
F832 | CONFIGPARAM | i - c -1 或 0 | 以 cell c 的形式返回整数索引 i 的全局配置参数的值,以及指示成功的标志位。等同于 CONFIGDICT DICTIGETREF . | |
F833 | CONFIGOPTPARAM | i - c^? | 以 可能的cell c^? 的形式返回整数索引 i 的全局配置参数的值。等同于 CONFIGDICT DICTIGETOPTREF . |
11.4 全局变量原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F840 | GETGLOBVAR | k - x | 返回第 k 个全局变量,对于 0 <= k < 255 。相当于 c7 PUSHCTR SWAP INDEXVARQ 。 | 26 |
F85_k | [k] GETGLOB | - x | 返回第 k 个全局变量,对于 1 <= k <= 31 。相当于 c7 PUSHCTR [k] INDEXQ 。 | 26 |
F860 | SETGLOBVAR | x k - | 将 x 分配给第 k 个全局变量,对于 0 <= k < 255 。相当于 c7 PUSHCTR ROTREV SETINDEXVARQ c7 POPCTR 。 | 26+\|c7’\| |
F87_k | [k] SETGLOB | x - | 将 x 分配给第 k 个全局变量,对于 1 <= k <= 31 。相当于 c7 PUSHCTR SWAP k SETINDEXQ c7 POPCTR 。 | 26+\|c7’\| |
11.5 哈希和密码学原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F900 | HASHCU | c - x | 计算 cell c 的表示哈希,并将其作为 256 位无符号整数 x 返回。用于对由cell树表示的任意实体进行签名和检查签名。 | 26 |
F901 | HASHSU | s - x | 计算 分片 s 的哈希,并将其作为 256 位无符号整数 x 返回。结果与如果创建了一个仅包含 s 的数据和引用的普通cell并通过 HASHCU 计算其哈希相同。 | 526 |
F902 | SHA256U | s - x | 对 分片 s 的数据位计算 Sha 。如果 s 的位长度不能被八整除,抛出一个cell下溢异常。哈希值作为 256 位无符号整数 x 返回。 | 26 |
F910 | CHKSIGNU | h 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 |
F911 | CHKSIGNS | d s k - ? | 检查 s 是否是使用公钥 k 对 分片 d 的数据部分的有效 Ed25519 签名,类似于 CHKSIGNU 。如果 分片 d 的位长度不能被八整除,抛出一个cell下溢异常。Ed25519 签名的验证是标准的,使用 Sha 将 d 缩减为实际签名的 256 位数字。 | 26 |
11.6 其他原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
F940 | CDATASIZEQ | c n - x y z -1 或 0 | 递归计算以 cell c 为根的 dag 中不同cell x 、数据位 y 和cell引用 z 的计数,有效地返回考虑等价cell标识时该 dag 使用的总存储量。x 、y 和 z 的值通过该 dag 的深度优先遍历来计算,使用访问过的cell哈希表来防止已访问cell的重复访问。访问的cell总数 x 不能超过非负 整数 n ;否则,在访问第 (n+1) 个cell之前计算被中断,并返回零表示失败。如果 c 为 空,则返回 x=y=z=0 。 | |
F941 | CDATASIZE | c n - x y z | CDATASIZEQ 的非静默版本,失败时抛出cell溢出异常(8)。 | |
F942 | SDATASIZEQ | s n - x y z -1 或 0 | 类似于 CDATASIZEQ ,但接受一个 分片 s 而非 cell。返回的 x 值不包括包含切片 s 本身的cell;然而,s 的数据位和cell引用在 y 和 z 中被计算在内。 | |
F943 | SDATASIZE | s n - x y z | SDATASIZEQ 的非静默版本,失败时抛出cell溢出异常(8)。 |
11.7 代币操作原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
FA00 | LDGRAMS LDVARUINT16 | s - x s' | 从 分片 s 中加载(反序列化)一个 Gram 或 VarUInteger 16 数量,并以 整数 x 形式返回数量及 s 的剩余部分 s' 。x 的预期序列化格式包括一个 4 位无符号大端整数 l ,随后是 x 的一个 8l 位无符号大端表示。其效果大致等同于 4 LDU SWAP 3 LSHIFT# LDUX 。 | 26 |
FA01 | LDVARINT16 | s - x s' | 与 LDVARUINT16 相似,但加载一个 有符号 整数 x 。大致等同于 4 LDU SWAP 3 LSHIFT# LDIX 。 | 26 |
FA02 | STGRAMS STVARUINT16 | b x - b' | 将范围为 0...2^120-1 内的 整数 x 存储(序列化)到 构建器 b 中,并返回 构建器 b' 的结果。x 的序列化格式包括一个 4 位无符号大端整数 l ,这是满足 x<2^(8l) 的最小的 l>=0 整数,随后是 x 的一个 8l 位无符号大端表示。如果 x 不在支持的范围内,则抛出范围检查异常。 | 26 |
FA03 | STVARINT16 | b x - b' | 类似于 STVARUINT16 ,但序列化一个范围为 -2^119...2^119-1 的 有符号 整数 x 。 | 26 |
11.8 消息和地址操作原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
FA40 | LDMSGADDR | s - s' s'' | 从 分片 s 中加载唯一有效的 MsgAddress 前缀,并将该前缀 s' 和 s 的剩余部分 s'' 作为分片返回。 | 26 |
FA41 | LDMSGADDRQ | s - s' s'' -1 或 s 0 | LDMSGADDR 的静默版本:成功时额外推送 -1 ;失败时推送原始 s 和零。 | 26 |
FA42 | PARSEMSGADDR | s - t | 将包含有效 MsgAddress 的 分片 s 分解为一个具有此 MsgAddress 独立字段的 元组 t 。如果 s 不是有效的 MsgAddress ,则抛出cell反序列化异常。 | 26 |
FA43 | PARSEMSGADDRQ | s - t -1 或 0 | PARSEMSGADDR 的静默版本:错误时返回零而不是抛出异常。 | 26 |
FA44 | REWRITESTDADDR | s - x y | 解析包含有效 MsgAddressInt (通常是 msg_addr_std )的 分片 s ,应用从 anycast (如果存在)到地址的相同长度前缀的重写,并以整数形式返回工作链 x 和 256 位地址 y 。如果地址不是 256 位的,或者如果 s 不是有效的 MsgAddressInt 序列化,则抛出cell反序列化异常。 | 26 |
FA45 | REWRITESTDADDRQ | s - x y -1 或 0 | 原语 REWRITESTDADDR 的静默版本。 | 26 |
FA46 | REWRITEVARADDR | s - x s' | REWRITESTDADDR 的变体,即使地址不是完全为 256 位长(由 msg_addr_var 表示),也返回(重写的)地址作为 分片 s 。 | 26 |
FA47 | REWRITEVARADDRQ | s - x s' -1 或 0 | 原语 REWRITEVARADDR 的静默版本。 | 26 |
11.9 出站消息和输出操作原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
FB00 | SENDRAWMSG | c x - | 发送包含在 cell c 中的原始消息,其中应包含正确序列化的对象 Message X ,唯一的例外是源地址允许有虚拟值 addr_none (将自动替换为当前智能合约地址),且 ihr_fee 、fwd_fee 、created_lt 和 created_at 字段可以有任意值(在当前交易的操作阶段将被正确值重写)。整数参数 x 包含标志位。当前 x=0 用于普通消息;x=128 用于携带当前智能合约所有剩余余额的消息(而非消息最初指示的值);x=64 用于携带除初始指示的新消息值外,入站消息的所有剩余值的消息(如果未设置位 0,则此金额中扣除 gas 费用);x'=x+1 表示发送者想要单独支付转账费用;x'=x+2 表示在操作阶段处理此消息时发生的任何错误都应被忽略。最后,x'=x+32 意味着如果当前账户的最终余额为零,则必须销毁该账户。这个标志位通常与 +128 一起使用。 | 526 |
FB02 | RAWRESERVE | x y - | 创建一个输出操作,该操作将从账户的剩余余额中准确预留 x nanograms(如果 y=0 ),最多 x nanograms(如果 y=2 ),或除 x nanograms外的所有nanograms(如果 y=1 或 y=3 )。这大致相当于创建一个携带 x nanograms(或 b-x nanograms,其中 b 是剩余余额)到自己的出站消息,以便后续输出操作无法花费超过剩余金额的资金。y 中的位 +2 表明,如果无法预留指定金额,外部操作不会失败;相反,将预留所有剩余余额。y 中的位 +8 表示在执行任何进一步操作之前 x:=-x 。y 中的位 +4 表示在执行任何其他检查和操作之前,x 会增加当前帐户(在计算阶段之前)的原始余额,包括所有额外货币。当前 x 必须是非负整数,且 y 必须在 0...15 范围内。 | 526 |
FB03 | RAWRESERVEX | x D y - | 类似于 RAWRESERVE ,但也接受一个代表额外代币的字典 D (由 cell 或 空 表示)。这种方式可以预留Grams以外的货币。 | 526 |
FB04 | SETCODE | c - | 创建一个输出操作,该操作将此智能合约代码更改为由 cell c 给出的代码。请注意,此更改仅在当前智能合约运行成功终止后生效。 | 526 |
FB06 | SETLIBCODE | c x - | 创建一个输出操作,用于修改此智能合约库的集合,通过添加或移除在 cell c 中给定代码的库。如果 x=0 ,若库先前存在于集合中,则实际上会被移除(如果不存在,则此操作无效)。如果 x=1 ,则库被作为私有库添加;如果 x=2 ,则库被作为公共库添加(如果当前智能合约位于主链中,则变得对所有智能合约可用);如果库之前已存在于集合中,则其公共/私有状态将根据 x 改变。另外,16 可以加到 x 上,以在失败时启用弹回交易。x 的值除了 0...2 (+16 可能) 之外都是无效的。 | 526 |
FB07 | CHANGELIB | h x - | 类似于 SETLIBCODE ,创建一个输出操作,但它接受库的哈希而非库代码,哈希以无符号 256 位整数 h 的形式给出。如果 x!=0 且该智能合约的库集合中不存在哈希值为 h 的库,此输出操作将失败。 | 526 |
12 调试原语
以 FE
开头的操作码保留给调试原语使用。这些原语具有已知的固定操作长度,并且作为(多字节)NOP
操作行为。
然而,当在启用调试模式的 TVM 实例中调用时,这些原语可以产生特定输出到 TVM 实例的文本调试日志中,不影响 TVM 状态。
DEBUG
和 DEBUGSTR
是两个调试原语,它们涵盖了所有以 FE
开头的操作码。当调试启用时,这里列出的其他原语具有其指定的效果。当调试禁用时,它们表现为 NOP
。
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
FEnn | {nn} DEBUG | - | 0 <= nn < 240 | 26 |
FEFnssss | {string} DEBUGSTR {string} {x} DEBUGSTRI | - | 0 <= n < 16 。ssss 的长度为 n+1 字节。{string} 是一个字符串字面量。DEBUGSTR : ssss 是给定的字符串。DEBUGSTRI : ssss 是由一个字节的整数 0 <= x <= 255 加上给定字符串组成。 | 26 |
FE00 | DUMPSTK | - | 转储堆栈(最多顶部 255 个值)并显示总堆栈深度。 | 26 |
FE2i | s[i] DUMP | - | 转储 s[i] 。 | 26 |
13 代码页原语
xxxxxxx 操作码 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 描述 | xxxx Gas |
---|---|---|---|---|
FFnn | [nn] SETCP | - | 选择 TVM 代码页 0 <= nn < 240 。如果不支持代码页,则抛出无效的操作码异常。 | 26 |
FF00 | SETCP0 | - | 选择本文档描述的 TVM(测试)代码页零。 | 26 |
FFFz | [z-16] SETCP | - | 选择 TVM 代码页 z-16 ,适用于 1 <= z <= 15 。负代码页 -13...-1 保留用于验证其他代码页中 TVM 运行所需的限制性 TVM 版本。负代码页 -14 保留用于实验性代码页,不一定在不同 TVM 实现之间兼容,并且应在 TVM 的生产版本中禁用。 | 26 |
FFF0 | SETCPX | c - | 选择通过栈顶传入的代码页 c ,-2^15 <= c < 2^15 。 | 26 |