Require an explicit drop call on a gc allocation

This commit is contained in:
bad 2022-09-16 23:27:49 +02:00
parent 2f690250ae
commit 8c95fcbd85
3 changed files with 24 additions and 15 deletions

View file

@ -30,8 +30,14 @@ impl GCAllocator {
root.trace(&mut tracer);
// And sweep
self.allocations
let inaccessible = self
.allocations
.drain_filter(|a| !tracer.is_accessible(a.ptr));
// And sweep
for mut to_free in inaccessible {
to_free.drop();
}
}
// Specialization when ;-;
@ -46,9 +52,14 @@ impl GCAllocator {
tracer.mark_reachable_rec(root);
root.trace(&mut tracer);
// And sweep
self.allocations
let inaccessible = self
.allocations
.drain_filter(|a| !tracer.is_accessible(a.ptr));
// And sweep
for mut to_free in inaccessible {
to_free.drop();
}
}
}
@ -68,9 +79,7 @@ impl Allocation {
Self { ptr, drop }
}
}
impl Drop for Allocation {
fn drop(&mut self) {
unsafe { (self.drop)(self.ptr) };
}

View file

@ -13,9 +13,7 @@ pub mod test_utils;
pub(crate) mod tests {
use super::allocator::GCAllocator;
use super::gc_ref::GcRef;
use super::test_utils::GotDropped;
use super::trace::GCTrace;
#[test]
fn gc_allocates_and_frees_structs() {

View file

@ -20,10 +20,10 @@ impl Environment {
pub fn update_var(&mut self, name: &str, v: Primitive) -> Option<Primitive> {
if let Some(cur) = self.variables.get_mut(name) {
Some(std::mem::replace(cur, v))
} else if let Some(ref parent) = self.parent {
unsafe { parent.get().borrow_mut().update_var(name, v) }
} else {
self.parent
.as_ref()
.and_then(|parent| parent.borrow_mut().update_var(name, v))
None
}
}
@ -34,9 +34,11 @@ impl Environment {
pub fn get_var(&self, name: &str) -> Option<Primitive> {
self.variables.get(name).cloned().or_else(|| {
self.parent
.as_ref()
.and_then(|v| (**v).borrow().get_var(name))
if let Some(ref parent) = self.parent {
unsafe { parent.get().borrow().get_var(name) }
} else {
None
}
})
}
}
@ -48,10 +50,10 @@ pub struct World {
impl World {
pub fn set_var(&mut self, name: String, v: Primitive) -> Option<Primitive> {
self.env.borrow_mut().set_var(name, v)
unsafe { self.env.get().borrow_mut().set_var(name, v) }
}
pub fn get_var(&self, name: &str) -> Option<Primitive> {
self.env.borrow().get_var(name)
unsafe { self.env.get().borrow().get_var(name) }
}
}