Skip to content

Commit aafb7c9

Browse files
committed
Auto merge of #1128 - RalfJung:cleanup, r=RalfJung
use new try_from methods and a bit of other cleanup
2 parents b1e97df + cd12f47 commit aafb7c9

File tree

1 file changed

+32
-47
lines changed

1 file changed

+32
-47
lines changed

src/helpers.rs

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
445445
'tcx: 'a,
446446
'mir: 'a,
447447
{
448+
#[cfg(target_os = "unix")]
449+
fn bytes_to_os_str<'tcx, 'a>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
450+
Ok(std::os::unix::ffi::OsStringExt::from_bytes(bytes))
451+
}
452+
#[cfg(not(target_os = "unix"))]
453+
fn bytes_to_os_str<'tcx, 'a>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
454+
let s = std::str::from_utf8(bytes)
455+
.map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
456+
Ok(&OsStr::new(s))
457+
}
458+
448459
let this = self.eval_context_ref();
449460
let bytes = this.memory.read_c_str(scalar)?;
450461
bytes_to_os_str(bytes)
@@ -460,6 +471,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
460471
scalar: Scalar<Tag>,
461472
size: u64,
462473
) -> InterpResult<'tcx, bool> {
474+
#[cfg(target_os = "unix")]
475+
fn os_str_to_bytes<'tcx, 'a>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
476+
std::os::unix::ffi::OsStringExt::into_bytes(os_str)
477+
}
478+
#[cfg(not(target_os = "unix"))]
479+
fn os_str_to_bytes<'tcx, 'a>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
480+
// On non-unix platforms the best we can do to transform bytes from/to OS strings is to do the
481+
// intermediate transformation into strings. Which invalidates non-utf8 paths that are actually
482+
// valid.
483+
os_str
484+
.to_str()
485+
.map(|s| s.as_bytes())
486+
.ok_or_else(|| err_unsup_format!("{:?} is not a valid utf-8 string", os_str).into())
487+
}
488+
463489
let bytes = os_str_to_bytes(os_str)?;
464490
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
465491
// terminator to memory using the `ptr` pointer would cause an out-of-bounds access.
@@ -473,63 +499,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
473499
}
474500
}
475501

476-
#[cfg(target_os = "unix")]
477-
fn os_str_to_bytes<'tcx, 'a>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
478-
std::os::unix::ffi::OsStringExt::into_bytes(os_str)
479-
}
480-
481-
#[cfg(target_os = "unix")]
482-
fn bytes_to_os_str<'tcx, 'a>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
483-
Ok(std::os::unix::ffi::OsStringExt::from_bytes(bytes))
484-
}
485-
486-
// On non-unix platforms the best we can do to transform bytes from/to OS strings is to do the
487-
// intermediate transformation into strings. Which invalidates non-utf8 paths that are actually
488-
// valid.
489-
#[cfg(not(target_os = "unix"))]
490-
fn os_str_to_bytes<'tcx, 'a>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
491-
os_str
492-
.to_str()
493-
.map(|s| s.as_bytes())
494-
.ok_or_else(|| err_unsup_format!("{:?} is not a valid utf-8 string", os_str).into())
495-
}
496-
497-
#[cfg(not(target_os = "unix"))]
498-
fn bytes_to_os_str<'tcx, 'a>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
499-
let s = std::str::from_utf8(bytes)
500-
.map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
501-
Ok(&OsStr::new(s))
502-
}
503-
504-
// FIXME: change `ImmTy::from_int` so it returns an `InterpResult` instead and remove this
505-
// function.
506502
pub fn immty_from_int_checked<'tcx>(
507503
int: impl Into<i128>,
508504
layout: TyLayout<'tcx>,
509505
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
510506
let int = int.into();
511-
// If `int` does not fit in `size` bits, we error instead of letting
512-
// `ImmTy::from_int` panic.
513-
let size = layout.size;
514-
let truncated = truncate(int as u128, size);
515-
if sign_extend(truncated, size) as i128 != int {
516-
throw_unsup_format!("Signed value {:#x} does not fit in {} bits", int, size.bits())
517-
}
518-
Ok(ImmTy::from_int(int, layout))
507+
Ok(ImmTy::try_from_int(int, layout).ok_or_else(||
508+
err_unsup_format!("Signed value {:#x} does not fit in {} bits", int, layout.size.bits())
509+
)?)
519510
}
520511

521-
// FIXME: change `ImmTy::from_uint` so it returns an `InterpResult` instead and remove this
522-
// function.
523512
pub fn immty_from_uint_checked<'tcx>(
524513
int: impl Into<u128>,
525514
layout: TyLayout<'tcx>,
526515
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
527516
let int = int.into();
528-
// If `int` does not fit in `size` bits, we error instead of letting
529-
// `ImmTy::from_int` panic.
530-
let size = layout.size;
531-
if truncate(int, size) != int {
532-
throw_unsup_format!("Unsigned value {:#x} does not fit in {} bits", int, size.bits())
533-
}
534-
Ok(ImmTy::from_uint(int, layout))
517+
Ok(ImmTy::try_from_uint(int, layout).ok_or_else(||
518+
err_unsup_format!("Signed value {:#x} does not fit in {} bits", int, layout.size.bits())
519+
)?)
535520
}

0 commit comments

Comments
 (0)