Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Memory API #1082

Merged
merged 5 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/wasmi/benches/benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::{
sync::OnceLock,
};
use wasmi::{
core::{Pages, TrapCode, ValType, F32, F64},
core::{TrapCode, ValType, F32, F64},
CompilationMode,
Engine,
Extern,
Expand Down Expand Up @@ -1328,7 +1328,7 @@ fn bench_execute_memory_sum(c: &mut Criterion) {
.get_export(&store, "mem")
.and_then(Extern::into_memory)
.unwrap();
mem.grow(&mut store, Pages::new(1).unwrap()).unwrap();
mem.grow(&mut store, 1).unwrap();
let len = 100_000;
let mut expected_sum: i64 = 0;
for (n, byte) in &mut mem.data_mut(&mut store)[..len].iter_mut().enumerate() {
Expand Down Expand Up @@ -1360,7 +1360,7 @@ fn bench_execute_memory_fill(c: &mut Criterion) {
.get_export(&store, "mem")
.and_then(Extern::into_memory)
.unwrap();
mem.grow(&mut store, Pages::new(1).unwrap()).unwrap();
mem.grow(&mut store, 1).unwrap();
let ptr = 0x100;
let len = 100_000;
let value = 0x42_u8;
Expand Down Expand Up @@ -1470,7 +1470,7 @@ fn bench_execute_vec_add(c: &mut Criterion) {
.get_export(&store, "mem")
.and_then(Extern::into_memory)
.unwrap();
mem.grow(&mut store, Pages::new(25).unwrap()).unwrap();
mem.grow(&mut store, 1).unwrap();
let len = 100_000;
test_for(
b,
Expand Down
15 changes: 3 additions & 12 deletions crates/wasmi/src/engine/executor/instrs/memory.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use crate::{core::Pages, store::StoreInner, Store};

use super::Executor;
use crate::{
core::TrapCode,
Expand All @@ -8,8 +6,9 @@ use crate::{
code_map::InstructionPtr,
},
error::EntityGrowError,
store::ResourceLimiterRef,
store::{ResourceLimiterRef, StoreInner},
Error,
Store,
};

impl<'engine> Executor<'engine> {
Expand All @@ -35,7 +34,7 @@ impl<'engine> Executor<'engine> {
#[inline(always)]
pub fn execute_memory_size(&mut self, store: &StoreInner, result: Register) {
let memory = self.get_default_memory();
let size: u32 = store.resolve_memory(&memory).current_pages().into();
let size = store.resolve_memory(&memory).size();
self.set_register(result, size);
self.next_instr()
}
Expand Down Expand Up @@ -79,14 +78,6 @@ impl<'engine> Executor<'engine> {
self.execute_memory_size(store, result);
return Ok(());
}
let delta = match Pages::new(delta) {
Some(pages) => pages,
None => {
// Cannot grow memory so we push the expected error value.
self.set_register(result, EntityGrowError::ERROR_CODE);
return self.try_next_instr();
}
};
let memory = self.get_default_memory();
let (memory, fuel) = store.resolve_memory_and_fuel_mut(&memory);
let return_value = memory
Expand Down
4 changes: 2 additions & 2 deletions crates/wasmi/src/memory/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ use std::{slice, vec, vec::Vec};
#[derive(Debug)]
pub struct ByteBuffer {
/// The pointer to the underlying byte buffer.
ptr: *mut u8,
pub(super) ptr: *mut u8,
/// The current length of the byte buffer.
///
/// # Note
///
/// - **Vec:** `vec.len()`
/// - **Static:** The accessible subslice of the entire underlying static byte buffer.
len: usize,
pub(super) len: usize,
/// The capacity of the current allocation.
///
/// # Note
Expand Down
77 changes: 56 additions & 21 deletions crates/wasmi/src/memory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,15 @@
}

/// Returns the amount of pages in use by the linear memory.
pub fn current_pages(&self) -> Pages {
fn current_pages(&self) -> Pages {
self.current_pages
}

/// Returns the size, in WebAssembly pages, of this Wasm linear memory.
pub fn size(&self) -> u32 {
self.current_pages.into()
}

/// Grows the linear memory by the given amount of new pages.
///
/// Returns the amount of pages before the operation upon success.
Expand All @@ -237,26 +242,28 @@
/// the grow operation.
pub fn grow(
&mut self,
additional: Pages,
additional: u32,
fuel: Option<&mut Fuel>,
limiter: &mut ResourceLimiterRef<'_>,
) -> Result<Pages, EntityGrowError> {
) -> Result<u32, EntityGrowError> {
fn notify_limiter(
limiter: &mut ResourceLimiterRef<'_>,
err: EntityGrowError,
) -> Result<Pages, EntityGrowError> {
) -> Result<u32, EntityGrowError> {
if let Some(limiter) = limiter.as_resource_limiter() {
limiter.memory_grow_failed(&MemoryError::OutOfBoundsGrowth)
}
Err(err)
}

let current_pages = self.current_pages();
if additional == Pages::from(0) {
// Nothing to do in this case. Bail out early.
return Ok(current_pages);
if additional == 0 {
return Ok(self.size());

Check warning on line 260 in crates/wasmi/src/memory/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/wasmi/src/memory/mod.rs#L260

Added line #L260 was not covered by tests
}
let Some(additional) = Pages::new(additional) else {
return Err(EntityGrowError::InvalidGrow);
};

let current_pages = self.current_pages();
let maximum_pages = self.ty().maximum_pages().unwrap_or_else(Pages::max);
let desired_pages = current_pages.checked_add(additional);

Expand Down Expand Up @@ -300,7 +307,7 @@
// 3. There is enough fuel for the operation.
self.bytes.grow(new_size);
self.current_pages = new_pages;
Ok(current_pages)
Ok(u32::from(current_pages))
}

/// Returns a shared slice to the bytes underlying to the byte buffer.
Expand All @@ -313,6 +320,18 @@
self.bytes.data_mut()
}

/// Returns the base pointer, in the host’s address space, that the [`Memory`] is located at.
pub fn data_ptr(&self) -> *mut u8 {
self.bytes.ptr
}

Check warning on line 326 in crates/wasmi/src/memory/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/wasmi/src/memory/mod.rs#L324-L326

Added lines #L324 - L326 were not covered by tests

/// Returns the byte length of this [`Memory`].
///
/// The returned value will be a multiple of the wasm page size, 64k.
pub fn data_size(&self) -> usize {
self.bytes.len
}

Check warning on line 333 in crates/wasmi/src/memory/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/wasmi/src/memory/mod.rs#L331-L333

Added lines #L331 - L333 were not covered by tests

/// Reads `n` bytes from `memory[offset..offset+n]` into `buffer`
/// where `n` is the length of `buffer`.
///
Expand Down Expand Up @@ -426,17 +445,13 @@
.dynamic_ty()
}

/// Returns the amount of pages in use by the linear memory.
/// Returns the size, in WebAssembly pages, of this Wasm linear memory.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn current_pages(&self, ctx: impl AsContext) -> Pages {
ctx.as_context()
.store
.inner
.resolve_memory(self)
.current_pages()
pub fn size(&self, ctx: impl AsContext) -> u32 {
ctx.as_context().store.inner.resolve_memory(self).size()
}

/// Grows the linear memory by the given amount of new pages.
Expand All @@ -451,11 +466,7 @@
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn grow(
&self,
mut ctx: impl AsContextMut,
additional: Pages,
) -> Result<Pages, MemoryError> {
pub fn grow(&self, mut ctx: impl AsContextMut, additional: u32) -> Result<u32, MemoryError> {
let (inner, mut limiter) = ctx
.as_context_mut()
.store
Expand Down Expand Up @@ -498,6 +509,30 @@
(memory.data_mut(), store)
}

/// Returns the base pointer, in the host’s address space, that the [`Memory`] is located at.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn data_ptr(&self, ctx: impl AsContext) -> *mut u8 {
ctx.as_context().store.inner.resolve_memory(self).data_ptr()
}

/// Returns the byte length of this [`Memory`].
///
/// The returned value will be a multiple of the wasm page size, 64k.
///
/// # Panics
///
/// Panics if `ctx` does not own this [`Memory`].
pub fn data_size(&self, ctx: impl AsContext) -> usize {
ctx.as_context()
.store
.inner
.resolve_memory(self)
.data_size()
}

/// Reads `n` bytes from `memory[offset..offset+n]` into `buffer`
/// where `n` is the length of `buffer`.
///
Expand Down
Loading