- Change memory model: random access via
(map page-number=@ page-array=@)
- Revisit the model of
block
/loop
/if
andcall
/call_indirect
execution: it appears that the current model causes unnecessary copies of the entire membuffer, slowing down the computation. So instead of cloning the core, interpreting an expression and back-propagating changes in the global state, I need to call an evaluating arm that will edit the global state in-place - Cache function fetching:
- Have a gate
fetch-operation
withinapply-instruction
that takesterm
of aninstruction
as an argument and returns a number of operands to be consumed and a gate to be applied to the immediate arguments and consumed operands - Cache that gate
- Fetching gate and operation gates must be defined outside of
hwasm
core - Use four letters for operators (shoudld speed things up since 4 letter
term
is a direct atom)
- Have a gate
- Floating point: verify roundings and such (iirc they are different in Wasm spec an
Below are instructions to run -mass
from this project:
- Clone my versions of vere and urbit repos (mind the branches, modernize-mass and mass-thread respectively)
- Build vere binary
- Boot a fakezod:
./vere/bazel-bin/pkg/vere/urbit -F zod -B urbit/bin/brass.pill -A urbit/pkg/arvo
- Run
-mass
in dojo, After the usual printfs, you should get something like:
A few months ago I started working on mass modernization project to learn about Arvo and Vere and to contribute to the core development. Since then I had some success working on WebAssembly interpreter, and I decided that it would be wise to focus my attention on that project instead.
I managed to achieve the first milestone outlined in the grant proposal. To ensure my efforts don't go in vain I will describe what I achieved and learned while working on that milestone.
In this gist I will go through several strategies for jetting in urwasm, delineate their strengths and weaknesses and explain my motivation for choosing a particular strategy (Lia interpreter). I will then draw a rough sketch of the jetted function specification and the implementation of its jet.
urwasm is a project which aims at executing WebAssembly modules within an Urbit instance. Determinism is the key feature of Urbit computer, and in addition to that I want Wasm execution to be as fast as possible. Currently, a Wasm interpreter in Hoon is being developed, intended to be a complete Wasm runtime. However, it would not be a practical one due to its poor performance. To go from a merely complete interpreter to a practical Wasm runtime I will have to jet it.
To jet the interpreter, I would have to pair a function written in Hoon with a code in C that must be extensionally equivalent to the Hoon code. In that sense function definition in Hoon would act as a formal mathematical specif
In this gist I will describe Lia interpreter model in a greater detail. As an addendum to the first part, I'd like to point out yet another advantage of jetting another interpreter on top of Wasm that would take a list of actions to be performed, as opposed to jetting just the invocation gate.
Both in Vere and Ares, at least right now, a jetting function that is called instead of performing Nock 9 on a jetted core requires that core must not be modified. Therefore, the jetting function must only read from the input core, allocating memory for the results.
Since ++invoke
gate has module store, including linear memory as its input and output, any Wasm function invocation from Urbit would require copying the entire store. It might be a prohibitive overhead for some memory-heavy applications of Wasm, like emulating x86, and something to keep in mind for smaller cases.
On the other hand, interacting with an instantiated module in the c
WebAssembly is a low-level language for a portable virtual machine. Wasm is designed to be a compilation target for a variety of programming languages and its design is hardware independent and relatively simple, making its support ubiquitous in modern browsers. Its simple design made it a perfect first candidate for a first emulator of an conventional computational system on a novel functional computer: Urbit. In this paper I discuss the current state of urwasm
project and some technical details, as well as describe the strategy to jet the interpreter of a state machine in a functional environment.
This UIP draft describes a proposal to add a new virtual Nock operator to provide manual memory management without changing the base-level Nock. I believe this would allow to greatly increase the performance for certain tasks without requiring more difficult and less fine-grained optimization techniques like atom paging.
It would be beneficial for Nock performance to have an ability to allocate a byte buffer in order to manually manage memory in it. Other languages have similar features, where in addition to garbage-collected objects a programmer can choose to allocate some memory in order to run some algorithms faster. A recent example is ++cue
implementation in JS, where the solution was (AFAIK, to check) to allocate a ByteBuffer with the jammed noun for a faster traversal. Nock 13 would give the same affordance to virtual Nock without breaking the original Nock specification. Some gates (bitwise logic, maybe arithmetics) could be rewritten with Nock 13 i
:: Brainfuck interpreter in Hoon with Nock 13 virtual operator | |
:: (https://gist.github.com/Quodss/2608695c50ed2d25b9107fa45f316828) | |
:: | |
:: ++bink-mem is assumed as a virtual Nock interpreter for this code | |
:: | |
:: .% (dotcen) is compiled: | |
:: (compile .%(p)) -> [%13 (compile p)] | |
:: | |
:: .> (dotgar) desugars: | |
:: .>(p q) -> |