use prometeu_bytecode::{assemble, disassemble}; use prometeu_bytecode::isa::core::CoreOpCode; fn emit(op: CoreOpCode, imm: Option<&[u8]>, out: &mut Vec) { out.extend_from_slice(&(op as u16).to_le_bytes()); if let Some(bytes) = imm { out.extend_from_slice(bytes); } } #[test] fn roundtrip_disasm_assemble_byte_equal_with_closures_and_coroutines() { // Program: PUSH_I32 7; MAKE_CLOSURE fn=1,captures=0; CALL_CLOSURE argc=1; // SPAWN fn=2,argc=1; YIELD; SLEEP 3; SYSCALL 0x1003; FRAME_SYNC; HALT 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 gfx.draw_line (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 rebuilt = assemble(&text).expect("assemble ok"); assert_eq!(rebuilt, prog, "re-assembled bytes must match original"); }