mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-29 00:21:34 +00:00
Create a grow error and refactor grow impl to return result (#191)
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
use crate::error::GrowError;
|
||||
use crate::{
|
||||
error::CreationError,
|
||||
sys,
|
||||
@ -14,9 +15,9 @@ pub const DYNAMIC_GUARD_SIZE: usize = 4096;
|
||||
/// when first created. Over time, as it grows, it may reallocate to
|
||||
/// a different location and size.
|
||||
///
|
||||
/// Dynamic memories are signifigantly faster to create than static
|
||||
/// Dynamic memories are significantly faster to create than static
|
||||
/// memories and use much less virtual memory, however, they require
|
||||
/// the webassembly module to bounds-check memory accesses.
|
||||
/// the WebAssembly module to bounds-check memory accesses.
|
||||
///
|
||||
/// While, a dynamic memory could use a vector of some sort as its
|
||||
/// backing memory, we use mmap (or the platform-equivalent) to allow
|
||||
@ -65,26 +66,29 @@ impl DynamicMemory {
|
||||
self.current
|
||||
}
|
||||
|
||||
pub fn grow(&mut self, delta: Pages, local: &mut vm::LocalMemory) -> Option<Pages> {
|
||||
pub fn grow(&mut self, delta: Pages, local: &mut vm::LocalMemory) -> Result<Pages, GrowError> {
|
||||
if delta == Pages(0) {
|
||||
return Some(self.current);
|
||||
return Ok(self.current);
|
||||
}
|
||||
|
||||
let new_pages = self.current.checked_add(delta)?;
|
||||
let new_pages = self.current.checked_add(delta).map_err(|e| e.into())?;
|
||||
|
||||
if let Some(max) = self.max {
|
||||
if new_pages > max {
|
||||
return None;
|
||||
return Err(GrowError::ExceededMaxPagesForMemory(
|
||||
new_pages.0 as usize,
|
||||
max.0 as usize,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let mut new_memory =
|
||||
sys::Memory::with_size(new_pages.bytes().0 + DYNAMIC_GUARD_SIZE).ok()?;
|
||||
let mut new_memory = sys::Memory::with_size(new_pages.bytes().0 + DYNAMIC_GUARD_SIZE)
|
||||
.map_err(|e| e.into())?;
|
||||
|
||||
unsafe {
|
||||
new_memory
|
||||
.protect(0..new_pages.bytes().0, sys::Protect::ReadWrite)
|
||||
.ok()?;
|
||||
.map_err(|e| e.into())?;
|
||||
|
||||
new_memory.as_slice_mut()[..self.current.bytes().0]
|
||||
.copy_from_slice(&self.memory.as_slice()[..self.current.bytes().0]);
|
||||
@ -97,7 +101,7 @@ impl DynamicMemory {
|
||||
|
||||
let old_pages = self.current;
|
||||
self.current = new_pages;
|
||||
Some(old_pages)
|
||||
Ok(old_pages)
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
error::CreationError,
|
||||
error::{CreationError, GrowError},
|
||||
export::Export,
|
||||
import::IsExport,
|
||||
memory::dynamic::DYNAMIC_GUARD_SIZE,
|
||||
@ -89,8 +89,8 @@ impl Memory {
|
||||
self.desc
|
||||
}
|
||||
|
||||
/// Grow this memory by the specfied number of pages.
|
||||
pub fn grow(&self, delta: Pages) -> Option<Pages> {
|
||||
/// Grow this memory by the specified number of pages.
|
||||
pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> {
|
||||
match &self.variant {
|
||||
MemoryVariant::Unshared(unshared_mem) => unshared_mem.grow(delta),
|
||||
MemoryVariant::Shared(shared_mem) => shared_mem.grow(delta),
|
||||
@ -244,7 +244,7 @@ impl UnsharedMemory {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn grow(&self, delta: Pages) -> Option<Pages> {
|
||||
pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> {
|
||||
let mut storage = self.internal.storage.borrow_mut();
|
||||
|
||||
let mut local = self.internal.local.get();
|
||||
@ -292,7 +292,7 @@ impl SharedMemory {
|
||||
Ok(Self { desc })
|
||||
}
|
||||
|
||||
pub fn grow(&self, _delta: Pages) -> Option<Pages> {
|
||||
pub fn grow(&self, _delta: Pages) -> Result<Pages, GrowError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::error::GrowError;
|
||||
use crate::{
|
||||
error::CreationError,
|
||||
memory::static_::{SAFE_STATIC_GUARD_SIZE, SAFE_STATIC_HEAP_SIZE},
|
||||
@ -61,27 +62,30 @@ impl StaticMemory {
|
||||
self.current
|
||||
}
|
||||
|
||||
pub fn grow(&mut self, delta: Pages, local: &mut vm::LocalMemory) -> Option<Pages> {
|
||||
pub fn grow(&mut self, delta: Pages, local: &mut vm::LocalMemory) -> Result<Pages, GrowError> {
|
||||
if delta == Pages(0) {
|
||||
return Some(self.current);
|
||||
return Ok(self.current);
|
||||
}
|
||||
|
||||
let new_pages = self.current.checked_add(delta)?;
|
||||
let new_pages = self.current.checked_add(delta).map_err(|e| e.into())?;
|
||||
|
||||
if let Some(max) = self.max {
|
||||
if new_pages > max {
|
||||
return None;
|
||||
return Err(GrowError::ExceededMaxPagesForMemory(
|
||||
new_pages.0 as usize,
|
||||
max.0 as usize,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let _ = unsafe {
|
||||
self.memory
|
||||
.protect(
|
||||
self.current.bytes().0..new_pages.bytes().0,
|
||||
sys::Protect::ReadWrite,
|
||||
)
|
||||
.ok()?;
|
||||
}
|
||||
.map_err(|e| e.into())
|
||||
}?;
|
||||
|
||||
local.bound = new_pages.bytes().0;
|
||||
|
||||
@ -89,7 +93,7 @@ impl StaticMemory {
|
||||
|
||||
self.current = new_pages;
|
||||
|
||||
Some(old_pages)
|
||||
Ok(old_pages)
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
|
Reference in New Issue
Block a user