Attempt to implement runtime types.
This commit is contained in:
parent
9bc27b841b
commit
7903c1cfb3
@ -5,7 +5,7 @@ fn main() {
|
||||
let mut code: Vec<u8> = Vec::new();
|
||||
add_mov_int(&mut code, 0, 42);
|
||||
add_platform_call_to(&mut code, &String::from("std::core::print"), 0, 1, &vec![0u8]);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&mut code);
|
||||
println!()
|
||||
}
|
78
src/vm/mem.rs
Normal file
78
src/vm/mem.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use crate::vm::types::{DmImplementation, DmProperty, DmType};
|
||||
use crate::vm::values::DmValue;
|
||||
use std::alloc::Layout;
|
||||
|
||||
pub struct DmAllocObject<'a> {
|
||||
pub data: *mut u8,
|
||||
pub size: usize,
|
||||
pub layout: Layout,
|
||||
pub object_type: &'a DmImplementation<'a>,
|
||||
}
|
||||
|
||||
pub unsafe fn get_property_value(dm_property: &DmProperty, dm_property_object: &DmAllocObject) -> DmValue {
|
||||
let mut data: Vec<u8> = Vec::with_capacity(dm_property.dm_type.size_in_bytes());
|
||||
for i in dm_property.data_offset..(dm_property.data_offset + dm_property.dm_type.size_in_bytes()) {
|
||||
data.push(dm_property_object.data.offset(i as isize).read());
|
||||
}
|
||||
match dm_property.dm_type {
|
||||
DmType::Byte => {
|
||||
DmValue::DmByte(data[0])
|
||||
}
|
||||
DmType::Int => {
|
||||
DmValue::DmInt(i32::from_ne_bytes(data[0..4].try_into().unwrap()))
|
||||
}
|
||||
DmType::Long => {
|
||||
DmValue::DmLong(i64::from_ne_bytes(data[0..8].try_into().unwrap()))
|
||||
}
|
||||
DmType::Double => {
|
||||
DmValue::DmDouble(f64::from_ne_bytes(data[0..8].try_into().unwrap()))
|
||||
}
|
||||
DmType::Boolean => {
|
||||
DmValue::DmBoolean(i32::from_ne_bytes(data[0..4].try_into().unwrap()) != 0)
|
||||
}
|
||||
DmType::ObjectPointer(_) => {
|
||||
DmValue::DmPointer(usize::from_ne_bytes(data[0..8].try_into().unwrap()) as *mut DmAllocObject)
|
||||
}
|
||||
DmType::ByteArray(_) => {
|
||||
DmValue::DmByteArray(data)
|
||||
}
|
||||
DmType::IntArray(length) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(i32::from_ne_bytes(data[(i * 4)..(i * 4 + 4)].try_into().unwrap()));
|
||||
}
|
||||
DmValue::DmIntArray(result)
|
||||
}
|
||||
DmType::LongArray(length) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(i64::from_ne_bytes(data[i * 8..(i * 8 + 8)].try_into().unwrap()));
|
||||
}
|
||||
DmValue::DmLongArray(result)
|
||||
}
|
||||
DmType::DoubleArray(length) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(f64::from_ne_bytes(data[i * 8..(i * 8 + 8)].try_into().unwrap()));
|
||||
}
|
||||
DmValue::DmDoubleArray(result)
|
||||
}
|
||||
DmType::BooleanArray(length) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(i32::from_ne_bytes(data[(i * 4)..(i * 4 + 4)].try_into().unwrap()) != 0);
|
||||
}
|
||||
DmValue::DmBooleanArray(result)
|
||||
}
|
||||
DmType::ObjectPointerArray(length, _) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(usize::from_ne_bytes(data[(i * 8)..(i * 8 + 8)].try_into().unwrap()) as *mut DmAllocObject);
|
||||
}
|
||||
DmValue::DmPointerArray(result)
|
||||
}
|
||||
DmType::Unit => {
|
||||
DmValue::DmUnit
|
||||
}
|
||||
}
|
||||
}
|
@ -4,13 +4,15 @@ pub mod platform;
|
||||
pub mod types;
|
||||
pub mod util;
|
||||
pub mod values;
|
||||
mod mem;
|
||||
|
||||
use crate::vm::module::DmFunction;
|
||||
use crate::vm::mem::DmAllocObject;
|
||||
use crate::vm::module::DmModule;
|
||||
use crate::vm::platform::init_platform_functions;
|
||||
use crate::vm::types::{DmFn, DmImplementation};
|
||||
use op_codes::*;
|
||||
use std::alloc::{alloc_zeroed, dealloc, Layout};
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Index;
|
||||
use types::DmType;
|
||||
use util::{get_32_le, get_64_le};
|
||||
use values::DmValue;
|
||||
@ -25,15 +27,15 @@ enum CallFrame {
|
||||
|
||||
pub struct PlatformCallFrame {
|
||||
pub name: String,
|
||||
pub args: Vec<u64>,
|
||||
pub arg_types: Vec<DmType>,
|
||||
pub args: Vec<DmValue>,
|
||||
}
|
||||
|
||||
struct DeimosCallFrame {
|
||||
return_address: usize,
|
||||
}
|
||||
|
||||
pub struct DmVirtualMachine {
|
||||
pub struct DmVirtualMachine<'a> {
|
||||
modules: Vec<DmModule<'a>>,
|
||||
platform_functions: HashMap<String, PlatformFunction>,
|
||||
ip: usize,
|
||||
call_stack: Vec<CallFrame>,
|
||||
@ -41,9 +43,10 @@ pub struct DmVirtualMachine {
|
||||
register_state_stack: Vec<Vec<DmValue>>,
|
||||
}
|
||||
|
||||
impl DmVirtualMachine {
|
||||
pub fn new() -> DmVirtualMachine {
|
||||
impl DmVirtualMachine<'_> {
|
||||
pub fn new(modules: Vec<DmModule>) -> DmVirtualMachine {
|
||||
DmVirtualMachine {
|
||||
modules,
|
||||
ip: 0,
|
||||
registers: Vec::new(),
|
||||
platform_functions: init_platform_functions(),
|
||||
@ -54,7 +57,7 @@ impl DmVirtualMachine {
|
||||
|
||||
pub fn call(
|
||||
&mut self,
|
||||
dm_function: &DmFunction,
|
||||
dm_function: &DmFn,
|
||||
args: Vec<DmValue>,
|
||||
) -> DmValue {
|
||||
// save current state
|
||||
@ -110,15 +113,36 @@ impl DmVirtualMachine {
|
||||
i += 3;
|
||||
}
|
||||
ALLOC => {
|
||||
let target_register = code[i + 1] as usize;
|
||||
let size = get_32_le!(code, i, 2, usize);
|
||||
i += 1;
|
||||
let target_register = code[i] as usize;
|
||||
i += 1;
|
||||
let symbol_name_length = get_32_le!(code, i, 0, usize);
|
||||
i += 4;
|
||||
let raw_symbol_name = code[i..(i + symbol_name_length)].to_vec();
|
||||
i += symbol_name_length;
|
||||
let symbol_name = String::from_utf8(raw_symbol_name).unwrap();
|
||||
|
||||
// find implementation
|
||||
let mut implementation_result: Option<&DmImplementation> = None;
|
||||
'module_find: for module in self.modules.iter() {
|
||||
if let Some(dm_implementation) = module.implementations.get(&symbol_name) {
|
||||
implementation_result = Some(dm_implementation);
|
||||
break 'module_find;
|
||||
}
|
||||
}
|
||||
if implementation_result == None {
|
||||
panic!("Implementation {} not found", symbol_name);
|
||||
}
|
||||
|
||||
let dm_implementation = implementation_result.unwrap();
|
||||
let size = dm_implementation.size_in_bytes;
|
||||
let layout = Layout::from_size_align(size, 4).unwrap();
|
||||
let pointer = unsafe { alloc_zeroed(layout) };
|
||||
let dm_object = Box::new(DmObject {
|
||||
let dm_object = Box::new(DmAllocObject {
|
||||
object_type: dm_implementation,
|
||||
data: pointer,
|
||||
size,
|
||||
layout,
|
||||
object_type: todo!(),
|
||||
});
|
||||
let dm_object_pointer = Box::into_raw(dm_object);
|
||||
self.registers.insert(target_register, DmPointer(dm_object_pointer));
|
||||
@ -201,30 +225,6 @@ impl DmVirtualMachine {
|
||||
|
||||
}
|
||||
|
||||
pub struct DmObjectType {
|
||||
name: String,
|
||||
properties: HashMap<String, DmObjectProperty>,
|
||||
fields: HashMap<String, DmObjectField>,
|
||||
methods: HashMap<String, DmFunction>,
|
||||
}
|
||||
|
||||
pub struct DmObject {
|
||||
object_type: Box<DmObjectType>,
|
||||
data: *mut u8,
|
||||
size: usize,
|
||||
layout: Layout,
|
||||
}
|
||||
|
||||
pub struct DmObjectProperty {
|
||||
name: String,
|
||||
property_type: DmType,
|
||||
}
|
||||
|
||||
pub struct DmObjectField {
|
||||
name: String,
|
||||
field_type: DmType,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod dvm_run_tests {
|
||||
use super::*;
|
||||
@ -240,7 +240,7 @@ mod dvm_run_tests {
|
||||
fn mov_1_as_int() {
|
||||
let mut code = Vec::new();
|
||||
add_mov_int(&mut code, 0, 1);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
assert_register!(DmInt(1), vm.registers.get(0));
|
||||
}
|
||||
@ -249,7 +249,7 @@ mod dvm_run_tests {
|
||||
fn move_65535_as_int() {
|
||||
let mut code = Vec::new();
|
||||
add_mov_int(&mut code, 0, 0xffff);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
assert_register!(DmInt(0xffff), vm.registers.get(0));
|
||||
}
|
||||
@ -258,7 +258,7 @@ mod dvm_run_tests {
|
||||
fn move_int_max_as_int() {
|
||||
let mut code = Vec::new();
|
||||
add_mov_int(&mut code, 0, 0x0fff_ffff);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
assert_register!(DmInt(0x0fff_ffff), vm.registers.get(0));
|
||||
}
|
||||
@ -268,7 +268,7 @@ mod dvm_run_tests {
|
||||
let mut code = Vec::new();
|
||||
add_mov_int(&mut code, 1, 1);
|
||||
add_mov_register(&mut code, 0, 1);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.registers.resize(2, DmUnit);
|
||||
vm.run(&code);
|
||||
assert_register!(DmInt(1), vm.registers.get(0));
|
||||
@ -280,7 +280,7 @@ mod dvm_run_tests {
|
||||
let mut code = Vec::new();
|
||||
add_alloc(&mut code, 0, 4);
|
||||
add_mov_int_to(&mut code, 0, 0, 0xff);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
let box_address = vm.registers.get(0).unwrap().clone();
|
||||
match box_address {
|
||||
@ -299,7 +299,7 @@ mod dvm_run_tests {
|
||||
let mut code = Vec::new();
|
||||
add_alloc(&mut code, 0, 4);
|
||||
add_dealloc(&mut code, 0);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
assert_register!(DmUnit, vm.registers.get(0));
|
||||
}
|
||||
|
@ -1,17 +1,20 @@
|
||||
use crate::get_32_le;
|
||||
use crate::vm::types::{DmFn, DmImplementation, DmInterface};
|
||||
use std::collections::HashMap;
|
||||
use std::io::Read;
|
||||
|
||||
pub const DEIMOS_MAGIC_NUMBER: u64 = 0x00_00_64_65_69_6d_6f_73; // ascii 'deimos'
|
||||
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'
|
||||
|
||||
pub const VERSION_STRING: &str = "0.1.0";
|
||||
pub const COMPILER_VERSION_STRING: &str = "0.1.0";
|
||||
|
||||
pub struct DmModule {
|
||||
name: String,
|
||||
version: String,
|
||||
constants: HashMap<String, DmConstant>,
|
||||
functions: HashMap<String, DmFunction>,
|
||||
pub struct DmModule<'a> {
|
||||
pub compiler_version: String,
|
||||
pub fqn: String,
|
||||
pub short_name: String,
|
||||
pub constants: HashMap<String, DmConstant>,
|
||||
pub interfaces: HashMap<String, DmInterface<'a>>,
|
||||
pub implementations: HashMap<String, DmImplementation<'a>>,
|
||||
pub functions: HashMap<String, DmFn>,
|
||||
}
|
||||
|
||||
pub enum DmConstant {
|
||||
@ -21,12 +24,6 @@ pub enum DmConstant {
|
||||
String(String),
|
||||
}
|
||||
|
||||
pub struct DmFunction {
|
||||
pub name: String,
|
||||
pub byte_code: Vec<u8>,
|
||||
pub num_registers: usize,
|
||||
}
|
||||
|
||||
const CONST_SYMBOL: u8 = 0x01;
|
||||
const FUNCTION_SYMBOL: u8 = 0x02;
|
||||
|
||||
@ -74,10 +71,10 @@ pub fn write_module(module: DmModule) -> Vec<u8> {
|
||||
push_byte_array!(result, DEIMOS_MAGIC_STRING);
|
||||
|
||||
// Push version string
|
||||
push_string!(result, module.version);
|
||||
push_string!(result, module.compiler_version);
|
||||
|
||||
// Push module name length, little endian
|
||||
push_string!(result, module.name);
|
||||
push_string!(result, module.fqn);
|
||||
|
||||
result
|
||||
}
|
||||
|
@ -1,26 +1,5 @@
|
||||
use crate::vm::module::DmFunction;
|
||||
use crate::vm::DmValue::*;
|
||||
use crate::vm::{DmObject, DmValue, DmVirtualMachine};
|
||||
|
||||
fn get_method<'a>(ptr: *mut DmObject, name: String) -> Option<&'a DmFunction> {
|
||||
unsafe {
|
||||
(*ptr).object_type.methods.get(&name)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_rust_string_from_dm_object(ptr: &*mut DmObject) -> String {
|
||||
unsafe {
|
||||
let dm_object = Box::from_raw(*ptr);
|
||||
format!("{}@{:?}", dm_object.object_type.name, dm_object.data)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_rust_string_from_dm_string(ptr: *mut DmObject) -> String {
|
||||
unsafe {
|
||||
let dm_string = Box::from_raw(ptr);
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
use crate::vm::{mem, DmValue, DmVirtualMachine};
|
||||
|
||||
pub fn dm_print(args: Vec<DmValue>, vm: &mut DmVirtualMachine) -> DmValue {
|
||||
if args.len() != 1 {
|
||||
@ -42,20 +21,26 @@ pub fn dm_print(args: Vec<DmValue>, vm: &mut DmVirtualMachine) -> DmValue {
|
||||
DmBoolean(b) => {
|
||||
print!("{}", *b);
|
||||
}
|
||||
DmPointer(ptr) => {
|
||||
if let Some(to_string) = get_method(*ptr, String::from("to_string")) {
|
||||
let call_result = vm.call(&to_string, vec![args[0].clone()]);
|
||||
match call_result {
|
||||
DmPointer(dm_string_ptr) => {
|
||||
let string = get_rust_string_from_dm_string(dm_string_ptr);
|
||||
print!("{}", string);
|
||||
}
|
||||
_ => {
|
||||
// TODO: vm throw or return exception?
|
||||
DmPointer(ptr) => unsafe {
|
||||
let dm_alloc_object = Box::from_raw(*ptr);
|
||||
let dm_object_type = &dm_alloc_object.object_type;
|
||||
if let Some(to_string_method) = dm_object_type.get_method(String::from("std::core::Object::to_string"), &dm_alloc_object) {
|
||||
let call_result = vm.call(to_string_method, vec![args[0].clone()]);
|
||||
if let DmPointer(dm_string_pointer) = call_result {
|
||||
let dm_string_object = Box::from_raw(dm_string_pointer);
|
||||
let bytes_property = dm_string_object.object_type.get_property(String::from("bytes"), &dm_string_object).unwrap();
|
||||
let string_bytes_value = mem::get_property_value(bytes_property, &dm_string_object);
|
||||
if let DmByteArray(raw_string_bytes) = string_bytes_value {
|
||||
// TODO: other encodings
|
||||
print!("{}", String::from_utf8(raw_string_bytes).unwrap());
|
||||
} else {
|
||||
panic!("Expected std::core::String.bytes to be a ByteArray.")
|
||||
}
|
||||
} else {
|
||||
panic!("Expected {} to return a string.", to_string_method.fqn)
|
||||
}
|
||||
} else {
|
||||
print!("{}", get_rust_string_from_dm_object(ptr));
|
||||
println!("{}@{:?}", dm_object_type.get_fqn(), dm_alloc_object.data)
|
||||
}
|
||||
},
|
||||
DmByteArray(bs) => {
|
||||
|
164
src/vm/types.rs
164
src/vm/types.rs
@ -1,14 +1,162 @@
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
|
||||
pub enum DmType {
|
||||
use crate::vm::mem::DmAllocObject;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum DmType<'a> {
|
||||
Byte,
|
||||
Int,
|
||||
Long,
|
||||
Double,
|
||||
Boolean,
|
||||
Pointer,
|
||||
IntArray,
|
||||
LongArray,
|
||||
DoubleArray,
|
||||
BooleanArray,
|
||||
PointerArray,
|
||||
ObjectPointer(&'a dyn DmObjectType),
|
||||
ByteArray(usize),
|
||||
IntArray(usize),
|
||||
LongArray(usize),
|
||||
DoubleArray(usize),
|
||||
BooleanArray(usize),
|
||||
ObjectPointerArray(usize, &'a dyn DmObjectType),
|
||||
Unit,
|
||||
}
|
||||
|
||||
impl DmType<'_> {
|
||||
pub fn size_in_bytes(&self) -> usize {
|
||||
match self {
|
||||
DmType::Byte => 1,
|
||||
DmType::Int => 4,
|
||||
DmType::Long => 8,
|
||||
DmType::Double => 8,
|
||||
DmType::Boolean => 4,
|
||||
DmType::ObjectPointer(_) => 8,
|
||||
DmType::ByteArray(length) => *length,
|
||||
DmType::IntArray(length) => *length * 4,
|
||||
DmType::LongArray(length) => *length * 8,
|
||||
DmType::DoubleArray(length) => *length * 8,
|
||||
DmType::BooleanArray(length) => *length * 4,
|
||||
DmType::ObjectPointerArray(length, _) => length * 8,
|
||||
DmType::Unit => 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DmObjectType {
|
||||
fn get_fqn(&self) -> &String;
|
||||
fn get_method(&self, name: String, self_object: &DmAllocObject) -> Option<&DmFn>;
|
||||
fn get_property(&self, name: String, self_object: &DmAllocObject) -> Option<&DmProperty>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmFn {
|
||||
pub fqn: String,
|
||||
pub short_name: String,
|
||||
pub byte_code: Vec<u8>,
|
||||
pub num_registers: usize,
|
||||
}
|
||||
|
||||
impl PartialEq for DmFn {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.fqn == other.fqn
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmInterface<'a> {
|
||||
fqn: String,
|
||||
short_name: String,
|
||||
properties: HashMap<String, DmProperty<'a>>,
|
||||
virtual_methods: HashMap<String, DmVirtualMethod>,
|
||||
impl_methods: HashMap<String, DmFn>,
|
||||
}
|
||||
|
||||
impl PartialEq for DmInterface<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.fqn == other.fqn
|
||||
}
|
||||
}
|
||||
|
||||
impl DmObjectType for DmInterface<'_> {
|
||||
fn get_fqn(&self) -> &String {
|
||||
&self.fqn
|
||||
}
|
||||
|
||||
fn get_method(&self, name: String, self_object: &DmAllocObject) -> Option<&DmFn> {
|
||||
if self.impl_methods.contains_key(&name) {
|
||||
self.impl_methods.get(&name)
|
||||
} else if self.virtual_methods.contains_key(&name) {
|
||||
self_object.object_type.get_method(name, &self_object)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property(&self, name: String, self_object: &DmAllocObject) -> Option<&DmProperty> {
|
||||
self.properties.get(&name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmVirtualMethod {
|
||||
pub fqn: String,
|
||||
pub short_name: String,
|
||||
}
|
||||
|
||||
impl PartialEq for DmVirtualMethod {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.fqn == other.fqn
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmImplementation<'a> {
|
||||
pub fqn: String,
|
||||
pub short_name: String,
|
||||
pub interface: &'a DmInterface<'a>,
|
||||
pub properties: HashMap<String, DmProperty<'a>>,
|
||||
pub fields: HashMap<String, DmField<'a>>,
|
||||
pub size_in_bytes: usize,
|
||||
pub methods: HashMap<String, DmFn>
|
||||
}
|
||||
|
||||
impl PartialEq for DmImplementation<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.fqn == other.fqn
|
||||
}
|
||||
}
|
||||
|
||||
impl DmObjectType for DmImplementation<'_> {
|
||||
fn get_fqn(&self) -> &String {
|
||||
&self.fqn
|
||||
}
|
||||
|
||||
fn get_method(&self, name: String, self_object: &DmAllocObject) -> Option<&DmFn> {
|
||||
self.methods.get(&name)
|
||||
}
|
||||
|
||||
fn get_property(&self, name: String, self_object: &DmAllocObject) -> Option<&DmProperty> {
|
||||
self.properties.get(&name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmProperty<'a> {
|
||||
pub name: String,
|
||||
pub data_offset: usize,
|
||||
pub dm_type: DmType<'a>
|
||||
}
|
||||
|
||||
impl PartialEq for DmProperty<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmField<'a> {
|
||||
name: String,
|
||||
dm_type: DmType<'a>,
|
||||
}
|
||||
|
||||
impl PartialEq for DmField<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use crate::vm::DmObject;
|
||||
use crate::vm::mem::DmAllocObject;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum DmValue {
|
||||
@ -7,12 +7,12 @@ pub enum DmValue {
|
||||
DmLong(i64),
|
||||
DmDouble(f64),
|
||||
DmBoolean(bool),
|
||||
DmPointer(*mut DmObject),
|
||||
DmPointer(*mut DmAllocObject),
|
||||
DmByteArray(Vec<u8>),
|
||||
DmIntArray(Vec<i32>),
|
||||
DmLongArray(Vec<i64>),
|
||||
DmDoubleArray(Vec<f64>),
|
||||
DmBooleanArray(Vec<bool>),
|
||||
DmPointerArray(Vec<*mut DmObject>),
|
||||
DmPointerArray(Vec<*mut DmAllocObject>),
|
||||
DmUnit,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user