Skip to content

Commit e9e04e5

Browse files
committed
move path methods together, to the bottom of the string helpers
1 parent 8817397 commit e9e04e5

File tree

1 file changed

+79
-77
lines changed

1 file changed

+79
-77
lines changed

src/helpers.rs

Lines changed: 79 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -498,42 +498,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
498498
bytes_to_os_str(bytes)
499499
}
500500

501-
/// Read a null-terminated sequence of bytes, and perform path separator conversion if needed.
502-
fn read_path_from_c_str<'a>(&'a self, scalar: Scalar<Tag>) -> InterpResult<'tcx, Cow<'a, Path>>
503-
where
504-
'tcx: 'a,
505-
'mir: 'a,
506-
{
507-
let this = self.eval_context_ref();
508-
let os_str = this.read_os_str_from_c_str(scalar)?;
509-
510-
#[cfg(windows)]
511-
return Ok(if this.tcx.sess.target.target.target_os == "windows" {
512-
// Windows-on-Windows, all fine.
513-
Cow::Borrowed(Path::new(os_str))
514-
} else {
515-
// Unix target, Windows host. Need to convert target '/' to host '\'.
516-
let converted = os_str
517-
.encode_wide()
518-
.map(|wchar| if wchar == '/' as u16 { '\\' as u16 } else { wchar })
519-
.collect::<Vec<_>>();
520-
Cow::Owned(PathBuf::from(OsString::from_wide(&converted)))
521-
});
522-
#[cfg(unix)]
523-
return Ok(if this.tcx.sess.target.target.target_os == "windows" {
524-
// Windows target, Unix host. Need to convert target '\' to host '/'.
525-
let converted = os_str
526-
.as_bytes()
527-
.iter()
528-
.map(|&wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar })
529-
.collect::<Vec<_>>();
530-
Cow::Owned(PathBuf::from(OsString::from_vec(converted)))
531-
} else {
532-
// Unix-on-Unix, all is fine.
533-
Cow::Borrowed(Path::new(os_str))
534-
});
535-
}
536-
537501
/// Helper function to read an OsString from a 0x0000-terminated sequence of u16,
538502
/// which is what the Windows APIs usually handle.
539503
fn read_os_str_from_wide_str<'a>(&'a self, scalar: Scalar<Tag>) -> InterpResult<'tcx, OsString>
@@ -595,46 +559,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
595559
Ok((true, string_length))
596560
}
597561

598-
/// Write a Path to the machine memory, adjusting path separators if needed.
599-
fn write_path_to_c_str(
600-
&mut self,
601-
path: &Path,
602-
scalar: Scalar<Tag>,
603-
size: u64,
604-
) -> InterpResult<'tcx, (bool, u64)> {
605-
let this = self.eval_context_mut();
606-
607-
#[cfg(windows)]
608-
let os_str = if this.tcx.sess.target.target.target_os == "windows" {
609-
// Windows-on-Windows, all fine.
610-
Cow::Borrowed(path.as_os_str())
611-
} else {
612-
// Unix target, Windows host. Need to convert host '\\' to target '/'.
613-
let converted = path
614-
.as_os_str()
615-
.encode_wide()
616-
.map(|wchar| if wchar == '\\' as u16 { '/' as u16 } else { wchar })
617-
.collect::<Vec<_>>();
618-
Cow::Owned(OsString::from_wide(&converted))
619-
};
620-
#[cfg(unix)]
621-
let os_str = if this.tcx.sess.target.target.target_os == "windows" {
622-
// Windows target, Unix host. Need to convert host '/' to target '\'.
623-
let converted = path
624-
.as_os_str()
625-
.as_bytes()
626-
.iter()
627-
.map(|&wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar })
628-
.collect::<Vec<_>>();
629-
Cow::Owned(OsString::from_vec(converted))
630-
} else {
631-
// Unix-on-Unix, all is fine.
632-
Cow::Borrowed(path.as_os_str())
633-
};
634-
635-
this.write_os_str_to_c_str(&os_str, scalar, size)
636-
}
637-
638562
/// Helper function to write an OsStr as a 0x0000-terminated u16-sequence, which is what
639563
/// the Windows APIs usually handle. This function returns `Ok((false, length))` without trying
640564
/// to write if `size` is not large enough to fit the contents of `os_string` plus a null
@@ -674,7 +598,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
674598
// Store the UTF-16 string.
675599
let char_size = Size::from_bytes(2);
676600
for (idx, c) in u16_vec.into_iter().chain(iter::once(0x0000)).enumerate() {
677-
let place = this.mplace_field(mplace, idx as u64)?;
601+
let place = this.mplace_field(mplace, u64::try_from(idx).unwrap())?;
678602
this.write_scalar(Scalar::from_uint(c, char_size), place.into())?;
679603
}
680604
Ok((true, string_length))
@@ -695,6 +619,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
695619
}
696620
}
697621

622+
/// Allocate enough memory to store the given `OsStr` as a null-terminated sequence of bytes.
698623
fn alloc_os_str_as_c_str(
699624
&mut self,
700625
os_str: &OsStr,
@@ -709,6 +634,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
709634
arg_place.ptr.assert_ptr()
710635
}
711636

637+
/// Allocate enough memory to store the given `OsStr` as a null-terminated sequence of `u16`.
712638
fn alloc_os_str_as_wide_str(
713639
&mut self,
714640
os_str: &OsStr,
@@ -722,6 +648,82 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
722648
assert!(self.write_os_str_to_wide_str(os_str, arg_place, size).unwrap().0);
723649
arg_place.ptr.assert_ptr()
724650
}
651+
652+
/// Read a null-terminated sequence of bytes, and perform path separator conversion if needed.
653+
fn read_path_from_c_str<'a>(&'a self, scalar: Scalar<Tag>) -> InterpResult<'tcx, Cow<'a, Path>>
654+
where
655+
'tcx: 'a,
656+
'mir: 'a,
657+
{
658+
let this = self.eval_context_ref();
659+
let os_str = this.read_os_str_from_c_str(scalar)?;
660+
661+
#[cfg(windows)]
662+
return Ok(if this.tcx.sess.target.target.target_os == "windows" {
663+
// Windows-on-Windows, all fine.
664+
Cow::Borrowed(Path::new(os_str))
665+
} else {
666+
// Unix target, Windows host. Need to convert target '/' to host '\'.
667+
let converted = os_str
668+
.encode_wide()
669+
.map(|wchar| if wchar == '/' as u16 { '\\' as u16 } else { wchar })
670+
.collect::<Vec<_>>();
671+
Cow::Owned(PathBuf::from(OsString::from_wide(&converted)))
672+
});
673+
#[cfg(unix)]
674+
return Ok(if this.tcx.sess.target.target.target_os == "windows" {
675+
// Windows target, Unix host. Need to convert target '\' to host '/'.
676+
let converted = os_str
677+
.as_bytes()
678+
.iter()
679+
.map(|&wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar })
680+
.collect::<Vec<_>>();
681+
Cow::Owned(PathBuf::from(OsString::from_vec(converted)))
682+
} else {
683+
// Unix-on-Unix, all is fine.
684+
Cow::Borrowed(Path::new(os_str))
685+
});
686+
}
687+
688+
/// Write a Path to the machine memory, adjusting path separators if needed.
689+
fn write_path_to_c_str(
690+
&mut self,
691+
path: &Path,
692+
scalar: Scalar<Tag>,
693+
size: u64,
694+
) -> InterpResult<'tcx, (bool, u64)> {
695+
let this = self.eval_context_mut();
696+
697+
#[cfg(windows)]
698+
let os_str = if this.tcx.sess.target.target.target_os == "windows" {
699+
// Windows-on-Windows, all fine.
700+
Cow::Borrowed(path.as_os_str())
701+
} else {
702+
// Unix target, Windows host. Need to convert host '\\' to target '/'.
703+
let converted = path
704+
.as_os_str()
705+
.encode_wide()
706+
.map(|wchar| if wchar == '\\' as u16 { '/' as u16 } else { wchar })
707+
.collect::<Vec<_>>();
708+
Cow::Owned(OsString::from_wide(&converted))
709+
};
710+
#[cfg(unix)]
711+
let os_str = if this.tcx.sess.target.target.target_os == "windows" {
712+
// Windows target, Unix host. Need to convert host '/' to target '\'.
713+
let converted = path
714+
.as_os_str()
715+
.as_bytes()
716+
.iter()
717+
.map(|&wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar })
718+
.collect::<Vec<_>>();
719+
Cow::Owned(OsString::from_vec(converted))
720+
} else {
721+
// Unix-on-Unix, all is fine.
722+
Cow::Borrowed(path.as_os_str())
723+
};
724+
725+
this.write_os_str_to_c_str(&os_str, scalar, size)
726+
}
725727
}
726728

727729
pub fn immty_from_int_checked<'tcx>(

0 commit comments

Comments
 (0)