Skip to main content

Overview

The invoke syscall calls another program, creating a new execution frame. This enables cross-program invocation and modularity in the ThruVM runtime.

Syscall Code

Code: 0x0A (TN_SYSCALL_CODE_INVOKE)

C SDK Function

ulong tsys_invoke(void const* instr_data, ulong instr_data_sz, ushort program_account_idx, ulong* invoke_err_code);

Arguments

instr_data
void const*
required
Pointer to the instruction data to pass to the invoked program.
instr_data_sz
ulong
required
Length of the instruction data in bytes.
program_account_idx
ushort
required
Index of the program account to invoke. Must be a valid program account.
invoke_err_code
ulong*
required
Pointer to store the error code returned by the invoked program. This will be set to the exit code of the invoked program.

Return Value

Returns a syscall result code:
Success
ulong
  • TN_VM_SYSCALL_SUCCESS (0) - Program invocation initiated successfully
Error Codes
ulong
  • TN_VM_ERR_SYSCALL_INVALID_ACCOUNT_INDEX (-7) - Program account index out of bounds
  • TN_VM_ERR_SYSCALL_ACCOUNT_DOES_NOT_EXIST (-8) - Program account does not exist
  • TN_VM_ERR_SYSCALL_ACCOUNT_IS_NOT_PROGRAM (-16) - Account is not a valid program
  • TN_VM_ERR_SYSCALL_CALL_DEPTH_TOO_DEEP (-23) - Maximum call depth exceeded

Resource Consumption

Compute Units

  • Base cost: TN_VM_SYSCALL_BASE_COST (512 units)
  • Additional cost: None for the invoke syscall itself
  • Note: The invoked program will consume additional compute units during its execution

Memory Pages

  • Page usage: No direct page allocation
  • Shadow stack: Uses existing shadow stack pages to save execution state
  • Call overhead: Minimal memory overhead for call frame management

Side Effects

  • Execution context: Creates new execution frame and updates call stack
  • Register setup: Sets a0 to instruction data address, a1 to data length
  • Program counter: Resets PC to 0 for the new program
  • Call tracking: Increments frame and call indices
  • Shadow stack: Saves current execution state on shadow stack

Call Stack Management

The syscall manages a call stack with the following updates:
  • Frame index: Incremented to create new frame
  • Call depth: Updated to reflect nesting level
  • Shadow stack: Current state saved for restoration on return
  • Program context: Switches to the invoked program’s bytecode

Program Validation

  • The target account must have the PROGRAM flag set
  • Program bytecode is validated before invocation
  • Account must exist and be accessible in the transaction

Depth Limiting

  • Maximum call depth is enforced (TN_VM_CALL_DEPTH_MAX)
  • Prevents infinite recursion and stack overflow
  • Call depth is tracked per execution frame

Register State

Upon successful invocation:
  • a0: Set to instruction data virtual address
  • a1: Set to instruction data length
  • PC: Reset to 0 (start of invoked program)
  • Other registers: Preserved from calling context

Usage Notes

  • Instruction data can be any format understood by the target program
  • The invoked program executes with the same transaction context
  • Account permissions and writability are preserved
  • Return values are passed through program exit mechanisms

Example

#include "tn_sdk_syscall.h"
#include <stdint.h>

// Invoke a calculator program with operation data
ushort calculator_program_idx = 5;

// Prepare instruction data
struct calc_instruction {
    uint32_t operation;  // 1 = add, 2 = multiply
    uint64_t operand_a;
    uint64_t operand_b;
} instruction = {
    .operation = 1,      // Addition
    .operand_a = 100,
    .operand_b = 200
};

ulong result = tsys_invoke(&instruction, sizeof(instruction), calculator_program_idx);

if (result == TN_VM_SYSCALL_SUCCESS) {
    // Calculator program is now executing
    // It will receive instruction data in a0, a1
    // Current program state saved on shadow stack
    // Execution will continue in calculator program
}