about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLuv-Ray <zhuoxun.yang777@outlook.com>2024-05-13 16:17:56 +0800
committerLuv-Ray <zhuoxun.yang777@outlook.com>2024-05-13 16:17:56 +0800
commit99c6b2e604125f99bd7e66326dcf1f31a81febac (patch)
treed64b62c6cd8de0cc1bb6ac55331a605d96ca1c8f
parentd4937cb2295aae52d10a91147d1603324cafb0c5 (diff)
downloadrust-99c6b2e604125f99bd7e66326dcf1f31a81febac.tar.gz
rust-99c6b2e604125f99bd7e66326dcf1f31a81febac.zip
Give `FileDescription::{read, write}` access to the `InterpCx`
-rw-r--r--src/tools/miri/src/shims/unix/fd.rs37
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs5
-rw-r--r--src/tools/miri/src/shims/unix/linux/eventfd.rs5
3 files changed, 28 insertions, 19 deletions
diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs
index a53cd607ef0..8159960f826 100644
--- a/src/tools/miri/src/shims/unix/fd.rs
+++ b/src/tools/miri/src/shims/unix/fd.rs
@@ -7,7 +7,6 @@ use std::collections::BTreeMap;
 use std::io::{self, ErrorKind, IsTerminal, Read, SeekFrom, Write};
 use std::rc::Rc;
 
-use rustc_middle::ty::TyCtxt;
 use rustc_target::abi::Size;
 
 use crate::shims::unix::*;
@@ -22,7 +21,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
         &mut self,
         _communicate_allowed: bool,
         _bytes: &mut [u8],
-        _tcx: TyCtxt<'tcx>,
+        _ecx: &mut MiriInterpCx<'_, 'tcx>,
     ) -> InterpResult<'tcx, io::Result<usize>> {
         throw_unsup_format!("cannot read from {}", self.name());
     }
@@ -32,7 +31,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
         &mut self,
         _communicate_allowed: bool,
         _bytes: &[u8],
-        _tcx: TyCtxt<'tcx>,
+        _ecx: &mut MiriInterpCx<'_, 'tcx>,
     ) -> InterpResult<'tcx, io::Result<usize>> {
         throw_unsup_format!("cannot write to {}", self.name());
     }
@@ -82,7 +81,7 @@ impl FileDescription for io::Stdin {
         &mut self,
         communicate_allowed: bool,
         bytes: &mut [u8],
-        _tcx: TyCtxt<'tcx>,
+        _ecx: &mut MiriInterpCx<'_, 'tcx>,
     ) -> InterpResult<'tcx, io::Result<usize>> {
         if !communicate_allowed {
             // We want isolation mode to be deterministic, so we have to disallow all reads, even stdin.
@@ -105,7 +104,7 @@ impl FileDescription for io::Stdout {
         &mut self,
         _communicate_allowed: bool,
         bytes: &[u8],
-        _tcx: TyCtxt<'tcx>,
+        _ecx: &mut MiriInterpCx<'_, 'tcx>,
     ) -> InterpResult<'tcx, io::Result<usize>> {
         // We allow writing to stderr even with isolation enabled.
         let result = Write::write(self, bytes);
@@ -133,7 +132,7 @@ impl FileDescription for io::Stderr {
         &mut self,
         _communicate_allowed: bool,
         bytes: &[u8],
-        _tcx: TyCtxt<'tcx>,
+        _ecx: &mut MiriInterpCx<'_, 'tcx>,
     ) -> InterpResult<'tcx, io::Result<usize>> {
         // We allow writing to stderr even with isolation enabled.
         // No need to flush, stderr is not buffered.
@@ -158,7 +157,7 @@ impl FileDescription for NullOutput {
         &mut self,
         _communicate_allowed: bool,
         bytes: &[u8],
-        _tcx: TyCtxt<'tcx>,
+        _ecx: &mut MiriInterpCx<'_, 'tcx>,
     ) -> InterpResult<'tcx, io::Result<usize>> {
         // We just don't write anything, but report to the user that we did.
         Ok(Ok(bytes.len()))
@@ -173,6 +172,14 @@ impl FileDescriptor {
         FileDescriptor(Rc::new(RefCell::new(Box::new(fd))))
     }
 
+    pub fn borrow(&self) -> Ref<'_, dyn FileDescription> {
+        Ref::map(self.0.borrow(), |fd| fd.as_ref())
+    }
+
+    pub fn borrow_mut(&self) -> RefMut<'_, dyn FileDescription> {
+        RefMut::map(self.0.borrow_mut(), |fd| fd.as_mut())
+    }
+
     pub fn close<'ctx>(self, communicate_allowed: bool) -> InterpResult<'ctx, io::Result<()>> {
         // Destroy this `Rc` using `into_inner` so we can call `close` instead of
         // implicitly running the destructor of the file description.
@@ -242,12 +249,12 @@ impl FdTable {
 
     pub fn get(&self, fd: i32) -> Option<Ref<'_, dyn FileDescription>> {
         let fd = self.fds.get(&fd)?;
-        Some(Ref::map(fd.0.borrow(), |fd| fd.as_ref()))
+        Some(fd.borrow())
     }
 
     pub fn get_mut(&self, fd: i32) -> Option<RefMut<'_, dyn FileDescription>> {
         let fd = self.fds.get(&fd)?;
-        Some(RefMut::map(fd.0.borrow_mut(), |fd| fd.as_mut()))
+        Some(fd.borrow_mut())
     }
 
     pub fn dup(&self, fd: i32) -> Option<FileDescriptor> {
@@ -370,7 +377,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             .min(u64::try_from(isize::MAX).unwrap());
         let communicate = this.machine.communicate();
 
-        let Some(mut file_descriptor) = this.machine.fds.get_mut(fd) else {
+        // We temporarily dup the FD to be able to retain mutable access to `this`.
+        let Some(file_descriptor) = this.machine.fds.dup(fd) else {
             trace!("read: FD not found");
             return this.fd_not_found();
         };
@@ -383,7 +391,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         // `File::read` never returns a value larger than `count`,
         // so this cannot fail.
         let result = file_descriptor
-            .read(communicate, &mut bytes, *this.tcx)?
+            .borrow_mut()
+            .read(communicate, &mut bytes, this)?
             .map(|c| i64::try_from(c).unwrap());
         drop(file_descriptor);
 
@@ -421,12 +430,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let communicate = this.machine.communicate();
 
         let bytes = this.read_bytes_ptr_strip_provenance(buf, Size::from_bytes(count))?.to_owned();
-        let Some(mut file_descriptor) = this.machine.fds.get_mut(fd) else {
+        // We temporarily dup the FD to be able to retain mutable access to `this`.
+        let Some(file_descriptor) = this.machine.fds.dup(fd) else {
             return this.fd_not_found();
         };
 
         let result = file_descriptor
-            .write(communicate, &bytes, *this.tcx)?
+            .borrow_mut()
+            .write(communicate, &bytes, this)?
             .map(|c| i64::try_from(c).unwrap());
         drop(file_descriptor);
 
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index eb241556a56..82bc49536b0 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -9,7 +9,6 @@ use std::path::{Path, PathBuf};
 use std::time::SystemTime;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_middle::ty::TyCtxt;
 use rustc_target::abi::Size;
 
 use crate::shims::os_str::bytes_to_os_str;
@@ -34,7 +33,7 @@ impl FileDescription for FileHandle {
         &mut self,
         communicate_allowed: bool,
         bytes: &mut [u8],
-        _tcx: TyCtxt<'tcx>,
+        _ecx: &mut MiriInterpCx<'_, 'tcx>,
     ) -> InterpResult<'tcx, io::Result<usize>> {
         assert!(communicate_allowed, "isolation should have prevented even opening a file");
         Ok(self.file.read(bytes))
@@ -44,7 +43,7 @@ impl FileDescription for FileHandle {
         &mut self,
         communicate_allowed: bool,
         bytes: &[u8],
-        _tcx: TyCtxt<'tcx>,
+        _ecx: &mut MiriInterpCx<'_, 'tcx>,
     ) -> InterpResult<'tcx, io::Result<usize>> {
         assert!(communicate_allowed, "isolation should have prevented even opening a file");
         Ok(self.file.write(bytes))
diff --git a/src/tools/miri/src/shims/unix/linux/eventfd.rs b/src/tools/miri/src/shims/unix/linux/eventfd.rs
index a865f2efff9..f31c2bb84ae 100644
--- a/src/tools/miri/src/shims/unix/linux/eventfd.rs
+++ b/src/tools/miri/src/shims/unix/linux/eventfd.rs
@@ -2,7 +2,6 @@
 //! Currently just a stub.
 use std::io;
 
-use rustc_middle::ty::TyCtxt;
 use rustc_target::abi::Endian;
 
 use crate::shims::unix::*;
@@ -52,11 +51,11 @@ impl FileDescription for Event {
         &mut self,
         _communicate_allowed: bool,
         bytes: &[u8],
-        tcx: TyCtxt<'tcx>,
+        ecx: &mut MiriInterpCx<'_, 'tcx>,
     ) -> InterpResult<'tcx, io::Result<usize>> {
         let bytes: [u8; 8] = bytes.try_into().unwrap(); // FIXME fail gracefully when this has the wrong size
         // Convert from target endianness to host endianness.
-        let num = match tcx.sess.target.endian {
+        let num = match ecx.tcx.sess.target.endian {
             Endian::Little => u64::from_le_bytes(bytes),
             Endian::Big => u64::from_be_bytes(bytes),
         };