@@ -833,17 +833,57 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
833
833
ptr : Scalar < M :: PointerTag > ,
834
834
src : impl IntoIterator < Item = u8 > ,
835
835
) -> InterpResult < ' tcx > {
836
- let src = src. into_iter ( ) ;
836
+ let mut src = src. into_iter ( ) ;
837
837
let size = Size :: from_bytes ( src. size_hint ( ) . 0 ) ;
838
838
// `write_bytes` checks that this lower bound `size` matches the upper bound and reality.
839
839
let ptr = match self . check_ptr_access ( ptr, size, Align :: from_bytes ( 1 ) . unwrap ( ) ) ? {
840
840
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
+ }
842
846
} ;
843
847
let tcx = self . tcx . tcx ;
844
848
self . get_raw_mut ( ptr. alloc_id ) ?. write_bytes ( & tcx, ptr, src)
845
849
}
846
850
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
+
847
887
/// Expects the caller to have checked bounds and alignment.
848
888
pub fn copy (
849
889
& mut self ,
0 commit comments