From 94f496a63da09dea3d13ba80ef21924afb4e41c8 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Mon, 14 Apr 2025 07:59:51 -0500 Subject: [PATCH] Sketch DvmObjectFile type and related functions. --- src/bin/dvm/main.rs | 11 +++++- src/lib.rs | 9 ++--- src/object_file/mod.rs | 76 ++++++++++++++++++++++++++++++++++++++++ src/vm/implementation.rs | 8 ++--- src/vm/interface.rs | 8 ++--- src/vm/lib/mod.rs | 8 ++--- src/vm/mod.rs | 48 ++++++++++++++++++++----- 7 files changed, 142 insertions(+), 26 deletions(-) create mode 100644 src/object_file/mod.rs diff --git a/src/bin/dvm/main.rs b/src/bin/dvm/main.rs index 7d88870..a65fabb 100644 --- a/src/bin/dvm/main.rs +++ b/src/bin/dvm/main.rs @@ -1,3 +1,4 @@ +use deimos::object_file::{DvmObjectFile, DvmPath}; use deimos::vm::constant::DvmConstant; use deimos::vm::function::DvmFunction; use deimos::vm::instruction::{Immediate, Instruction, Location}; @@ -16,6 +17,8 @@ fn main() { // fn main() { // println "Hello, World!" // } + let mut greeter_object_file = DvmObjectFile::new(DvmPath::new("greeter", "greeter.dmo")); + let main_instructions = vec![ Instruction::MoveImmediate { destination: Location::Register(0), @@ -55,10 +58,16 @@ fn main() { char: 1, }, ); + + greeter_object_file.add_function(main_function); let mut state = DvmState::new(); - let mut context = DvmContext::new(Rc::new(main_function)); + let mut context = DvmContext::new("greeter::main"); context.add_platform_functions(get_std_lib_platform_functions()); + greeter_object_file.load_to_context(&mut context, &|path| { + todo!() + }); + let exit_code = run_main_function(&mut state, &context); dump_state(&state, "After main!"); diff --git a/src/lib.rs b/src/lib.rs index ce83d69..43dd3a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,8 @@ #![allow(warnings)] -mod compiler; -pub mod parser; -mod util; -pub mod vm; pub mod ast; +pub mod compiler; pub mod module; +pub mod object_file; +pub mod parser; +pub mod util; +pub mod vm; diff --git a/src/object_file/mod.rs b/src/object_file/mod.rs new file mode 100644 index 0000000..f08ae2a --- /dev/null +++ b/src/object_file/mod.rs @@ -0,0 +1,76 @@ +use crate::vm::function::DvmFunction; +use crate::vm::implementation::DvmImplementation; +use crate::vm::interface::DvmInterface; +use crate::vm::DvmContext; + +pub struct DvmObjectFile { + path: DvmPath, + dependencies: Vec, + interfaces: Vec, + implementations: Vec, + functions: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DvmPath { + base_fqn: String, + file_name: String, +} + +impl DvmPath { + pub fn new(base_fqn: &str, file_name: &str) -> Self { + DvmPath { + base_fqn: base_fqn.to_string(), + file_name: file_name.to_string(), + } + } +} + +impl DvmObjectFile { + pub fn new(path: DvmPath) -> Self { + DvmObjectFile { + path, + dependencies: vec![], + interfaces: vec![], + implementations: vec![], + functions: vec![], + } + } + + pub fn add_function(&mut self, function: DvmFunction) { + self.functions.push(function); + } + + pub fn add_dependency(&mut self, path: DvmPath) { + self.dependencies.push(path); + } + + pub fn load_to_context( + self, + context: &mut DvmContext, + linker: &impl Fn(&DvmPath) -> DvmObjectFile, + ) { + if context.is_object_file_loaded(&self.path) { + return; + } + + // Offload our own declarations + for interface in self.interfaces { + context.add_interface(interface); + } + for implementation in self.implementations { + context.add_implementation(implementation); + } + for function in self.functions { + context.add_static_function(function); + } + + context.mark_object_file_as_loaded(self.path); + + // Recursively load dependencies + for dependency in &self.dependencies { + let dependency_object_file = linker(dependency); + dependency_object_file.load_to_context(context, linker); + } + } +} diff --git a/src/vm/implementation.rs b/src/vm/implementation.rs index bf4310c..881c73c 100644 --- a/src/vm/implementation.rs +++ b/src/vm/implementation.rs @@ -1,6 +1,6 @@ use crate::vm::field::DvmField; use crate::vm::function::DvmFunction; -use crate::vm::interface::DmInterface; +use crate::vm::interface::DvmInterface; use crate::vm::method::DvmMethod; use crate::vm::object::DvmObject; use std::collections::HashMap; @@ -10,7 +10,7 @@ use std::rc::Rc; #[derive(Debug, Eq)] pub struct DvmImplementation { fqn: String, - interface: Option>, + interface: Option>, static_functions: HashMap>, methods: HashMap>, fields: HashMap>, @@ -23,7 +23,7 @@ impl PartialEq for DvmImplementation { } impl DvmImplementation { - pub fn new(fqn: &str, interface: Option>) -> Self { + pub fn new(fqn: &str, interface: Option>) -> Self { DvmImplementation { fqn: fqn.to_string(), interface, @@ -59,7 +59,7 @@ impl DvmImplementation { pub fn find_field(&self, name: &str, self_object: &DvmObject) -> Option> { self.fields.get(name).cloned() } - + pub fn field_count(&self) -> usize { self.fields.len() } diff --git a/src/vm/interface.rs b/src/vm/interface.rs index a4daf69..9b43bf3 100644 --- a/src/vm/interface.rs +++ b/src/vm/interface.rs @@ -3,21 +3,21 @@ use crate::vm::virtual_method::DmVirtualMethod; use std::rc::Rc; #[derive(Debug, Eq)] -pub struct DmInterface { +pub struct DvmInterface { fqn: String, static_functions: Vec>, virtual_methods: Vec, } -impl PartialEq for DmInterface { +impl PartialEq for DvmInterface { fn eq(&self, other: &Self) -> bool { self.fqn == other.fqn } } -impl DmInterface { +impl DvmInterface { pub fn new(fqn: &str) -> Self { - DmInterface { + DvmInterface { fqn: fqn.to_string(), static_functions: Vec::new(), virtual_methods: Vec::new(), diff --git a/src/vm/lib/mod.rs b/src/vm/lib/mod.rs index 11b65c1..437155a 100644 --- a/src/vm/lib/mod.rs +++ b/src/vm/lib/mod.rs @@ -5,13 +5,13 @@ mod write; use crate::vm::function::DvmFunction; use crate::vm::implementation::DvmImplementation; -use crate::vm::interface::DmInterface; +use crate::vm::interface::DvmInterface; use std::rc::Rc; pub struct DmLib { name: String, constants: Vec, - interfaces: Vec>, + interfaces: Vec>, implementations: Vec>, functions: Vec>, } @@ -39,11 +39,11 @@ impl DmLib { self.constants.push(constant); } - pub fn interfaces(&self) -> &Vec> { + pub fn interfaces(&self) -> &Vec> { &self.interfaces } - pub fn add_interface(&mut self, interface: DmInterface) { + pub fn add_interface(&mut self, interface: DvmInterface) { self.interfaces.push(Rc::new(interface)); } diff --git a/src/vm/mod.rs b/src/vm/mod.rs index da368a2..27e6b6c 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -1,12 +1,12 @@ -mod array; +pub mod array; pub mod constant; -mod field; +pub mod field; pub mod function; pub mod implementation; pub mod instruction; -mod interface; +pub mod interface; pub mod lib; -mod method; +pub mod method; pub mod object; pub mod op_codes; pub mod platform; @@ -14,12 +14,14 @@ pub mod source_code_location; pub mod r#type; pub mod util; pub mod value; -mod virtual_method; +pub mod virtual_method; +use crate::object_file::DvmPath; use crate::vm::array::DvmArray; use crate::vm::constant::{DvmConstant, DvmConstantArray}; use crate::vm::implementation::DvmImplementation; use crate::vm::instruction::{Immediate, Instruction, Location}; +use crate::vm::interface::DvmInterface; use crate::vm::object::DvmObject; use crate::vm::value::DvmValue; use function::DvmFunction; @@ -95,19 +97,23 @@ impl DvmState { } pub struct DvmContext { - main_function: Rc, + main_function: String, + interfaces: HashMap>, implementations: HashMap>, static_functions: HashMap>, platform_functions: HashMap, + loaded_object_files: Vec, } impl DvmContext { - pub fn new(main_function: Rc) -> Self { + pub fn new(main_function: &str) -> Self { DvmContext { - main_function, + main_function: main_function.to_string(), + interfaces: HashMap::new(), implementations: HashMap::new(), static_functions: HashMap::new(), platform_functions: HashMap::new(), + loaded_object_files: vec![], } } @@ -119,6 +125,29 @@ impl DvmContext { self.platform_functions.insert(fqn, platform_function); } } + + pub fn is_object_file_loaded(&self, path: &DvmPath) -> bool { + self.loaded_object_files.contains(path) + } + + pub fn add_interface(&mut self, interface: DvmInterface) { + self.interfaces + .insert(interface.fqn().to_string(), Rc::new(interface)); + } + + pub fn add_implementation(&mut self, implementation: DvmImplementation) { + self.implementations + .insert(implementation.fqn().to_string(), Rc::new(implementation)); + } + + pub fn add_static_function(&mut self, function: DvmFunction) { + self.static_functions + .insert(function.fqn().to_string(), Rc::new(function)); + } + + pub fn mark_object_file_as_loaded(&mut self, path: DvmPath) { + self.loaded_object_files.push(path); + } } pub struct DvmCall { @@ -281,7 +310,8 @@ fn immediate_to_value(immediate: &Immediate) -> DvmValue { } pub fn run_main_function(state: &mut DvmState, context: &DvmContext) -> i32 { - let main_function = context.main_function.clone(); + let main_function = context.static_functions.get(&context.main_function) + .expect(&format!("No such main function: {}", context.main_function)); push_call_frame( Rc::new(main_function.fqn().to_string()), main_function.source_code_location().clone(),