Add mem and obj modules, move to nightly
* mem and obj modules are roughly divided between doing memory-specific things and object-specific things * Box::new_uninit() is a nightly feature and it's quite useful, so I'm enabling that for now * Check out src/obj/attrs.rs for possible undefined behavior in the Attrs::new() function. I'm sure it'll be just fine. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
86
src/obj/attrs.rs
Normal file
86
src/obj/attrs.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
use crate::{
|
||||
mem::ptr::{DynRef, ObjCell},
|
||||
obj::prelude::*,
|
||||
};
|
||||
use std::{
|
||||
cell::Cell,
|
||||
mem::MaybeUninit,
|
||||
ptr::{self, NonNull},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Attrs {
|
||||
attrs: Vec<(Sym, DynRef)>,
|
||||
marked: Cell<bool>,
|
||||
this: ObjRef<Attrs>,
|
||||
}
|
||||
|
||||
impl Attrs {
|
||||
pub fn new(ctx: &mut ObjCtx) -> Self {
|
||||
let obj: Box<ObjCell<Attrs>> = unsafe {
|
||||
let mut obj: Box<MaybeUninit<ObjCell<Attrs>>> = Box::new_uninit();
|
||||
// maybe UB? taking away the uninit right before it's initialized may be bad
|
||||
let this = &*obj as *const _ as *const ObjCell<Attrs>;
|
||||
|
||||
obj.as_mut_ptr().write(ObjCell::new(Attrs {
|
||||
attrs: Default::default(),
|
||||
marked: Cell::new(false),
|
||||
this: ObjRef::new(NonNull::new(this as *mut _).unwrap()),
|
||||
}));
|
||||
|
||||
obj.assume_init()
|
||||
};
|
||||
|
||||
let attrs = {
|
||||
let obj_ref: &Attrs = &obj.borrow();
|
||||
assert!(
|
||||
ptr::eq(&*obj as *const _, obj_ref.this.as_ptr()),
|
||||
"Attr 'this' member does not point to itself"
|
||||
);
|
||||
obj_ref.clone()
|
||||
};
|
||||
|
||||
// Add the object to the allocator pool
|
||||
ctx.gc_mut().add_obj(obj);
|
||||
|
||||
attrs
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for Attrs {
|
||||
fn attrs(&self) -> ObjRef<Attrs> {
|
||||
self.this
|
||||
}
|
||||
|
||||
fn is_marked(&self) -> bool {
|
||||
self.marked.get()
|
||||
}
|
||||
|
||||
fn mark(&self) {
|
||||
if self.is_marked() {
|
||||
return;
|
||||
}
|
||||
self.marked.set(true);
|
||||
self.attrs.iter().for_each(|(_, v)| v.borrow().mark());
|
||||
}
|
||||
|
||||
fn unmark(&self) {
|
||||
if !self.is_marked() {
|
||||
return;
|
||||
}
|
||||
self.marked.set(false);
|
||||
self.attrs.iter().for_each(|(_, v)| v.borrow().unmark());
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_attrs_new() {
|
||||
/*
|
||||
use crate::mem::*;
|
||||
let mut ctx = ObjCtx::new(
|
||||
*/
|
||||
}
|
||||
Reference in New Issue
Block a user