Skip to content

Commit

Permalink
Support multi-memory proposal
Browse files Browse the repository at this point in the history
Multiple memories were already supported in new instructions which have corresponding placeholders, but the part that needs to treat old load/store instructions as bitflags will require an explicit feature flag for now as it might be subject to change.
  • Loading branch information
RReverser committed Jan 20, 2024
1 parent 8cfb491 commit b43465d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 4 deletions.
9 changes: 8 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,16 @@ once_cell = "1.19.0"

[features]
default = []
proposals = ["exception-handling", "extended-name-section", "tail-call", "threads"]
proposals = [
"exception-handling",
"extended-name-section",
"multi-memory",
"tail-call",
"threads",
]
exception-handling = []
extended-name-section = []
multi-memory = []
tail-call = []
threads = []
nightly = []
Expand Down
39 changes: 38 additions & 1 deletion src/instructions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,49 @@ pub type Expression = Vec<Instruction>;
impl crate::builtins::WasmbinCountable for Expression {}

/// [Memory immediate argument](https://webassembly.github.io/spec/core/binary/instructions.html#memory-instructions).
#[derive(Wasmbin, Debug, PartialEq, Eq, Hash, Clone, Visit)]
#[derive(Debug, PartialEq, Eq, Hash, Clone, Visit)]
#[cfg_attr(not(feature = "multi-memory"), derive(Wasmbin))]
pub struct MemArg {
pub align_log2: u32,
#[cfg(feature = "multi-memory")]
pub memory: MemId,
pub offset: u32,
}

#[cfg(feature = "multi-memory")]
const _: () = {
const MULTI_MEMORY_FLAG: u32 = 1 << 6;

impl Encode for MemArg {
fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
if self.memory.index != 0 {
(self.align_log2 | MULTI_MEMORY_FLAG).encode(w)?;
self.memory.encode(w)?;
} else {
self.align_log2.encode(w)?;
}
self.offset.encode(w)
}
}

impl Decode for MemArg {
fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
let mut align_log2 = u32::decode(r)?;
let memory = if align_log2 & MULTI_MEMORY_FLAG != 0 {
align_log2 &= !MULTI_MEMORY_FLAG;
MemId::decode(r)?
} else {
MemId::from(0)
};
Ok(Self {
align_log2,
memory,
offset: u32::decode(r)?,
})
}
}
};

/// An [indirect call](https://webassembly.github.io/spec/core/binary/instructions.html#control-instructions).
#[derive(Wasmbin, Debug, PartialEq, Eq, Hash, Clone, Visit)]
pub struct CallIndirect {
Expand Down
13 changes: 11 additions & 2 deletions src/instructions/threads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,25 @@
// limitations under the License.

use super::MemArg;
#[cfg(feature = "multi-memory")]
use crate::instructions::MemId;
use crate::io::{Decode, DecodeError, Encode, Wasmbin};
use crate::visit::Visit;

/// Variant of [`MemArg`] with a fixed compile-time alignment.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Visit)]
#[repr(transparent)]
pub struct AlignedMemArg<const ALIGN_LOG2: u32> {
#[cfg(feature = "multi-memory")]
pub memory: MemId,
pub offset: u32,
}

impl<const ALIGN_LOG2: u32> From<AlignedMemArg<ALIGN_LOG2>> for MemArg {
fn from(arg: AlignedMemArg<ALIGN_LOG2>) -> MemArg {
MemArg {
align_log2: ALIGN_LOG2,
#[cfg(feature = "multi-memory")]
memory: arg.memory,
offset: arg.offset,
}
}
Expand All @@ -44,7 +49,11 @@ impl<const ALIGN_LOG2: u32> Decode for AlignedMemArg<ALIGN_LOG2> {
if arg.align_log2 != ALIGN_LOG2 {
return Err(DecodeError::unsupported_discriminant::<Self>(arg.offset));
}
Ok(Self { offset: arg.offset })
Ok(Self {
#[cfg(feature = "multi-memory")]
memory: arg.memory,
offset: arg.offset,
})
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ impl Tests {
}

read_proposal_tests!(? "exception-handling");
read_proposal_tests!(? "multi-memory");
read_proposal_tests!(? "tail-call");
read_proposal_tests!(? "threads");

Expand Down

0 comments on commit b43465d

Please sign in to comment.