Sketching mem.
This commit is contained in:
parent
08625404ae
commit
4c744bf2d6
49
dvm-lib/mem.md
Normal file
49
dvm-lib/mem.md
Normal 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,
|
||||
|
||||
}
|
||||
```
|
||||
@ -1,3 +1,5 @@
|
||||
#![feature(ptr_metadata)]
|
||||
|
||||
pub mod instruction;
|
||||
pub mod platform_function;
|
||||
pub mod vm;
|
||||
|
||||
148
dvm-lib/src/vm/mem.rs
Normal file
148
dvm-lib/src/vm/mem.rs
Normal 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!()
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,7 @@ pub mod array;
|
||||
pub mod class;
|
||||
pub mod constant;
|
||||
pub mod function;
|
||||
mod mem;
|
||||
pub mod object;
|
||||
pub mod operand;
|
||||
mod operand_helpers;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user