Documentation

The official Dryad language documentation. Browse by category or use the sidebar on individual pages for quick navigation between sections.

Architecture

8. Triple Execution Model

Dryad's execution engine is not a single interpreter or compiler — it is a three-layer pipeline where each layer feeds the next with progressively richer type information. Layer 1 (AST Interpreter) walks the syntax tree directly and collects runtime type observations for every variable slot, call site, and branch. Layer 2 (Bytecode VM) consumes the AST and the interpreter's type observations to emit type-specialized opcodes — ADD_F64 instead of ADD_GENERIC when the observed type is f64. Each compiled function carries a Metadata Header with the observed type signatures, allowing subsequent layers to skip type inference. Layer 3 (AOT Compiler) reads the type-annotated bytecode and emits LLVM IR with zero type checks for statically-known paths, falling back to guarded branches (fast path with runtime check) only when types are genuinely ambiguous. This design distributes type intelligence across all three layers: the interpreter observes, the VM annotates, and the AOT consumes.

12. Minimal Runtime Architecture

Dryad's runtime implements in C++ a minimal set of approximately 50 primitive syscalls (intrinsics), enabling the Standard Library to be almost 100% written in pure Dryad, facilitating self-hosting and broad debugging. All raw intrinsic calls are wrapped in safe Dryad functions that validate inputs and manage cleanup — raw intrinsics may only be used within the standard library's boundary layer. The runtime includes a native Buffer type with bounds-checked access, zero-copy I/O operations, and a Hardware Abstraction Layer (HAL) that isolates platform-specific syscall differences behind a uniform interface.

13. Bytecode & Intermediate Representation

The Dryad Bytecode VM is a stack-based virtual machine that compiles AST into linear OpCodes for efficient sequential execution. The Intermediate Representation (IR) sits between bytecode and native assembly — it is register-based (unlike the stack-based bytecode), architecture-independent, and enables classical optimizations before code generation.

14. AOT Compilation Pipeline

The Ahead-of-Time (AOT) compiler transforms Dryad bytecode into native machine code through a multi-stage pipeline that avoids emitting assembly or object files directly — instead it leverages LLVM IR as its backend target. The pipeline: (1) Bytecode → Micro-IR — stack-based opcodes are converted to a register-based 3-address SSA form where each instruction is R1 = R2 op R3, using the Metadata Header to drive type mapping; (2) Micro-IR → LLVM IR — each Micro-IR instruction maps to LLVM IR instructions with native types (double, i32, i8*); (3) LLVM Optimization — LLVM's pass manager applies constant folding, dead code elimination, loop unrolling, SIMD vectorization, and inlining at -O2; (4) Code Generation — LLVM's backend emits object files for ARM64 or x86_64; (5) Linking — the object file is linked against the Dryad runtime library to produce an ELF or PE executable. Every intrinsic syscall has dual entry points: a Fast Path (native C ABI, zero overhead) and a Slow Path (Variant-based, for dynamic fallback). The dryad --analyze tool reports every call site that would use the Slow Path, with suggestions for promoting to Fast Path via type annotations.