From fffec5660e726fc658e4eb96a26e38e8117ed16c Mon Sep 17 00:00:00 2001 From: Nickolai Zeldovich Date: Tue, 10 Feb 2026 09:39:57 -0500 Subject: [PATCH] implement memory.fill and memory.copy --- src/parser.rs | 2 ++ src/printer.rs | 18 ++++++++++++++++++ src/wasm.rs | 2 ++ 3 files changed, 22 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 1ac91eb..29a5e09 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -560,6 +560,8 @@ generate! { instr -> Instr = { 0x05 => Instr::ICvtOp(BitSize::B64, intop::CvtOp::TruncSatUF32), 0x06 => Instr::ICvtOp(BitSize::B64, intop::CvtOp::TruncSatSF64), 0x07 => Instr::ICvtOp(BitSize::B64, intop::CvtOp::TruncSatUF64), + 0x0a => { run!(expect_byte(0x00)); run!(expect_byte(0x00)); Instr::MemCopy }, + 0x0b => { run!(expect_byte(0x00)); Instr::MemFill }, b => err!("Invalid saturation trunctation {:#x}", b), } } diff --git a/src/printer.rs b/src/printer.rs index 42b01ca..46d71c7 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -639,6 +639,24 @@ fn print_instr( } } } + MemFill => { + let n = pop!(i32); + let v = pop!(i32); + let addr = pop!(i32); + let addr_end = format!("({} + {})", addr, n); + + Ok(format!("self.memory[{} as usize..{} as usize].fill({} as u8);", + addr, addr_end, v)) + } + MemCopy => { + let n = pop!(i32); + let src = pop!(i32); + let dst = pop!(i32); + let src_end = format!("({} + {})", src, n); + + Ok(format!("self.memory.copy_within({} as usize..{} as usize, {} as usize);", + src, src_end, dst)) + } MemSize => { // Note: The spec defines Page Size = 65536 let inner_mem_size = if opts.fixed_mem_size.is_some() { diff --git a/src/wasm.rs b/src/wasm.rs index b03c314..c6f2be6 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -273,6 +273,8 @@ pub mod syntax { MemStore(MemStore), MemSize, MemGrow, + MemCopy, + MemFill, // Control instructions Nop,