diff --git a/src/bin/dvm/main.rs b/src/bin/dvm/main.rs index 104a505..b75921e 100644 --- a/src/bin/dvm/main.rs +++ b/src/bin/dvm/main.rs @@ -4,7 +4,7 @@ use deimos::vm::dvm_value::DvmValue; fn main() { // TODO: - // - write a single module with a main() fn which takes cli args + // - write a single module with a main() // - call the main fn let mut code: Vec = Vec::new(); diff --git a/src/vm/dvm_value.rs b/src/vm/dvm_value.rs index 496fca8..44b0a77 100644 --- a/src/vm/dvm_value.rs +++ b/src/vm/dvm_value.rs @@ -1,3 +1,6 @@ +use std::rc::Rc; +use crate::vm::mem::DmAllocObject; + #[derive(Debug, Clone, PartialEq)] pub enum DvmValue { Byte(u8), @@ -5,12 +8,12 @@ pub enum DvmValue { Long(i64), Double(f64), Boolean(bool), - Pointer(Box), + Pointer(Rc), ByteArray(Vec), IntArray(Vec), LongArray(Vec), DoubleArray(Vec), BooleanArray(Vec), - PointerArray(Vec>), + PointerArray(Vec>), Unit, } diff --git a/src/vm/mem.rs b/src/vm/mem.rs index c25fe0a..5250e50 100644 --- a/src/vm/mem.rs +++ b/src/vm/mem.rs @@ -1,10 +1,11 @@ use crate::vm::dm_type::DmPrimitiveType; use crate::vm::dvm_value::DvmValue; -use crate::vm::object_type::DmProperty; use crate::vm::object_type::DmImplementation; +use crate::vm::object_type::DmProperty; use std::alloc::Layout; use std::rc::Rc; +#[derive(Debug, PartialEq, Eq)] pub struct DmAllocObject { pub data: *mut u8, pub size: usize, @@ -36,7 +37,7 @@ pub unsafe fn get_property_value( DmPrimitiveType::Pointer(_) => { // read the pointer's (address) value let address = usize::from_ne_bytes(raw_data[0..data_size].try_into().unwrap()); - DvmValue::Pointer(Box::from_raw(address as *mut DvmValue)) + DvmValue::Pointer(Rc::from_raw(address as *const DmAllocObject)) } DmPrimitiveType::ByteArray(_) => DvmValue::ByteArray(raw_data), DmPrimitiveType::IntArray(length) => DvmValue::IntArray(read_i32_array(&raw_data, *length)), @@ -46,13 +47,11 @@ pub unsafe fn get_property_value( DmPrimitiveType::DoubleArray(length) => { DvmValue::DoubleArray(read_f64_array(&raw_data, *length)) } - DmPrimitiveType::BooleanArray(length) => { - DvmValue::BooleanArray(read_bool_array(&raw_data)) - } + DmPrimitiveType::BooleanArray(length) => DvmValue::BooleanArray(read_bool_array(&raw_data)), DmPrimitiveType::PointerArray(length, _) => DvmValue::PointerArray( read_usize_array(&raw_data, *length) .iter() - .map(|raw_usize| Box::from_raw(*raw_usize as *mut DvmValue)) + .map(|raw_usize| Rc::from_raw(*raw_usize as *const DmAllocObject)) .collect(), ), DmPrimitiveType::Unit => DvmValue::Unit, diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 5c4e838..e6e36c3 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -13,6 +13,7 @@ use crate::vm::object_type::DmFn; use crate::vm::platform::init_platform_functions; use op_codes::*; use std::collections::HashMap; +use std::rc::Rc; use util::{get_32_le, get_64_le}; pub type PlatformFunction = fn(args: Vec, &mut DmVirtualMachine) -> DvmValue; @@ -33,6 +34,7 @@ struct DeimosCallFrame { pub struct DmVirtualMachine { modules: Vec, + functions: HashMap>, platform_functions: HashMap, ip: usize, call_stack: Vec, @@ -40,13 +42,25 @@ pub struct DmVirtualMachine { register_state_stack: Vec>, } +fn load_functions(modules: &Vec) -> HashMap> { + let mut functions: HashMap> = HashMap::new(); + for module in modules { + for module_fn in &module.functions { + functions.insert(module_fn.fqn.clone(), module_fn.clone()); + } + for interface in &module.interfaces {} + } + functions +} + impl DmVirtualMachine { pub fn new(modules: Vec) -> DmVirtualMachine { DmVirtualMachine { modules, + functions: HashMap::new(), + platform_functions: init_platform_functions(), ip: 0, registers: Vec::new(), - platform_functions: init_platform_functions(), call_stack: Vec::new(), register_state_stack: Vec::new(), } diff --git a/src/vm/module.rs b/src/vm/module.rs index c80079d..49c09a1 100644 --- a/src/vm/module.rs +++ b/src/vm/module.rs @@ -1,6 +1,6 @@ +use std::rc::Rc; use crate::get_32_le; use crate::vm::object_type::{DmFn, DmImplementation, DmInterface}; -use std::collections::HashMap; pub const DEIMOS_MAGIC_NUMBER: u64 = 0x00_00_64_65_69_6d_6f_73; // ascii 'deimos' pub const DEIMOS_MAGIC_STRING: [u8; 6] = [0x64, 0x65, 0x69, 0x6d, 0x6f, 0x73]; // ascii 'deimos' @@ -11,10 +11,10 @@ pub struct DmModule { pub compiler_version: String, pub fqn: String, pub short_name: String, - pub constants: HashMap, - pub interfaces: HashMap, - pub implementations: HashMap, - pub functions: HashMap, + pub constants: Vec, + pub interfaces: Vec>, + pub implementations: Vec>, + pub functions: Vec>, } pub enum DmConstant { diff --git a/src/vm/object_type.rs b/src/vm/object_type.rs index 21f4c2d..bd8029c 100644 --- a/src/vm/object_type.rs +++ b/src/vm/object_type.rs @@ -1,6 +1,5 @@ use crate::vm::dm_type::DmPrimitiveType; use crate::vm::mem::DmAllocObject; -use std::collections::HashMap; use std::fmt::Debug; use std::rc::Rc; @@ -14,6 +13,7 @@ pub enum DmObjectType { pub struct DmFn { pub fqn: String, pub short_name: String, + pub implements: Option, pub byte_code: Vec, pub num_registers: usize, } @@ -26,11 +26,11 @@ impl PartialEq for DmFn { #[derive(Debug, Eq)] pub struct DmInterface { - fqn: String, + pub fqn: String, short_name: String, - properties: HashMap, - virtual_methods: HashMap, - impl_methods: HashMap, + properties: Vec>, + virtual_methods: Vec>, + impl_methods: Vec>, } impl PartialEq for DmInterface { @@ -40,22 +40,22 @@ impl PartialEq for DmInterface { } impl DmInterface { - fn get_fqn(&self) -> &str { - &self.fqn - } - - fn get_method<'a>(&'a self, name: &str, self_object: &'a DmAllocObject) -> Option<&'a DmFn> { - if self.impl_methods.contains_key(name) { - self.impl_methods.get(name) - } else if self.virtual_methods.contains_key(name) { - self_object.implementation.get_method(name, self_object) - } else { - None + pub fn get_method(&self, name: &str, self_object: &DmAllocObject) -> Option> { + if let Some(dm_fn) = self.impl_methods.iter().find(|&dm_fn| dm_fn.fqn == name) { + return Some(dm_fn.clone()); + } else if self + .virtual_methods + .iter() + .find(|&dm_fn| dm_fn.fqn == name) + .is_some() + { + return self_object.implementation.get_method(name, self_object); } + None } - fn get_property(&self, name: &str, self_object: &DmAllocObject) -> Option<&DmProperty> { - self.properties.get(name) + pub fn get_property(&self, name: &str, self_object: &DmAllocObject) -> Option<&DmProperty> { + todo!() } } @@ -76,10 +76,10 @@ pub struct DmImplementation { pub fqn: String, pub short_name: String, pub interface: Rc, - pub properties: HashMap, - pub fields: HashMap, pub size_in_bytes: usize, - pub methods: HashMap, + properties: Vec, + fields: Vec, + methods: Vec>, } impl PartialEq for DmImplementation { @@ -89,16 +89,25 @@ impl PartialEq for DmImplementation { } impl DmImplementation { - fn get_fqn(&self) -> &str { - &self.fqn + pub fn get_method(&self, name: &str, self_object: &DmAllocObject) -> Option> { + for method in &self.methods { + if method.fqn == name { + return Some(method.clone()); + } else if let Some(implements) = &method.implements { + if implements.fqn == name { + return Some(method.clone()); + } + } + } + None } - fn get_method<'a>(&'a self, name: &str, self_object: &'a DmAllocObject) -> Option<&'a DmFn> { - self.methods.get(name) + pub fn get_property(&self, name: &str, self_object: &DmAllocObject) -> Option> { + todo!() } - fn get_property(&self, name: &str, self_object: &DmAllocObject) -> Option<&DmProperty> { - self.properties.get(name) + pub fn get_field(&self, name: &str, self_object: &DmAllocObject) -> Option> { + todo!() } } diff --git a/src/vm/platform/std_lib/core.rs b/src/vm/platform/std_lib/core.rs index e8d82e8..aa32649 100644 --- a/src/vm/platform/std_lib/core.rs +++ b/src/vm/platform/std_lib/core.rs @@ -1,11 +1,13 @@ use crate::vm::dvm_value::DvmValue; +use crate::vm::mem::DmAllocObject; use crate::vm::DmVirtualMachine; +use std::rc::Rc; pub fn dm_print(args: Vec, vm: &mut DmVirtualMachine) -> DvmValue { if args.len() != 1 { return DvmValue::Unit; // TODO: make exception } - print!("{}", get_string(&args[0])); + print!("{}", get_string(&args[0], vm)); DvmValue::Unit } @@ -13,18 +15,18 @@ pub fn dm_println(args: Vec, vm: &mut DmVirtualMachine) -> DvmValue { if args.len() != 1 { return DvmValue::Unit; } - println!("{}", get_string(&args[0])); + println!("{}", get_string(&args[0], vm)); DvmValue::Unit } -fn get_string(dvm_value: &DvmValue) -> String { +fn get_string(dvm_value: &DvmValue, vm: &mut DmVirtualMachine) -> String { match dvm_value { DvmValue::Byte(b) => b.to_string(), DvmValue::Int(i) => i.to_string(), DvmValue::Long(l) => l.to_string(), DvmValue::Double(d) => d.to_string(), DvmValue::Boolean(b) => b.to_string(), - DvmValue::Pointer(value_box) => get_string(value_box), + DvmValue::Pointer(alloc_object_rc) => convert_to_string(alloc_object_rc.clone(), vm), DvmValue::ByteArray(_) => todo!(), DvmValue::IntArray(_) => todo!(), DvmValue::LongArray(_) => todo!(), @@ -34,3 +36,15 @@ fn get_string(dvm_value: &DvmValue) -> String { DvmValue::Unit => String::from("Unit"), } } + +fn convert_to_string(alloc_object_rc: Rc, vm: &mut DmVirtualMachine) -> String { + let to_string_result = vm.call_by_fqn( + "std::Display::to_string", + vec![DvmValue::Pointer(alloc_object_rc)], + ); + if let DvmValue::Pointer(to_string_result_alloc_object) = to_string_result { + todo!("Convert to_string_result_alloc_object (a String) to bytes to pass to print") + } else { + panic!("to_string did not return a pointer") + } +}