From e9ad59d9da18793c7107f1e6cffed4214ae5ac6c Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 14 Jun 2017 17:56:45 +0300 Subject: [PATCH 1/3] memory upgrade --- src/interpreter/memory.rs | 70 +++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/src/interpreter/memory.rs b/src/interpreter/memory.rs index 7aadcae..2b8995b 100644 --- a/src/interpreter/memory.rs +++ b/src/interpreter/memory.rs @@ -18,6 +18,18 @@ pub struct MemoryInstance { maximum_size: u32, } +struct CheckedRegion<'a, B: 'a> where B: ::std::ops::Deref> { + _buffer: &'a B, + offset: usize, + size: usize, +} + +impl<'a, B: 'a> CheckedRegion<'a, B> where B: ::std::ops::Deref> { + fn range(&self) -> ::std::ops::Range { + self.offset..self.offset+self.size + } +} + impl MemoryInstance { /// Create new linear memory instance. pub fn new(memory_type: &MemoryType) -> Result, Error> { @@ -48,36 +60,18 @@ impl MemoryInstance { /// Get data at given offset. pub fn get(&self, offset: u32, size: usize) -> Result, Error> { - let begin = offset as usize; - let end = match begin.checked_add(size) { - Some(end) => end, - None => return Err(Error::Memory(format!("trying to read memory block of size {} from offset {}", size, offset))), - }; - let buffer = self.buffer.read(); - if buffer.len() < end { - return Err(Error::Memory(format!("trying to read region [{}..{}] in memory [0..{}]", begin, end, buffer.len()))); - } + let region = self.checked_region(&buffer, offset as usize, size)?; - Ok(buffer[begin..end].to_vec()) + Ok(buffer[region.range()].to_vec()) } /// Set data at given offset. pub fn set(&self, offset: u32, value: &[u8]) -> Result<(), Error> { - let size = value.len(); - let begin = offset as usize; - let end = match begin.checked_add(size) { - Some(end) => end, - None => return Err(Error::Memory(format!("trying to update memory block of size {} from offset {}", size, offset))), - }; - let mut buffer = self.buffer.write(); - if buffer.len() < end { - return Err(Error::Memory(format!("trying to update region [{}..{}] in memory [0..{}]", begin, end, buffer.len()))); - } + let range = self.checked_region(&buffer, offset as usize, value.len())?.range(); - let mut mut_buffer = buffer.as_mut_slice(); - mut_buffer[begin..end].copy_from_slice(value); + buffer[range].copy_from_slice(value); Ok(()) } @@ -96,4 +90,36 @@ impl MemoryInstance { }, } } + + fn checked_region<'a, B>(&self, buffer: &'a B, offset: usize, size: usize) -> Result, Error> + where B: ::std::ops::Deref> + { + let end = offset.checked_add(size) + .ok_or(Error::Memory(format!("trying to access memory block of size {} from offset {}", size, offset)))?; + + if end > buffer.len() { + return Err(Error::Memory(format!("trying to access region [{}..{}] in memory [0..{}]", offset, end, buffer.len()))); + } + + Ok(CheckedRegion { + _buffer: buffer, + offset: offset, + size: size, + }) + } + + pub fn copy(&self, src_offset: usize, dst_offset: usize, len: usize) -> Result<(), Error> { + let buffer = self.buffer.write(); + + let read_region = self.checked_region(&buffer, src_offset, len)?; + let write_region = self.checked_region(&buffer, dst_offset, len)?; + + unsafe { ::std::ptr::copy( + buffer[read_region.range()].as_ptr(), + buffer[write_region.range()].as_ptr() as *mut _, + len, + )} + + Ok(()) + } } From 40a07cfb75037d07f9f3b2f9a3087d5cfc463989 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 14 Jun 2017 18:00:59 +0300 Subject: [PATCH 2/3] fix warnings --- src/interpreter/memory.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/interpreter/memory.rs b/src/interpreter/memory.rs index 2b8995b..0bca676 100644 --- a/src/interpreter/memory.rs +++ b/src/interpreter/memory.rs @@ -19,7 +19,7 @@ pub struct MemoryInstance { } struct CheckedRegion<'a, B: 'a> where B: ::std::ops::Deref> { - _buffer: &'a B, + buffer: &'a B, offset: usize, size: usize, } @@ -28,6 +28,10 @@ impl<'a, B: 'a> CheckedRegion<'a, B> where B: ::std::ops::Deref> fn range(&self) -> ::std::ops::Range { self.offset..self.offset+self.size } + + fn slice(&self) -> &[u8] { + &*self.buffer + } } impl MemoryInstance { @@ -63,7 +67,7 @@ impl MemoryInstance { let buffer = self.buffer.read(); let region = self.checked_region(&buffer, offset as usize, size)?; - Ok(buffer[region.range()].to_vec()) + Ok(region.slice().to_vec()) } /// Set data at given offset. @@ -102,12 +106,13 @@ impl MemoryInstance { } Ok(CheckedRegion { - _buffer: buffer, + buffer: buffer, offset: offset, size: size, }) } + /// Copy memory region pub fn copy(&self, src_offset: usize, dst_offset: usize, len: usize) -> Result<(), Error> { let buffer = self.buffer.write(); From 4a171aef7e4006874c7817a0cbd81f0d026098b7 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 14 Jun 2017 18:09:33 +0300 Subject: [PATCH 3/3] fix range --- src/interpreter/memory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interpreter/memory.rs b/src/interpreter/memory.rs index 0bca676..1c208a7 100644 --- a/src/interpreter/memory.rs +++ b/src/interpreter/memory.rs @@ -30,7 +30,7 @@ impl<'a, B: 'a> CheckedRegion<'a, B> where B: ::std::ops::Deref> } fn slice(&self) -> &[u8] { - &*self.buffer + &self.buffer[self.range()] } }