跳到主要内容

Continuation 和控制流原语

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

TVM 指令内容列表

Continuation 和控制流原语

无条件控制流原语

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

条件控制流原语

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

控制流原语:循环

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

操作 continuation 栈

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

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

创建简单的 continuations 和 闭包

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

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

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

字典子程序调用和跳转

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

TVM 指令内容列表