Rollup merge of #69326 - JOE1994:os_str_widestring, r=RalfJung
mir-interpret: add method to read wide strings from Memory
Implemented *step2* from [instructions](https://github.com/rust-lang/miri/issues/707#issuecomment-561564057) laid out in rust-lang/miri#707.
Added 2 new methods to struct `rustc_mir::interpret::InterpCx`.
* `read_os_str_from_wide_str` (src/librustc_mir/interpret/operand.rs)
* `write_os_str_to_wide_str` (src/librustc_mir/interpret/place.rs)
- used existing logic implemented in [MIRI/src/eval.rs](94732aaf7b/src/eval.rs (L132-L141)
)
These methods are intended to be used for environment variable emulation in Windows.
This commit is contained in:
commit
ff961789bc
@ -612,6 +612,11 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
|
||||
self.not_undef()?.to_u8()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_u16(self) -> InterpResult<'tcx, u16> {
|
||||
self.not_undef()?.to_u16()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_u32(self) -> InterpResult<'tcx, u32> {
|
||||
self.not_undef()?.to_u32()
|
||||
@ -632,6 +637,11 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
|
||||
self.not_undef()?.to_i8()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_i16(self) -> InterpResult<'tcx, i16> {
|
||||
self.not_undef()?.to_i16()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_i32(self) -> InterpResult<'tcx, i32> {
|
||||
self.not_undef()?.to_i32()
|
||||
|
@ -798,6 +798,33 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||
self.get_raw(ptr.alloc_id)?.read_c_str(self, ptr)
|
||||
}
|
||||
|
||||
/// Reads a 0x0000-terminated u16-sequence from memory. Returns them as a Vec<u16>.
|
||||
/// Terminator 0x0000 is not included in the returned Vec<u16>.
|
||||
///
|
||||
/// Performs appropriate bounds checks.
|
||||
pub fn read_wide_str(&self, ptr: Scalar<M::PointerTag>) -> InterpResult<'tcx, Vec<u16>> {
|
||||
let size_2bytes = Size::from_bytes(2);
|
||||
let align_2bytes = Align::from_bytes(2).unwrap();
|
||||
// We need to read at least 2 bytes, so we *need* a ptr.
|
||||
let mut ptr = self.force_ptr(ptr)?;
|
||||
let allocation = self.get_raw(ptr.alloc_id)?;
|
||||
let mut u16_seq = Vec::new();
|
||||
|
||||
loop {
|
||||
ptr = self
|
||||
.check_ptr_access(ptr.into(), size_2bytes, align_2bytes)?
|
||||
.expect("cannot be a ZST");
|
||||
let single_u16 = allocation.read_scalar(self, ptr, size_2bytes)?.to_u16()?;
|
||||
if single_u16 != 0x0000 {
|
||||
u16_seq.push(single_u16);
|
||||
ptr = ptr.offset(size_2bytes, self)?;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(u16_seq)
|
||||
}
|
||||
|
||||
/// Writes the given stream of bytes into memory.
|
||||
///
|
||||
/// Performs appropriate bounds checks.
|
||||
|
Loading…
x
Reference in New Issue
Block a user