Language Guide

Execution Model

VM, LLVM/native, hybrid, and how `@Main`, `@Runtime`, and `@Native` shape current Kira execution.

Kira currently has three execution targets.

TargetWhat runsBest for
VMbytecode under kira_vm_runtimethe simplest runnable subset
LLVM/nativenative object + host executablefully native proof targets
hybridbytecode plus native shared librarymixed @Runtime and @Native programs

VM

The default run path is the VM:

kira run examples/hello

Pipeline:

source -> lexer -> parser -> semantics -> IR -> bytecode -> VM

VM 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/callbacks

Use 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:

  • @Runtime functions stay in bytecode
  • @Native functions 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:

  • @Runtime code may call @Native helpers directly
  • @Runtime code may construct, read, and mutate @Native structs and classes
  • @Native code may call back into @Runtime helpers
  • the bridge handles materialization and copy-back across the boundary so @Native is an execution/performance boundary, not a usability quarantine

Example:

kira run --backend hybrid examples/hybrid_roundtrip

Current output:

native main
runtime helper
native helper

Debug Trace

For mixed execution debugging, run also exposes a debug-only execution trace:

kira run --backend hybrid --trace-execution examples/hybrid_roundtrip

When enabled, Kira writes structured trace lines to stderr so you can see where execution is actually happening:

  • VM for bytecode-side prints and runtime execution helpers
  • NATIVE for native print/output helpers
  • BRIDGE for runtime/native materialization and copy steps
  • TRAMPOLINE for native-to-runtime invocations
  • CALLBACK for 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 @Native Kira helpers do not become native automatically
  • outside direct FFI usage, @Runtime and @Native are execution-boundary annotations rather than usability restrictions

On this page