Here's an overview of v86 workings. For details, check the source.
The major limitations of WebAssembly are:
- structured control flow (you can't generate arbitrary jumps)
- no control over registers (you can't keep x86 registers in wasm locals across functions)
- no mmap (paging needs to be fully emulated)
- no patching
- module generation is fairly slow, but at least it's asynchronous, so other things can keep running
- there is some memory overhead per module, so you can't generate more than a few thousand