2026-03-24 13:40:41 +00:00

56 lines
2.2 KiB
Rust

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 })
);
}