Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is the sort of iterative process other interpreters have gone through as well, the balance between startup speed and memory usage leads to byte code, the stack based interpreter is replaced by a register based one. Later but not yet in this project, the byte code is replaced with a list of addresses, and then these are converted to machine code and inlined, in the simplest possible form of compilation, next code is generated for branches to make loops and flow control fast and we eventually get back to a jit. This gets saved to a binary image and we have a compiler.


Yes this iterative process is indeed very visible. Wasmi started out as a mostly safe Rust interpreter and over time went more and more into a performance oriented direction.

Though I have to say that the "list of addresses" approach is not optimal in Rust today since Rust is missing explicit tail calls. Stitch applies some tricks to achieve tail calls in Rust but this has some drawbacks that are discussed in detail at Stitch's README.

Furthermore the "list of addresses" (or also known as threaded code dispatch) has some variance. From what I know both Wasm3 and Stitch use direct threaded code which stores a list of function pointers to instruction handlers and use tail calls or computed-goto to fetch the next instruction. The downside compared to bytecode is that direct threaded code uses more memory and also it is only faster when coupled with computed-goto or tail calls. Otherwise compilers nowadawys are pretty solid in their optimizations for loop-switch constructs and could technically even generate computed-goto-like code.

Thus, due to the lower memory usage, the downsides of using tail calls in Rust and the potential of compiler optimizations with loop-switch constructs we went for the bytecode approach in Wasmi.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: