Create a grow error and refactor grow impl to return result (#191)

This commit is contained in:
Mackenzie Clark
2019-02-22 22:18:59 -08:00
committed by GitHub
parent fa596d2d23
commit 82eef13f41
13 changed files with 250 additions and 112 deletions

2
Cargo.lock generated
View File

@ -1197,7 +1197,7 @@ dependencies = [
[[package]] [[package]]
name = "wasmer" name = "wasmer"
version = "0.1.4" version = "0.2.0"
dependencies = [ dependencies = [
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -208,15 +208,14 @@ pub extern "C" fn wasmer_memory_grow(
delta: uint32_t, delta: uint32_t,
) -> wasmer_result_t { ) -> wasmer_result_t {
let memory = unsafe { &*(memory as *mut Memory) }; let memory = unsafe { &*(memory as *mut Memory) };
let maybe_delta = memory.grow(Pages(delta)); let delta_result = memory.grow(Pages(delta));
if let Some(_delta) = maybe_delta { match delta_result {
wasmer_result_t::WASMER_OK Ok(_) => wasmer_result_t::WASMER_OK,
} else { Err(grow_error) => {
update_last_error(CApiError { update_last_error(grow_error);
msg: "unable to grow memory".to_string(),
});
wasmer_result_t::WASMER_ERROR wasmer_result_t::WASMER_ERROR
} }
}
} }
/// Returns the current length in pages of the given memory /// Returns the current length in pages of the given memory
@ -277,15 +276,14 @@ pub extern "C" fn wasmer_table_grow(
delta: uint32_t, delta: uint32_t,
) -> wasmer_result_t { ) -> wasmer_result_t {
let table = unsafe { &*(table as *mut Table) }; let table = unsafe { &*(table as *mut Table) };
let maybe_delta = table.grow(delta); let delta_result = table.grow(delta);
if let Some(_delta) = maybe_delta { match delta_result {
wasmer_result_t::WASMER_OK Ok(_) => wasmer_result_t::WASMER_OK,
} else { Err(grow_error) => {
update_last_error(CApiError { update_last_error(grow_error);
msg: "unable to grow table".to_string(),
});
wasmer_result_t::WASMER_ERROR wasmer_result_t::WASMER_ERROR
} }
}
} }
/// Returns the current length of the given Table /// Returns the current length of the given Table

View File

@ -38,23 +38,26 @@ int main()
char *error_str = malloc(error_len); char *error_str = malloc(error_len);
wasmer_last_error_message(error_str, error_len); wasmer_last_error_message(error_str, error_len);
printf("Error str: `%s`\n", error_str); printf("Error str: `%s`\n", error_str);
assert(0 == strcmp(error_str, "unable to grow memory")); assert(0 == strcmp(error_str, "Failed to add pages because would exceed maximum number of pages for the memory. Left: 22, Added: 15"));
free(error_str); free(error_str);
wasmer_memory_t *bad_memory = NULL;
wasmer_limits_t bad_descriptor;
bad_descriptor.min = 15;
wasmer_limit_option_t max2;
max2.has_some = true;
max2.some = 10;
bad_descriptor.max = max2;
wasmer_result_t bad_memory_result = wasmer_memory_new(&bad_memory, bad_descriptor);
printf("Bad memory result: %d\n", bad_memory_result);
assert(bad_memory_result == WASMER_ERROR);
// wasmer_memory_t *bad_memory = NULL; int error_len2 = wasmer_last_error_length();
// wasmer_limits_t bad_descriptor; char *error_str2 = malloc(error_len2);
// bad_descriptor.min = 15; wasmer_last_error_message(error_str2, error_len2);
// bad_descriptor.max = 10; printf("Error str 2: `%s`\n", error_str2);
// wasmer_result_t bad_memory_result = wasmer_memory_new(&bad_memory, bad_descriptor); assert(0 == strcmp(error_str2, "Unable to create because the supplied descriptor is invalid: \"Max number of memory pages is less than the minimum number of pages\""));
// printf("Bad memory result: %d\n", bad_memory_result); free(error_str2);
// assert(memory_result == WASMER_MEMORY_ERROR);
//
// int error_len = wasmer_last_error_length();
// char *error_str = malloc(error_len);
// wasmer_last_error_message(error_str, error_len);
// assert(0 == strcmp(error_str, "Creation error"));
// free(error_str);
printf("Destroy memory\n"); printf("Destroy memory\n");
wasmer_memory_destroy(memory); wasmer_memory_destroy(memory);

View File

@ -9,7 +9,7 @@ int main()
wasmer_limits_t descriptor; wasmer_limits_t descriptor;
descriptor.min = 10; descriptor.min = 10;
wasmer_limit_option_t max; wasmer_limit_option_t max;
// max.has_some = false; // max.has_some = false;
max.has_some = true; max.has_some = true;
max.some = 15; max.some = 15;
descriptor.max = max; descriptor.max = max;
@ -21,26 +21,29 @@ int main()
printf("Table length: %d\n", len); printf("Table length: %d\n", len);
assert(len == 10); assert(len == 10);
// wasmer_result_t grow_result1 = wasmer_table_grow(table, 5); wasmer_result_t grow_result1 = wasmer_table_grow(table, 5);
// assert(grow_result1 == WASMER_OK); assert(grow_result1 == WASMER_OK);
// uint32_t len_grow1 = wasmer_table_length(table); uint32_t len_grow1 = wasmer_table_length(table);
// printf("Table length: %d\n", len_grow1); printf("Table length: %d\n", len_grow1);
// assert(len_grow1 == 15); assert(len_grow1 == 15);
// // Try to grow beyond max // Try to grow beyond max
// wasmer_result_t grow_result2 = wasmer_table_grow(&table, 1); wasmer_result_t grow_result2 = wasmer_table_grow(table, 1);
// assert(grow_result2 == WASMER_ERROR); assert(grow_result2 == WASMER_ERROR);
// uint32_t len_grow2 = wasmer_table_length(table); uint32_t len_grow2 = wasmer_table_length(table);
// printf("Table length: %d\n", len_grow2); printf("Table length: %d\n", len_grow2);
// assert(len_grow2 == 15); assert(len_grow2 == 15);
// wasmer_table_t *table_bad = NULL; wasmer_table_t *table_bad = NULL;
// wasmer_limits_t bad_descriptor; wasmer_limits_t bad_descriptor;
// bad_descriptor.min = 15; bad_descriptor.min = 15;
// bad_descriptor.max = 10; wasmer_limit_option_t max2;
// wasmer_result_t table_bad_result = wasmer_table_new(&table_bad, bad_descriptor); max2.has_some = true;
// printf("Table result: %d\n", table_bad_result); max2.some = 10;
// assert(table_result == WASMER_ERROR); bad_descriptor.max = max2;
wasmer_result_t table_bad_result = wasmer_table_new(&table_bad, bad_descriptor);
printf("Table result: %d\n", table_bad_result);
assert(table_bad_result == WASMER_ERROR);
printf("Destroy table\n"); printf("Destroy table\n");
wasmer_table_destroy(table); wasmer_table_destroy(table);

View File

@ -1,3 +1,4 @@
use crate::sys::Memory;
use crate::types::{ use crate::types::{
FuncSig, GlobalDescriptor, MemoryDescriptor, MemoryIndex, TableDescriptor, TableIndex, Type, FuncSig, GlobalDescriptor, MemoryDescriptor, MemoryIndex, TableDescriptor, TableIndex, Type,
}; };
@ -369,3 +370,105 @@ impl std::fmt::Display for Error {
} }
impl std::error::Error for Error {} impl std::error::Error for Error {}
#[derive(Debug)]
pub enum GrowError {
MemoryGrowError,
TableGrowError,
ExceededMaxPages(PageError),
ExceededMaxPagesForMemory(usize, usize),
CouldNotProtectMemory(MemoryProtectionError),
CouldNotCreateMemory(MemoryCreationError),
}
impl std::fmt::Display for GrowError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
GrowError::MemoryGrowError => write!(f, "Unable to grow memory"),
GrowError::TableGrowError => write!(f, "Unable to grow table"),
GrowError::ExceededMaxPages(e) => write!(f, "Grow Error: {}", e),
GrowError::ExceededMaxPagesForMemory(left, added) => write!(f, "Failed to add pages because would exceed maximum number of pages for the memory. Left: {}, Added: {}", left, added),
GrowError::CouldNotCreateMemory(e) => write!(f, "Grow Error: {}", e),
GrowError::CouldNotProtectMemory(e) => write!(f, "Grow Error: {}", e),
}
}
}
impl std::error::Error for GrowError {}
#[derive(Debug)]
pub enum PageError {
// left, right, added
ExceededMaxPages(usize, usize, usize),
}
impl std::fmt::Display for PageError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
PageError::ExceededMaxPages(left, right, added) => write!(f, "Failed to add pages because would exceed maximum number of pages. Left: {}, Right: {}, Pages added: {}", left, right, added),
}
}
}
impl std::error::Error for PageError {}
impl Into<GrowError> for PageError {
fn into(self) -> GrowError {
GrowError::ExceededMaxPages(self)
}
}
#[derive(Debug)]
pub enum MemoryCreationError {
VirtualMemoryAllocationFailed(usize, String),
CouldNotCreateMemoryFromFile(std::io::Error),
}
impl std::fmt::Display for MemoryCreationError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
MemoryCreationError::VirtualMemoryAllocationFailed(size, msg) => write!(
f,
"Allocation virtual memory with size {} failed. \nErrno message: {}",
size, msg
),
MemoryCreationError::CouldNotCreateMemoryFromFile(e) => write!(f, "IO Error: {}", e),
}
}
}
impl std::error::Error for MemoryCreationError {}
impl Into<GrowError> for MemoryCreationError {
fn into(self) -> GrowError {
GrowError::CouldNotCreateMemory(self)
}
}
impl From<std::io::Error> for MemoryCreationError {
fn from(io_error: std::io::Error) -> Self {
MemoryCreationError::CouldNotCreateMemoryFromFile(io_error)
}
}
#[derive(Debug)]
pub enum MemoryProtectionError {
ProtectionFailed(usize, usize, String),
}
impl std::fmt::Display for MemoryProtectionError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
MemoryProtectionError::ProtectionFailed(start, size, msg) => write!(
f,
"Allocation virtual memory starting at {} with size {} failed. \nErrno message: {}",
start, size, msg
),
}
}
}
impl std::error::Error for MemoryProtectionError {}
impl Into<GrowError> for MemoryProtectionError {
fn into(self) -> GrowError {
GrowError::CouldNotProtectMemory(self)
}
}

View File

@ -1,3 +1,4 @@
use crate::error::GrowError;
use crate::{ use crate::{
error::CreationError, error::CreationError,
sys, sys,
@ -14,9 +15,9 @@ pub const DYNAMIC_GUARD_SIZE: usize = 4096;
/// when first created. Over time, as it grows, it may reallocate to /// when first created. Over time, as it grows, it may reallocate to
/// a different location and size. /// 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 /// 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 /// While, a dynamic memory could use a vector of some sort as its
/// backing memory, we use mmap (or the platform-equivalent) to allow /// backing memory, we use mmap (or the platform-equivalent) to allow
@ -65,26 +66,29 @@ impl DynamicMemory {
self.current 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) { 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 let Some(max) = self.max {
if new_pages > max { if new_pages > max {
return None; return Err(GrowError::ExceededMaxPagesForMemory(
new_pages.0 as usize,
max.0 as usize,
));
} }
} }
let mut new_memory = let mut new_memory = sys::Memory::with_size(new_pages.bytes().0 + DYNAMIC_GUARD_SIZE)
sys::Memory::with_size(new_pages.bytes().0 + DYNAMIC_GUARD_SIZE).ok()?; .map_err(|e| e.into())?;
unsafe { unsafe {
new_memory new_memory
.protect(0..new_pages.bytes().0, sys::Protect::ReadWrite) .protect(0..new_pages.bytes().0, sys::Protect::ReadWrite)
.ok()?; .map_err(|e| e.into())?;
new_memory.as_slice_mut()[..self.current.bytes().0] new_memory.as_slice_mut()[..self.current.bytes().0]
.copy_from_slice(&self.memory.as_slice()[..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; let old_pages = self.current;
self.current = new_pages; self.current = new_pages;
Some(old_pages) Ok(old_pages)
} }
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
error::CreationError, error::{CreationError, GrowError},
export::Export, export::Export,
import::IsExport, import::IsExport,
memory::dynamic::DYNAMIC_GUARD_SIZE, memory::dynamic::DYNAMIC_GUARD_SIZE,
@ -89,8 +89,8 @@ impl Memory {
self.desc self.desc
} }
/// Grow this memory by the specfied number of pages. /// Grow this memory by the specified number of pages.
pub fn grow(&self, delta: Pages) -> Option<Pages> { pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> {
match &self.variant { match &self.variant {
MemoryVariant::Unshared(unshared_mem) => unshared_mem.grow(delta), MemoryVariant::Unshared(unshared_mem) => unshared_mem.grow(delta),
MemoryVariant::Shared(shared_mem) => shared_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 storage = self.internal.storage.borrow_mut();
let mut local = self.internal.local.get(); let mut local = self.internal.local.get();
@ -292,7 +292,7 @@ impl SharedMemory {
Ok(Self { desc }) Ok(Self { desc })
} }
pub fn grow(&self, _delta: Pages) -> Option<Pages> { pub fn grow(&self, _delta: Pages) -> Result<Pages, GrowError> {
unimplemented!() unimplemented!()
} }

View File

@ -1,3 +1,4 @@
use crate::error::GrowError;
use crate::{ use crate::{
error::CreationError, error::CreationError,
memory::static_::{SAFE_STATIC_GUARD_SIZE, SAFE_STATIC_HEAP_SIZE}, memory::static_::{SAFE_STATIC_GUARD_SIZE, SAFE_STATIC_HEAP_SIZE},
@ -61,27 +62,30 @@ impl StaticMemory {
self.current 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) { 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 let Some(max) = self.max {
if new_pages > 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 self.memory
.protect( .protect(
self.current.bytes().0..new_pages.bytes().0, self.current.bytes().0..new_pages.bytes().0,
sys::Protect::ReadWrite, sys::Protect::ReadWrite,
) )
.ok()?; .map_err(|e| e.into())
} }?;
local.bound = new_pages.bytes().0; local.bound = new_pages.bytes().0;
@ -89,7 +93,7 @@ impl StaticMemory {
self.current = new_pages; self.current = new_pages;
Some(old_pages) Ok(old_pages)
} }
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {

View File

@ -1,3 +1,5 @@
use crate::error::MemoryCreationError;
use crate::error::MemoryProtectionError;
use errno; use errno;
use nix::libc; use nix::libc;
use page_size; use page_size;
@ -16,13 +18,13 @@ pub struct Memory {
} }
impl Memory { impl Memory {
pub fn from_file_path<P>(path: P, protection: Protect) -> Result<Self, String> pub fn from_file_path<P>(path: P, protection: Protect) -> Result<Self, MemoryCreationError>
where where
P: AsRef<Path>, P: AsRef<Path>,
{ {
let file = File::open(path).map_err(|e| e.to_string())?; let file = File::open(path)?;
let file_len = file.metadata().map_err(|e| e.to_string())?.len(); let file_len = file.metadata()?.len();
let raw_fd = RawFd::from_file(file); let raw_fd = RawFd::from_file(file);
@ -38,7 +40,10 @@ impl Memory {
}; };
if ptr == -1 as _ { if ptr == -1 as _ {
Err(errno::errno().to_string()) Err(MemoryCreationError::VirtualMemoryAllocationFailed(
file_len as usize,
errno::errno().to_string(),
))
} else { } else {
Ok(Self { Ok(Self {
ptr: ptr as *mut u8, ptr: ptr as *mut u8,
@ -84,7 +89,7 @@ impl Memory {
} }
} }
pub fn with_size(size: usize) -> Result<Self, String> { pub fn with_size(size: usize) -> Result<Self, MemoryCreationError> {
if size == 0 { if size == 0 {
return Ok(Self { return Ok(Self {
ptr: ptr::null_mut(), ptr: ptr::null_mut(),
@ -108,7 +113,10 @@ impl Memory {
}; };
if ptr == -1 as _ { if ptr == -1 as _ {
Err(errno::errno().to_string()) Err(MemoryCreationError::VirtualMemoryAllocationFailed(
size,
errno::errno().to_string(),
))
} else { } else {
Ok(Self { Ok(Self {
ptr: ptr as *mut u8, ptr: ptr as *mut u8,
@ -123,7 +131,7 @@ impl Memory {
&mut self, &mut self,
range: impl RangeBounds<usize>, range: impl RangeBounds<usize>,
protection: Protect, protection: Protect,
) -> Result<(), String> { ) -> Result<(), MemoryProtectionError> {
let protect = protection.to_protect_const(); let protect = protection.to_protect_const();
let range_start = match range.start_bound() { let range_start = match range.start_bound() {
@ -147,7 +155,11 @@ impl Memory {
let success = libc::mprotect(start as _, size, protect as i32); let success = libc::mprotect(start as _, size, protect as i32);
if success == -1 { if success == -1 {
Err(errno::errno().to_string()) Err(MemoryProtectionError::ProtectionFailed(
start as usize,
size,
errno::errno().to_string(),
))
} else { } else {
self.protection = protection; self.protection = protection;
Ok(()) Ok(())

View File

@ -1,3 +1,5 @@
use crate::error::MemoryCreationError;
use crate::error::MemoryProtectionError;
use page_size; use page_size;
use std::ops::{Bound, RangeBounds}; use std::ops::{Bound, RangeBounds};
use std::{ptr, slice}; use std::{ptr, slice};
@ -44,7 +46,7 @@ impl Memory {
} }
} }
pub fn with_size(size: usize) -> Result<Self, String> { pub fn with_size(size: usize) -> Result<Self, MemoryCreationError> {
if size == 0 { if size == 0 {
return Ok(Self { return Ok(Self {
ptr: ptr::null_mut(), ptr: ptr::null_mut(),
@ -58,7 +60,10 @@ impl Memory {
let ptr = unsafe { VirtualAlloc(ptr::null_mut(), size, MEM_RESERVE, PAGE_NOACCESS) }; let ptr = unsafe { VirtualAlloc(ptr::null_mut(), size, MEM_RESERVE, PAGE_NOACCESS) };
if ptr.is_null() { if ptr.is_null() {
Err("unable to allocate memory".to_string()) Err(MemoryCreationError::VirtualMemoryAllocationFailed(
size,
"unable to allocate memory".to_string(),
))
} else { } else {
Ok(Self { Ok(Self {
ptr: ptr as *mut u8, ptr: ptr as *mut u8,
@ -72,7 +77,7 @@ impl Memory {
&mut self, &mut self,
range: impl RangeBounds<usize>, range: impl RangeBounds<usize>,
protect: Protect, protect: Protect,
) -> Result<(), String> { ) -> Result<(), MemoryProtectionError> {
let protect_const = protect.to_protect_const(); let protect_const = protect.to_protect_const();
let range_start = match range.start_bound() { let range_start = match range.start_bound() {
@ -98,7 +103,11 @@ impl Memory {
let ptr = VirtualAlloc(start as _, size, MEM_COMMIT, protect_const); let ptr = VirtualAlloc(start as _, size, MEM_COMMIT, protect_const);
if ptr.is_null() { if ptr.is_null() {
Err("unable to protect memory".to_string()) Err(MemoryProtectionError::ProtectionFailed(
start as usize,
size,
"unable to protect memory".to_string(),
))
} else { } else {
self.protection = protect; self.protection = protect;
Ok(()) Ok(())

View File

@ -11,6 +11,7 @@ mod anyfunc;
pub use self::anyfunc::Anyfunc; pub use self::anyfunc::Anyfunc;
use self::anyfunc::AnyfuncTable; use self::anyfunc::AnyfuncTable;
use crate::error::GrowError;
pub enum Element<'a> { pub enum Element<'a> {
Anyfunc(Anyfunc<'a>), Anyfunc(Anyfunc<'a>),
@ -108,15 +109,15 @@ impl Table {
} }
/// Grow this table by `delta`. /// Grow this table by `delta`.
pub fn grow(&self, delta: u32) -> Option<u32> { pub fn grow(&self, delta: u32) -> Result<u32, GrowError> {
if delta == 0 { if delta == 0 {
return Some(self.size()); return Ok(self.size());
} }
match &mut *self.storage.borrow_mut() { match &mut *self.storage.borrow_mut() {
(TableStorage::Anyfunc(ref mut anyfunc_table), ref mut local) => { (TableStorage::Anyfunc(ref mut anyfunc_table), ref mut local) => anyfunc_table
anyfunc_table.grow(delta, local) .grow(delta, local)
} .ok_or(GrowError::TableGrowError),
} }
} }

View File

@ -1,3 +1,4 @@
use crate::error::PageError;
use std::{ use std::{
fmt, fmt,
ops::{Add, Sub}, ops::{Add, Sub},
@ -11,12 +12,16 @@ const WASM_MAX_PAGES: usize = 65_536;
pub struct Pages(pub u32); pub struct Pages(pub u32);
impl Pages { impl Pages {
pub fn checked_add(self, rhs: Pages) -> Option<Pages> { pub fn checked_add(self, rhs: Pages) -> Result<Pages, PageError> {
let added = (self.0 as usize) + (rhs.0 as usize); let added = (self.0 as usize) + (rhs.0 as usize);
if added <= WASM_MAX_PAGES { if added <= WASM_MAX_PAGES {
Some(Pages(added as u32)) Ok(Pages(added as u32))
} else { } else {
None Err(PageError::ExceededMaxPages(
self.0 as usize,
rhs.0 as usize,
added,
))
} }
} }

View File

@ -20,10 +20,9 @@ pub unsafe extern "C" fn local_static_memory_grow(
let local_memory = *ctx.memories.add(memory_index.index()); let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory; let memory = (*local_memory).memory as *mut StaticMemory;
if let Some(old) = (*memory).grow(delta, &mut *local_memory) { match (*memory).grow(delta, &mut *local_memory) {
old.0 as i32 Ok(old) => old.0 as i32,
} else { Err(_) => -1,
-1
} }
} }
@ -45,10 +44,9 @@ pub unsafe extern "C" fn local_dynamic_memory_grow(
let local_memory = *ctx.memories.add(memory_index.index()); let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory; let memory = (*local_memory).memory as *mut DynamicMemory;
if let Some(old) = (*memory).grow(delta, &mut *local_memory) { match (*memory).grow(delta, &mut *local_memory) {
old.0 as i32 Ok(old) => old.0 as i32,
} else { Err(_) => -1,
-1
} }
} }
@ -74,10 +72,9 @@ pub unsafe extern "C" fn imported_static_memory_grow(
let local_memory = *ctx.imported_memories.add(import_memory_index.index()); let local_memory = *ctx.imported_memories.add(import_memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory; let memory = (*local_memory).memory as *mut StaticMemory;
if let Some(old) = (*memory).grow(delta, &mut *local_memory) { match (*memory).grow(delta, &mut *local_memory) {
old.0 as i32 Ok(old) => old.0 as i32,
} else { Err(_) => -1,
-1
} }
} }
@ -99,10 +96,9 @@ pub unsafe extern "C" fn imported_dynamic_memory_grow(
let local_memory = *ctx.imported_memories.add(memory_index.index()); let local_memory = *ctx.imported_memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory; let memory = (*local_memory).memory as *mut DynamicMemory;
if let Some(old) = (*memory).grow(delta, &mut *local_memory) { match (*memory).grow(delta, &mut *local_memory) {
old.0 as i32 Ok(old) => old.0 as i32,
} else { Err(_) => -1,
-1
} }
} }