Skip to content

Commit de3d1e9

Browse files
authoredMar 26, 2020
Rollup merge of #70397 - JOE1994:write_wide_str, r=RalfJung
add 'fn write_u16s' to Memory Added new function `Memory::write_u16s`. Needed in `MIRI` for implementing helper function to write wide_str to memory (for Windows).
2 parents b15423e + 4538f89 commit de3d1e9

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed
 

‎src/librustc_mir/interpret/memory.rs

+42-2
Original file line numberDiff line numberDiff line change
@@ -833,17 +833,57 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
833833
ptr: Scalar<M::PointerTag>,
834834
src: impl IntoIterator<Item = u8>,
835835
) -> InterpResult<'tcx> {
836-
let src = src.into_iter();
836+
let mut src = src.into_iter();
837837
let size = Size::from_bytes(src.size_hint().0);
838838
// `write_bytes` checks that this lower bound `size` matches the upper bound and reality.
839839
let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(1).unwrap())? {
840840
Some(ptr) => ptr,
841-
None => return Ok(()), // zero-sized access
841+
None => {
842+
// zero-sized access
843+
src.next().expect_none("iterator said it was empty but returned an element");
844+
return Ok(());
845+
}
842846
};
843847
let tcx = self.tcx.tcx;
844848
self.get_raw_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src)
845849
}
846850

851+
/// Writes the given stream of u16s into memory.
852+
///
853+
/// Performs appropriate bounds checks.
854+
pub fn write_u16s(
855+
&mut self,
856+
ptr: Scalar<M::PointerTag>,
857+
src: impl IntoIterator<Item = u16>,
858+
) -> InterpResult<'tcx> {
859+
let mut src = src.into_iter();
860+
let (lower, upper) = src.size_hint();
861+
let len = upper.expect("can only write bounded iterators");
862+
assert_eq!(lower, len, "can only write iterators with a precise length");
863+
864+
let size = Size::from_bytes(lower);
865+
let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(2).unwrap())? {
866+
Some(ptr) => ptr,
867+
None => {
868+
// zero-sized access
869+
src.next().expect_none("iterator said it was empty but returned an element");
870+
return Ok(());
871+
}
872+
};
873+
let tcx = self.tcx.tcx;
874+
let allocation = self.get_raw_mut(ptr.alloc_id)?;
875+
876+
for idx in 0..len {
877+
let val = Scalar::from_u16(
878+
src.next().expect("iterator was shorter than it said it would be"),
879+
);
880+
let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication
881+
allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?;
882+
}
883+
src.next().expect_none("iterator was longer than it said it would be");
884+
Ok(())
885+
}
886+
847887
/// Expects the caller to have checked bounds and alignment.
848888
pub fn copy(
849889
&mut self,

‎src/librustc_mir/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust.
2424
#![feature(range_is_empty)]
2525
#![feature(stmt_expr_attributes)]
2626
#![feature(trait_alias)]
27+
#![feature(option_expect_none)]
2728
#![recursion_limit = "256"]
2829

2930
#[macro_use]

0 commit comments

Comments
 (0)