-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvalidator.rs
More file actions
63 lines (57 loc) · 2.25 KB
/
Copy pathvalidator.rs
File metadata and controls
63 lines (57 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use crate::module::BytecodeModule;
use crate::operand::Operand;
/// Performs integrity checks on function chunks, indices, and jump offsets.
pub struct BytecodeValidator;
impl Default for BytecodeValidator {
fn default() -> Self {
Self::new()
}
}
impl BytecodeValidator {
/// Creates a new BytecodeValidator.
pub fn new() -> Self {
Self
}
/// Validates the module.
pub fn validate(&self, module: &BytecodeModule) -> Result<(), String> {
for func in &module.functions {
let num_insts = func.chunk.instructions.len();
let mut stack_height = 0i32;
for (idx, inst) in func.chunk.instructions.iter().enumerate() {
// 1. Stack height check
let effect = inst.op.stack_effect();
stack_height += effect;
if stack_height < 0 {
return Err(format!(
"Validation error in function '{}': Stack underflow at instruction index {}",
func.name, idx
));
}
// 2. Operand checks
for op in &inst.operands {
match op {
Operand::ConstantIndex(c_idx) => {
if func.chunk.constants.get(*c_idx).is_none() {
return Err(format!(
"Validation error in function '{}': Reference to invalid ConstantPool index {}",
func.name, c_idx
));
}
}
Operand::JumpOffset(offset) => {
let target = (idx as i32) + offset;
if target < 0 || target >= (num_insts as i32) {
return Err(format!(
"Validation error in function '{}': Out of bounds jump offset {} targeting index {}",
func.name, offset, target
));
}
}
_ => {}
}
}
}
}
Ok(())
}
}