DynLoad API Reference

Dynamic module loading, WASM sandboxing, and hot reload support

Import

U std/dynload

Overview

The dynload module provides comprehensive support for:

  • Runtime loading and unloading of dynamic libraries
  • WASM plugin sandboxing with resource limits and capabilities
  • Hot reload for development workflows
  • Plugin discovery from standard paths

Constants

Loading Flags

NameValueDescription
RTLD_NOW2Load library immediately (resolve all symbols)
RTLD_LAZY1Lazy loading (resolve symbols as needed)
RTLD_GLOBAL256Make symbols available to subsequently loaded libraries

Plugin Capabilities

NameValueDescription
CAP_NONE0No capabilities
CAP_CONSOLE1Console output
CAP_TIME2Time/clock access
CAP_RANDOM4Random number generation
CAP_FS_READ8File system read
CAP_FS_WRITE16File system write
CAP_NETWORK32Network access
CAP_ENV64Environment variables
CAP_PROCESS128Process spawning
CAP_THREADING256Multi-threading
CAP_GPU512GPU/compute access

Structs

ModuleHandle

Represents a loaded dynamic module.

S ModuleHandle {
    handle: i64,      # dlopen handle
    path: i64,        # Path to the module (string pointer)
    version: i64,     # Module version (incremented on reload)
    loaded: i64       # 1 if loaded, 0 if not
}

Functions:

FunctionSignatureDescription
module_handle_newF module_handle_new() -> ModuleHandleCreate empty module handle
module_is_loadedF module_is_loaded(m: ModuleHandle) -> i64Check if module is loaded
module_versionF module_version(m: ModuleHandle) -> i64Get module version

ResourceLimits

Resource limits for sandboxed execution.

S ResourceLimits {
    max_memory_bytes: i64,     # Maximum memory in bytes
    max_time_ms: i64,          # Maximum execution time in milliseconds
    max_stack_bytes: i64,      # Maximum stack size
    max_call_depth: i64        # Maximum function call depth
}

Functions:

FunctionSignatureDescription
default_limitsF default_limits() -> ResourceLimits64MB RAM, 5s timeout, 1MB stack, 1000 depth
restrictive_limitsF restrictive_limits() -> ResourceLimits16MB RAM, 1s timeout, 256KB stack, 500 depth
permissive_limitsF permissive_limits() -> ResourceLimits256MB RAM, 60s timeout, 4MB stack, 5000 depth

WasmSandbox

WASM sandbox handle for plugin execution.

S WasmSandbox {
    handle: i64,
    capabilities: i64
}

Functions:

FunctionSignatureDescription
sandbox_newF sandbox_new() -> WasmSandboxCreate new sandbox with default settings (console enabled)
sandbox_restrictiveF sandbox_restrictive() -> WasmSandboxCreate restrictive sandbox for untrusted plugins (no caps)
sandbox_destroyF sandbox_destroy(s: WasmSandbox) -> i64Destroy sandbox
sandbox_grantF sandbox_grant(s: WasmSandbox, cap: i64) -> WasmSandboxGrant capability to sandbox
sandbox_revokeF sandbox_revoke(s: WasmSandbox, cap: i64) -> WasmSandboxRevoke capability from sandbox
sandbox_loadF sandbox_load(s: WasmSandbox, bytes: i64, len: i64) -> WasmInstanceLoad WASM module into sandbox

WasmInstance

WASM instance handle for calling functions.

S WasmInstance {
    handle: i64,
    sandbox: i64
}

Functions:

FunctionSignatureDescription
wasm_callF wasm_call(inst: WasmInstance, name: i64) -> i64Call function with no args
wasm_call1F wasm_call1(inst: WasmInstance, name: i64, arg: i64) -> i64Call function with one i64 arg
wasm_call2F wasm_call2(inst: WasmInstance, name: i64, arg1: i64, arg2: i64) -> i64Call function with two i64 args
wasm_is_validF wasm_is_valid(inst: WasmInstance) -> i64Check if instance is valid

HotReloadConfig

Configuration for hot reload.

S HotReloadConfig {
    source_path: i64,      # Path to source file
    output_dir: i64,       # Output directory for compiled modules
    debounce_ms: i64,      # Debounce time for file changes
    verbose: i64           # Enable verbose logging
}

Functions:

FunctionSignatureDescription
hot_reload_configF hot_reload_config(source_path: i64) -> HotReloadConfigCreate default hot reload config (100ms debounce, non-verbose)

HotReloader

Hot reloader handle.

S HotReloader {
    handle: i64,
    version: i64,
    running: i64
}

Functions:

FunctionSignatureDescription
hot_reloader_newF hot_reloader_new(source_path: i64) -> HotReloaderCreate new hot reloader
hot_reloader_startF hot_reloader_start(r: HotReloader) -> HotReloaderStart hot reloading
hot_reloader_stopF hot_reloader_stop(r: HotReloader) -> HotReloaderStop hot reloading
hot_reloader_checkF hot_reloader_check(r: HotReloader) -> i64Check for changes and reload (returns 1 if reloaded)
hot_reloader_versionF hot_reloader_version(r: HotReloader) -> i64Get current version

Module Loading Functions

FunctionSignatureDescription
load_moduleF load_module(path: i64) -> ModuleHandleLoad dynamic library with RTLD_NOW
load_module_lazyF load_module_lazy(path: i64) -> ModuleHandleLoad with lazy binding (RTLD_LAZY)
unload_moduleF unload_module(m: ModuleHandle) -> i64Unload module (returns 1 on success)
reload_moduleF reload_module(m: ModuleHandle) -> ModuleHandleReload module with incremented version
get_functionF get_function(m: ModuleHandle, name: i64) -> i64Get function pointer by name
get_load_errorF get_load_error() -> i64Get last error message

Capability System Functions

FunctionSignatureDescription
has_capabilityF has_capability(caps: i64, required: i64) -> i64Check if capability is granted
add_capabilityF add_capability(caps: i64, cap: i64) -> i64Add capability to flags
remove_capabilityF remove_capability(caps: i64, cap: i64) -> i64Remove capability from flags
has_dangerous_capabilitiesF has_dangerous_capabilities(caps: i64) -> i64Check for FS_WRITE, NETWORK, PROCESS, or ENV

Utility Functions

FunctionSignatureDescription
get_library_extensionF get_library_extension() -> i64Get platform-specific library extension (dylib/so/dll)
is_plugin_libraryF is_plugin_library(path: i64) -> i64Check if file is a plugin library

External C Functions

FunctionSignatureDescription
dlopenX F dlopen(path: i64, flags: i64) -> i64Open dynamic library
dlcloseX F dlclose(handle: i64) -> i64Close library
dlsymX F dlsym(handle: i64, symbol: i64) -> i64Get symbol address
dlerrorX F dlerror() -> i64Get error message
vais_get_user_plugin_dirX F vais_get_user_plugin_dir() -> i64Get user plugin directory (~/.vais/plugins/)
vais_get_system_plugin_dirX F vais_get_system_plugin_dir() -> i64Get system plugin directory (/usr/local/lib/vais/plugins/)
getenvX F getenv(name: i64) -> i64Get environment variable

Examples

Basic Dynamic Loading

U std/dynload

F main() -> i64 {
    # Load a dynamic library
    module := load_module("/path/to/plugin.dylib")

    I module_is_loaded(module) == 1 {
        # Get function pointer
        init_fn := get_function(module, "plugin_init")

        # Call the function (would need to cast and call)
        # ...

        # Unload when done
        unload_module(module)
    } E {
        # Error loading
        err := get_load_error()
        # Handle error
    }

    0
}

WASM Sandbox with Capabilities

U std/dynload

F main() -> i64 {
    # Create restrictive sandbox
    sandbox := sandbox_restrictive()

    # Grant specific capabilities
    sandbox = sandbox_grant(sandbox, CAP_CONSOLE)
    sandbox = sandbox_grant(sandbox, CAP_TIME)

    # Load WASM plugin
    wasm_bytes := load_wasm_file("plugin.wasm")
    wasm_len := get_wasm_size(wasm_bytes)

    instance := sandbox_load(sandbox, wasm_bytes, wasm_len)

    I wasm_is_valid(instance) == 1 {
        # Call plugin function
        result := wasm_call1(instance, "process", 42)
    }

    # Cleanup
    sandbox_destroy(sandbox)
    0
}

Hot Reload

U std/dynload

F main() -> i64 {
    # Create hot reloader for a source file
    reloader := hot_reloader_new("./src/plugin.vais")
    reloader = hot_reloader_start(reloader)

    # Main loop
    L 1 {
        # Check for changes
        changed := hot_reloader_check(reloader)

        I changed == 1 {
            version := hot_reloader_version(reloader)
            # Plugin was reloaded, update references
        }

        # Do work
        # ...
    }

    reloader = hot_reloader_stop(reloader)
    0
}

Capability Checking

U std/dynload

F verify_plugin_safety(plugin_caps: i64) -> i64 {
    # Check if plugin has dangerous capabilities
    I has_dangerous_capabilities(plugin_caps) == 1 {
        # Warn user or reject plugin
        0
    } E {
        # Safe to load
        1
    }
}

F main() -> i64 {
    # Build capability set for a plugin
    caps := CAP_CONSOLE
    caps = add_capability(caps, CAP_TIME)
    caps = add_capability(caps, CAP_RANDOM)

    # Check specific capability
    I has_capability(caps, CAP_NETWORK) == 1 {
        # Has network access
    }

    verify_plugin_safety(caps)
    0
}