Sketching mem.

This commit is contained in:
Jesse Brault 2026-07-30 21:05:13 -05:00
parent 08625404ae
commit 4c744bf2d6
4 changed files with 200 additions and 0 deletions

49
dvm-lib/mem.md Normal file
View File

@ -0,0 +1,49 @@
# Object/Memory/Heap Concepts for Deimos/DVM
```rust
use std::any::TypeId;
trait Trace {
fn grays(&self) -> &[GcAny];
}
struct Gc<T: Trace> {
inner: *mut GcInner<T>,
}
impl<T> Gc {
fn data(&self) -> &T {
&self.inner.data
}
}
struct GcMut<T: Trace> {
inner: *mut GcInner<T>,
}
struct GcInner<T: Trace> {
data: T,
gc_count: usize,
gc_mut_count: bool,
next: Option<GcAny>,
color: bool,
}
struct GcAny {
inner: *mut (), // like void* in C
v_table: *const GcAnyVTable,
type_id: *const TypeId,
}
enum Value {
Object(Gc<Object>),
Int(i32),
String(Gc<String>),
Null
}
struct Object {
class: *const Class,
}
```

View File

@ -1,3 +1,5 @@
#![feature(ptr_metadata)]
pub mod instruction; pub mod instruction;
pub mod platform_function; pub mod platform_function;
pub mod vm; pub mod vm;

148
dvm-lib/src/vm/mem.rs Normal file
View File

@ -0,0 +1,148 @@
use std::any::TypeId;
use std::ptr::Pointee;
use std::rc::Rc;
use std::sync::OnceLock;
trait Trace {
fn grays(&self) -> Vec<GcAny>;
}
struct Gc<T: Trace + ?Sized> {
inner: *mut GcInner<T>,
}
impl<T: Trace + ?Sized> Gc<T> {
fn from_inner(inner: *mut GcInner<T>) -> Self {
Self { inner }
}
fn data(&self) -> &T {
unsafe { &(*self.inner).data }
}
fn data_mut(&mut self) -> &mut T {
unsafe { &mut (*self.inner).data }
}
}
impl<T: Trace + ?Sized + 'static> Gc<T> {
fn erase(&self) -> GcAny {
GcAny::from_gc_inner(self.inner)
}
}
struct GcMut<T: Trace> {
inner: *mut GcInner<T>,
}
struct GcInner<T: Trace + ?Sized> {
borrow_count: usize,
borrow_mut_count: bool,
next: Option<GcAny>,
color: bool,
data: T,
}
impl<T: Trace> GcInner<T> {
fn new(data: T) -> Self {
Self {
borrow_count: 0,
borrow_mut_count: false,
next: None,
color: false,
data,
}
}
}
struct GcAny {
inner_ptr: *mut (), // like void* in C
inner_ptr_metadata: *const (), // type-erased metadata
v_table: *const GcAnyVTable,
type_id: *const TypeId,
}
impl GcAny {
fn from_gc_inner<T: Trace + ?Sized + 'static>(gc_inner: *mut GcInner<T>) -> Self {
fn trace<T: Trace + ?Sized>(
inner_ptr: *const (),
inner_ptr_metadata: *const (),
) -> Vec<GcAny> {
let metadata: <GcInner<T> as Pointee>::Metadata =
unsafe { std::mem::transmute_copy(&inner_ptr_metadata) };
let gc_inner: *const GcInner<T> = std::ptr::from_raw_parts(inner_ptr, metadata);
unsafe { &*gc_inner }.data.grays()
}
let (inner_ptr, metadata) = gc_inner.to_raw_parts();
let inner_pointer_metadata = unsafe { std::mem::transmute_copy(&metadata) };
static V_TABLE: OnceLock<GcAnyVTable> = OnceLock::new();
let v_table = V_TABLE.get_or_init(|| GcAnyVTable { trace: trace::<T> });
static TYPE_ID: OnceLock<TypeId> = OnceLock::new();
let type_id = TYPE_ID.get_or_init(|| TypeId::of::<T>());
Self {
inner_ptr,
inner_ptr_metadata: inner_pointer_metadata,
v_table,
type_id,
}
}
fn trace(&self) -> Vec<GcAny> {
((unsafe { &*self.v_table }).trace)(self.inner_ptr, self.inner_ptr_metadata)
}
fn is<T: 'static>(&self) -> bool {
unsafe { *self.type_id == TypeId::of::<T>() }
}
fn downcast<T: Trace + 'static>(&self) -> Option<Gc<T>> {
if self.is::<T>() {
Some(Gc::from_inner(self.inner_ptr as *mut GcInner<T>))
} else {
None
}
}
}
struct GcAnyVTable {
trace: fn(*const (), *const ()) -> Vec<GcAny>,
}
enum Value {
Object(Gc<Object>),
Int(i32),
String(Gc<str>),
Null,
}
struct Class {
name: Rc<str>,
}
#[repr(C)]
struct Object {
class: *const Class,
fields: [Value],
}
impl Trace for Object {
fn grays(&self) -> Vec<GcAny> {
vec![] // todo
}
}
impl Trace for str {
fn grays(&self) -> Vec<GcAny> {
vec![]
}
}
impl From<&str> for Gc<str> {
fn from(value: &str) -> Self {
todo!()
}
}

View File

@ -21,6 +21,7 @@ pub mod array;
pub mod class; pub mod class;
pub mod constant; pub mod constant;
pub mod function; pub mod function;
mod mem;
pub mod object; pub mod object;
pub mod operand; pub mod operand;
mod operand_helpers; mod operand_helpers;