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 | ROT22ROT | 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 | SWAP22SWAP | a b c d - c d a b | 等同于 2 2 BLKSWAP 或 s3 s2 XCHG2。 | 18 |
5B | DROP22DROP | a b - | 等同于两次执行 DROP。 | 18 |
5C | DUP22DUP | a b - a b a b | 等同于 s1 s0 PUSH2。 | 18 |
5D | OVER22OVER | 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 | PICKPUSHX | 从堆栈弹出整数 i,然后执行 s[i] PUSH。 | 18 | |
61 | ROLLX | 从堆栈弹出整数 i,然后执行 1 [i] BLKSWAP。 | 18 | |
62 | -ROLLXROLLREVX | 从堆栈弹出整数 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 | NULLPUSHNULL | - 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 | PAIRCONS | 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 | FIRSTCAR | t - x | 返回 Tuple 的第一个元素。 | 26 |
6F11 | SECONDCDR | 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 | UNPAIRUNCONS | 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 | FIRSTQCARQ | t - x | 返回 Tuple 的第一个元素。 | 26 |
6F61 | SECONDQCDRQ | 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 | TPUSHCOMMA | 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 | ZEROFALSE | - 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{} PUSHSLICEx{ABCD1234} PUSHSLICEb{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 }> CONTCONT:<{ 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 | MINMAXINTSORT2 | x y - x y or y x | 排序两个整数。如果任一参数为 NaNs,静默版本的此操作返回两个 NaNs。 | 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 | STBREFRENDCST | 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 | STBRBCONCAT | 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 | STBRQBCONCATQ | 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 | EXECUTECALLX | 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 | RETRETTRUE | 返回 到 continuation c0。当前 continuation cc的剩余部分被丢弃。大致相当于 c0 PUSHCTR JMPX。 | 26 | |
DB31 | RETALTRETFALSE | 返回 到 continuation c1。大致相当于 c1 PUSHCTR JMPX。 | 26 | |
DB32 | BRANCHRETBOOL | 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 | IFRETIFNOT: | f - | 如果整数 f 非零,则执行 RET。如果 f 是 NaN, 抛出一个整数溢出异常。 | 18 |
DD | IFNOTRETIF: | 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 | REPEATENDREPEAT: | 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 | UNTILENDUNTIL: | - | 类似于 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 | AGAINENDAGAIN: | - | 类似于 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 | UNTILENDBRKUNTILBRK: | - | 等同于 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 | AGAINENDBRKAGAINBRK: | - | 等同于 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] PUSHCTRc[i] PUSH | - x | 推送控制寄存器 c(i) 的当前值。如果当前代码页不支持该控制寄存器,或者它没有值,则触发异常。 | 26 |
ED44 | c4 PUSHCTRc4 PUSH | - x | 推送“全局数据根”cell引用,从而使访问持久智能合约数据成为可能。 | 26 |
ED5i | c[i] POPCTRc[i] POP | x - | 从栈中弹出一个值 x 并存储到控制寄存器 c(i) 中(如果当前代码页支持)。注意,如果控制寄存器仅接受特定类型的值,则可能发生类型检查异常。 | 26 |
ED54 | c4 POPCTRc4 POP | x - | 设置“全局数据根”cell引用,从而允许修改持久智能合约数据。 | 26 |
ED6i | c[i] SETCONTc[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] POPSAVEc[i] POPCTRSAVE | x - | 类似于 c[i] POPCTR,但还将 c[i] 的旧值保存到 continuation c0 中。等同于(直到异常) c[i] SAVECTR c[i] POPCTR。 | 26 |
EDAi | c[i] SAVEc[i] SAVECTR | 将 c(i) 的当前值保存到 continuation c0 的 savelist 中。如果 c0 的 savelist 中已存在 c[i] 的条目,则不做任何操作。等同于 c[i] PUSHCTR c[i] SETRETCTR。 | 26 | |
EDBi | c[i] SAVEALTc[i] SAVEALTCTR | 类似于 c[i] SAVE,但将 c[i] 的当前值保存到 c1(而不是 c0)的 savelist 中。 | 26 | |
EDCi | c[i] SAVEBOTHc[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 | COMPOSBOOLAND | c c' - c'' | 计算组合 compose0(c, c’),它的意义为“执行 c,如果成功,执行 c'”(如果 c 是布尔电路)或简单地“执行 c,然后执行 c'”。等同于 SWAP c0 SETCONT。 | 26 |
EDF1 | COMPOSALTBOOLOR | 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 | STDICTSTOPTREF | D b - b' | 将字典 D 存入构建器 b,返回结果 构建器 b'。换言之,如果 D 是一个cell,执行 STONE 和 STREF;如果 D 是 Null,执行 NIP 和 STZERO;否则抛出类型检查异常。 | 26 |
F401 | SKIPDICTSKIPOPTREF | 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 | LDDICTLDOPTREF | s - D s' | 从切片 s中加载(解析)字典 D,并将 s的剩余部分作为 s' 返回。可应用于字典或任意 (^Y)? 类型的值。 | 26 |
F405 | PLDDICTPLDOPTREF | 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 | ADDRANDRANDOMIZE | 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 | LDGRAMSLDVARUINT16 | 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 | STGRAMSSTVARUINT16 | 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 |