Overview
Theinvoke 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
Arguments
Pointer to the instruction data to pass to the invoked program.
Length of the instruction data in bytes.
Index of the program account to invoke. Must be a valid program account.
Optional invoke authorization descriptor. Pass
NULL to use default authorization behavior.
When provided, the descriptor is validated by the SDK before the syscall is issued.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:TN_VM_SYSCALL_SUCCESS(0) - Program invocation initiated successfully
TN_VM_ERR_SYSCALL_INVALID_ACCOUNT_INDEX(-8) - Program account index out of boundsTN_VM_ERR_SYSCALL_ACCOUNT_DOES_NOT_EXIST(-9) - Program account does not existTN_VM_ERR_SYSCALL_ACCOUNT_IS_NOT_PROGRAM(-17) - Account is not a valid programTN_VM_ERR_SYSCALL_CALL_DEPTH_TOO_DEEP(-24) - Maximum call depth exceeded
Resource Consumption
Compute Units
- Base cost:
TN_VM_SYSCALL_BASE_COST(512 units)- Represents the overhead of saving and restoring VM register state
- Implementation details:
- Save operation: All 32 registers (256 bytes) are saved to the public shadow stack
- Restore operation: When returning from the invoked program (via exit syscall), the registers (256 bytes) are restored from the public shadow stack back to the VM
- Total memory operations per invoke/exit cycle: 512 bytes (256 saved + 256 restored)
- Cost calculation: 32 registers × 8 bytes × 2 operations (save + restore) = 512 CUs
- 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
- Stores all 32 registers (256 bytes) in the public shadow stack
- Public shadow stack is read-only memory accessible to programs via memory segment 0x0002
- Preserves program context including stack/heap page counts
- Creates accessible snapshot for cross-program inspection and state restoration
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
- If
authis non-NULL, SDK-side validation runs before the syscall:- bad auth magic:
0xBAD0A170 - auth account not owned by current program:
0xBAD0A171 - invalid account index in auth/deauth lists:
0xBAD0A173
- bad auth magic: