]> Repositorios git - scryer-prolog.git/commitdiff
32-bit system support, addressing all (at most) 4GB addresses of RAM.
authorRujia Liu <[email protected]>
Thu, 24 Aug 2023 12:05:40 +0000 (20:05 +0800)
committerRujia Liu <[email protected]>
Thu, 24 Aug 2023 12:05:40 +0000 (20:05 +0800)
src/arena.rs
src/atom_table.rs
src/machine/copier.rs
src/machine/gc.rs
src/machine/machine_indices.rs
src/machine/mod.rs
src/machine/streams.rs
src/machine/system_calls.rs
src/macros.rs
src/types.rs

index 5f5f8a91deb067a0ed196c97a42f6da6d9a6eeea..9434b28d76cc06f75a55d2681345bf3c28232265 100644 (file)
@@ -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::<ArenaHeader>()
     }
 
     unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated {
         let size = value.size() + mem::size_of::<AllocSlab>();
 
+        #[cfg(target_pointer_width="32")]
+        let align = mem::align_of::<AllocSlab>() * 2;
+
+        #[cfg(target_pointer_width="64")]
         let align = mem::align_of::<AllocSlab>();
         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!() }
index f0661db26b0fed941e2258b43787165d2a592c59..79c83805c42364d9a7b79b388267a7917084a3c0 100644 (file)
@@ -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())
     }
 }
index 0d09146894e0cb680b4bdfe3de35794c12a4a1f8..23330fd510b660e60585bd6aea8593f94de01f34 100644 (file)
@@ -187,8 +187,8 @@ impl<T: CopierTarget> CopyTermState<T> {
     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));
index 1de28ffef2ec3b8b149a773b4ca3267989447eb3..ad42b1d536f636447b31ddfe38a120ef45314494 100644 (file)
@@ -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<UMP>,
 }
 
@@ -153,14 +153,14 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
     }
 
     fn forward_var(&mut self) -> Option<HeapCellValue> {
-        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);
index 7389cacacb68dfcc65e80c8c7a07ebbabe563a4c..c040743f7c56ecd3bcfa4682c5bb02012e1976d6 100644 (file)
@@ -143,6 +143,10 @@ impl IndexPtr {
 #[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)]
 pub struct CodeIndex(TypedArenaPtr<IndexPtr>);
 
+#[cfg(target_pointer_width="32")]
+const_assert!(std::mem::align_of::<CodeIndex>() == 4);
+
+#[cfg(target_pointer_width="64")]
 const_assert!(std::mem::align_of::<CodeIndex>() == 8);
 
 impl Deref for CodeIndex {
@@ -164,7 +168,7 @@ impl DerefMut for CodeIndex {
 impl From<CodeIndex> 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)
     }
 }
 
index 98db014d767cc13636a32b5704b4c7eba2d883cd..ea96f1b434b6386ac6b57d4a053ba392515ff135 100644 (file)
@@ -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) {
index e5d9d05fc48fe33eac72ccb10c4cda9d344c4ebd..f4ce6cbd4f9a5667bc953edf92d41249c4e04c65 100644 (file)
@@ -372,7 +372,7 @@ impl StreamOptions {
     #[inline]
     pub fn get_alias(self) -> Option<Atom> {
         if self.has_alias() {
-            Some(Atom::from((self.alias() << 3) as usize))
+            Some(Atom::from((self.alias() as u64) << 3))
         } else {
             None
         }
index d68facdedaea7658766a05756dd2a369726c23f9..b158d428e22d8a96b5642b1dca182b9ef4e81841 100644 (file)
@@ -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)]
index 9bd89ab7180572ad53c03a4c4001fc7f38e5be11..ef47ff27290e753f9e9e38b215890ea3085e1844 100644 (file)
@@ -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
     }};
index 12add4ef0813331abe933b5d0dc6570342add092..a816f84f2ae555ee3cc48ecd210cbf1ea9a552a4 100644 (file)
@@ -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<Atom> {
         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<PartialString> {
         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<UntypedArenaPtr> {
-        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::<UntypedArenaPtr>() == 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<UntypedArenaPtr> 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<usize> 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<usize> 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<i64> 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