diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-03-26 21:44:03 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-26 21:44:03 +0100 |
| commit | de3d1e9fa9743db0e99ea41b9c0b127b19d1bbbb (patch) | |
| tree | 73cc7e0620d17fd8c2cf255b1fe7ed30c0745272 /src | |
| parent | b15423e72e48125a40a3192c2d49a48e54b5c314 (diff) | |
| parent | 4538f8953b3395dd0eac5acae2f2782d89370aff (diff) | |
| download | rust-de3d1e9fa9743db0e99ea41b9c0b127b19d1bbbb.tar.gz rust-de3d1e9fa9743db0e99ea41b9c0b127b19d1bbbb.zip | |
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).
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_mir/interpret/memory.rs | 44 | ||||
| -rw-r--r-- | src/librustc_mir/lib.rs | 1 |
2 files changed, 43 insertions, 2 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 8437399752e..7b6de4b0726 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -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, diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 7d3aba3ff03..85e44adc30b 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -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] |
