notes
notes copied to clipboard
Extending WebAssembly to be a Resource Aware Recursive Virtual Machine (RARVM)
I love the idea of programs jumping between systems.
Why WebAssembly
Advantages:
- open source, acceptable license
- supported by all major browsers, but not limited to the web
- specifically designed to be a general compiler target
- formal specification exists, many different implementations
- limited complexity, very small Trusted Computing Base
- only local nondeterminism, can be avoided by transforming source code
- O(n) module verification
- growing tooling ecosystem
Disadvantages:
- future releases may include complex mandatory features (multithreading, garbage collection etc.)
Intra-call persistence
https://github.com/ewasm/wasm-metering/issues/20
Wasm-metering achieves result based persistence between wasm invocations by storing all available fields of the instance (code, memory etc.) after execution.
What is not possible yet is creating snapshots of (and thus comparing) running programs (as in truebit) and restoring the full program state in another instance.
The wasm-metering/Dfinity approach only stores modified memories after/between calls (inter-call). If an execution traps, it is not possible to capture the full VM state and resume the execution.
Achieving full state snapshots
Future Wasm features may allow at least partial implementation (through continuations/exceptions) of this.
At the moment, it may be possible to transform .wasm sources into programs that
- mirror their state to memory
- halt execution when resource limits are reached (wasm-metering achieves this)
- extract and serialize their state when this happens
Unfortunately, Wasm has many limitations when it comes to accessing program state, due to optimization:
- the stack of the enclosing blocks cannot be accessed
- there is only one memory, which would require interleaving the mirrored program state representation with normal state while keeping the latter intact
- as far as I know it's not possible to restore the stack state from scratch (especially call frames) without reexecution
There seem to be three ways of solving this:
- hoping for future support (never going to happen)
- transforming .wast source code like https://github.com/ewasm/wasm-metering … does it (hard, not sure if 100% possible)
- building a custom wasm-compatible vm (hard, less performant)
Due to the stack access issue, I pursue option 3 right now.
VM implementations that allow extension in reasonable time
warpy
https://github.com/kanaka/warpy/
I managed to extend the https://github.com/kanaka/warpy RPython Wasm JIT VM and extracted full state snapshots.
RPython Advantages:
- seems to be reasonably fast
- statically typed, easily JITted
- Python is nice
Disadvantages:
- no easy way to browser support
- no explicit typing. this sucks hard
- complete lack of useful RPython documentation
- warpy is not a complete, spec compliant implementation
https://github.com/kanaka/warpy/issues/2
webassemblyjs
https://github.com/xtuc/webassemblyjs/
Advantages:
- seems to be a complete implementation
- highly professionally written, complete with test suites
- right in the browser
- easily extendable
Disadvantages:
- no JIT, simple switch/case interpreter, probably very slow
- undocumented development workflow
https://github.com/xtuc/webassemblyjs/issues/432