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:
parent
cccbc6d819
commit
d4280f40e1
@ -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();
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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(),
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user