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:
2020-05-14 17:10:53 -04:00
parent e233ff1cfc
commit ccb12306d4
15 changed files with 615 additions and 0 deletions

86
src/obj/attrs.rs Normal file
View 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(
*/
}