ABI
Xila's C ABI surface is split between declarations and symbol definitions. Rust services use explicit managers; C entrypoints receive their VFS and time capabilities through a separately installed process-wide runtime context.
Responsibilities and boundaries
- Export C-compatible signatures, types, constants, and numeric result conventions.
- Adapt raw pointers and identifiers to Xila's file, memory, task, and time APIs.
- Keep declarations/header generation separate from concrete exported symbols.
Coverage remains incremental. This ABI is distinct from the Wasmi runtime's local WASI and graphics imports; it is not a claim of full WASI compatibility.
Internal architecture
abi_declarationscrate: C declarations and generated header surface.abi_definitionscrate: exported#[unsafe(no_mangle)] extern "C"functions, types, and service adapters.abi_definitions::RuntimeContext: static VFS/time references stored once for C entrypoints.
The old abi_context crate and its Context::call_abi path are not part of the current workspace. Wasmi keeps file descriptors and active task information in its own per-execution WasiContext.
Lifecycle and execution model
- The final binary constructs the managers and VFS and keeps them alive.
- It calls
abi_definitions::initialize(RuntimeContext { virtual_file_system, time_manager })before C ABI use. - Exported functions obtain this runtime context and dispatch through its references. File/directory entrypoints that require task identity accept it in their C arguments.
- Synchronous boundaries use synchronous VFS wrappers or
task::block_onwhere required.
Registration uses OnceLock: the first context remains installed for the process. Calling a context-dependent entrypoint before registration panics. This is an intentional global FFI boundary, not the production lifecycle of every Rust module.
Concurrency and failure semantics
- Module locks and ABI-local synchronization protect the operations they own.
- Success is generally zero; nonzero codes map service errors at the C boundary.
- Invalid pointers/identifiers must be checked at conversion boundaries.
- Several exported functions remain
todo!(); inspect the symbol implementation before depending on it.
Extension points
Extend definitions and declarations together, regenerate headers, and preserve signature/layout/error-code compatibility. Use explicit Rust manager references inside services and confine runtime-context access to the C boundary.