-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Commit new files + fix const eval error
rust-lang/rust#51910 We will have to provide the drop_in_place::<T> ptr upon Arena<T> registration
- Loading branch information
1 parent
34aca3b
commit f21881f
Showing
6 changed files
with
224 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use super::auto_traits::*; | ||
use super::gc::*; | ||
use super::trace::Trace; | ||
use super::Mark; | ||
use std::ptr; | ||
|
||
pub struct Arena<T> { | ||
// roots: usize, | ||
high_ptr: *const T, | ||
capacity: u16, | ||
} | ||
|
||
impl<T: Trace> Arena<T> { | ||
pub fn new() -> Self { | ||
// GC_BUS.with(|type_map| T::TRACE_TYPE_INFOtype_map.entry()); | ||
Self { | ||
high_ptr: ptr::null(), | ||
capacity: 1000, | ||
} | ||
} | ||
pub fn gc_alloc<'r>(&'r self, _t: T) -> Gc<'r, T> | ||
where | ||
T: 'r, | ||
{ | ||
unimplemented!() | ||
} | ||
|
||
pub fn advance(&mut self) -> Self { | ||
unimplemented!() | ||
} | ||
} | ||
|
||
unsafe impl<'o, 'n, T: NoGc + Immutable> Mark<'o, 'n, T, T> for Arena<T> { | ||
fn mark(&'n self, o: Gc<'o, T>) -> Gc<'n, T> { | ||
unsafe { std::mem::transmute(o) } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
use std::cell::UnsafeCell; | ||
use super::gc::*; | ||
|
||
pub unsafe auto trait NoGc {} | ||
impl<'r, T> !NoGc for Gc<'r, T> {} | ||
unsafe impl<'r, T: NoGc> NoGc for Box<T> {} | ||
|
||
/// Shallow immutability | ||
pub unsafe auto trait Immutable {} | ||
impl<T> !Immutable for &mut T {} | ||
impl<T> !Immutable for UnsafeCell<T> {} | ||
unsafe impl<T> Immutable for Box<T> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
use super::auto_traits::*; | ||
use super::trace::*; | ||
|
||
use std::ops::Deref; | ||
|
||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||
pub struct Gc<'r, T> { | ||
ptr: &'r T, | ||
} | ||
|
||
impl<'r, T: Trace> Deref for Gc<'r, T> { | ||
type Target = T; | ||
fn deref(&self) -> &T { | ||
self.ptr | ||
} | ||
} | ||
|
||
unsafe impl<'r, T: 'r + Immutable + Trace> Trace for Gc<'r, T> { | ||
fn trace(_: usize) {} | ||
// A Gc<Gc<T>> is equvlent to Gc<T> | ||
const TRACE_TYPE_INFO: GcTypeInfo = GcTypeInfo::new::<T>(); | ||
const TRACE_CHILD_TYPE_INFO: [Option<GcTypeInfo>; 8] = [ | ||
Some(GcTypeInfo::new::<T>()), | ||
None, | ||
None, | ||
None, | ||
None, | ||
None, | ||
None, | ||
None, | ||
]; | ||
fn trace_transitive_type_info(tti: &mut Tti) { | ||
tti.add_direct::<Self>(); | ||
T::trace_transitive_type_info(tti) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
use super::Gc; | ||
|
||
pub unsafe trait Mark<'o, 'n, O, N> { | ||
fn mark(&'n self, o: Gc<'o, O>) -> Gc<'n, N>; | ||
} | ||
|
||
// GAT Mark | ||
// pub unsafe trait Mark<'o, 'n, O> { | ||
// type Struct<'l>; | ||
// fn mark(&'n self, o: Gc<'o, Self::Struct<'o>>) -> Gc<'n, Self::Struct<'n>>; | ||
// } | ||
|
||
// Blanket Arena<T> impl is in src/arena.rs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
use super::auto_traits::*; | ||
|
||
use std::collections::HashSet; | ||
use std::mem::*; | ||
use std::ops::Deref; | ||
|
||
pub unsafe trait Trace { | ||
fn trace(t: usize); | ||
const TRACE_TYPE_INFO: GcTypeInfo; | ||
const TRACE_CHILD_TYPE_INFO: [Option<GcTypeInfo>; 8]; | ||
fn trace_transitive_type_info(tti: &mut Tti); | ||
} | ||
|
||
// Ideally would use negative impls | ||
// Blanket impl seems to be safe, since Mark's blanket requires NoGc | ||
// If you only implement Mark and not Trace CHILD_TYPE_INFO will all be const None | ||
unsafe impl<T: Immutable> Trace for T { | ||
default fn trace(_: usize) {} | ||
default const TRACE_TYPE_INFO: GcTypeInfo = GcTypeInfo::new::<Self>(); | ||
default const TRACE_CHILD_TYPE_INFO: [Option<GcTypeInfo>; 8] = [None; 8]; | ||
default fn trace_transitive_type_info(_: &mut Tti) {} | ||
} | ||
|
||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
pub struct GcTypeInfo { | ||
trace_ptr: fn(usize), | ||
needs_drop: bool, | ||
byte_size: u16, | ||
alignment: u16, | ||
} | ||
|
||
impl GcTypeInfo { | ||
pub const fn new<T: Trace>() -> Self { | ||
Self { | ||
trace_ptr: T::trace, | ||
needs_drop: needs_drop::<T>(), | ||
byte_size: size_of::<T>() as u16, | ||
alignment: align_of::<T>() as u16, | ||
} | ||
} | ||
|
||
pub(crate) const fn one_child<T: Trace>() -> [Option<GcTypeInfo>; 8] { | ||
[ | ||
Some(GcTypeInfo::new::<T>()), | ||
None, | ||
None, | ||
None, | ||
None, | ||
None, | ||
None, | ||
None, | ||
] | ||
} | ||
} | ||
|
||
pub struct Tti { | ||
/// Holds fn ptr of trace_transitive_type_info calls | ||
parrents: HashSet<usize>, | ||
type_info: HashSet<GcTypeInfo>, | ||
} | ||
|
||
impl Tti { | ||
pub fn new() -> Self { | ||
Self { | ||
parrents: HashSet::new(), | ||
type_info: HashSet::new(), | ||
} | ||
} | ||
|
||
pub fn add_direct<T: Trace>(&mut self) { | ||
self.type_info | ||
.extend(T::TRACE_CHILD_TYPE_INFO.iter().filter_map(|o| *o)); | ||
} | ||
|
||
pub fn add_trans(&mut self, tti: fn(&mut Tti)) { | ||
if self.parrents.insert(tti as *const fn(&mut Tti) as usize) { | ||
tti(self) | ||
} | ||
} | ||
} | ||
|
||
/// # std impls | ||
unsafe impl<'r, T: Immutable + Trace> Trace for Option<T> { | ||
default fn trace(o: usize) { | ||
if let Some(t) = unsafe { &*(o as *const Self) } { | ||
T::trace(t as *const T as usize) | ||
} | ||
} | ||
default const TRACE_TYPE_INFO: GcTypeInfo = GcTypeInfo::new::<Self>(); | ||
default const TRACE_CHILD_TYPE_INFO: [Option<GcTypeInfo>; 8] = GcTypeInfo::one_child::<T>(); | ||
default fn trace_transitive_type_info(tti: &mut Tti) { | ||
tti.add_direct::<Self>(); | ||
tti.add_trans(T::trace_transitive_type_info); | ||
} | ||
} | ||
|
||
unsafe impl<'r, T: Immutable + Trace + NoGc> Trace for Option<T> { | ||
fn trace(_: usize) {} | ||
const TRACE_TYPE_INFO: GcTypeInfo = GcTypeInfo::new::<Self>(); | ||
const TRACE_CHILD_TYPE_INFO: [Option<GcTypeInfo>; 8] = [None; 8]; | ||
fn trace_transitive_type_info(_: &mut Tti) {} | ||
} | ||
|
||
unsafe impl<T: Immutable + Trace> Trace for Box<T> { | ||
default fn trace(b: usize) { | ||
let t = unsafe { &*(b as *const Self) }.deref(); | ||
T::trace(t as *const T as usize) | ||
} | ||
default const TRACE_TYPE_INFO: GcTypeInfo = GcTypeInfo::new::<Self>(); | ||
default const TRACE_CHILD_TYPE_INFO: [Option<GcTypeInfo>; 8] = [None; 8]; | ||
default fn trace_transitive_type_info(_: &mut Tti) {} | ||
} | ||
|
||
unsafe impl<T: Immutable + Trace + NoGc> Trace for Box<T> { | ||
fn trace(_: usize) {} | ||
const TRACE_TYPE_INFO: GcTypeInfo = GcTypeInfo::new::<Self>(); | ||
const TRACE_CHILD_TYPE_INFO: [Option<GcTypeInfo>; 8] = GcTypeInfo::one_child::<T>(); | ||
fn trace_transitive_type_info(tti: &mut Tti) { | ||
tti.add_direct::<Self>(); | ||
tti.add_trans(T::trace_transitive_type_info); | ||
} | ||
} |