Skip to content

Commit c8527a1

Browse files
committed
fix(runtime): add missing store instructions (0x3A-0x3E)
This commit adds support for partial-width store instructions that were missing from the instruction parser, causing "Unknown instruction opcode" errors when executing real-world WASM modules. Added instructions: - 0x3A: i32.store8 - Store 8-bit value from i32 - 0x3B: i32.store16 - Store 16-bit value from i32 - 0x3C: i64.store8 - Store 8-bit value from i64 - 0x3D: i64.store16 - Store 16-bit value from i64 - 0x3E: i64.store32 - Store 32-bit value from i64 These instructions are commonly used for: - Byte-level memory manipulation - String operations (UTF-8 encoding) - Packed data structures - WASI syscall buffers Test results: - ✓ simple_inference.wasm (WASI-NN) now executes successfully - ✓ Fuel consumed: 60, Peak memory: 1202 bytes The Instruction enum already had these variants defined; this commit only adds the missing parser cases for the opcodes. Impact: Unlocks execution of WASI modules and real-world applications
1 parent 543e3c1 commit c8527a1

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

wrt-runtime/src/instruction_parser.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,61 @@ fn parse_instruction_with_provider(
283283
memory_index: 0,
284284
})
285285
},
286+
0x3A => {
287+
// i32.store8
288+
let (align, bytes1) = read_leb128_u32(bytecode, offset + 1)?;
289+
let (offset, bytes2) = read_leb128_u32(bytecode, offset + 1 + bytes1)?;
290+
consumed += bytes1 + bytes2;
291+
Instruction::I32Store8(MemArg {
292+
align_exponent: align,
293+
offset,
294+
memory_index: 0,
295+
})
296+
},
297+
0x3B => {
298+
// i32.store16
299+
let (align, bytes1) = read_leb128_u32(bytecode, offset + 1)?;
300+
let (offset, bytes2) = read_leb128_u32(bytecode, offset + 1 + bytes1)?;
301+
consumed += bytes1 + bytes2;
302+
Instruction::I32Store16(MemArg {
303+
align_exponent: align,
304+
offset,
305+
memory_index: 0,
306+
})
307+
},
308+
0x3C => {
309+
// i64.store8
310+
let (align, bytes1) = read_leb128_u32(bytecode, offset + 1)?;
311+
let (offset, bytes2) = read_leb128_u32(bytecode, offset + 1 + bytes1)?;
312+
consumed += bytes1 + bytes2;
313+
Instruction::I64Store8(MemArg {
314+
align_exponent: align,
315+
offset,
316+
memory_index: 0,
317+
})
318+
},
319+
0x3D => {
320+
// i64.store16
321+
let (align, bytes1) = read_leb128_u32(bytecode, offset + 1)?;
322+
let (offset, bytes2) = read_leb128_u32(bytecode, offset + 1 + bytes1)?;
323+
consumed += bytes1 + bytes2;
324+
Instruction::I64Store16(MemArg {
325+
align_exponent: align,
326+
offset,
327+
memory_index: 0,
328+
})
329+
},
330+
0x3E => {
331+
// i64.store32
332+
let (align, bytes1) = read_leb128_u32(bytecode, offset + 1)?;
333+
let (offset, bytes2) = read_leb128_u32(bytecode, offset + 1 + bytes1)?;
334+
consumed += bytes1 + bytes2;
335+
Instruction::I64Store32(MemArg {
336+
align_exponent: align,
337+
offset,
338+
memory_index: 0,
339+
})
340+
},
286341
0x3F => {
287342
consumed += 1; // Skip reserved byte
288343
Instruction::MemorySize(0)

0 commit comments

Comments
 (0)