use prometeu_bytecode::FunctionMeta; use prometeu_bytecode::isa::core::CoreOpCode as OpCode; use prometeu_vm::verifier::{Verifier, VerifierError}; fn enc_op(op: OpCode) -> [u8; 2] { [(op as u8), 0x00] } #[test] fn err_invalid_yield_with_non_empty_stack() { // Program: // 0..2: PUSH_I32 1 (imm 4 bytes) // 6..8: YIELD // 8..10: RET let mut code = Vec::new(); code.extend_from_slice(&enc_op(OpCode::PushI32)); code.extend_from_slice(&1u32.to_le_bytes()); code.extend_from_slice(&enc_op(OpCode::Yield)); code.extend_from_slice(&enc_op(OpCode::Ret)); let functions = vec![FunctionMeta { code_offset: 0, code_len: code.len() as u32, return_slots: 1, ..Default::default() }]; let res = Verifier::verify(&code, &functions); assert_eq!(res, Err(VerifierError::InvalidYieldContext { pc: 6, height: 1 })); } #[test] fn err_spawn_arg_mismatch() { // Caller at func 0: SPAWN fn_id=1, arg_count=1; RET // Callee at func 1: expects 2 param_slots let mut code = Vec::new(); code.extend_from_slice(&enc_op(OpCode::Spawn)); code.extend_from_slice(&1u32.to_le_bytes()); // fn_id code.extend_from_slice(&1u32.to_le_bytes()); // arg_count (mismatch: callee expects 2) code.extend_from_slice(&enc_op(OpCode::Ret)); let caller = FunctionMeta { code_offset: 0, code_len: code.len() as u32, return_slots: 0, ..Default::default() }; // Callee has no code here; only signature matters let callee = FunctionMeta { code_offset: code.len() as u32, code_len: 0, param_slots: 2, return_slots: 0, ..Default::default() }; let functions = vec![caller, callee]; let res = Verifier::verify(&code, &functions); assert_eq!(res, Err(VerifierError::BadSpawnArgCount { pc: 0, expected: 2, got: 1 })); } #[test] fn err_sleep_truncated_immediate() { // Encode SLEEP but provide only 1 of 4 immediate bytes let mut code = Vec::new(); code.extend_from_slice(&enc_op(OpCode::Sleep)); code.push(0xAB); let functions = vec![FunctionMeta { code_offset: 0, code_len: code.len() as u32, ..Default::default() }]; let res = Verifier::verify(&code, &functions); assert_eq!( res, Err(VerifierError::TruncatedImmediate { pc: 0, opcode: OpCode::Sleep, need: 4, have: 1 }) ); }