]> Repositorios git - scryer-prolog.git/commitdiff
Migrate to strict and exposed provenance
authorbakaq <[email protected]>
Sun, 27 Apr 2025 02:34:53 +0000 (23:34 -0300)
committerbakaq <[email protected]>
Sun, 27 Apr 2025 20:55:59 +0000 (17:55 -0300)
src/arena.rs
src/atom_table.rs
src/ffi.rs
src/heap_print.rs
src/machine/heap.rs
src/machine/lib_machine/mod.rs
src/machine/stack.rs
src/macros.rs
src/offset_table.rs
src/raw_block.rs
src/types.rs

index 47de6fa3d7ad2910ea57d7ebabdc74a1fc798f2a..a9f9a76b9a8d198a0156ab1f9f33c5057559c121 100644 (file)
@@ -611,12 +611,12 @@ mod tests {
         let mut wam = MockWAM::new();
         #[cfg(target_pointer_width = "32")]
         let const_value = HeapCellValue::from(ConsPtr::build_with(
-            0x0000_0431 as *const _,
+            std::ptr::without_provenance(0x0000_0431),
             ConsPtrMaskTag::Cons,
         ));
         #[cfg(target_pointer_width = "64")]
         let const_value = HeapCellValue::from(ConsPtr::build_with(
-            0x0000_5555_ff00_0431 as *const _,
+            std::ptr::without_provenance(0x0000_5555_ff00_0431),
             ConsPtrMaskTag::Cons,
         ));
 
index 8b36654989dfe058553f4ebef1be5ccd8c6a0179..12910753718da479dac738df125c7b0547f39578 100644 (file)
@@ -516,12 +516,12 @@ impl AtomTable {
                     }
                 };
 
-                let ptr_base = block_epoch.block.base as usize;
+                let ptr_base = block_epoch.block.base.addr();
 
                 write_to_ptr(string, len_ptr);
 
                 let atom = AtomCell::new()
-                    .with_name((STRINGS.len() + len_ptr as usize - ptr_base) as u64)
+                    .with_name((STRINGS.len() + len_ptr.addr() - ptr_base) as u64)
                     .with_arity(0)
                     .with_f(false)
                     .with_m(false)
index 2895009b013c4722176fa175b4d409412798942d..bd79a7565c31bfada56b9e84ced59773dcf5deb3 100644 (file)
@@ -507,7 +507,7 @@ impl Value {
     fn as_ptr(&mut self) -> Result<*mut c_void, FFIError> {
         match self {
             Value::CString(ref mut cstr) => Ok(&mut *cstr as *mut _ as *mut c_void),
-            Value::Int(n) => Ok(*n as *mut c_void),
+            Value::Int(n) => Ok(std::ptr::with_exposed_provenance_mut(*n as usize)),
             _ => Err(FFIError::ValueCast),
         }
     }
index 7bd227e2b4508cd6c0b5c5aeec113ec691e73d4d..9f1efee7146ec0346b13fb88c2176cead5ef8d89 100644 (file)
@@ -984,7 +984,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
 
     #[inline]
     fn print_raw_ptr(&mut self, ptr: *const ArenaHeader) {
-        append_str!(self, &format!("0x{:x}", ptr as *const u8 as usize));
+        append_str!(self, &format!("0x{:x}", ptr.addr()));
     }
 
     fn print_number(&mut self, max_depth: usize, n: NumberFocus, op: &Option<DirectedOp>) {
index c12af9d112da4fdfe32e235dc8b1e82b8a3b78f3..8d832f291937c0f7a495bfa97e7eaa5df7a5f1fc 100644 (file)
@@ -97,7 +97,7 @@ unsafe fn scan_slice_to_str(heap_slice: &[u8]) -> HeapStringScan {
         .unwrap_or(heap_slice.len());
     let zero_byte_addr = heap_slice.as_ptr().add(string_len);
 
-    let sentinel_len = pstr_sentinel_length(zero_byte_addr as usize);
+    let sentinel_len = pstr_sentinel_length(zero_byte_addr.addr());
     let tail_idx = cell_index!(
         (string_len + sentinel_len).next_multiple_of(ALIGN)
             + if sentinel_len <= 1 { heap_index!(1) } else { 0 }
index d11419e01b03ef78b25cbd389a88fedff881db79..7e87dc00674c4c3b507c20c0977ccc70df165847 100644 (file)
@@ -297,7 +297,7 @@ impl Term {
                                     Term::atom(alias.as_str().to_string())
                                 } else {
                                     Term::compound("$stream", [
-                                        Term::integer(stream.as_ptr() as usize)
+                                        Term::integer(stream.as_ptr().addr())
                                     ])
                                 };
                                 term_stack.push(stream_term);
index f0b136fa6d6835159d727cca57e931b886f52601..4247149fa0c11b83f81d21a1df93758a36c7631e 100644 (file)
@@ -59,9 +59,10 @@ impl Index<usize> for AndFrame {
 
         unsafe {
             let ptr = self as *const crate::machine::stack::AndFrame as *const u8;
-            let ptr = ptr as usize + prelude_offset + index_offset;
 
-            &*(ptr as *const HeapCellValue)
+            // This address falls outside the provenance for self, therefore we have to get it
+            // from exposed provenance.
+            &*std::ptr::with_exposed_provenance(ptr.addr() + prelude_offset + index_offset)
         }
     }
 }
@@ -72,10 +73,11 @@ impl IndexMut<usize> for AndFrame {
         let index_offset = (index - 1) * mem::size_of::<HeapCellValue>();
 
         unsafe {
-            let ptr = self as *mut crate::machine::stack::AndFrame as *const u8;
-            let ptr = ptr as usize + prelude_offset + index_offset;
+            let ptr = self as *mut crate::machine::stack::AndFrame as *mut u8;
 
-            &mut *(ptr as *mut HeapCellValue)
+            // This address falls outside the provenance for self, therefore we have to get it
+            // from exposed provenance.
+            &mut *std::ptr::with_exposed_provenance_mut(ptr.addr() + prelude_offset + index_offset)
         }
     }
 }
@@ -85,20 +87,14 @@ impl Index<usize> for Stack {
 
     #[inline]
     fn index(&self, index: usize) -> &Self::Output {
-        unsafe {
-            let ptr = self.buf.base as usize + index;
-            &*(ptr as *const HeapCellValue)
-        }
+        unsafe { &*self.buf.base.add(index).cast() }
     }
 }
 
 impl IndexMut<usize> for Stack {
     #[inline]
     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
-        unsafe {
-            let ptr = self.buf.base as usize + index;
-            &mut *(ptr as *mut HeapCellValue)
-        }
+        unsafe { &mut *self.buf.base.add(index).cast_mut().cast() }
     }
 }
 
@@ -132,9 +128,10 @@ impl Index<usize> for OrFrame {
 
         unsafe {
             let ptr = self as *const crate::machine::stack::OrFrame as *const u8;
-            let ptr = ptr as usize + prelude_offset + index_offset;
 
-            &*(ptr as *const HeapCellValue)
+            // This address falls outside the provenance for self, therefore we have to get it
+            // from exposed provenance.
+            &*std::ptr::with_exposed_provenance(ptr.addr() + prelude_offset + index_offset)
         }
     }
 }
@@ -146,10 +143,11 @@ impl IndexMut<usize> for OrFrame {
         let index_offset = index * mem::size_of::<HeapCellValue>();
 
         unsafe {
-            let ptr = self as *mut crate::machine::stack::OrFrame as *const u8;
-            let ptr = ptr as usize + prelude_offset + index_offset;
+            let ptr = self as *mut crate::machine::stack::OrFrame as *mut u8;
 
-            &mut *(ptr as *mut HeapCellValue)
+            // This address falls outside the provenance for self, therefore we have to get it
+            // from exposed provenance.
+            &mut *std::ptr::with_exposed_provenance_mut(ptr.addr() + prelude_offset + index_offset)
         }
     }
 }
@@ -187,15 +185,19 @@ impl Stack {
         let frame_size = AndFrame::size_of(num_cells);
 
         unsafe {
-            let e = (*self.buf.ptr.get_mut()) as usize - self.buf.base as usize;
+            let e = (*self.buf.ptr.get_mut()).addr() - self.buf.base.addr();
             let new_ptr = self.alloc(frame_size);
             let mut offset = prelude_size::<AndFramePrelude>();
 
             for idx in 0..num_cells {
-                ptr::write(
-                    new_ptr.add(offset) as *mut HeapCellValue,
-                    stack_loc_as_cell!(AndFrame, e, idx + 1),
-                );
+                let cell_ptr = new_ptr.add(offset) as *mut HeapCellValue;
+                ptr::write(cell_ptr, stack_loc_as_cell!(AndFrame, e, idx + 1));
+
+                // Because in the Index and IndexMut inplementations we need to get this from
+                // exposed provenance, we need to expose the provenance here, even though we don't
+                // actually use the value for anything. This is a reminder that `expose_provenance`
+                // isn't just a cast from a pointer to an integer but has actual side effects.
+                cell_ptr.expose_provenance();
 
                 offset += mem::size_of::<HeapCellValue>();
             }
@@ -208,22 +210,26 @@ impl Stack {
     }
 
     pub(crate) fn top(&self) -> usize {
-        unsafe { (*self.buf.ptr.get()) as usize - self.buf.base as usize }
+        unsafe { (*self.buf.ptr.get()).addr() - self.buf.base.addr() }
     }
 
     pub(crate) fn allocate_or_frame(&mut self, num_cells: usize) -> usize {
         let frame_size = OrFrame::size_of(num_cells);
 
         unsafe {
-            let b = (*self.buf.ptr.get_mut()) as usize - self.buf.base as usize;
+            let b = (*self.buf.ptr.get_mut()).addr() - self.buf.base.addr();
             let new_ptr = self.alloc(frame_size);
             let mut offset = prelude_size::<OrFramePrelude>();
 
             for idx in 0..num_cells {
-                ptr::write(
-                    new_ptr.byte_add(offset) as *mut HeapCellValue,
-                    stack_loc_as_cell!(OrFrame, b, idx),
-                );
+                let cell_ptr = new_ptr.byte_add(offset) as *mut HeapCellValue;
+                ptr::write(cell_ptr, stack_loc_as_cell!(OrFrame, b, idx));
+
+                // Because in the Index and IndexMut inplementations we need to get this from
+                // exposed provenance, we need to expose the provenance here, even though we don't
+                // actually use the value for anything. This is a reminder that `expose_provenance`
+                // isn't just a cast from a pointer to an integer but has actual side effects.
+                cell_ptr.expose_provenance();
 
                 offset += mem::size_of::<HeapCellValue>();
             }
@@ -237,10 +243,7 @@ impl Stack {
 
     #[inline(always)]
     pub(crate) fn index_and_frame(&self, e: usize) -> &AndFrame {
-        unsafe {
-            let ptr = self.buf.base as usize + e;
-            &*(ptr as *const AndFrame)
-        }
+        unsafe { &*self.buf.base.add(e).cast() }
     }
 
     #[inline(always)]
@@ -254,26 +257,20 @@ impl Stack {
 
     #[inline(always)]
     pub(crate) fn index_or_frame(&self, b: usize) -> &OrFrame {
-        unsafe {
-            let ptr = self.buf.base as usize + b;
-            &*(ptr as *const OrFrame)
-        }
+        unsafe { &*self.buf.base.add(b).cast() }
     }
 
     #[inline(always)]
     pub(crate) fn index_or_frame_mut(&mut self, b: usize) -> &mut OrFrame {
-        unsafe {
-            let ptr = self.buf.base as usize + b;
-            &mut *(ptr as *mut OrFrame)
-        }
+        unsafe { &mut *self.buf.base.add(b).cast_mut().cast() }
     }
 
     #[inline(always)]
     pub(crate) fn truncate(&mut self, b: usize) {
-        let base = self.buf.base as usize + b;
+        let base = unsafe { self.buf.base.add(b) };
 
-        if base < (*self.buf.ptr.get_mut()) as usize {
-            *self.buf.ptr.get_mut() = base as *mut _;
+        if base < (*self.buf.ptr.get_mut()) {
+            *self.buf.ptr.get_mut() = base.cast_mut();
         }
     }
 }
index 73c36b0df58c58a36668edfd3e48c952e1d62b22..5347af3c2679d346b6aa8d2c73128f0ced902d2e 100644 (file)
@@ -146,10 +146,11 @@ macro_rules! typed_arena_ptr_as_cell {
 macro_rules! raw_ptr_as_cell {
     ($ptr:expr) => {{
         // Cell is 64-bit, but raw ptr is 32-bit in 32-bit systems
-        // TODO use <*{const,mut} _>::addr instead of as when the strict_provenance feature is stable rust-lang/rust#95228
-        // we might need <*{const,mut} _>::expose_provenance for strict provenance, depending on how we recreate a pointer later
-        let ptr : *const _ = $ptr;
-        HeapCellValue::from_ptr_addr(ptr as usize)
+        let ptr: *const _ = $ptr;
+        // This needs to expose provenance because it needs to be turned back into a pointer
+        // in contexts where there is no available provenance locally. For example, in
+        // `ConsPtr::as_ptr`.
+        HeapCellValue::from_ptr_addr(ptr.expose_provenance())
     }};
 }
 
index 5afcf89b93d39e7b498cdadb0a41fc2ae7bacc84..7b47b96ffff00d57a19fdc31681a15978224ed74 100644 (file)
@@ -141,9 +141,8 @@ where
 
         ptr::write(ptr as *mut T, value);
 
-        let value = <OffsetTableImpl<T> as OffsetTable>::Offset::from(
-            ptr as usize - block_epoch.base as usize,
-        );
+        let value =
+            <OffsetTableImpl<T> as OffsetTable>::Offset::from(ptr.addr() - block_epoch.base.addr());
 
         // AtomTable would have to update the index table at this point
         // explicit drop to ensure we don't accidentally drop it early
@@ -270,7 +269,7 @@ where
     #[inline(always)]
     pub fn as_offset(&self) -> <OffsetTableImpl<T> as OffsetTable>::Offset {
         <OffsetTableImpl<T> as OffsetTable>::Offset::from(
-            self.0.get() as usize - RcuRef::get_root(&self.0).base as usize,
+            self.0.get().addr() - RcuRef::get_root(&self.0).base.addr(),
         )
     }
 }
index da75741529e6147210000537978aeb1f7a01a7bf..3c39c77d8f7823aa1ee19f012965630d4e7135d7 100644 (file)
@@ -66,8 +66,8 @@ impl<T: RawBlockTraits> RawBlock<T> {
                 false
             } else {
                 self.base = new_base;
-                self.top = (self.base as usize + size * 2) as *const _;
-                *self.ptr.get_mut() = (self.base as usize + size) as *mut _;
+                self.top = self.base.add(size * 2);
+                *self.ptr.get_mut() = self.base.add(size).cast_mut();
                 true
             }
         }
@@ -83,7 +83,7 @@ impl<T: RawBlockTraits> RawBlock<T> {
                 // allocation failed
                 None
             } else {
-                let allocated = (*self.ptr.get()) as usize - self.base as usize;
+                let allocated = (*self.ptr.get()).addr() - self.base.addr();
                 self.base.copy_to(new_block.base.cast_mut(), allocated);
                 *new_block.ptr.get_mut() = new_block.base.add(allocated).cast_mut();
                 Some(new_block)
@@ -93,7 +93,7 @@ impl<T: RawBlockTraits> RawBlock<T> {
 
     #[inline]
     pub fn size(&self) -> usize {
-        self.top as usize - self.base as usize
+        self.top.addr() - self.base.addr()
     }
 
     #[inline(always)]
@@ -105,7 +105,7 @@ impl<T: RawBlockTraits> RawBlock<T> {
             self.base
         );
 
-        self.top as usize - (*self.ptr.get()) as usize
+        self.top.addr() - (*self.ptr.get()).addr()
     }
 
     pub unsafe fn alloc(&self, size: usize) -> *mut u8 {
index ade9a01c0798d865d6ee0d8a1930bd84644528d5..39aaaa9f67fe51298fae4e1d51e594e516a43d74 100644 (file)
@@ -93,7 +93,7 @@ impl ConsPtr {
     #[inline(always)]
     pub fn build_with(ptr: *const ArenaHeader, tag: ConsPtrMaskTag) -> Self {
         ConsPtr::new()
-            .with_ptr(ptr as *const u8 as u64)
+            .with_ptr(ptr.expose_provenance() as u64)
             .with_f(false)
             .with_m(false)
             .with_tag(tag)
@@ -102,7 +102,7 @@ impl ConsPtr {
     #[inline(always)]
     pub fn as_ptr(self) -> *mut u8 {
         let addr: u64 = self.ptr();
-        addr as usize as *mut _
+        std::ptr::with_exposed_provenance_mut(addr as usize)
     }
 
     #[inline(always)]
@@ -377,7 +377,7 @@ where
 {
     #[inline]
     fn from(arena_ptr: TypedArenaPtr<T>) -> HeapCellValue {
-        HeapCellValue::from(arena_ptr.header_ptr() as u64)
+        HeapCellValue::from(arena_ptr.header_ptr().expose_provenance() as u64)
     }
 }
 
@@ -402,7 +402,7 @@ impl From<ConsPtr> for HeapCellValue {
     #[inline(always)]
     fn from(cons_ptr: ConsPtr) -> HeapCellValue {
         HeapCellValue::from_bytes(
-            ConsPtr::from(cons_ptr.as_ptr() as u64)
+            ConsPtr::from(cons_ptr.as_ptr().expose_provenance() as u64)
                 .with_tag(ConsPtrMaskTag::Cons)
                 .with_m(false)
                 .into_bytes(),
@@ -723,14 +723,14 @@ const_assert!(mem::size_of::<UntypedArenaPtr>() == 8);
 impl From<*const ArenaHeader> for UntypedArenaPtr {
     #[inline]
     fn from(ptr: *const ArenaHeader) -> UntypedArenaPtr {
-        UntypedArenaPtr::build_with(ptr as usize)
+        UntypedArenaPtr::build_with(ptr.expose_provenance())
     }
 }
 
 impl From<*const IndexPtr> for UntypedArenaPtr {
     #[inline]
     fn from(ptr: *const IndexPtr) -> UntypedArenaPtr {
-        UntypedArenaPtr::build_with(ptr as usize)
+        UntypedArenaPtr::build_with(ptr.expose_provenance())
     }
 }
 
@@ -750,7 +750,7 @@ impl UntypedArenaPtr {
     #[inline]
     pub fn get_ptr(self) -> *const u8 {
         let addr: u64 = self.ptr();
-        addr as usize as *const u8
+        std::ptr::with_exposed_provenance(addr as usize)
     }
 
     #[inline]