Skip to content

Commit 398b367

Browse files
authored
Add experimental memory.discard instruction (#882)
1 parent 9a51f6d commit 398b367

File tree

14 files changed

+56
-1
lines changed

14 files changed

+56
-1
lines changed

crates/wasm-encoder/src/core/code.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ pub enum Instruction<'a> {
367367
DataDrop(u32),
368368
MemoryCopy { src_mem: u32, dst_mem: u32 },
369369
MemoryFill(u32),
370+
MemoryDiscard(u32),
370371

371372
// Numeric instructions.
372373
I32Const(i32),
@@ -1092,6 +1093,11 @@ impl Encode for Instruction<'_> {
10921093
sink.push(0x0b);
10931094
mem.encode(sink);
10941095
}
1096+
Instruction::MemoryDiscard(mem) => {
1097+
sink.push(0xfc);
1098+
sink.push(0x12);
1099+
mem.encode(sink);
1100+
}
10951101

10961102
// Numeric instructions.
10971103
Instruction::I32Const(x) => {

crates/wasm-shrink/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ impl ShrinkRun {
234234
sign_extension: true,
235235
component_model: false,
236236
floats: true,
237+
memory_control: true,
237238
});
238239

239240
validator.validate_all(wasm)?;

crates/wasm-smith/tests/core.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ fn parser_features_from_config(config: &impl Config) -> WasmFeatures {
299299
floats: true,
300300
extended_const: false,
301301
component_model: false,
302+
memory_control: false,
302303
}
303304
}
304305

crates/wasmparser/benches/benchmark.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ fn define_benchmarks(c: &mut Criterion) {
251251
mutable_global: true,
252252
saturating_float_to_int: true,
253253
sign_extension: true,
254+
memory_control: true,
254255
})
255256
}
256257

crates/wasmparser/src/binary_reader.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,11 @@ impl<'a> BinaryReader<'a> {
10461046
visitor.visit_table_fill(table)
10471047
}
10481048

1049+
0x12 => {
1050+
let mem = self.read_var_u32()?;
1051+
visitor.visit_memory_discard(mem)
1052+
}
1053+
10491054
_ => bail!(pos, "unknown 0xfc subopcode: 0x{code:x}"),
10501055
})
10511056
}

crates/wasmparser/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,11 @@ macro_rules! for_each_operator {
338338
@reference_types TableGrow { table: u32 } => visit_table_grow
339339
@reference_types TableSize { table: u32 } => visit_table_size
340340

341+
// OxFC prefixed operators
342+
// memory control (experimental)
343+
// https://github.com/WebAssembly/design/issues/1439
344+
@memory_control MemoryDiscard { mem: u32 } => visit_memory_discard
345+
341346
// 0xFE prefixed operators
342347
// threads
343348
// https://github.com/WebAssembly/threads

crates/wasmparser/src/validator.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ pub struct WasmFeatures {
241241
pub extended_const: bool,
242242
/// The WebAssembly component model proposal.
243243
pub component_model: bool,
244+
/// The WebAssembly memory control proposal
245+
pub memory_control: bool,
244246
}
245247

246248
impl WasmFeatures {
@@ -277,6 +279,7 @@ impl Default for WasmFeatures {
277279
memory64: false,
278280
extended_const: false,
279281
component_model: false,
282+
memory_control: false,
280283

281284
// on-by-default features
282285
mutable_global: true,

crates/wasmparser/src/validator/operators.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,7 @@ macro_rules! validate_proposal {
936936
(desc sign_extension) => ("sign extension operations");
937937
(desc exceptions) => ("exceptions");
938938
(desc tail_call) => ("tail calls");
939+
(desc memory_control) => ("memory control");
939940
}
940941

941942
impl<'a, T> VisitOperator<'a> for WasmProposalValidator<'_, '_, T>
@@ -3018,6 +3019,12 @@ where
30183019
self.pop_operand(Some(ty))?;
30193020
Ok(())
30203021
}
3022+
fn visit_memory_discard(&mut self, mem: u32) -> Self::Output {
3023+
let ty = self.check_memory_index(mem)?;
3024+
self.pop_operand(Some(ty))?;
3025+
self.pop_operand(Some(ty))?;
3026+
Ok(())
3027+
}
30213028
fn visit_table_init(&mut self, segment: u32, table: u32) -> Self::Output {
30223029
if table > 0 {}
30233030
let table = match self.resources.table_at(table) {

crates/wasmprinter/src/operator.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,12 @@ macro_rules! define_visit {
279279
$self.memory_index($mem)?;
280280
}
281281
);
282+
(payload $self:ident MemoryDiscard $mem:ident) => (
283+
if $mem != 0 {
284+
$self.push_str(" ");
285+
$self.memory_index($mem)?;
286+
}
287+
);
282288
(payload $self:ident I32Const $val:ident) => (write!($self.result(), " {}", $val)?);
283289
(payload $self:ident I64Const $val:ident) => (write!($self.result(), " {}", $val)?);
284290
(payload $self:ident F32Const $val:ident) => (
@@ -362,6 +368,7 @@ macro_rules! define_visit {
362368
(name MemoryInit) => ("memory.init");
363369
(name MemoryCopy) => ("memory.copy");
364370
(name MemoryFill) => ("memory.fill");
371+
(name MemoryDiscard) => ("memory.discard");
365372
(name DataDrop) => ("data.drop");
366373
(name ElemDrop) => ("elem.drop");
367374
(name TableInit) => ("table.init");

crates/wast/src/core/expr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ instructions! {
568568
MemoryInit(MemoryInit<'a>) : [0xfc, 0x08] : "memory.init",
569569
MemoryCopy(MemoryCopy<'a>) : [0xfc, 0x0a] : "memory.copy",
570570
MemoryFill(MemoryArg<'a>) : [0xfc, 0x0b] : "memory.fill",
571+
MemoryDiscard(MemoryArg<'a>) : [0xfc, 0x12] : "memory.discard",
571572
DataDrop(Index<'a>) : [0xfc, 0x09] : "data.drop",
572573
ElemDrop(Index<'a>) : [0xfc, 0x0d] : "elem.drop",
573574
TableInit(TableInit<'a>) : [0xfc, 0x0c] : "table.init",

fuzz/fuzz_targets/validate.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ fuzz_target!(|data: &[u8]| {
3636
mutable_global: (byte2 & 0b0010_0000) != 0,
3737
saturating_float_to_int: (byte2 & 0b0100_0000) != 0,
3838
sign_extension: (byte2 & 0b1000_0000) != 0,
39+
memory_control: (byte3 & 0b0000_0001) != 0,
3940
});
40-
let use_maybe_invalid = byte3 & 0b0000_0001 != 0;
41+
let use_maybe_invalid = byte3 & 0b0000_0010 != 0;
4142

4243
let wasm = &data[3..];
4344
if log::log_enabled!(log::Level::Debug) {

tests/local/memory-discard.wat

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
(module
2+
(memory i32 2)
3+
4+
(func
5+
(memory.discard (i32.const 0) (i32.const 65536))
6+
)
7+
)

tests/roundtrip.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ impl TestState {
537537
saturating_float_to_int: true,
538538
sign_extension: true,
539539
mutable_global: true,
540+
memory_control: true,
540541
};
541542
for part in test.iter().filter_map(|t| t.to_str()) {
542543
match part {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(module
2+
(type (;0;) (func))
3+
(func (;0;) (type 0)
4+
i32.const 0
5+
i32.const 65536
6+
memory.discard
7+
)
8+
(memory (;0;) 2)
9+
)

0 commit comments

Comments
 (0)