-
Couldn't load subscription status.
- Fork 400
Add a helper for directly writing io::Result to places
#3777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Instead of having to repeat the conversion to `Scalar`
| /// This function uses `T: From<i32>` instead of `i32` directly because some IO related | ||
| /// functions return different integer types (like `read`, that returns an `i64`). | ||
| fn try_unwrap_io_result<T: From<i32>>( | ||
| fn try_unwrap_io_result<T: WriteIoResult>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc comment above is outdated now.
| } | ||
| } | ||
|
|
||
| pub trait WriteIoResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a doc comment. Also the trait name is kind of confusing, maybe a doc comment will help coming up with a better one.
| Ok(written_bytes) => Ok(Scalar::from_target_isize(written_bytes, this)), | ||
| Err(e) => { | ||
| this.set_last_error_from_io_error(e)?; | ||
| Ok(Scalar::from_target_isize(-1, this)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code got worse than it used to be, what's happening here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are writing target sized integers, so i'll need to add a helper type to wrap the i64s in. The read method already could not be ported before and was written out fully. I want to fix both at the same time
| Ok(remove_dir(path)) | ||
| } | ||
|
|
||
| fn opendir(&mut self, name_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this one still return Scalar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It (and others) return error codes via this.eval_libc("EACCES"); without a corresponding ErrorKind existing in libcore. I plan to use an error enum that wraps io errors and has variants for all the eval_libc errors we use in miri. May turn out overkill, but I wanna see how it looks before discarding it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems easier to use Scalar as the universal type for what to store in errno -- we can already convert both io::Error and libc constants into Scalar.
| let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; | ||
| let result = this.chdir(path)?; | ||
| this.write_scalar(result, dest)?; | ||
| this.write_io_result(result, dest)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really such a big win to move the io::Result handling out of the shim?
A priori I think I'd prefer the version that returns a Scalar, as that matches the C function we're implementing and since it is a pattern we can use for all functions, not just IO functions. We can have more helpers inside those functions that make them easier to write and avoid hard-coding -1 anywhere, that seems like a more promising approach to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I initially wanted to add such helpers, but then it got annoying for handling i64, i32, and i64 but is actually target usize, as that would require explicit type annotations and reliance on runtime checks (Scalar size vs destination size). I then thought it would be nicer to keep some semblence of result handling around, as now all the return types must match up again, like before moving to scalars. I'll finish this PR to its conclusion and open a separate PR for just using helpers everywhere so you can compare.
| this.reject_in_isolation("`rmdir`", reject_with)?; | ||
| this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?; | ||
| return Ok(Scalar::from_i32(-1)); | ||
| return Ok(Err(ErrorKind::PermissionDenied.into())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For instance, this could become return Ok(this.return_io_error(ErrorKind::PermissionDenied.into())) where return_io_error sets the errno and then returns -1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, but I'd still need to say how big the scalar is supposed to be. Not the end of the world, but also not nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, the type...
Another option might be to pass dest to these functions and not have them return anything. A function that blocks usually already needs to do that anyway. Then they can use your new write_io_result internally for when they naturally have an io::Result, and some write_io_error for cases like this where we hard-code an error.
|
I think the other scheme will allow us to better simplify things, so I'm closing this PR and will cherry-pick the parts that are useful |
Instead of having to repeat the conversion to
Scalareverywhere.