use crate::rt;
use crate::rt::object;
#[derive(Debug)]
pub(crate) struct Allocation {
state: object::Ref<State>,
}
#[derive(Debug)]
pub(super) struct State {
is_dropped: bool,
}
pub(crate) fn alloc(ptr: *mut u8) {
rt::execution(|execution| {
let state = execution.objects.insert(State { is_dropped: false });
let allocation = Allocation { state };
let prev = execution.raw_allocations.insert(ptr as usize, allocation);
assert!(prev.is_none(), "pointer already tracked");
});
}
pub(crate) fn dealloc(ptr: *mut u8) {
let allocation =
rt::execution(
|execution| match execution.raw_allocations.remove(&(ptr as usize)) {
Some(allocation) => allocation,
None => panic!("pointer not tracked"),
},
);
drop(allocation);
}
impl Allocation {
pub(crate) fn new() -> Allocation {
rt::execution(|execution| {
let state = execution.objects.insert(State { is_dropped: false });
Allocation { state }
})
}
}
impl Drop for Allocation {
fn drop(&mut self) {
rt::execution(|execution| {
let state = self.state.get_mut(&mut execution.objects);
state.is_dropped = true;
});
}
}
impl State {
pub(super) fn check_for_leaks(&self) {
assert!(self.is_dropped, "object leaked");
}
}