Expand description
A virtual machine layer over the QCode interpreter.
qcode_emulator interprets QCode over a pre-lifted, immutable module: it
answers “what does this IR compute”. This crate adds what a machine needs on
top of that — mapped memory with permissions, faults delivered as values
rather than aborts, code discovered on demand as the guest reaches it, and
snapshots — so that a guest program can be run rather than merely evaluated.
§Faults are values, not aborts
A bad guest access is returned to the caller, so a harness can observe it and carry on rather than dying:
use qcode_vm::{VmMemory, FaultKind, perm};
let mut memory = VmMemory::new();
// One read-only page of initialised memory.
memory.mmu.map(0x1000, 0x1000, perm::MAP | perm::READ | perm::INIT).unwrap();
let mut buffer = [0u8; 4];
assert!(memory.mmu.read(0x1000, &mut buffer).is_ok());
// Writing it faults, and says why and where.
let fault = memory.mmu.write(0x1000, &[0xff]).unwrap_err();
assert_eq!(fault.kind, FaultKind::WritePerm);
assert_eq!(fault.addr, 0x1000);
// So does touching an address that was never mapped.
let fault = memory.mmu.read(0x9000, &mut buffer).unwrap_err();
assert_eq!(fault.kind, FaultKind::ReadUnmapped);Execution strategy is pluggable through set_block_executor, which is how
qcode_jit is installed on a machine.
Re-exports§
pub use jit_abi::ACCESS_FAULT;pub use jit_abi::ACCESS_OK;pub use jit_abi::qcode_jit_load;pub use jit_abi::qcode_jit_sdiv128;pub use jit_abi::qcode_jit_srem128;pub use jit_abi::qcode_jit_store;pub use jit_abi::qcode_jit_udiv128;pub use jit_abi::qcode_jit_urem128;pub use memory::VmMemory;pub use mmu::FaultKind;pub use mmu::MemFault;pub use mmu::Mmu;pub use mmu::MmuSnapshot;pub use mmu::PAGE_PERM_OFFSET;pub use mmu::PAGE_SIZE;pub use mmu::PageData;pub use mmu::Perm;pub use mmu::perm;pub use optimize::Cleanup;pub use optimize::forward_temp_stores;pub use stats::Stats;pub use tlb::TLB_ENTRIES;pub use tlb::TLB_INDEX_BITS;pub use tlb::TlbEntry;pub use tlb::TranslationCache;pub use vm::BlockExecutor;pub use vm::CodeError;pub use vm::CodeSource;pub use vm::Executed;pub use vm::Vm;pub use vm::VmExit;
Modules§
- flat
- Flat storage for the spaces a guest does not address.
- jit_abi
- The calling interface between compiled code and this VM’s memory.
- memory
- The bridge between the interpreter’s memory interface and the
Mmu. - mmu
- Software MMU: page-granular mapping with per-byte permissions.
- optimize
- A cheap cleanup round for freshly lifted code.
- stats
- Where a run’s time and work actually go.
- tlb
- A software TLB: the shape compiled code needs to reach guest memory without calling back into Rust.
- vm
- The run loop: a machine that owns its code, discovers more of it as the guest reaches it, and stops with a reason instead of an error.