Skip to content

Commit

Permalink
Add support for Wasm multi-memory proposal (#1191)
Browse files Browse the repository at this point in the history
* add Memory index type

* adjust load instructions for multi-memory proposal

* improve docs for 16-bit offset variants

* re-design store instruction for multi-memory proposal

* minor fix in store instruction docs

* adjust executor to support re-designed load instructions

* fix docs for fetch_ptr_and_offset

* adjust executor to support new and re-designed store instructions

* optionally encode Instruction::MemoryIndex after load_at instructions

* implement translation of new load instruction

* apply clippy suggestion

* apply rustfmt

* fix 32_store16_imm snake name

* teach Wasmi translator to encode the new store instruction

* update encoding docs of store_at instructions

* add multi-memory support to wasmi::Config

* support optional MemoryIndex param for store instrs in executor

* add #[inline] to fetch_optional_memory

* improve docs of TableFill instructions

* update docs for bulk memory instructions

* implement multi-memory support for bulk-memory instrs in translator and executor

* disable multi-memory for MVP test config

* fix bug in load instruction translation

* apply rustfmt

* fix memory_size translation tests

* update and fix load instruction translation tests

* fix translation of memory.grow

* update and fix memory.grow translation tests

* update and fix memory.copy translation tests

* fix and adjust memory.fill translation tests

* fix and adjust memory.init translation tests

* adjust and fix some store instruction translation tests

* add store_imm16 translation test

* update and fix remaining store translation tests

* fix bug in executor for memory.grow

* fix clippy warnings

* remove commented out code

* remove commented out code (2)

* remove outdated debug assertion

* include multi-memory spec tests

* update Wasm spec testsuite by 1 rev

* fix bug in memory.copy execution

* improve naming of locals
  • Loading branch information
Robbepop authored Sep 24, 2024
1 parent 1d98b71 commit 0b39af8
Show file tree
Hide file tree
Showing 29 changed files with 2,077 additions and 591 deletions.
848 changes: 696 additions & 152 deletions crates/ir/src/for_each_op.rs

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions crates/ir/src/immeditate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@ impl TryFrom<NonZeroU64> for AnyConst16 {
}
}

impl From<i8> for AnyConst16 {
fn from(value: i8) -> Self {
Self(value as u8 as u16 as i16)
}
}

impl From<i16> for AnyConst16 {
fn from(value: i16) -> Self {
Self(value)
Expand All @@ -460,6 +466,18 @@ impl From<u16> for AnyConst16 {
}
}

impl From<AnyConst16> for i8 {
fn from(value: AnyConst16) -> Self {
value.0 as i8
}
}

impl From<AnyConst16> for i16 {
fn from(value: AnyConst16) -> Self {
value.0
}
}

impl From<AnyConst16> for i32 {
fn from(value: AnyConst16) -> Self {
Self::from(value.0)
Expand Down
9 changes: 9 additions & 0 deletions crates/ir/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ macro_rules! for_each_index {
InternalFunc(pub(crate) u32);
/// A Wasm global variable index.
Global(pub(crate) u32);
/// A Wasm linear memory index.
Memory(pub(crate) u32);
/// A Wasm table index.
Table(pub(crate) u32);
/// A Wasm data segment index.
Expand All @@ -30,6 +32,13 @@ macro_rules! for_each_index {
};
}

impl Memory {
/// Returns `true` if `self` refers to the default linear memory which always is at index 0.
pub fn is_default(&self) -> bool {
self.0 == 0
}
}

macro_rules! define_index {
(
$(
Expand Down
3 changes: 1 addition & 2 deletions crates/ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ mod tests;

use wasmi_core as core;

use self::immeditate::AnyConst16;
#[doc(inline)]
pub use self::{
error::Error,
immeditate::{AnyConst32, Const16, Const32},
immeditate::{AnyConst16, AnyConst32, Const16, Const32},
index::Instr,
index::Reg,
primitive::{BlockFuel, BranchOffset, BranchOffset16, Comparator, ComparatorAndOffset, Sign},
Expand Down
1 change: 1 addition & 0 deletions crates/ir/src/visit_regs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl_host_visitor_for!(
Func,
FuncType,
Global,
Memory,
Table,
Elem,
Data,
Expand Down
17 changes: 16 additions & 1 deletion crates/wasmi/src/engine/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub struct Config {
saturating_float_to_int: bool,
/// Is `true` if the [`multi-value`] Wasm proposal is enabled.
multi_value: bool,
/// Is `true` if the [`multi-memory`] Wasm proposal is enabled.
multi_memory: bool,
/// Is `true` if the [`bulk-memory`] Wasm proposal is enabled.
bulk_memory: bool,
/// Is `true` if the [`reference-types`] Wasm proposal is enabled.
Expand Down Expand Up @@ -176,6 +178,7 @@ impl Default for Config {
sign_extension: true,
saturating_float_to_int: true,
multi_value: true,
multi_memory: true,
bulk_memory: true,
reference_types: true,
tail_call: true,
Expand Down Expand Up @@ -266,6 +269,18 @@ impl Config {
self
}

/// Enable or disable the [`multi-memory`] Wasm proposal for the [`Config`].
///
/// # Note
///
/// Enabled by default.
///
/// [`multi-memory`]: https://github.com/WebAssembly/multi-memory
pub fn wasm_multi_memory(&mut self, enable: bool) -> &mut Self {
self.multi_memory = enable;
self
}

/// Enable or disable the [`bulk-memory`] Wasm proposal for the [`Config`].
///
/// # Note
Expand Down Expand Up @@ -419,7 +434,7 @@ impl Config {
simd: false,
relaxed_simd: false,
threads: false,
multi_memory: false,
multi_memory: self.multi_memory,
exceptions: false,
memory64: false,
memory_control: false,
Expand Down
4 changes: 2 additions & 2 deletions crates/wasmi/src/engine/executor/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ impl CachedInstance {
///
/// It is the callers responsibility to use this method only when the caches are fresh.
#[inline]
pub unsafe fn get_memory(&self, index: u32) -> Option<Memory> {
pub unsafe fn get_memory(&self, index: index::Memory) -> Option<Memory> {
let instance = unsafe { self.as_ref() };
instance.get_memory(index)
instance.get_memory(u32::from(index))
}

/// Returns the [`Table`] at the `index` if any.
Expand Down
Loading

0 comments on commit 0b39af8

Please sign in to comment.