diff --git a/dvm-lib/src/vm/mod.rs b/dvm-lib/src/vm/mod.rs index 0091539..6b2dace 100644 --- a/dvm-lib/src/vm/mod.rs +++ b/dvm-lib/src/vm/mod.rs @@ -10,6 +10,7 @@ use std::rc::Rc; pub mod constant; pub mod function; +pub mod object; pub mod value; pub struct DvmContext { diff --git a/dvm-lib/src/vm/object.rs b/dvm-lib/src/vm/object.rs new file mode 100644 index 0000000..a2b9ac4 --- /dev/null +++ b/dvm-lib/src/vm/object.rs @@ -0,0 +1,50 @@ +use crate::vm::value::Value; +use std::alloc::{Layout, alloc}; + +#[repr(C)] +pub struct Object { + header: ObjectHeader, + fields: [Value], +} + +pub struct ObjectHeader { + field_count: usize, +} + +fn get_object(field_count: usize) -> Box { + let (layout, fields_base) = Layout::array::(field_count) + .and_then(|fields_array_layout| Layout::new::().extend(fields_array_layout)) + .unwrap(); + println!("{:?}", layout); + let ptr = unsafe { alloc(layout) }; + if ptr.is_null() { + panic!("failed to allocate memory"); + } + unsafe { + ptr.cast::() + .write(ObjectHeader { field_count }); + let fields_ptr = ptr.add(fields_base).cast::(); + // initialize each field to Value::Null + for i in 0..field_count { + fields_ptr.add(i).write(Value::Null); + } + + // this is somehow magic + // https://stackoverflow.com/questions/64120001/how-to-create-a-smart-pointer-to-an-unsized-type-with-an-embedded-slice + Box::from_raw(std::ptr::slice_from_raw_parts(ptr as *mut Value, field_count) as *mut Object) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn melt_the_processor() { + let mut o = get_object(3); + assert_eq!(o.header.field_count, 3); + assert_eq!(o.fields.len(), 3); + o.fields.fill(Value::Int(42)); + assert!(o.fields.iter().all(|v| *v == Value::Int(42))); + } +}