gc-alloc 0.1.0

A Rust library for garbage-collected memory allocation using libgc (bdwgc).
use std::{ffi::c_void, ptr::NonNull};

use crate::gc;

pub fn alloc<T>(val: T) -> &'static mut T {
    let ptr =
        unsafe { gc::GC_memalign(std::mem::size_of::<T>(), std::mem::align_of::<T>()) as *mut T };
    let mut ptr = NonNull::new(ptr).expect("GC_malloc failed");
    unsafe { ptr.write(val) };

    register_finalizer(ptr.as_ptr());
    unsafe { ptr.as_mut() }
}

fn register_finalizer<T>(ptr: *mut T) {
    if std::mem::needs_drop::<T>() {
        extern "C" fn finalizer<T>(obj: *mut c_void, _: *mut c_void) {
            let ptr = obj as *mut T;
            unsafe { std::ptr::drop_in_place(ptr) };
        }

        unsafe {
            gc::GC_register_finalizer(
                ptr as *mut std::ffi::c_void,
                Some(finalizer::<T>),
                std::ptr::null_mut(),
                std::ptr::null_mut(),
                std::ptr::null_mut(),
            );
        }
    }
}