More work on DvmValues and such to eventually be able to call to_string and get String bytes for printing.

This commit is contained in:
Jesse Brault 2024-12-06 15:18:19 -06:00
parent cccbc6d819
commit d4280f40e1
7 changed files with 85 additions and 46 deletions

View File

@ -4,7 +4,7 @@ use deimos::vm::dvm_value::DvmValue;
fn main() { fn main() {
// TODO: // TODO:
// - write a single module with a main() fn which takes cli args // - write a single module with a main()
// - call the main fn // - call the main fn
let mut code: Vec<u8> = Vec::new(); let mut code: Vec<u8> = Vec::new();

View File

@ -1,3 +1,6 @@
use std::rc::Rc;
use crate::vm::mem::DmAllocObject;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum DvmValue { pub enum DvmValue {
Byte(u8), Byte(u8),
@ -5,12 +8,12 @@ pub enum DvmValue {
Long(i64), Long(i64),
Double(f64), Double(f64),
Boolean(bool), Boolean(bool),
Pointer(Box<DvmValue>), Pointer(Rc<DmAllocObject>),
ByteArray(Vec<u8>), ByteArray(Vec<u8>),
IntArray(Vec<i32>), IntArray(Vec<i32>),
LongArray(Vec<i64>), LongArray(Vec<i64>),
DoubleArray(Vec<f64>), DoubleArray(Vec<f64>),
BooleanArray(Vec<bool>), BooleanArray(Vec<bool>),
PointerArray(Vec<Box<DvmValue>>), PointerArray(Vec<Rc<DmAllocObject>>),
Unit, Unit,
} }

View File

@ -1,10 +1,11 @@
use crate::vm::dm_type::DmPrimitiveType; use crate::vm::dm_type::DmPrimitiveType;
use crate::vm::dvm_value::DvmValue; use crate::vm::dvm_value::DvmValue;
use crate::vm::object_type::DmProperty;
use crate::vm::object_type::DmImplementation; use crate::vm::object_type::DmImplementation;
use crate::vm::object_type::DmProperty;
use std::alloc::Layout; use std::alloc::Layout;
use std::rc::Rc; use std::rc::Rc;
#[derive(Debug, PartialEq, Eq)]
pub struct DmAllocObject { pub struct DmAllocObject {
pub data: *mut u8, pub data: *mut u8,
pub size: usize, pub size: usize,
@ -36,7 +37,7 @@ pub unsafe fn get_property_value(
DmPrimitiveType::Pointer(_) => { DmPrimitiveType::Pointer(_) => {
// read the pointer's (address) value // read the pointer's (address) value
let address = usize::from_ne_bytes(raw_data[0..data_size].try_into().unwrap()); 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::ByteArray(_) => DvmValue::ByteArray(raw_data),
DmPrimitiveType::IntArray(length) => DvmValue::IntArray(read_i32_array(&raw_data, *length)), DmPrimitiveType::IntArray(length) => DvmValue::IntArray(read_i32_array(&raw_data, *length)),
@ -46,13 +47,11 @@ pub unsafe fn get_property_value(
DmPrimitiveType::DoubleArray(length) => { DmPrimitiveType::DoubleArray(length) => {
DvmValue::DoubleArray(read_f64_array(&raw_data, *length)) DvmValue::DoubleArray(read_f64_array(&raw_data, *length))
} }
DmPrimitiveType::BooleanArray(length) => { DmPrimitiveType::BooleanArray(length) => DvmValue::BooleanArray(read_bool_array(&raw_data)),
DvmValue::BooleanArray(read_bool_array(&raw_data))
}
DmPrimitiveType::PointerArray(length, _) => DvmValue::PointerArray( DmPrimitiveType::PointerArray(length, _) => DvmValue::PointerArray(
read_usize_array(&raw_data, *length) read_usize_array(&raw_data, *length)
.iter() .iter()
.map(|raw_usize| Box::from_raw(*raw_usize as *mut DvmValue)) .map(|raw_usize| Rc::from_raw(*raw_usize as *const DmAllocObject))
.collect(), .collect(),
), ),
DmPrimitiveType::Unit => DvmValue::Unit, DmPrimitiveType::Unit => DvmValue::Unit,

View File

@ -13,6 +13,7 @@ use crate::vm::object_type::DmFn;
use crate::vm::platform::init_platform_functions; use crate::vm::platform::init_platform_functions;
use op_codes::*; use op_codes::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc;
use util::{get_32_le, get_64_le}; use util::{get_32_le, get_64_le};
pub type PlatformFunction = fn(args: Vec<DvmValue>, &mut DmVirtualMachine) -> DvmValue; pub type PlatformFunction = fn(args: Vec<DvmValue>, &mut DmVirtualMachine) -> DvmValue;
@ -33,6 +34,7 @@ struct DeimosCallFrame {
pub struct DmVirtualMachine { pub struct DmVirtualMachine {
modules: Vec<DmModule>, modules: Vec<DmModule>,
functions: HashMap<String, Rc<DmFn>>,
platform_functions: HashMap<String, PlatformFunction>, platform_functions: HashMap<String, PlatformFunction>,
ip: usize, ip: usize,
call_stack: Vec<CallFrame>, call_stack: Vec<CallFrame>,
@ -40,13 +42,25 @@ pub struct DmVirtualMachine {
register_state_stack: Vec<Vec<DvmValue>>, register_state_stack: Vec<Vec<DvmValue>>,
} }
fn load_functions(modules: &Vec<DmModule>) -> HashMap<String, Rc<DmFn>> {
let mut functions: HashMap<String, Rc<DmFn>> = 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 { impl DmVirtualMachine {
pub fn new(modules: Vec<DmModule>) -> DmVirtualMachine { pub fn new(modules: Vec<DmModule>) -> DmVirtualMachine {
DmVirtualMachine { DmVirtualMachine {
modules, modules,
functions: HashMap::new(),
platform_functions: init_platform_functions(),
ip: 0, ip: 0,
registers: Vec::new(), registers: Vec::new(),
platform_functions: init_platform_functions(),
call_stack: Vec::new(), call_stack: Vec::new(),
register_state_stack: Vec::new(), register_state_stack: Vec::new(),
} }

View File

@ -1,6 +1,6 @@
use std::rc::Rc;
use crate::get_32_le; use crate::get_32_le;
use crate::vm::object_type::{DmFn, DmImplementation, DmInterface}; 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_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' 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 compiler_version: String,
pub fqn: String, pub fqn: String,
pub short_name: String, pub short_name: String,
pub constants: HashMap<String, DmConstant>, pub constants: Vec<DmConstant>,
pub interfaces: HashMap<String, DmInterface>, pub interfaces: Vec<Rc<DmInterface>>,
pub implementations: HashMap<String, DmImplementation>, pub implementations: Vec<Rc<DmImplementation>>,
pub functions: HashMap<String, DmFn>, pub functions: Vec<Rc<DmFn>>,
} }
pub enum DmConstant { pub enum DmConstant {

View File

@ -1,6 +1,5 @@
use crate::vm::dm_type::DmPrimitiveType; use crate::vm::dm_type::DmPrimitiveType;
use crate::vm::mem::DmAllocObject; use crate::vm::mem::DmAllocObject;
use std::collections::HashMap;
use std::fmt::Debug; use std::fmt::Debug;
use std::rc::Rc; use std::rc::Rc;
@ -14,6 +13,7 @@ pub enum DmObjectType {
pub struct DmFn { pub struct DmFn {
pub fqn: String, pub fqn: String,
pub short_name: String, pub short_name: String,
pub implements: Option<DmVirtualMethod>,
pub byte_code: Vec<u8>, pub byte_code: Vec<u8>,
pub num_registers: usize, pub num_registers: usize,
} }
@ -26,11 +26,11 @@ impl PartialEq for DmFn {
#[derive(Debug, Eq)] #[derive(Debug, Eq)]
pub struct DmInterface { pub struct DmInterface {
fqn: String, pub fqn: String,
short_name: String, short_name: String,
properties: HashMap<String, DmProperty>, properties: Vec<Rc<DmProperty>>,
virtual_methods: HashMap<String, DmVirtualMethod>, virtual_methods: Vec<Rc<DmVirtualMethod>>,
impl_methods: HashMap<String, DmFn>, impl_methods: Vec<Rc<DmFn>>,
} }
impl PartialEq for DmInterface { impl PartialEq for DmInterface {
@ -40,22 +40,22 @@ impl PartialEq for DmInterface {
} }
impl DmInterface { impl DmInterface {
fn get_fqn(&self) -> &str { pub fn get_method(&self, name: &str, self_object: &DmAllocObject) -> Option<Rc<DmFn>> {
&self.fqn if let Some(dm_fn) = self.impl_methods.iter().find(|&dm_fn| dm_fn.fqn == name) {
} return Some(dm_fn.clone());
} else if self
fn get_method<'a>(&'a self, name: &str, self_object: &'a DmAllocObject) -> Option<&'a DmFn> { .virtual_methods
if self.impl_methods.contains_key(name) { .iter()
self.impl_methods.get(name) .find(|&dm_fn| dm_fn.fqn == name)
} else if self.virtual_methods.contains_key(name) { .is_some()
self_object.implementation.get_method(name, self_object) {
} else { return self_object.implementation.get_method(name, self_object);
None
} }
None
} }
fn get_property(&self, name: &str, self_object: &DmAllocObject) -> Option<&DmProperty> { pub fn get_property(&self, name: &str, self_object: &DmAllocObject) -> Option<&DmProperty> {
self.properties.get(name) todo!()
} }
} }
@ -76,10 +76,10 @@ pub struct DmImplementation {
pub fqn: String, pub fqn: String,
pub short_name: String, pub short_name: String,
pub interface: Rc<DmInterface>, pub interface: Rc<DmInterface>,
pub properties: HashMap<String, DmProperty>,
pub fields: HashMap<String, DmField>,
pub size_in_bytes: usize, pub size_in_bytes: usize,
pub methods: HashMap<String, DmFn>, properties: Vec<DmProperty>,
fields: Vec<DmField>,
methods: Vec<Rc<DmFn>>,
} }
impl PartialEq for DmImplementation { impl PartialEq for DmImplementation {
@ -89,16 +89,25 @@ impl PartialEq for DmImplementation {
} }
impl DmImplementation { impl DmImplementation {
fn get_fqn(&self) -> &str { pub fn get_method(&self, name: &str, self_object: &DmAllocObject) -> Option<Rc<DmFn>> {
&self.fqn 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> { pub fn get_property(&self, name: &str, self_object: &DmAllocObject) -> Option<Rc<DmProperty>> {
self.methods.get(name) todo!()
} }
fn get_property(&self, name: &str, self_object: &DmAllocObject) -> Option<&DmProperty> { pub fn get_field(&self, name: &str, self_object: &DmAllocObject) -> Option<Rc<DmField>> {
self.properties.get(name) todo!()
} }
} }

View File

@ -1,11 +1,13 @@
use crate::vm::dvm_value::DvmValue; use crate::vm::dvm_value::DvmValue;
use crate::vm::mem::DmAllocObject;
use crate::vm::DmVirtualMachine; use crate::vm::DmVirtualMachine;
use std::rc::Rc;
pub fn dm_print(args: Vec<DvmValue>, vm: &mut DmVirtualMachine) -> DvmValue { pub fn dm_print(args: Vec<DvmValue>, vm: &mut DmVirtualMachine) -> DvmValue {
if args.len() != 1 { if args.len() != 1 {
return DvmValue::Unit; // TODO: make exception return DvmValue::Unit; // TODO: make exception
} }
print!("{}", get_string(&args[0])); print!("{}", get_string(&args[0], vm));
DvmValue::Unit DvmValue::Unit
} }
@ -13,18 +15,18 @@ pub fn dm_println(args: Vec<DvmValue>, vm: &mut DmVirtualMachine) -> DvmValue {
if args.len() != 1 { if args.len() != 1 {
return DvmValue::Unit; return DvmValue::Unit;
} }
println!("{}", get_string(&args[0])); println!("{}", get_string(&args[0], vm));
DvmValue::Unit DvmValue::Unit
} }
fn get_string(dvm_value: &DvmValue) -> String { fn get_string(dvm_value: &DvmValue, vm: &mut DmVirtualMachine) -> String {
match dvm_value { match dvm_value {
DvmValue::Byte(b) => b.to_string(), DvmValue::Byte(b) => b.to_string(),
DvmValue::Int(i) => i.to_string(), DvmValue::Int(i) => i.to_string(),
DvmValue::Long(l) => l.to_string(), DvmValue::Long(l) => l.to_string(),
DvmValue::Double(d) => d.to_string(), DvmValue::Double(d) => d.to_string(),
DvmValue::Boolean(b) => b.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::ByteArray(_) => todo!(),
DvmValue::IntArray(_) => todo!(), DvmValue::IntArray(_) => todo!(),
DvmValue::LongArray(_) => todo!(), DvmValue::LongArray(_) => todo!(),
@ -34,3 +36,15 @@ fn get_string(dvm_value: &DvmValue) -> String {
DvmValue::Unit => String::from("Unit"), DvmValue::Unit => String::from("Unit"),
} }
} }
fn convert_to_string(alloc_object_rc: Rc<DmAllocObject>, 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")
}
}