From 239d7251c358ddcb9d38975133a6531573ed8a0f Mon Sep 17 00:00:00 2001 From: Nilton Constantino Date: Sat, 31 Jan 2026 23:49:24 +0000 Subject: [PATCH] pr 51 --- .../src/v0}/linker.rs | 44 ++++++++++--------- crates/prometeu-bytecode/src/v0/mod.rs | 2 + .../prometeu-core/src/virtual_machine/mod.rs | 3 -- .../src/virtual_machine/program.rs | 30 ++++++++++++- .../src/virtual_machine/virtual_machine.rs | 16 +++---- 5 files changed, 61 insertions(+), 34 deletions(-) rename crates/{prometeu-core/src/virtual_machine => prometeu-bytecode/src/v0}/linker.rs (90%) diff --git a/crates/prometeu-core/src/virtual_machine/linker.rs b/crates/prometeu-bytecode/src/v0/linker.rs similarity index 90% rename from crates/prometeu-core/src/virtual_machine/linker.rs rename to crates/prometeu-bytecode/src/v0/linker.rs index de5a52f3..7ba198d8 100644 --- a/crates/prometeu-core/src/virtual_machine/linker.rs +++ b/crates/prometeu-bytecode/src/v0/linker.rs @@ -1,6 +1,5 @@ -use crate::virtual_machine::{ProgramImage, Value}; -use prometeu_bytecode::v0::{BytecodeModule, DebugInfo, ConstantPoolEntry}; -use prometeu_bytecode::opcode::OpCode; +use crate::v0::{BytecodeModule, DebugInfo, ConstantPoolEntry, FunctionMeta}; +use crate::opcode::OpCode; use std::collections::HashMap; #[derive(Debug, Clone, PartialEq, Eq)] @@ -11,8 +10,18 @@ pub enum LinkError { pub struct Linker; +/// Internal representation for linking process +#[derive(Debug)] +pub struct LinkedProgram { + pub rom: Vec, + pub constant_pool: Vec, + pub functions: Vec, + pub debug_info: Option, + pub exports: HashMap, +} + impl Linker { - pub fn link(modules: &[BytecodeModule]) -> Result { + pub fn link(modules: &[BytecodeModule]) -> Result { let mut combined_code = Vec::new(); let mut combined_functions = Vec::new(); let mut combined_constants = Vec::new(); @@ -56,14 +65,7 @@ impl Linker { // Relocate constant pool entries for this module for entry in &module.const_pool { - combined_constants.push(match entry { - ConstantPoolEntry::Int32(v) => Value::Int32(*v), - ConstantPoolEntry::Int64(v) => Value::Int64(*v), - ConstantPoolEntry::Float64(v) => Value::Float(*v), - ConstantPoolEntry::Boolean(v) => Value::Boolean(*v), - ConstantPoolEntry::String(v) => Value::String(v.clone()), - ConstantPoolEntry::Null => Value::Null, - }); + combined_constants.push(entry.clone()); } // Patch relocations for imports @@ -143,21 +145,21 @@ impl Linker { None }; - Ok(ProgramImage::new( - combined_code, - combined_constants, - combined_functions, + Ok(LinkedProgram { + rom: combined_code, + constant_pool: combined_constants, + functions: combined_functions, debug_info, exports, - )) + }) } } #[cfg(test)] mod tests { use super::*; - use prometeu_bytecode::v0::{BytecodeModule, FunctionMeta, Export, Import}; - use prometeu_bytecode::opcode::OpCode; + use crate::v0::{BytecodeModule, FunctionMeta, Export, Import}; + use crate::opcode::OpCode; #[test] fn test_linker_basic() { @@ -280,8 +282,8 @@ mod tests { let result = Linker::link(&[m1, m2]).unwrap(); assert_eq!(result.constant_pool.len(), 2); - assert_eq!(result.constant_pool[0], Value::Int32(42)); - assert_eq!(result.constant_pool[1], Value::Int32(99)); + assert_eq!(result.constant_pool[0], ConstantPoolEntry::Int32(42)); + assert_eq!(result.constant_pool[1], ConstantPoolEntry::Int32(99)); // Code for module 1 (starts at 0) let idx1 = u32::from_le_bytes(result.rom[2..6].try_into().unwrap()); diff --git a/crates/prometeu-bytecode/src/v0/mod.rs b/crates/prometeu-bytecode/src/v0/mod.rs index 0b682d92..fd8acaba 100644 --- a/crates/prometeu-bytecode/src/v0/mod.rs +++ b/crates/prometeu-bytecode/src/v0/mod.rs @@ -1,3 +1,5 @@ +pub mod linker; + use crate::opcode::OpCode; use crate::abi::SourceSpan; diff --git a/crates/prometeu-core/src/virtual_machine/mod.rs b/crates/prometeu-core/src/virtual_machine/mod.rs index 53e0c27c..ca184fb0 100644 --- a/crates/prometeu-core/src/virtual_machine/mod.rs +++ b/crates/prometeu-core/src/virtual_machine/mod.rs @@ -7,7 +7,6 @@ pub mod local_addressing; pub mod opcode_spec; pub mod bytecode; pub mod verifier; -pub mod linker; use crate::hardware::HardwareBridge; pub use program::ProgramImage; @@ -16,7 +15,6 @@ pub use value::Value; pub use virtual_machine::{BudgetReport, LogicalFrameEndingReason, VirtualMachine}; pub use prometeu_bytecode::abi::TrapInfo; pub use verifier::VerifierError; -pub use linker::{Linker, LinkError}; pub type SyscallId = u32; @@ -31,7 +29,6 @@ pub enum VmInitError { InvalidFormat, UnsupportedFormat, PbsV0LoadFailed(prometeu_bytecode::v0::LoadError), - LinkFailed(LinkError), EntrypointNotFound, VerificationFailed(VerifierError), } diff --git a/crates/prometeu-core/src/virtual_machine/program.rs b/crates/prometeu-core/src/virtual_machine/program.rs index 6adaf5c3..024ba214 100644 --- a/crates/prometeu-core/src/virtual_machine/program.rs +++ b/crates/prometeu-core/src/virtual_machine/program.rs @@ -1,5 +1,5 @@ use crate::virtual_machine::Value; -use prometeu_bytecode::v0::{FunctionMeta, DebugInfo}; +use prometeu_bytecode::v0::{FunctionMeta, DebugInfo, BytecodeModule, ConstantPoolEntry}; use prometeu_bytecode::abi::TrapInfo; use std::sync::Arc; use std::collections::HashMap; @@ -63,3 +63,31 @@ impl ProgramImage { .map(|(_, name)| name.as_str()) } } + +impl From for ProgramImage { + fn from(module: BytecodeModule) -> Self { + let constant_pool: Vec = module.const_pool.iter().map(|entry| { + match entry { + ConstantPoolEntry::Null => Value::Null, + ConstantPoolEntry::Int64(v) => Value::Int64(*v), + ConstantPoolEntry::Float64(v) => Value::Float(*v), + ConstantPoolEntry::Boolean(v) => Value::Boolean(*v), + ConstantPoolEntry::String(v) => Value::String(v.clone()), + ConstantPoolEntry::Int32(v) => Value::Int32(*v), + } + }).collect(); + + let mut exports = HashMap::new(); + for export in module.exports { + exports.insert(export.symbol, export.func_idx); + } + + ProgramImage::new( + module.code, + constant_pool, + module.functions, + module.debug_info, + exports, + ) + } +} diff --git a/crates/prometeu-core/src/virtual_machine/virtual_machine.rs b/crates/prometeu-core/src/virtual_machine/virtual_machine.rs index d608f966..af43efd4 100644 --- a/crates/prometeu-core/src/virtual_machine/virtual_machine.rs +++ b/crates/prometeu-core/src/virtual_machine/virtual_machine.rs @@ -125,21 +125,19 @@ impl VirtualMachine { let program = if program_bytes.starts_with(b"PBS\0") { match prometeu_bytecode::v0::BytecodeLoader::load(&program_bytes) { Ok(module) => { - // Link module(s) - let mut linked_program = crate::virtual_machine::Linker::link(&[module]) - .map_err(VmInitError::LinkFailed)?; - - // Run verifier on the linked program - let max_stacks = crate::virtual_machine::verifier::Verifier::verify(&linked_program.rom, &linked_program.functions) + // Run verifier on the module + let max_stacks = crate::virtual_machine::verifier::Verifier::verify(&module.code, &module.functions) .map_err(VmInitError::VerificationFailed)?; - let mut functions = linked_program.functions.as_ref().to_vec(); + let mut program = ProgramImage::from(module); + + let mut functions = program.functions.as_ref().to_vec(); for (func, max_stack) in functions.iter_mut().zip(max_stacks) { func.max_stack_slots = max_stack; } - linked_program.functions = std::sync::Arc::from(functions); + program.functions = std::sync::Arc::from(functions); - linked_program + program } Err(prometeu_bytecode::v0::LoadError::InvalidVersion) => return Err(VmInitError::UnsupportedFormat), Err(e) => {