Skip to content

Commit

Permalink
add 'fn write_u16s'(rustc_mir::interpret::Memory)
Browse files Browse the repository at this point in the history
  • Loading branch information
JOE1994 committed Mar 26, 2020
1 parent e4519e2 commit 4538f89
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
44 changes: 42 additions & 2 deletions src/librustc_mir/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,17 +833,57 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
ptr: Scalar<M::PointerTag>,
src: impl IntoIterator<Item = u8>,
) -> InterpResult<'tcx> {
let src = src.into_iter();
let mut src = src.into_iter();
let size = Size::from_bytes(src.size_hint().0);
// `write_bytes` checks that this lower bound `size` matches the upper bound and reality.
let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(1).unwrap())? {
Some(ptr) => ptr,
None => return Ok(()), // zero-sized access
None => {
// zero-sized access
src.next().expect_none("iterator said it was empty but returned an element");
return Ok(());
}
};
let tcx = self.tcx.tcx;
self.get_raw_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src)
}

/// Writes the given stream of u16s into memory.
///
/// Performs appropriate bounds checks.
pub fn write_u16s(
&mut self,
ptr: Scalar<M::PointerTag>,
src: impl IntoIterator<Item = u16>,
) -> InterpResult<'tcx> {
let mut src = src.into_iter();
let (lower, upper) = src.size_hint();
let len = upper.expect("can only write bounded iterators");
assert_eq!(lower, len, "can only write iterators with a precise length");

let size = Size::from_bytes(lower);
let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(2).unwrap())? {
Some(ptr) => ptr,
None => {
// zero-sized access
src.next().expect_none("iterator said it was empty but returned an element");
return Ok(());
}
};
let tcx = self.tcx.tcx;
let allocation = self.get_raw_mut(ptr.alloc_id)?;

for idx in 0..len {
let val = Scalar::from_u16(
src.next().expect("iterator was shorter than it said it would be"),
);
let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication
allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?;
}
src.next().expect_none("iterator was longer than it said it would be");
Ok(())
}

/// Expects the caller to have checked bounds and alignment.
pub fn copy(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust.
#![feature(range_is_empty)]
#![feature(stmt_expr_attributes)]
#![feature(trait_alias)]
#![feature(option_expect_none)]
#![recursion_limit = "256"]

#[macro_use]
Expand Down

0 comments on commit 4538f89

Please sign in to comment.