56 lines
2.2 KiB
Rust
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 })
|
|
);
|
|
}
|