Require an explicit drop call on a gc allocation
This commit is contained in:
parent
2f690250ae
commit
8c95fcbd85
3 changed files with 24 additions and 15 deletions
|
@ -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) };
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue