Conversation
|
Thanks for the feedback, I will slowly address them. So currently Currently, I still need to:
|
|
Wow, the only difference between 7721683 and dc74101 is just one inlined variable, but dc74101 somehow failed EDIT: After a closer look, this should be caused by the variable I reverted the entire inline variable commit. |
|
You changed evaluation order: // Runs `bytes.to_vec()` after `Read::read.
let result = Read::read(&mut { self }, bytes);
ecx.read_byte_helper(ptr, bytes.to_vec(), result, dest)?;// Runs `bytes.to_vec()` before `Read::read.
ecx.read_byte_helper(ptr, bytes.to_vec(), Read::read(&mut { self }, bytes), dest)?;So maybe that explains the difference. |
|
Is there any nice way to deref Pointer type to a place? So for eventfd, I perhaps can directly write to the user supplied buffer using fn read_byte_helper_ev(
&mut self,
buf_place: &MPlaceTy<'tcx>,
read_val: u64,
result: io::Result<usize>,
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
// `File::read` never returns a value larger than `count`, so this cannot fail.
match result.map(|c| i64::try_from(c).unwrap()) {
// try to pass this the write_ptr inside write
// Pass the pointer inside the write function.
Ok(read_bytes) => {
// Write to the user supplied buffer.
this.write_int(read_val, buf_place)?; // <-- Here!!
// Write to the function return value place.
this.write_int(read_bytes, dest)?;
return Ok(());
}
Err(e) => {
this.set_last_error_from_io_error(e)?;
this.write_int(-1, dest)?;
return Ok(());
}
}
}Unfortunately I can't just use |
71 | let buf_place = ecx.deref_pointer_as(&ptr, ecx.machine.layouts.u64);
| ---------------- ^^^^ the trait `rustc_const_eval::interpret::Readable<'_, machine::Provenance>` is not implemented for `rustc_const_eval::interpret::Pointer<std::option::Option<machine::Provenance>>`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `rustc_const_eval::interpret::Readable<'tcx, Prov>`:
rustc_const_eval::interpret::ImmTy<'tcx, Prov>
rustc_const_eval::interpret::MPlaceTy<'tcx, Prov>
rustc_const_eval::interpret::OpTy<'tcx, Prov>We might also need to keep it as a Pointer type (instead of using // Check that the *entire* buffer is actually valid memory.
this.check_ptr_access(buf, Size::from_bytes(count), CheckInAllocMsg::MemoryAccessTest)?; |
|
Yes, Instead of passing it as a pointer, you could also try passing it as an |
|
Another idea here: These are all the file description that implements
So for the first three |
|
I think they should all just take a Pointer. We already have a helper function (I think) to write a bunch of bytes to a pointer, so it should not be hard for fs and socket to use that.
|
|
☔ The latest upstream changes (presumably #3867) made this pull request unmergeable. Please resolve the merge conflicts. |
|
This is partially blocked by rust-lang/rust#130215 as I'd need the |
|
@rustbot ready |
|
Please squash the commits, then r=me @bors delegate+ |
Refactor fd read/write This PR passed the responsibility of reading to user supplied buffer and dest place to each implementation of ``FileDescription::read/write/pread/pwrite``. This is part of #3665.
|
@bors r- |
src/shims/unix/linux/eventfd.rs
Outdated
| // eventfd read at the size of u64. | ||
| let buf_place = ecx.ptr_to_mplace_unaligned(ptr, ecx.machine.layouts.u64); |
There was a problem hiding this comment.
Please do this after the size check.
There was a problem hiding this comment.
Unfortunately inside the size check, return return_read_bytes_and_count_ev(&buf_place, None, result, dest, ecx); is called, so we need buf_place. I probably should separate these two code path in return_read_bytes_and_count into different function.
match result {
Ok(read_bytes) => {
// If reading to `bytes` did not fail, we write those bytes to the buffer.
// Crucially, if fewer than `bytes.len()` bytes were read, only write
// that much into the output buffer!
this.write_bytes_ptr(buf, bytes[..read_bytes].iter().copied())?;
// The actual read size is always less than what got originally requested so this cannot fail.
this.write_int(u64::try_from(read_bytes).unwrap(), dest)?;
return Ok(());
}
Err(e) => {
this.set_last_error_from_io_error(e)?;
this.write_int(-1, dest)?;
return Ok(());
}
}This is the same issue as #3852 (comment).
src/shims/unix/linux/eventfd.rs
Outdated
|
|
||
| Ok(Ok(U64_ARRAY_SIZE)) | ||
| let result = Ok(U64_ARRAY_SIZE); | ||
| ecx.return_written_byte_count_or_error(result, dest) |
There was a problem hiding this comment.
Why is return_written_byte_count_or_error a helper function? Every single caller fixes either Err or Ok so this is funneling through a Result without a good reason, it just makes the code harder to follow.
If there is any helper we want here, it is a new very generic helper that sets the last errors and also writes -1 to dest. But that's probably better done in a future PR, for now you can just copy those 2 lines here I would say, like we do everywhere else.
src/shims/unix/linux/eventfd.rs
Outdated
| ecx.check_and_update_readiness(self_ref)?; | ||
|
|
||
| return Ok(Ok(U64_ARRAY_SIZE)); | ||
| return_read_bytes_and_count_ev(&buf_place, Some(counter), result, dest, ecx) |
There was a problem hiding this comment.
Why is return_read_bytes_and_count_ev a helper function? Every single caller fixes either Err or Ok so this is funneling through a Result without a good reason, it just makes the code harder to follow.
If there is any helper we want here, it is a new very generic helper that sets the last errors and also writes -1 to dest. But that's probably better done in a future PR, for now you can just copy those 2 lines here I would say, like we do everywhere else.
|
☀️ Try build successful - checks-actions |
|
Instead of separating the helper with match result {
Ok(read_bytes) => {
// If reading to `bytes` did not fail, we write those bytes to the buffer.
// Crucially, if fewer than `bytes.len()` bytes were read, only write
// that much into the output buffer!
this.write_bytes_ptr(buf, bytes[..read_bytes].iter().copied())?;
// The actual read size is always less than what got originally requested so this cannot fail.
this.write_int(u64::try_from(read_bytes).unwrap(), dest)?;
return Ok(());
}
Err(e) => {
this.set_last_error_from_io_error(e)?;
this.write_int(-1, dest)?;
return Ok(());
}
}or use As this could be done in a new PR, @rustbot ready |
… len in read to usize
0d090f7 to
d7741a9
Compare
|
Thanks! I've done some further minor tweaks, mostly to remove a bunch of Also I re-did eventfd a bit, see the last commit. I didn't think that helper function was helpful so I removed it. Further improvements are possible I think (specifically some sort of helper for the quite common case of "set errno and return -1"), but that can be a separate PR. @bors r+ |
|
☀️ Test successful - checks-actions |
This PR passed the responsibility of reading to user supplied buffer and dest place to each implementation of
FileDescription::read/write/pread/pwrite.This is part of #3665.