don't erase ptr type early when construction a Cons HeapCellValue

rather than passing an address as usize pass the ArenaHeader pointer
similarly don't return a u8 ptr but use a ArenaHeader pointer instead

Don't convert the pointer to a ConsPtr by going through native endian
bytes in between.
We are exploiting the fact that the 3 least significant bytes are zero
for pointer to types of alignment 8 and we expect these to line up with
the f, m, and tag field at the end of the ConsPtr struct, but using
native endiannes for this would only work on big endian systems.
This commit is contained in:
Skgland
2026-04-22 23:22:27 +02:00
parent 6765921666
commit b4db85c8c3
4 changed files with 61 additions and 54 deletions

View File

@@ -633,16 +633,22 @@ mod tests {
#[test]
fn heap_cell_value_const_cast() {
let mut wam = MockWAM::new();
#[cfg(target_pointer_width = "32")]
let const_value = HeapCellValue::from(ConsPtr::build_with(
std::ptr::without_provenance(0x0000_0431),
ConsPtrMaskTag::Cons,
));
assert_eq!(ConsPtr::NICHE_SHIFT, 0);
#[cfg(not(target_pointer_width = "32"))]
assert_eq!(ConsPtr::NICHE_SHIFT, 3);
#[cfg(target_pointer_width = "32")]
let dummy_ptr: *const ArenaHeader = std::ptr::without_provenance(0x0000_0438);
#[cfg(target_pointer_width = "64")]
let const_value = HeapCellValue::from(ConsPtr::build_with(
std::ptr::without_provenance(0x0000_5555_ff00_0431),
ConsPtrMaskTag::Cons,
));
let dummy_ptr: *const ArenaHeader = std::ptr::without_provenance(0x0000_5555_ff00_0438);
assert!(dummy_ptr.is_aligned());
let const_value = HeapCellValue::from_arena_header_ptr(dummy_ptr);
match const_value.to_untyped_arena_ptr() {
Some(arena_ptr) => {
@@ -657,8 +663,7 @@ mod tests {
}
let stream = Stream::from_static_string("test", &mut wam.machine_st.arena);
let stream_cell =
HeapCellValue::from(ConsPtr::build_with(stream.as_ptr(), ConsPtrMaskTag::Cons));
let stream_cell = HeapCellValue::from_arena_header_ptr(stream.as_ptr());
match stream_cell.to_untyped_arena_ptr() {
Some(arena_ptr) => {
@@ -727,7 +732,7 @@ mod tests {
Some(untyped_arena_ptr) => {
assert_eq!(
Some(big_rat_ptr.header_ptr()),
Some(untyped_arena_ptr.into()),
Some(untyped_arena_ptr.get_ptr()),
);
}
None => {