Skip to content

Commit

Permalink
Add experimental memory.discard instruction (#882)
Browse files Browse the repository at this point in the history
  • Loading branch information
bvisness authored Jan 20, 2023
1 parent 9a51f6d commit 398b367
Show file tree
Hide file tree
Showing 14 changed files with 56 additions and 1 deletion.
6 changes: 6 additions & 0 deletions crates/wasm-encoder/src/core/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ pub enum Instruction<'a> {
DataDrop(u32),
MemoryCopy { src_mem: u32, dst_mem: u32 },
MemoryFill(u32),
MemoryDiscard(u32),

// Numeric instructions.
I32Const(i32),
Expand Down Expand Up @@ -1092,6 +1093,11 @@ impl Encode for Instruction<'_> {
sink.push(0x0b);
mem.encode(sink);
}
Instruction::MemoryDiscard(mem) => {
sink.push(0xfc);
sink.push(0x12);
mem.encode(sink);
}

// Numeric instructions.
Instruction::I32Const(x) => {
Expand Down
1 change: 1 addition & 0 deletions crates/wasm-shrink/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ impl ShrinkRun {
sign_extension: true,
component_model: false,
floats: true,
memory_control: true,
});

validator.validate_all(wasm)?;
Expand Down
1 change: 1 addition & 0 deletions crates/wasm-smith/tests/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ fn parser_features_from_config(config: &impl Config) -> WasmFeatures {
floats: true,
extended_const: false,
component_model: false,
memory_control: false,
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/wasmparser/benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ fn define_benchmarks(c: &mut Criterion) {
mutable_global: true,
saturating_float_to_int: true,
sign_extension: true,
memory_control: true,
})
}

Expand Down
5 changes: 5 additions & 0 deletions crates/wasmparser/src/binary_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,11 @@ impl<'a> BinaryReader<'a> {
visitor.visit_table_fill(table)
}

0x12 => {
let mem = self.read_var_u32()?;
visitor.visit_memory_discard(mem)
}

_ => bail!(pos, "unknown 0xfc subopcode: 0x{code:x}"),
})
}
Expand Down
5 changes: 5 additions & 0 deletions crates/wasmparser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ macro_rules! for_each_operator {
@reference_types TableGrow { table: u32 } => visit_table_grow
@reference_types TableSize { table: u32 } => visit_table_size

// OxFC prefixed operators
// memory control (experimental)
// https://github.com/WebAssembly/design/issues/1439
@memory_control MemoryDiscard { mem: u32 } => visit_memory_discard

// 0xFE prefixed operators
// threads
// https://github.com/WebAssembly/threads
Expand Down
3 changes: 3 additions & 0 deletions crates/wasmparser/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ pub struct WasmFeatures {
pub extended_const: bool,
/// The WebAssembly component model proposal.
pub component_model: bool,
/// The WebAssembly memory control proposal
pub memory_control: bool,
}

impl WasmFeatures {
Expand Down Expand Up @@ -277,6 +279,7 @@ impl Default for WasmFeatures {
memory64: false,
extended_const: false,
component_model: false,
memory_control: false,

// on-by-default features
mutable_global: true,
Expand Down
7 changes: 7 additions & 0 deletions crates/wasmparser/src/validator/operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,7 @@ macro_rules! validate_proposal {
(desc sign_extension) => ("sign extension operations");
(desc exceptions) => ("exceptions");
(desc tail_call) => ("tail calls");
(desc memory_control) => ("memory control");
}

impl<'a, T> VisitOperator<'a> for WasmProposalValidator<'_, '_, T>
Expand Down Expand Up @@ -3018,6 +3019,12 @@ where
self.pop_operand(Some(ty))?;
Ok(())
}
fn visit_memory_discard(&mut self, mem: u32) -> Self::Output {
let ty = self.check_memory_index(mem)?;
self.pop_operand(Some(ty))?;
self.pop_operand(Some(ty))?;
Ok(())
}
fn visit_table_init(&mut self, segment: u32, table: u32) -> Self::Output {
if table > 0 {}
let table = match self.resources.table_at(table) {
Expand Down
7 changes: 7 additions & 0 deletions crates/wasmprinter/src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,12 @@ macro_rules! define_visit {
$self.memory_index($mem)?;
}
);
(payload $self:ident MemoryDiscard $mem:ident) => (
if $mem != 0 {
$self.push_str(" ");
$self.memory_index($mem)?;
}
);
(payload $self:ident I32Const $val:ident) => (write!($self.result(), " {}", $val)?);
(payload $self:ident I64Const $val:ident) => (write!($self.result(), " {}", $val)?);
(payload $self:ident F32Const $val:ident) => (
Expand Down Expand Up @@ -362,6 +368,7 @@ macro_rules! define_visit {
(name MemoryInit) => ("memory.init");
(name MemoryCopy) => ("memory.copy");
(name MemoryFill) => ("memory.fill");
(name MemoryDiscard) => ("memory.discard");
(name DataDrop) => ("data.drop");
(name ElemDrop) => ("elem.drop");
(name TableInit) => ("table.init");
Expand Down
1 change: 1 addition & 0 deletions crates/wast/src/core/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ instructions! {
MemoryInit(MemoryInit<'a>) : [0xfc, 0x08] : "memory.init",
MemoryCopy(MemoryCopy<'a>) : [0xfc, 0x0a] : "memory.copy",
MemoryFill(MemoryArg<'a>) : [0xfc, 0x0b] : "memory.fill",
MemoryDiscard(MemoryArg<'a>) : [0xfc, 0x12] : "memory.discard",
DataDrop(Index<'a>) : [0xfc, 0x09] : "data.drop",
ElemDrop(Index<'a>) : [0xfc, 0x0d] : "elem.drop",
TableInit(TableInit<'a>) : [0xfc, 0x0c] : "table.init",
Expand Down
3 changes: 2 additions & 1 deletion fuzz/fuzz_targets/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ fuzz_target!(|data: &[u8]| {
mutable_global: (byte2 & 0b0010_0000) != 0,
saturating_float_to_int: (byte2 & 0b0100_0000) != 0,
sign_extension: (byte2 & 0b1000_0000) != 0,
memory_control: (byte3 & 0b0000_0001) != 0,
});
let use_maybe_invalid = byte3 & 0b0000_0001 != 0;
let use_maybe_invalid = byte3 & 0b0000_0010 != 0;

let wasm = &data[3..];
if log::log_enabled!(log::Level::Debug) {
Expand Down
7 changes: 7 additions & 0 deletions tests/local/memory-discard.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(module
(memory i32 2)

(func
(memory.discard (i32.const 0) (i32.const 65536))
)
)
1 change: 1 addition & 0 deletions tests/roundtrip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ impl TestState {
saturating_float_to_int: true,
sign_extension: true,
mutable_global: true,
memory_control: true,
};
for part in test.iter().filter_map(|t| t.to_str()) {
match part {
Expand Down
9 changes: 9 additions & 0 deletions tests/snapshots/local/memory-discard.wat.print
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(module
(type (;0;) (func))
(func (;0;) (type 0)
i32.const 0
i32.const 65536
memory.discard
)
(memory (;0;) 2)
)

0 comments on commit 398b367

Please sign in to comment.