From 4fd059be5f5e33db14393e623842b238ccd049cd Mon Sep 17 00:00:00 2001 From: Rujia Liu Date: Thu, 24 Aug 2023 20:05:40 +0800 Subject: [PATCH] 32-bit system support, addressing all (at most) 4GB addresses of RAM. --- src/arena.rs | 21 ++++++-- src/atom_table.rs | 8 +-- src/machine/copier.rs | 4 +- src/machine/gc.rs | 42 ++++++++-------- src/machine/machine_indices.rs | 6 ++- src/machine/mod.rs | 4 +- src/machine/streams.rs | 2 +- src/machine/system_calls.rs | 24 ++++----- src/macros.rs | 29 +++++++---- src/types.rs | 91 +++++++++++++++++++++++++++------- 10 files changed, 156 insertions(+), 75 deletions(-) diff --git a/src/arena.rs b/src/arena.rs index 5f5f8a91..9434b28d 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -307,12 +307,16 @@ pub trait ArenaAllocated: Sized { fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated; fn header_offset_from_payload() -> usize { - mem::size_of::<*const ArenaHeader>() + mem::size_of::() } unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated { let size = value.size() + mem::size_of::(); + #[cfg(target_pointer_width="32")] + let align = mem::align_of::() * 2; + + #[cfg(target_pointer_width="64")] let align = mem::align_of::(); let layout = alloc::Layout::from_size_align_unchecked(size, align); @@ -656,9 +660,12 @@ impl ArenaAllocated for IndexPtr { } } +#[repr(C)] #[derive(Clone, Copy, Debug)] struct AllocSlab { next: *mut AllocSlab, + #[cfg(target_pointer_width="32")] + _padding: u32, header: ArenaHeader, } @@ -827,6 +834,12 @@ 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( + 0x0000_0431 as *const _, + ConsPtrMaskTag::Cons, + )); + #[cfg(target_pointer_width="64")] let const_value = HeapCellValue::from(ConsPtr::build_with( 0x0000_5555_ff00_0431 as *const _, ConsPtrMaskTag::Cons, @@ -834,7 +847,7 @@ mod tests { match const_value.to_untyped_arena_ptr() { Some(arena_ptr) => { - assert_eq!(arena_ptr.into_bytes(), const_value.into_bytes()); + assert_eq!(arena_ptr.into_bytes(), const_value.to_untyped_arena_ptr_bytes()); } None => { assert!(false); @@ -847,7 +860,7 @@ mod tests { match stream_cell.to_untyped_arena_ptr() { Some(arena_ptr) => { - assert_eq!(arena_ptr.into_bytes(), stream_cell.into_bytes()); + assert_eq!(arena_ptr.into_bytes(), stream_cell.to_untyped_arena_ptr_bytes()); } None => { assert!(false); @@ -1101,7 +1114,7 @@ mod tests { read_heap_cell!(cell, (HeapCellValueTag::Atom, (el, _arity)) => { - assert_eq!(el.flat_index() as usize, empty_list_as_cell!().get_value()); + assert_eq!(el.flat_index(), empty_list_as_cell!().get_value()); assert_eq!(el.as_str(), "[]"); } _ => { unreachable!() } diff --git a/src/atom_table.rs b/src/atom_table.rs index f0661db2..79c83805 100644 --- a/src/atom_table.rs +++ b/src/atom_table.rs @@ -169,8 +169,8 @@ impl Atom { } #[inline(always)] - pub fn from(index: usize) -> Self { - Self { index: index as u64 } + pub fn from(index: u64) -> Self { + Self { index } } #[inline(always)] @@ -386,7 +386,7 @@ impl AtomCell { #[inline] pub fn get_name(self) -> Atom { - Atom::from(self.get_index() << 3) + Atom::from((self.get_index() as u64) << 3) } #[inline] @@ -396,6 +396,6 @@ impl AtomCell { #[inline] pub fn get_name_and_arity(self) -> (Atom, usize) { - (Atom::from(self.get_index() << 3), self.get_arity()) + (Atom::from((self.get_index() as u64) << 3), self.get_arity()) } } diff --git a/src/machine/copier.rs b/src/machine/copier.rs index 0d091468..23330fd5 100644 --- a/src/machine/copier.rs +++ b/src/machine/copier.rs @@ -187,8 +187,8 @@ impl CopyTermState { fn copy_attr_var_list(&mut self, mut list_addr: HeapCellValue) { while let HeapCellValueTag::Lis = list_addr.get_tag() { let threshold = self.target.threshold(); - let heap_loc = list_addr.get_value(); - let str_loc = self.target[heap_loc].get_value(); + let heap_loc = list_addr.get_value() as usize; + let str_loc = self.target[heap_loc].get_value() as usize; self.target.push(heap_loc_as_cell!(threshold+2)); self.target.push(heap_loc_as_cell!(threshold+1)); diff --git a/src/machine/gc.rs b/src/machine/gc.rs index 1de28ffe..ad42b1d5 100644 --- a/src/machine/gc.rs +++ b/src/machine/gc.rs @@ -68,7 +68,7 @@ pub(crate) struct StacklessPreOrderHeapIter<'a, UMP: UnmarkPolicy> { orig_heap_len: usize, start: usize, current: usize, - next: usize, + next: u64, _marker: PhantomData, } @@ -153,14 +153,14 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { } fn forward_var(&mut self) -> Option { - if self.heap[self.next].get_forwarding_bit() { + if self.heap[self.next as usize].get_forwarding_bit() { return self.backward_and_return(); } - let temp = self.heap[self.next].get_value(); + let temp = self.heap[self.next as usize].get_value(); - self.heap[self.next].set_value(self.current); - self.current = self.next; + self.heap[self.next as usize].set_value(self.current as u64); + self.current = self.next as usize; self.next = temp; None @@ -175,23 +175,23 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { HeapCellValueTag::AttrVar => { if let Some(cell) = UMP::forward_attr_var(self) { return Some(cell); } - if self.heap[self.next].get_mark_bit() { + if self.heap[self.next as usize].get_mark_bit() { return Some(attr_var_as_cell!(self.current)); } } HeapCellValueTag::Var => { if let Some(cell) = self.forward_var() { return Some(cell); } - if self.heap[self.next].get_mark_bit() { + if self.heap[self.next as usize].get_mark_bit() { return Some(heap_loc_as_cell!(self.current)); } } HeapCellValueTag::Str => { - if self.heap[self.next + 1].get_forwarding_bit() { + if self.heap[self.next as usize + 1].get_forwarding_bit() { return self.backward_and_return(); } - let h = self.next; + let h = self.next as usize; let cell = self.heap[h]; let arity = cell_as_atom_cell!(self.heap[h]).get_arity(); @@ -203,13 +203,13 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { let last_cell_loc = h + arity; self.next = self.heap[last_cell_loc].get_value(); - self.heap[last_cell_loc].set_value(self.current); + self.heap[last_cell_loc].set_value(self.current as u64); self.current = last_cell_loc; return Some(cell); } HeapCellValueTag::Lis => { - let last_cell_loc = self.next + 1; + let last_cell_loc = self.next as usize + 1; if self.heap[last_cell_loc].get_forwarding_bit() { return self.backward_and_return(); @@ -218,13 +218,13 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { self.heap[last_cell_loc].set_forwarding_bit(true); self.next = self.heap[last_cell_loc].get_value(); - self.heap[last_cell_loc].set_value(self.current); + self.heap[last_cell_loc].set_value(self.current as u64); self.current = last_cell_loc; return Some(list_loc_as_cell!(last_cell_loc - 1)); } HeapCellValueTag::PStrLoc => { - let h = self.next; + let h = self.next as usize; let cell = self.heap[h]; if self.heap[h+1].get_forwarding_bit() { @@ -236,13 +236,13 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { self.heap[last_cell_loc].set_forwarding_bit(true); self.next = self.heap[last_cell_loc].get_value(); - self.heap[last_cell_loc].set_value(self.current); + self.heap[last_cell_loc].set_value(self.current as u64); self.current = last_cell_loc; } else { debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::PStrOffset); self.next = self.heap[h].get_value(); - self.heap[h].set_value(self.current); + self.heap[h].set_value(self.current as u64); self.current = h; if self.heap[h].get_mark_bit() { @@ -253,7 +253,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { return Some(cell); } HeapCellValueTag::PStrOffset => { - let h = self.next; + let h = self.next as usize; let cell = self.heap[h]; // mark the Fixnum offset. @@ -269,20 +269,20 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { self.heap[last_cell_loc].set_forwarding_bit(true); self.next = self.heap[last_cell_loc].get_value(); - self.heap[last_cell_loc].set_value(self.current); + self.heap[last_cell_loc].set_value(self.current as u64); self.current = last_cell_loc; } else { debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::CStr); self.next = self.heap[h].get_value(); - self.heap[h].set_value(self.current); + self.heap[h].set_value(self.current as u64); self.current = h; } return Some(cell); } tag @ HeapCellValueTag::Atom => { - let cell = HeapCellValue::build_with(tag, self.next as u64); + let cell = HeapCellValue::build_with(tag, self.next); let arity = AtomCell::from_bytes(cell.into_bytes()).get_arity(); if arity == 0 { @@ -315,8 +315,8 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { UMP::unmark(self.heap, self.current); self.heap[self.current].set_value(self.next); - self.next = self.current; - self.current = temp; + self.next = self.current as u64; + self.current = temp as usize; } self.heap[self.current].set_forwarding_bit(false); diff --git a/src/machine/machine_indices.rs b/src/machine/machine_indices.rs index 7389caca..c040743f 100644 --- a/src/machine/machine_indices.rs +++ b/src/machine/machine_indices.rs @@ -143,6 +143,10 @@ impl IndexPtr { #[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)] pub struct CodeIndex(TypedArenaPtr); +#[cfg(target_pointer_width="32")] +const_assert!(std::mem::align_of::() == 4); + +#[cfg(target_pointer_width="64")] const_assert!(std::mem::align_of::() == 8); impl Deref for CodeIndex { @@ -164,7 +168,7 @@ impl DerefMut for CodeIndex { impl From for UntypedArenaPtr { #[inline(always)] fn from(ptr: CodeIndex) -> UntypedArenaPtr { - unsafe { std::mem::transmute(ptr.0.as_ptr()) } + UntypedArenaPtr::build_with(ptr.0.as_ptr() as usize) } } diff --git a/src/machine/mod.rs b/src/machine/mod.rs index 98db014d..ea96f1b4 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -1247,7 +1247,7 @@ impl Machine { } } TrailEntryTag::TrailedBlackboardEntry => { - let key = Atom::from(h); + let key = Atom::from(h as u64); match self.indices.global_variables.get_mut(&key) { Some((_, ref mut loc)) => *loc = None, @@ -1255,7 +1255,7 @@ impl Machine { } } TrailEntryTag::TrailedBlackboardOffset => { - let key = Atom::from(h); + let key = Atom::from(h as u64); let value_cell = HeapCellValue::from(u64::from(self.machine_st.trail[i + 1])); match self.indices.global_variables.get_mut(&key) { diff --git a/src/machine/streams.rs b/src/machine/streams.rs index e5d9d05f..f4ce6cbd 100644 --- a/src/machine/streams.rs +++ b/src/machine/streams.rs @@ -372,7 +372,7 @@ impl StreamOptions { #[inline] pub fn get_alias(self) -> Option { if self.has_alias() { - Some(Atom::from((self.alias() << 3) as usize)) + Some(Atom::from((self.alias() as u64) << 3)) } else { None } diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index d68facde..b158d428 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -988,7 +988,7 @@ impl MachineState { pub(crate) fn call_continuation_chunk(&mut self, chunk: HeapCellValue, return_p: usize) -> usize { let chunk = self.store(self.deref(chunk)); - let s = chunk.get_value(); + let s = chunk.get_value() as usize; let arity = cell_as_atom_cell!(self.heap[s]).get_arity(); let num_cells = arity - 1; @@ -1169,7 +1169,7 @@ impl Machine { let attr_var = self.deref_register(1); if let HeapCellValueTag::AttrVar = attr_var.get_tag() { - let attr_var_loc = attr_var.get_value(); + let attr_var_loc = attr_var.get_value() as usize; self.machine_st.heap[attr_var_loc] = heap_loc_as_cell!(attr_var_loc); self.machine_st.trail(TrailRef::Ref(Ref::attr_var(attr_var_loc))); } @@ -1355,7 +1355,7 @@ impl Machine { } else { if is_internal_call { debug_assert_eq!(goal.get_tag(), HeapCellValueTag::Str); - goal = self.machine_st.heap[goal.get_value()+1]; + goal = self.machine_st.heap[goal.get_value() as usize+1]; (module_name, goal) = self.machine_st.strip_module(goal, module_name); if let Some((inner_name, inner_arity)) = self.machine_st.name_and_arity_from_heap(goal) { @@ -1585,7 +1585,7 @@ impl Machine { ); if HeapCellValueTag::Str == qualified_goal.get_tag() { - let s = qualified_goal.get_value(); + let s = qualified_goal.get_value() as usize; let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]) .get_name_and_arity(); @@ -4896,7 +4896,7 @@ impl Machine { Some(AttrListMatch { match_site: MatchSite::Match(match_site), .. }) => { let list_head = self.machine_st.heap[match_site]; - if list_head.get_value() == match_site { + if list_head.get_value() as usize == match_site { // at the end of the list, no match found in this case. self.machine_st.fail = true; } else { @@ -4969,7 +4969,7 @@ impl Machine { prev_tail } else { if self.machine_st.heap[match_site + 1].is_var() { - let h = attr_var.get_value(); + let h = attr_var.get_value() as usize; self.machine_st.heap[h] = heap_loc_as_cell!(h); self.machine_st.trail(TrailRef::Ref(Ref::attr_var(h))); @@ -5044,13 +5044,13 @@ impl Machine { } MatchSite::Match(match_site) => { let l = self.machine_st.heap[match_site].get_value(); - self.machine_st.heap[match_site].set_value(h); + self.machine_st.heap[match_site].set_value(h as u64); (match_site, l) } }; - self.machine_st.trail(TrailRef::AttrVarListLink(match_site, l)); + self.machine_st.trail(TrailRef::AttrVarListLink(match_site, l as usize)); } None => { // the list is empty. @@ -5080,7 +5080,7 @@ impl Machine { let mut prev_tail = None; while let HeapCellValueTag::Lis = attrs_list.get_tag() { - let mut list_head = self.machine_st.heap[attrs_list.get_value()]; + let mut list_head = self.machine_st.heap[attrs_list.get_value() as usize]; loop { read_heap_cell!(list_head, @@ -5100,7 +5100,7 @@ impl Machine { if module == module_loc && name == t_name && arity == t_arity { return Some(AttrListMatch { - match_site: MatchSite::Match(attrs_list.get_value()), + match_site: MatchSite::Match(attrs_list.get_value() as usize), prev_tail, }); } @@ -5113,7 +5113,7 @@ impl Machine { ); } - let tail_loc = attrs_list.get_value() + 1; + let tail_loc = attrs_list.get_value() as usize + 1; prev_tail = Some(tail_loc); // do the work of self.store(self.deref(...)) but inline it @@ -5458,7 +5458,7 @@ impl Machine { let value = self.deref_register(2); debug_assert_eq!(HeapCellValueTag::AttrVar, var.get_tag()); - self.machine_st.heap[var.get_value()] = value; + self.machine_st.heap[var.get_value() as usize] = value; } #[inline(always)] diff --git a/src/macros.rs b/src/macros.rs index 9bd89ab7..ef47ff27 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -73,9 +73,9 @@ macro_rules! cell_as_string { macro_rules! cell_as_atom { ($cell:expr) => {{ let cell = AtomCell::from_bytes($cell.into_bytes()); - let name = cell.get_index() << 3; + let name = (cell.get_index() as u64) << 3; - Atom::from(name as usize) + Atom::from(name) }}; } @@ -87,14 +87,14 @@ macro_rules! cell_as_atom_cell { macro_rules! cell_as_f64_ptr { ($cell:expr) => {{ - let offset = $cell.get_value(); + let offset = $cell.get_value() as usize; F64Ptr::from_offset(offset) }}; } macro_rules! cell_as_untyped_arena_ptr { ($cell:expr) => { - UntypedArenaPtr::from(u64::from($cell) as *const ArenaHeader) + UntypedArenaPtr::from_bytes($cell.to_untyped_arena_ptr_bytes()) }; } @@ -173,7 +173,14 @@ macro_rules! attr_var_loc_as_cell { macro_rules! typed_arena_ptr_as_cell { ($ptr:expr) => { - untyped_arena_ptr_as_cell!($ptr.header_ptr()) + raw_ptr_as_cell!($ptr.header_ptr()) + }; +} + +macro_rules! raw_ptr_as_cell { + ($ptr:expr) => { + // Cell is 64-bit, but raw ptr is 32-bit in 32-bit systems + HeapCellValue::from_raw_ptr_bytes(unsafe { std::mem::transmute($ptr) }) }; } @@ -217,7 +224,7 @@ macro_rules! string_as_pstr_cell { macro_rules! stream_as_cell { ($ptr:expr) => { - untyped_arena_ptr_as_cell!($ptr.as_ptr()) + raw_ptr_as_cell!($ptr.as_ptr()) }; } @@ -250,13 +257,15 @@ macro_rules! match_untyped_arena_ptr_pat_body { #[allow(unused_braces)] $code }}; - ($cell:ident, OssifiedOpDir, $n:ident, $code:expr) => {{ - let $n = cell_as_ossified_op_dir!($cell); + ($ptr:ident, OssifiedOpDir, $n:ident, $code:expr) => {{ + let payload_ptr = unsafe { std::mem::transmute::<_, *mut OssifiedOpDir>($ptr.payload_offset()) }; + let $n = TypedArenaPtr::new(payload_ptr); #[allow(unused_braces)] $code }}; - ($cell:ident, LiveLoadState, $n:ident, $code:expr) => {{ - let $n = cell_as_load_state_payload!($cell); + ($ptr:ident, LiveLoadState, $n:ident, $code:expr) => {{ + let payload_ptr = unsafe { std::mem::transmute::<_, *mut LiveLoadState>($ptr.payload_offset()) }; + let $n = TypedArenaPtr::new(payload_ptr); #[allow(unused_braces)] $code }}; diff --git a/src/types.rs b/src/types.rs index 12add4ef..a816f84f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -88,6 +88,15 @@ impl ConsPtr { .with_tag(tag) } + #[cfg(target_pointer_width="32")] + #[inline(always)] + pub fn as_ptr(self) -> *mut u8 { + let bytes = self.into_bytes(); + let raw_ptr_bytes = [bytes[1], bytes[2], bytes[3], bytes[4]]; + unsafe { mem::transmute(raw_ptr_bytes) } + } + + #[cfg(target_pointer_width="64")] #[inline(always)] pub fn as_ptr(self) -> *mut u8 { self.ptr() as *mut _ @@ -444,7 +453,7 @@ impl HeapCellValue { pub fn is_compound(self, heap: &[HeapCellValue]) -> bool { match self.get_tag() { HeapCellValueTag::Str => { - cell_as_atom_cell!(heap[self.get_value()]).get_arity() > 0 + cell_as_atom_cell!(heap[self.get_value() as usize]).get_arity() > 0 } HeapCellValueTag::Lis | HeapCellValueTag::CStr | @@ -491,13 +500,13 @@ impl HeapCellValue { } #[inline] - pub fn get_value(self) -> usize { - self.val() as usize + pub fn get_value(self) -> u64 { + self.val() as u64 } #[inline] - pub fn set_value(&mut self, val: usize) { - self.set_val(val as u64); + pub fn set_value(&mut self, val: u64) { + self.set_val(val); } #[inline] @@ -513,7 +522,7 @@ impl HeapCellValue { #[inline] pub fn to_atom(self) -> Option { match self.tag() { - HeapCellValueTag::Atom => Some(Atom::from((self.val() << 3) as usize)), + HeapCellValueTag::Atom => Some(Atom::from(self.val() << 3)), _ => None, } } @@ -522,7 +531,7 @@ impl HeapCellValue { pub fn to_pstr(self) -> Option { match self.tag() { HeapCellValueTag::PStr => { - Some(PartialString::from(Atom::from((self.val() as usize) << 3))) + Some(PartialString::from(Atom::from(self.val() << 3))) } _ => None, } @@ -536,10 +545,39 @@ impl HeapCellValue { } } + #[cfg(target_pointer_width="32")] + #[inline] + pub fn from_raw_ptr_bytes(ptr_bytes: [u8; 4]) -> Self { + HeapCellValue::from_bytes([ptr_bytes[0], ptr_bytes[1], ptr_bytes[2], ptr_bytes[3], 0, 0, 0, 0]) + } + #[cfg(target_pointer_width="64")] + #[inline] + pub fn from_raw_ptr_bytes(ptr_bytes: [u8; 8]) -> Self { + HeapCellValue::from_bytes(ptr_bytes) + } + + #[inline] + #[cfg(target_pointer_width="32")] + pub fn to_raw_ptr_bytes(self) -> [u8; 4] { + let bytes = self.into_bytes(); + [bytes[0], bytes[1], bytes[2], bytes[3]] + } + + #[inline] + #[cfg(target_pointer_width="64")] + pub fn to_raw_ptr_bytes(self) -> [u8; 8] { + self.into_bytes() + } + + #[inline] + pub fn to_untyped_arena_ptr_bytes(self) -> [u8; 8] { + self.into_bytes() + } + #[inline] pub fn to_untyped_arena_ptr(self) -> Option { - match self.tag() { - HeapCellValueTag::Cons => Some(UntypedArenaPtr::from_bytes(self.into_bytes())), + match self.get_tag() { + HeapCellValueTag::Cons => Some(UntypedArenaPtr::from_bytes(self.to_untyped_arena_ptr_bytes())), _ => None, } } @@ -607,7 +645,7 @@ impl HeapCellValue { Some(TermOrderCategory::Compound) } HeapCellValueTag::Str => { - let value = heap[self.get_value()]; + let value = heap[self.get_value() as usize]; let arity = cell_as_atom_cell!(value).get_arity(); if arity == 0 { @@ -647,26 +685,34 @@ pub struct UntypedArenaPtr { #[allow(unused)] padding: B2, } +impl UntypedArenaPtr { + #[inline(always)] + pub fn build_with(ptr: usize) -> Self { + UntypedArenaPtr::new() + .with_ptr(ptr as u64) + } +} + const_assert!(mem::size_of::() == 8); impl From<*const ArenaHeader> for UntypedArenaPtr { #[inline] fn from(ptr: *const ArenaHeader) -> UntypedArenaPtr { - unsafe { mem::transmute(ptr) } + UntypedArenaPtr::build_with(ptr as usize) } } impl From<*const IndexPtr> for UntypedArenaPtr { #[inline] fn from(ptr: *const IndexPtr) -> UntypedArenaPtr { - unsafe { mem::transmute(ptr) } + UntypedArenaPtr::build_with(ptr as usize) } } impl From for *const ArenaHeader { #[inline] fn from(ptr: UntypedArenaPtr) -> *const ArenaHeader { - unsafe { mem::transmute(ptr) } + ptr.get_ptr() as *const ArenaHeader } } @@ -676,15 +722,24 @@ impl UntypedArenaPtr { self.set_m(m); } + #[cfg(target_pointer_width="32")] + #[inline] + pub fn get_ptr(self) -> *const u8 { + let bytes = self.into_bytes(); + let raw_ptr_bytes = [bytes[0], bytes[1], bytes[2], bytes[3]]; + unsafe { mem::transmute(raw_ptr_bytes) } + } + + #[cfg(target_pointer_width="64")] #[inline] pub fn get_ptr(self) -> *const u8 { - self.ptr() as *const u8 + self.ptr() as *const u8 } #[inline] pub fn get_tag(self) -> ArenaHeaderTag { unsafe { - let header = *(self.ptr() as *const ArenaHeader); + let header = *(self.get_ptr() as *const ArenaHeader); header.get_tag() } } @@ -714,7 +769,7 @@ impl Add for HeapCellValue { tag @ HeapCellValueTag::PStrLoc | tag @ HeapCellValueTag::Var | tag @ HeapCellValueTag::AttrVar => { - HeapCellValue::build_with(tag, (self.get_value() + rhs) as u64) + HeapCellValue::build_with(tag, (self.get_value() as usize + rhs) as u64) } _ => { self @@ -734,7 +789,7 @@ impl Sub for HeapCellValue { tag @ HeapCellValueTag::PStrLoc | tag @ HeapCellValueTag::Var | tag @ HeapCellValueTag::AttrVar => { - HeapCellValue::build_with(tag, (self.get_value() - rhs) as u64) + HeapCellValue::build_with(tag, (self.get_value() as usize - rhs) as u64) } _ => { self @@ -762,7 +817,7 @@ impl Sub for HeapCellValue { tag @ HeapCellValueTag::PStrLoc | tag @ HeapCellValueTag::Var | tag @ HeapCellValueTag::AttrVar => { - HeapCellValue::build_with(tag, (self.get_value() + rhs.abs() as usize) as u64) + HeapCellValue::build_with(tag, self.get_value() + rhs.abs() as u64) } _ => { self -- 2.54.0