Skip to main content

RUNVM Specification

Currently, TVM does not provide a mechanism for executing external untrusted code within a secure sandbox environment. In other words, any external code invoked has unrestricted access and can permanently modify the contract's code and data or trigger actions such as transferring all funds.

The RUNVM instruction creates an isolated VM instance, allowing code execution while safely retrieving data such as stack state, registers, and gas consumption. This ensures the caller's state remains unaffected. This allows arbitrary code to run safely, which is helpful for v4-style plugins, Tact's init-style subcontract calculations, and similar use cases.

Fift syntaxStackDescription
flags RUNVMx_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c]Executes a child VM with the given code and stack values x_1 ... x_n. Returns the modified stack x'_1 ... x'_m along with an exit code.
Flags determine other arguments and return values. See details below.
RUNVMXx_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] flags - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c]It is the same as RUNVM but retrieves flags from the stack.

Flags operate similarly to RUNVMX in Fift:

  • +1: sets c3 to code.
  • +2: pushes an implicit 0 before executing the code.
  • +4: takes persistent data c4 from the stack and returns its final value.
  • +8: takes the gas limit g_l from the stack and returns the consumed gas g_c.
  • +16: takes c7 (smart contract context) from the stack.
  • +32: returns the final value of c5 (actions).
  • +64: pops the hard gas limit g_m enabled by ACCEPT from the stack.
  • +128: enables "isolated gas consumption", meaning the child VM maintains a separate set of visited cells and a chksgn counter.
  • +256: pops an integer r and ensures exactly r values are returned from the top of the stack:
    • If RUNVM call succeeds and r is set, it returns r elements. If r is not set, it returns all available elements.
    • If RUNVM is successful but lacks elements on the stack, meaning the stack depth is less than r, it is treated as an exception in the child VM. The exit_code is set to -3, and exit_arg is set to 0, so 0 is returned as the only stack element.
    • If RUNVM fails with an exception, only one element is returned, exit_arg, which should not be confused with exit_code.
    • In the case of running out of gas, exit_code is set to -14, and exit_arg contains the amount of gas.

Gas cost:

  • 66 gas;
  • 1 gas for each stack element passed to the child VM (the first 32 elements are free);
  • 1 gas for each stack element returned from the child VM (the first 32 elements are free).

See also