#![forbid(unsafe_code)]
#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))]
pub mod bytecode;
pub mod log;
pub mod natives;
pub mod samples;
pub mod scheduler;
pub mod vm;
pub use bytecode::{
asm_macros, decode, disassemble, encode, verify, Chunk, ChunkBuilder, FormatError,
FunctionDef, Instruction, Label, Message, Opcode, Value, VerifyError, ABI_VERSION, MAGIC,
};
pub use natives::{std_native_map, std_native_table, std_natives};
pub use scheduler::{
fault_count, next_flow_id, flow_id_from_u64, report_fault, CapId, CapRights, ChildSpec,
Delivery, Mailbox, Flow, FlowHandle, FlowId, FlowMetrics, FlowOutcome, FlowState,
RestartPolicy, Runtime, RuntimeConfig, RuntimeError, RuntimeMetrics,
RuntimeMetricsSnapshot, RuntimeSpawner, SendError, SpawnError, Supervisor,
SupervisorConfig, DEFAULT_QUANTUM,
};
pub use vm::{
expect_arg, expect_bool, expect_int, expect_message, expect_u64, Fault, NativeFn,
NativeResult, NativeTable, NativeTableBuilder, Vm, VmResult, MAX_CALL_DEPTH,
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn std_native_map_has_stable_indices() {
let map = std_native_map();
assert_eq!(map["print"], 0);
assert_eq!(map["now_ms"], 1);
assert_eq!(map["make_msg"], 2);
assert_eq!(map["msg_payload"], 6);
assert_eq!(map["msg_reply_cap"], 7);
}
#[test]
fn chunk_builder_with_std_natives() {
let mut b = ChunkBuilder::new("std-natives-demo");
b.begin_function("main", 0, 2);
b.emit_load_imm(0, 42);
b.emit_call_native(0, 0, 1);
b.emit_call_native(1, 1, 0);
b.emit_return(1);
let chunk = b.finish();
verify(&chunk).expect("verify");
let rt = Runtime::with_natives(chunk, std_native_table()).expect("runtime");
let outcome = rt.spawn(0, &[]).expect("spawn").join();
rt.shutdown();
match outcome {
FlowOutcome::Completed(Value::Int(ms)) => assert!(ms >= 0),
other => panic!("expected Completed(Value::Int(_)), got {other:?}"),
}
}
}