Most WebAssembly opcodes use a single byte.
i32.add = 0x6A
local.tee = 0x22
Some opcodes use two bytes.
memory.copy = 0xFC + 0x0A
i32.atomic.store = 0xFE + 0x17
SIMD opcodes use Leb128
This table seems to claim the following
v128.load = 0xFD + 0x00
But it actually is: 0xFD + encode_leb128(0x00)
which expands to: 0xFD + 0x80
LEB128 stands for little endian base 128, and is basically a number of bytes <0x80 (which each are taken for literal bits `total = total * 0x80 + byte`), and a byte >=0x80 that terminates the sequence (which is taken for bits, after masking off the 0x80 total = total * 0x80 + (byte | 0x7F)
)
Examples of LEB128
Examples of decoding LEB128:
decode_leb([0x80])
= 0x80
- 0x80 = 0
decode_leb([0x01, 0x80])
= 0x01
* 0x80 + 0x80
- 0x80 = 127
decode_leb([0x5F, 0x42, 0xFF])
= 0x5F
* 0x80 * 0x80 + 0x42
* 0x80 + 0xFF
- 0x80 = 0x17E17F
That's all i got. I hope that this can save someone from headache with WASM SIMD by hand.
Top comments (2)
Hi. I made that table you linked pengowray.github.io/wasm-ops/. You'll be glad to know today I finally fixed it to show LEB128 values.
I happened to come across your post while looking to double check I had the LEB128 values correct. Hopefully there'll be less future headaches.
Thank you so much. LEB128 is a tricky thing, and its nice to know when you're using it.