Skip to content

Commit 503b6af

Browse files
tiifRalfJung
authored andcommitted
Use &[u8] instead of Vec<u8> and improve docs
1 parent f392648 commit 503b6af

File tree

3 files changed

+25
-13
lines changed

3 files changed

+25
-13
lines changed

src/tools/miri/src/shims/unix/fd.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ pub trait FileDescription: std::fmt::Debug + Any {
2626
fn name(&self) -> &'static str;
2727

2828
/// Reads as much as possible into the given buffer, and returns the number of bytes read.
29-
/// `ptr` is the pointer to user supplied read buffer.
29+
/// `ptr` is the pointer to the user supplied read buffer.
30+
/// `len` indicates how many bytes the user requested.
31+
/// `dest` is where the return value should be stored.
3032
fn read<'tcx>(
3133
&self,
3234
_self_ref: &FileDescriptionRef,
@@ -40,6 +42,8 @@ pub trait FileDescription: std::fmt::Debug + Any {
4042
}
4143

4244
/// Writes as much as possible from the given buffer, and returns the number of bytes written.
45+
/// `bytes` is the buffer of bytes supplied by the caller to be written.
46+
/// `dest` is where the return value should be stored.
4347
fn write<'tcx>(
4448
&self,
4549
_self_ref: &FileDescriptionRef,
@@ -53,6 +57,9 @@ pub trait FileDescription: std::fmt::Debug + Any {
5357

5458
/// Reads as much as possible into the given buffer from a given offset,
5559
/// and returns the number of bytes read.
60+
/// `ptr` is the pointer to the user supplied read buffer.
61+
/// `len` indicates how many bytes the user requested.
62+
/// `dest` is where the return value should be stored.
5663
fn pread<'tcx>(
5764
&self,
5865
_communicate_allowed: bool,
@@ -67,6 +74,8 @@ pub trait FileDescription: std::fmt::Debug + Any {
6774

6875
/// Writes as much as possible from the given buffer starting at a given offset,
6976
/// and returns the number of bytes written.
77+
/// `bytes` is the buffer of bytes supplied by the caller to be written.
78+
/// `dest` is where the return value should be stored.
7079
fn pwrite<'tcx>(
7180
&self,
7281
_communicate_allowed: bool,
@@ -143,7 +152,7 @@ impl FileDescription for io::Stdin {
143152
helpers::isolation_abort_error("`read` from stdin")?;
144153
}
145154
let result = Read::read(&mut { self }, &mut bytes);
146-
ecx.return_read_bytes_and_count(ptr, bytes, result, dest)
155+
ecx.return_read_bytes_and_count(ptr, &bytes, result, dest)
147156
}
148157

149158
fn is_tty(&self, communicate_allowed: bool) -> bool {
@@ -641,12 +650,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
641650
Ok(())
642651
}
643652

644-
/// This function either writes to the user supplied buffer and to dest place, or sets the
645-
/// last libc error and writes -1 to dest.
653+
/// Helper to implement `FileDescription::read`:
654+
/// `result` should be the return value of some underlying `read` call that used `bytes` as its output buffer.
655+
/// The length of `bytes` must not exceed either the host's or the target's `isize`.
656+
/// If `Result` indicates success, `bytes` is written to `buf` and the size is written to `dest`.
657+
/// Otherwise, `-1` is written to `dest` and the last libc error is set appropriately.
646658
fn return_read_bytes_and_count(
647659
&mut self,
648660
buf: Pointer,
649-
bytes: Vec<u8>,
661+
bytes: &[u8],
650662
result: io::Result<usize>,
651663
dest: &MPlaceTy<'tcx>,
652664
) -> InterpResult<'tcx> {
@@ -657,7 +669,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
657669
// Crucially, if fewer than `bytes.len()` bytes were read, only write
658670
// that much into the output buffer!
659671
this.write_bytes_ptr(buf, bytes[..read_bytes].iter().copied())?;
660-
// The actual read size is always lesser than `count` so this cannot fail.
672+
// The actual read size is always less than what got originally requested so this cannot fail.
661673
this.write_int(u64::try_from(read_bytes).unwrap(), dest)?;
662674
return Ok(());
663675
}
@@ -669,7 +681,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
669681
}
670682
}
671683

672-
/// This function writes the number of written bytes to dest place, or sets the
684+
/// This function writes the number of written bytes (given in `result`) to `dest`, or sets the
673685
/// last libc error and writes -1 to dest.
674686
fn return_written_byte_count_or_error(
675687
&mut self,

src/tools/miri/src/shims/unix/fs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl FileDescription for FileHandle {
4242
assert!(communicate_allowed, "isolation should have prevented even opening a file");
4343
let mut bytes = vec![0; usize::try_from(len).unwrap()];
4444
let result = (&mut &self.file).read(&mut bytes);
45-
ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest)
45+
ecx.return_read_bytes_and_count(ptr, &bytes, result, dest)
4646
}
4747

4848
fn write<'tcx>(
@@ -83,7 +83,7 @@ impl FileDescription for FileHandle {
8383
res
8484
};
8585
let result = f();
86-
ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest)
86+
ecx.return_read_bytes_and_count(ptr, &bytes, result, dest)
8787
}
8888

8989
fn pwrite<'tcx>(

src/tools/miri/src/shims/unix/unnamed_socket.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ impl FileDescription for AnonSocket {
137137
// Always succeed on read size 0.
138138
if request_byte_size == 0 {
139139
let result = Ok(0);
140-
return ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest);
140+
return ecx.return_read_bytes_and_count(ptr, &bytes, result, dest);
141141
}
142142

143143
let Some(readbuf) = &self.readbuf else {
@@ -151,7 +151,7 @@ impl FileDescription for AnonSocket {
151151
// Socketpair with no peer and empty buffer.
152152
// 0 bytes successfully read indicates end-of-file.
153153
let result = Ok(0);
154-
return ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest);
154+
return ecx.return_read_bytes_and_count(ptr, &bytes, result, dest);
155155
} else {
156156
if self.is_nonblock {
157157
// Non-blocking socketpair with writer and empty buffer.
@@ -160,7 +160,7 @@ impl FileDescription for AnonSocket {
160160
// POSIX.1-2001 allows either error to be returned for this case.
161161
// Since there is no ErrorKind for EAGAIN, WouldBlock is used.
162162
let result = Err(Error::from(ErrorKind::WouldBlock));
163-
return ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest);
163+
return ecx.return_read_bytes_and_count(ptr, &bytes, result, dest);
164164
} else {
165165
// Blocking socketpair with writer and empty buffer.
166166
// FIXME: blocking is currently not supported
@@ -193,7 +193,7 @@ impl FileDescription for AnonSocket {
193193
}
194194

195195
let result = Ok(actual_read_size);
196-
ecx.return_read_bytes_and_count(ptr, bytes.to_vec(), result, dest)
196+
ecx.return_read_bytes_and_count(ptr, &bytes, result, dest)
197197
}
198198

199199
fn write<'tcx>(

0 commit comments

Comments
 (0)