RISC-V (RV64IM) emulator for the Lambda VM. Loads ELF binaries, runs them against an in-memory VM state, and emits the per-instruction execution logs that the prover turns into a STARK trace.
Published as executor. Used directly by the CLI and the prover; you can also drive it from Rust.
use executor::elf::Elf;
use executor::vm::execution::Executor;
let elf_bytes = std::fs::read("program.elf")?;
let program = Elf::load(&elf_bytes)?;
let executor = Executor::new(&program, /* private input */ vec![])?;
let result = executor.run()?;
println!("Executed {} instructions", result.logs.len());For chunked execution (useful when you don't want to hold all logs in memory), drive the executor via executor.resume() in a loop until it yields None, then call executor.finish(). See bin/cli/src/main.rs for an example.
The repo ships ready-to-use guest programs in three flavours, all compiled by Makefile targets at the repo root:
programs/asm/— raw RISC-V assembly. Built withmake compile-programs-asmintoprogram_artifacts/asm/.programs/rust/— Rust guest projects (fibonacci,keccak,hashmap, …). Built withmake compile-programs-rustintoprogram_artifacts/rust/. Requires the pinned nightly toolchain and sysroot — see the rootREADME.md.programs/bench/— benchmark programs. Built withmake compile-bench.
The custom RISC-V target spec used for Rust guests lives at programs/riscv64im-lambda-vm-elf.json.
# Compile all programs and run executor tests
make test-executor
# Just the asm tests
make test-asm
# Just the Rust tests
make test-rustTo add a new test:
- ASM: add a
.sfile underprograms/asm/and a matching entry intests/asm.rs. - Rust: add a cargo project under
programs/rust/<name>/(the directory and theCargo.tomlpackage name must match) and a matching entry intests/rust.rs.
The executor includes a flamegraph generator (executor::flamegraph::FlamegraphGenerator) that produces folded-stack output by instruction count. Drive it via the CLI: cli execute <elf> --flamegraph stacks.txt. See bin/cli/README.md for details.