Execution Model
VM, LLVM/native, hybrid, and how `@Main`, `@Runtime`, and `@Native` shape current Kira execution.
Kira currently has three execution targets.
| Target | What runs | Best for |
|---|---|---|
| VM | bytecode under kira_vm_runtime | the simplest runnable subset |
| LLVM/native | native object + host executable | fully native proof targets |
| hybrid | bytecode plus native shared library | mixed @Runtime and @Native programs |
VM
The default run path is the VM:
kira run examples/helloPipeline:
source -> lexer -> parser -> semantics -> IR -> bytecode -> VMVM is the simplest backend, but it cannot execute @Native functions. The fail corpus proves KBUILD001 when a native entrypoint is forced through VM execution.
The VM also does not execute FFI directly. A declaration that directly calls or references an FFI-bound extern must be marked @Native, so the compiler can route that edge through native code rather than pretending bytecode can invoke a C ABI symbol.
LLVM / Native
The native path lowers shared IR through the LLVM path and links a host executable:
kira run --backend llvm examples/callbacksUse it when the program should run natively and the entrypoint is native-capable. The LLVM/native path is no longer meant to be a tiny restricted subset for ordinary Kira programs.
Hybrid
Hybrid mode makes the mixed model explicit:
@Runtimefunctions stay in bytecode@Nativefunctions compile into native code- both sides run in one process through the hybrid runtime and native bridge
Hybrid is VM execution plus native trampolines and bridges. It is not a blanket permission for runtime bytecode to call FFI symbols directly, but it is the normal home for mixed @Runtime and @Native Kira code.
That execution split is meant to feel natural in ordinary Kira code:
@Runtimecode may call@Nativehelpers directly@Runtimecode may construct, read, and mutate@Nativestructs and classes@Nativecode may call back into@Runtimehelpers- the bridge handles materialization and copy-back across the boundary so
@Nativeis an execution/performance boundary, not a usability quarantine
Example:
kira run --backend hybrid examples/hybrid_roundtripCurrent output:
native main
runtime helper
native helperDebug Trace
For mixed execution debugging, run also exposes a debug-only execution trace:
kira run --backend hybrid --trace-execution examples/hybrid_roundtripWhen enabled, Kira writes structured trace lines to stderr so you can see where execution is actually happening:
VMfor bytecode-side prints and runtime execution helpersNATIVEfor native print/output helpersBRIDGEfor runtime/native materialization and copy stepsTRAMPOLINEfor native-to-runtime invocationsCALLBACKfor runtime callback entry/return flow
The trace is for development and debugging. Normal runs stay quiet unless you opt in.
Practical Rule
Read execution annotations this way today:
- VM wants runtime execution only
- LLVM/native needs a native-capable entrypoint
- hybrid is the natural home for mixed runtime/native programs, especially FFI-heavy ones
- direct FFI usage requires
@Native, but callers of@NativeKira helpers do not become native automatically - outside direct FFI usage,
@Runtimeand@Nativeare execution-boundary annotations rather than usability restrictions
Interop and FFI
The current compiler-visible FFI surface: extern declarations, callbacks, pointers, structs, aliases, arrays, and generated bindings.
Memory and Safety
Kira's current ownership model: owned-by-default values, borrowed parameters, explicit moves, and the parts that are still intentionally limited.