@@ -215,9 +215,7 @@ impl Interval {
215215 }
216216
217217 fn write_from_interval ( & self , memory : & mut Evaluator < ' _ > , interval : Interval ) -> Result < ( ) > {
218- // FIXME: this could be more efficient
219- let bytes = & interval. get ( memory) ?. to_vec ( ) ;
220- memory. write_memory ( self . addr , bytes)
218+ memory. copy_from_interval ( self . addr , interval)
221219 }
222220
223221 fn slice ( self , range : Range < usize > ) -> Interval {
@@ -1760,6 +1758,48 @@ impl Evaluator<'_> {
17601758 Ok ( ( ) )
17611759 }
17621760
1761+ fn copy_from_interval ( & mut self , addr : Address , r : Interval ) -> Result < ( ) > {
1762+ if r. size == 0 {
1763+ return Ok ( ( ) ) ;
1764+ }
1765+
1766+ let oob = || MirEvalError :: UndefinedBehavior ( "out of bounds memory write" . to_string ( ) ) ;
1767+
1768+ match ( addr, r. addr ) {
1769+ ( Stack ( dst) , Stack ( src) ) => {
1770+ if self . stack . len ( ) < src + r. size || self . stack . len ( ) < dst + r. size {
1771+ return Err ( oob ( ) ) ;
1772+ }
1773+ self . stack . copy_within ( src..src + r. size , dst)
1774+ }
1775+ ( Heap ( dst) , Heap ( src) ) => {
1776+ if self . stack . len ( ) < src + r. size || self . stack . len ( ) < dst + r. size {
1777+ return Err ( oob ( ) ) ;
1778+ }
1779+ self . heap . copy_within ( src..src + r. size , dst)
1780+ }
1781+ ( Stack ( dst) , Heap ( src) ) => {
1782+ self . stack
1783+ . get_mut ( dst..dst + r. size )
1784+ . ok_or_else ( oob) ?
1785+ . copy_from_slice ( self . heap . get ( src..src + r. size ) . ok_or_else ( oob) ?) ;
1786+ }
1787+ ( Heap ( dst) , Stack ( src) ) => {
1788+ self . heap
1789+ . get_mut ( dst..dst + r. size )
1790+ . ok_or_else ( oob) ?
1791+ . copy_from_slice ( self . stack . get ( src..src + r. size ) . ok_or_else ( oob) ?) ;
1792+ }
1793+ _ => {
1794+ return Err ( MirEvalError :: UndefinedBehavior ( format ! (
1795+ "invalid memory write at address {addr:?}"
1796+ ) ) )
1797+ }
1798+ }
1799+
1800+ Ok ( ( ) )
1801+ }
1802+
17631803 fn size_align_of ( & self , ty : & Ty , locals : & Locals ) -> Result < Option < ( usize , usize ) > > {
17641804 if let Some ( layout) = self . layout_cache . borrow ( ) . get ( ty) {
17651805 return Ok ( layout
0 commit comments