@@ -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 ,
0 commit comments