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() {
// 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<u8> = Vec::new();

View File

@ -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<DvmValue>),
Pointer(Rc<DmAllocObject>),
ByteArray(Vec<u8>),
IntArray(Vec<i32>),
LongArray(Vec<i64>),
DoubleArray(Vec<f64>),
BooleanArray(Vec<bool>),
PointerArray(Vec<Box<DvmValue>>),
PointerArray(Vec<Rc<DmAllocObject>>),
Unit,
}

View File

@ -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,

View File

@ -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<DvmValue>, &mut DmVirtualMachine) -> DvmValue;
@ -33,6 +34,7 @@ struct DeimosCallFrame {
pub struct DmVirtualMachine {
modules: Vec<DmModule>,
functions: HashMap<String, Rc<DmFn>>,
platform_functions: HashMap<String, PlatformFunction>,
ip: usize,
call_stack: Vec<CallFrame>,
@ -40,13 +42,25 @@ pub struct DmVirtualMachine {
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 {
pub fn new(modules: Vec<DmModule>) -> 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(),
}

View File

@ -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<String, DmConstant>,
pub interfaces: HashMap<String, DmInterface>,
pub implementations: HashMap<String, DmImplementation>,
pub functions: HashMap<String, DmFn>,
pub constants: Vec<DmConstant>,
pub interfaces: Vec<Rc<DmInterface>>,
pub implementations: Vec<Rc<DmImplementation>>,
pub functions: Vec<Rc<DmFn>>,
}
pub enum DmConstant {

View File

@ -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<DmVirtualMethod>,
pub byte_code: Vec<u8>,
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<String, DmProperty>,
virtual_methods: HashMap<String, DmVirtualMethod>,
impl_methods: HashMap<String, DmFn>,
properties: Vec<Rc<DmProperty>>,
virtual_methods: Vec<Rc<DmVirtualMethod>>,
impl_methods: Vec<Rc<DmFn>>,
}
impl PartialEq for DmInterface {
@ -40,22 +40,22 @@ impl PartialEq for DmInterface {
}
impl DmInterface {
fn get_fqn(&self) -> &str {
&self.fqn
pub fn get_method(&self, name: &str, self_object: &DmAllocObject) -> Option<Rc<DmFn>> {
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);
}
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
}
}
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<DmInterface>,
pub properties: HashMap<String, DmProperty>,
pub fields: HashMap<String, DmField>,
pub size_in_bytes: usize,
pub methods: HashMap<String, DmFn>,
properties: Vec<DmProperty>,
fields: Vec<DmField>,
methods: Vec<Rc<DmFn>>,
}
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<Rc<DmFn>> {
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<Rc<DmProperty>> {
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<Rc<DmField>> {
todo!()
}
}

View File

@ -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<DvmValue>, 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<DvmValue>, 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<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")
}
}