Stitch lazily compiles each wasm function to a form of threaded code in which each instruction has multiple variants, depending on where it loads its operands from.
Each operand is either stored on the stack (s), a virtual register (r), or as an immediate value (i). The add instruction, for instance, has an add_ss variant, an add_rs, and an add_ri variant, among others.
Most instructions store their result in a register, so that subsequent instructions operating on the result can avoid a stack load.
i32/i64/f32/f64.const instructions are completely elided: instead of storing constant values on the stack, they are stored as an immediate operand for the next instruction (this is one area where stitch differs from wasm3, which preloads all constants for a function on the stack every time the function is called)
That’s a good point! I did’t even think about that. For Stitch to become self hosting, we’d either have to implement those instructions, or implement a fallback mode using an interpreter loop with a trampoline. The latter would negate most of the speed benefits of Stitch though.
I haven’t tried this, but Stitch should technically be able to run itself if we gave it a C-like API that you could export from a Wasm module. Would be fun to try at some point :-)
I'm the author of Stitch. Rik is somewhat overpromising: Stitch is only faster than Wasm3 on Windows (by about 15%). On Mac and Linux, it is about as fast. It does get within 4x of Wasmtime (which is the JIT I've compared it against), but only on Mac. On Linux and Windows, it gets within 8x.
Each operand is either stored on the stack (s), a virtual register (r), or as an immediate value (i). The add instruction, for instance, has an add_ss variant, an add_rs, and an add_ri variant, among others.
Most instructions store their result in a register, so that subsequent instructions operating on the result can avoid a stack load.
i32/i64/f32/f64.const instructions are completely elided: instead of storing constant values on the stack, they are stored as an immediate operand for the next instruction (this is one area where stitch differs from wasm3, which preloads all constants for a function on the stack every time the function is called)
I hope that clarifies things :-)