Nilton Constantino 83e24920b4
pr 49
2026-01-31 18:48:22 +00:00

63 lines
2.0 KiB
Rust

use crate::virtual_machine::Value;
use prometeu_bytecode::v0::{FunctionMeta, DebugInfo};
use prometeu_bytecode::abi::TrapInfo;
use std::sync::Arc;
#[derive(Debug, Clone, Default)]
pub struct ProgramImage {
pub rom: Arc<[u8]>,
pub constant_pool: Arc<[Value]>,
pub functions: Arc<[FunctionMeta]>,
pub debug_info: Option<DebugInfo>,
}
impl ProgramImage {
pub fn new(rom: Vec<u8>, constant_pool: Vec<Value>, mut functions: Vec<FunctionMeta>, debug_info: Option<DebugInfo>) -> Self {
if functions.is_empty() && !rom.is_empty() {
functions.push(FunctionMeta {
code_offset: 0,
code_len: rom.len() as u32,
..Default::default()
});
}
Self {
rom: Arc::from(rom),
constant_pool: Arc::from(constant_pool),
functions: Arc::from(functions),
debug_info,
}
}
pub fn create_trap(&self, code: u32, opcode: u16, mut message: String, pc: u32) -> TrapInfo {
let span = self.debug_info.as_ref().and_then(|di| {
di.pc_to_span.iter().find(|(p, _)| *p == pc).map(|(_, s)| s.clone())
});
if let Some(func_idx) = self.find_function_index(pc) {
if let Some(func_name) = self.get_function_name(func_idx) {
message = format!("{} (in function {})", message, func_name);
}
}
TrapInfo {
code,
opcode,
message,
pc,
span,
}
}
pub fn find_function_index(&self, pc: u32) -> Option<usize> {
self.functions.iter().position(|f| {
pc >= f.code_offset && pc < (f.code_offset + f.code_len)
})
}
pub fn get_function_name(&self, func_idx: usize) -> Option<&str> {
self.debug_info.as_ref()
.and_then(|di| di.function_names.iter().find(|(idx, _)| *idx as usize == func_idx))
.map(|(_, name)| name.as_str())
}
}