Skip to content

Commit 062074a

Browse files
committed
Add tests for 'epsilon_static_array!' (FAILS)
New plan: Make GcArray generic over the underlying array representation.
1 parent 2dcb786 commit 062074a

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

src/epsilon.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@ use self::{alloc::{EpsilonAlloc}, layout::TypeInfo};
2626
/// This will never actually be collected
2727
/// and will always be valid
2828
#[inline]
29-
pub fn gc<'gc, T: GcSafe<'gc, EpsilonCollectorId> + 'gc>(ptr: &'gc T) -> Gc<'gc, T> {
30-
unsafe {
31-
Gc::from_raw(NonNull::from(ptr))
32-
}
29+
pub const fn gc<'gc, T: GcSafe<'gc, EpsilonCollectorId> + 'gc>(ptr: &'gc T) -> Gc<'gc, T> {
30+
/*
31+
* SAFETY: Epsilon never collects unless explicitly added to
32+
* the linked list of allocated objects.
33+
* Therefore any reference can be assumed to be a Gc ptr.
34+
*/
35+
unsafe { std::mem::transmute::<&'gc T, crate::Gc<'gc, T, EpsilonCollectorId>>(ptr) }
3336
}
3437

3538
/// Statically allocate an array of the specified values
@@ -50,7 +53,7 @@ macro_rules! epsilon_static_array {
5053
};
5154
std::mem::transmute::<
5255
&'static ArrayWithHeader<$target, { $len }>,
53-
$crate::epsilon::GcArray<'static, $target, $crate::epsilon::EpsilonCollectorId>,
56+
$crate::vec::GcArray<'static, $target, $crate::epsilon::EpsilonCollectorId>,
5457
>(HEADERED)
5558
}}
5659
}

src/epsilon/layout.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ pub struct EpsilonHeader {
1616
/// The next allocated object, or `None` if this is the final object.
1717
pub next: Option<NonNull<EpsilonHeader>>
1818
}
19+
/*
20+
* We are Send + Sync because once we are allocated
21+
* `next` and `type_info` cannot change
22+
*/
23+
unsafe impl Send for EpsilonHeader {}
24+
unsafe impl Sync for EpsilonHeader {}
1925
impl EpsilonHeader {
2026
pub const LAYOUT: Layout = Layout::new::<Self>();
2127
/// Assume the specified object has a header,

tests/epsilon.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use std::fmt::Debug;
2+
13
use zerogc_derive::Trace;
24

3-
use zerogc::{safepoint_recurse, Gc, GcSimpleAlloc};
4-
use zerogc::epsilon::{EpsilonCollectorId, EpsilonContext, EpsilonSystem};
5+
use zerogc::{Gc, GcArray, GcContext, GcSimpleAlloc, epsilon_static_array, safepoint_recurse};
6+
use zerogc::epsilon::{self, EpsilonCollectorId, EpsilonContext, EpsilonSystem};
57

68
#[derive(Trace)]
79
#[zerogc(collector_ids(EpsilonCollectorId))]
@@ -41,3 +43,29 @@ fn recursive() {
4143
safepoint_recurse!(ctx, first, |ctx, root| recurse(ctx, 18, root));
4244
}
4345

46+
#[test]
47+
fn static_alloc() {
48+
fn recurse<'gc, T: ?Sized + PartialEq + Debug>(
49+
_ctx: &'gc EpsilonContext,
50+
expected: &T,
51+
test: Gc<'gc, T, EpsilonCollectorId>
52+
) {
53+
assert_eq!(test.value(), expected);
54+
}
55+
fn recurse_array<'gc, T: PartialEq + Debug>(
56+
_ctx: &'gc EpsilonContext,
57+
expected: &[T],
58+
test: GcArray<'gc, T, EpsilonCollectorId>
59+
) {
60+
assert_eq!(test.as_slice(), expected);
61+
}
62+
const BAR: &i32 = &12;
63+
let sys = EpsilonSystem::leak();
64+
let ctx = sys.new_context();
65+
recurse(&ctx, BAR, epsilon::gc(BAR));
66+
const FOO: &[u8; 29] = b"Do you wanna build a snowman?";
67+
const FOO_LEN: usize = FOO.len();
68+
let array: GcArray<'static, u8, EpsilonCollectorId>
69+
= epsilon_static_array!([u8; FOO_LEN] => *FOO);
70+
recurse_array(&ctx, &*FOO, array);
71+
}

0 commit comments

Comments
 (0)