42 lines
1.5 KiB
Rust

use prometeu_bytecode::disassemble;
use prometeu_bytecode::isa::core::CoreOpCode;
fn emit(op: CoreOpCode, imm: Option<&[u8]>, out: &mut Vec<u8>) {
out.extend_from_slice(&(op as u16).to_le_bytes());
if let Some(bytes) = imm {
out.extend_from_slice(bytes);
}
}
#[test]
fn snapshot_representative_program_is_stable() {
let mut prog = Vec::new();
emit(CoreOpCode::PushI32, Some(&7i32.to_le_bytes()), &mut prog);
// MAKE_CLOSURE (fn=1, captures=0)
let mut mc = [0u8; 8];
mc[0..4].copy_from_slice(&1u32.to_le_bytes());
mc[4..8].copy_from_slice(&0u32.to_le_bytes());
emit(CoreOpCode::MakeClosure, Some(&mc), &mut prog);
// CALL_CLOSURE argc=1
emit(CoreOpCode::CallClosure, Some(&1u32.to_le_bytes()), &mut prog);
// SPAWN (fn=2, argc=1)
let mut sp = [0u8; 8];
sp[0..4].copy_from_slice(&2u32.to_le_bytes());
sp[4..8].copy_from_slice(&1u32.to_le_bytes());
emit(CoreOpCode::Spawn, Some(&sp), &mut prog);
// YIELD
emit(CoreOpCode::Yield, None, &mut prog);
// SLEEP 3
emit(CoreOpCode::Sleep, Some(&3u32.to_le_bytes()), &mut prog);
// SYSCALL 0x1003
emit(CoreOpCode::Syscall, Some(&0x1003u32.to_le_bytes()), &mut prog);
// FRAME_SYNC
emit(CoreOpCode::FrameSync, None, &mut prog);
// HALT
emit(CoreOpCode::Halt, None, &mut prog);
let text = disassemble(&prog).expect("disasm ok");
let expected = "PUSH_I32 7\nMAKE_CLOSURE fn=1, captures=0\nCALL_CLOSURE argc=1\nSPAWN fn=2, argc=1\nYIELD\nSLEEP 3\nSYSCALL 0x1003\nFRAME_SYNC\nHALT";
assert_eq!(text, expected);
}