DLR-FT / wasm-interpreter

A minimal in-place WebAssembly interpreter, written in Rust, almost without use of external dependencies
https://dlr-ft.github.io/wasm-interpreter/main/
Apache License 2.0
4 stars 4 forks source link

Discussion: Matching opcodes & arguments #29

Open florianhartung opened 3 months ago

florianhartung commented 3 months ago

This issue exists to discuss solutions for matching opcodes and their arguments.

Summary of the initial discussion (https://github.com/DLR-FT/wasm-interpreter/pull/23#discussion_r1665625248)

The initial solution was to match just the opcode byte and then read the opcode's arguments:

match wasm.read_u8().unwrap() {
    MY_OPCODE => {
        let some_opcode_argument = wasm.read_var_u32()?;
        ...
    }
}

Then the approach to use slice patterns for matching was suggested:

match &wasm.full_contents[wasm.pc..] {
    [MY_OPCODE, ..] => { .. }
}

Here we could also match some arguments directly:

[MY_OPCODE, some_opcode_argument, ..] => { .. }

However this only works for fixed-size arguments and WASM integers are encoded through a variable-length encoding format (specified here).

Solutions

  1. A hybrid solution where only fixed-size arguments are matched in the slice pattern and others arguments are read as usual.
  2. Match just the opcodes in the slice patterns and the arguments in each body. Some opcodes are still multiple bytes long:
    [MY_OPCODE_BYTE1, MY_OPCODE_BYTE2, ..] => { .. }
  3. Execute the match statement on one byte at a time. Then use nested match statements for multi-byte opcodes.
florianhartung commented 3 months ago

Personally I'd prefer the 3. solution.

Also I'm curious about what your opinion is on this topic @wucke13