diff --git a/pulley/fuzz/src/interp.rs b/pulley/fuzz/src/interp.rs index 2777ef1fcc4a..5fd70b082c16 100644 --- a/pulley/fuzz/src/interp.rs +++ b/pulley/fuzz/src/interp.rs @@ -32,7 +32,7 @@ pub fn interp(ops: Vec) { match vm.call(NonNull::from(&encoded[0]), args, rets.into_iter().copied()) { Ok(rets) => assert_eq!(rets.count(), 0), Err(pc) => { - let pc = pc as usize; + let pc = pc.as_ptr() as usize; let start = &encoded[0] as *const u8 as usize; let end = encoded.last().unwrap() as *const u8 as usize; diff --git a/pulley/src/decode.rs b/pulley/src/decode.rs index 09f4da80d901..89b52d0543c4 100644 --- a/pulley/src/decode.rs +++ b/pulley/src/decode.rs @@ -1,5 +1,7 @@ //! Decoding support for pulley bytecode. +use core::ptr::NonNull; + use alloc::vec::Vec; use cranelift_bitset::scalar::ScalarBitSetStorage; use cranelift_bitset::ScalarBitSet; @@ -194,7 +196,7 @@ pub enum Uninhabited {} /// /// This is a wrapper over a raw pointer to bytecode somewhere in memory. #[derive(Clone, Copy, Debug)] -pub struct UnsafeBytecodeStream(*mut u8); +pub struct UnsafeBytecodeStream(NonNull); impl UnsafeBytecodeStream { /// Construct a new `UnsafeBytecodeStream` pointing at the given PC. @@ -208,8 +210,7 @@ impl UnsafeBytecodeStream { /// new PC, this stream must not be used to read just after the /// unconditional jump instruction because there is no guarantee that that /// memory is part of the bytecode stream or not. - pub unsafe fn new(pc: *mut u8) -> Self { - assert!(!pc.is_null()); + pub unsafe fn new(pc: NonNull) -> Self { UnsafeBytecodeStream(pc) } @@ -226,14 +227,13 @@ impl UnsafeBytecodeStream { } /// Get this stream's underlying raw pointer. - pub fn as_ptr(&self) -> *mut u8 { + pub fn as_ptr(&self) -> NonNull { self.0 } } impl BytecodeStream for UnsafeBytecodeStream { fn read(&mut self) -> Result<[u8; N], Self::Error> { - debug_assert!(!self.0.is_null()); let bytes = unsafe { self.0.cast::<[u8; N]>().read() }; self.0 = unsafe { self.0.add(N) }; Ok(bytes) diff --git a/pulley/src/interp.rs b/pulley/src/interp.rs index 664b9cf72bc5..647bed8fca1c 100644 --- a/pulley/src/interp.rs +++ b/pulley/src/interp.rs @@ -72,7 +72,7 @@ impl Vm { func: NonNull, args: &[Val], rets: impl IntoIterator + 'a, - ) -> Result + 'a, *mut u8> { + ) -> Result + 'a, NonNull> { // NB: make sure this method stays in sync with // `PulleyMachineDeps::compute_arg_locs`! @@ -97,7 +97,7 @@ impl Vm { } } - self.run(func.as_ptr())?; + self.run(func)?; let mut x_rets = (0..16).map(|x| XReg::new_unchecked(x)); let mut f_rets = (0..16).map(|f| FReg::new_unchecked(f)); @@ -119,7 +119,7 @@ impl Vm { })) } - unsafe fn run(&mut self, pc: *mut u8) -> Result<(), *mut u8> { + unsafe fn run(&mut self, pc: NonNull) -> Result<(), NonNull> { let mut visitor = InterpreterVisitor { state: &mut self.state, pc: UnsafeBytecodeStream::new(pc), @@ -148,13 +148,13 @@ impl Vm { #[cold] #[inline(never)] - fn return_to_host(&self) -> Result<(), *mut u8> { + fn return_to_host(&self) -> Result<(), NonNull> { Ok(()) } #[cold] #[inline(never)] - fn trap(&self, pc: *mut u8) -> Result<(), *mut u8> { + fn trap(&self, pc: NonNull) -> Result<(), NonNull> { // We are given the VM's PC upon having executed a trap instruction, // which is actually pointing to the next instruction after the // trap. Back the PC up to point exactly at the trap. @@ -164,7 +164,7 @@ impl Vm { #[cold] #[inline(never)] - fn host_call(&self) -> Result<(), *mut u8> { + fn host_call(&self) -> Result<(), NonNull> { todo!() } } @@ -624,15 +624,15 @@ impl OpVisitor for InterpreterVisitor<'_> { Continuation::ReturnToHost } else { let return_addr = self.state[XReg::lr].get_ptr(); - self.pc = unsafe { UnsafeBytecodeStream::new(return_addr) }; + self.pc = unsafe { UnsafeBytecodeStream::new(NonNull::new_unchecked(return_addr)) }; // log::trace!("returning to {return_addr:#p}"); Continuation::Continue } } fn call(&mut self, offset: PcRelOffset) -> Self::Return { - let return_addr = u64::try_from(self.pc.as_ptr() as usize).unwrap(); - self.state[XReg::lr].set_u64(return_addr); + let return_addr = self.pc.as_ptr(); + self.state[XReg::lr].set_ptr(return_addr.as_ptr()); self.pc_rel_jump(offset, 5) } diff --git a/pulley/tests/all/interp.rs b/pulley/tests/all/interp.rs index 085c09cf3044..8015cfed1412 100644 --- a/pulley/tests/all/interp.rs +++ b/pulley/tests/all/interp.rs @@ -13,7 +13,7 @@ fn encoded(ops: &[Op]) -> Vec { encoded } -unsafe fn run(vm: &mut Vm, ops: &[Op]) -> Result<(), *mut u8> { +unsafe fn run(vm: &mut Vm, ops: &[Op]) -> Result<(), NonNull> { let _ = env_logger::try_init(); let ops = encoded(ops); let _ = vm.call(NonNull::from(&ops[..]).cast(), &[], [])?;