Skip to main contentForeign Functions in Stoffel
This page explains how foreign functions are implemented in Stoffel’s virtual machine, their structure, and how they interact with the VM’s execution environment.
Rationale
Foreign functions extend Stoffel’s capabilities by allowing integration with the host environment. They enable the VM to access functionality that would be difficult or inefficient to implement within the VM’s instruction set, such as file I/O, object creation, and specialized algorithms. The foreign function mechanism provides a bridge between the VM and the host environment while maintaining a clean separation between the two.
Comprehensive Overview
Foreign functions in Stoffel are implemented as Rust closures that operate on VM values and can modify VM state. Each foreign function is registered with the VM under a string name and can then be called from within Stoffel programs using the same calling convention as regular VM functions.
The foreign function mechanism uses a context-based approach where each function receives a context object containing its arguments and a mutable reference to the VM state. This design gives foreign functions full access to the VM’s internal state while maintaining a clean API boundary.
Foreign Function Structure
-
ForeignFunctionPtr:
The core type representing a foreign function implementation.
- Wrapped in an
Arc (atomic reference counter) for thread-safe sharing
- Takes a
ForeignFunctionContext parameter providing access to arguments and VM state
- Returns a
Result<Value, String> indicating success or failure with an error message
-
ForeignFunction:
A wrapper structure for registered foreign functions.
name: String identifier used to reference the function
func: The actual function implementation as a ForeignFunctionPtr
-
ForeignFunctionContext:
The execution context passed to foreign function implementations.
args: A slice containing the function’s arguments as Value objects
vm_state: A mutable reference to the current VMState, allowing full access to VM internals
Registering Foreign Functions
Foreign functions are registered with the VM using a registration API that takes a name and a function implementation:
- The VM creates a
ForeignFunction struct with the provided name and function implementation
- The function is wrapped in an
Arc for thread-safe sharing
- The
ForeignFunction is stored in the VM’s functions map under its name
- The function can then be called from Stoffel code using its registered name
Calling Foreign Functions
When a foreign function is called, either directly or through the CALL instruction:
- The VM locates the function in its registry by name
- It creates a
ForeignFunctionContext with:
- A reference to the arguments array
- A mutable reference to the current VM state
- The VM triggers a
BeforeFunctionCall hook event
- The function is executed with the context
- The result is captured and the VM triggers an
AfterFunctionCall hook event
- The result is returned to the caller or stored in register 0
Unlike VM functions, foreign functions don’t create a new activation record. Instead, they execute within the context of the calling function and can modify the VM state directly.
VM State Access
Foreign functions have full access to the VM’s internal state through the vm_state field of the context:
functions: Registry of all VM and foreign functions
activation_records: The stack of function calls currently being executed
current_instruction: The current instruction pointer
object_store: Storage for Stoffel objects and arrays
foreign_objects: Storage for host environment objects
hook_manager: Event hook system for debugging and monitoring
This access allows foreign functions to implement complex behaviors that would be difficult to express in the VM’s instruction set, such as object creation, array manipulation, and integration with host environment resources.
Standard Library Implementation
Many of Stoffel’s standard library functions are implemented as foreign functions, including:
- Object and array creation and manipulation
- Closure creation and management
- Type information access
These functions provide the essential building blocks for Stoffel programs while abstracting away the complexity of their implementation details.