Skip to content

Instantly share code, notes, and snippets.

@gsnedders
Last active May 23, 2017 06:52
Show Gist options
  • Save gsnedders/0cbe42412315da53dbde70bea1d91963 to your computer and use it in GitHub Desktop.
Save gsnedders/0cbe42412315da53dbde70bea1d91963 to your computer and use it in GitHub Desktop.
A Vague Plan for a JS VM in Rust

Many years ago, myself and @farre discussed a number of things we would like to do differently in a new JS VM, back when both of us were working on Carakan (myself, admittedly, mostly getting fed up of doing whitebox testing and starting to play around with stuff; I can't claim to have implemented much!).

While the gains of a new VM in Rust are inherently limited if there's some form of JIT (as Rust's memory safety inherently will not cover any generated code), it does nevertheless provide some new impetus to try and write such a VM.

From my personal point-of-view, the VM should:

  • have a memory-safe interpreter for cold code;
  • operate almost entirely on IRs, with:
    • a high-level IR mapping closely to JS constructs designed for interpreter performance (i.e., coarse-grained register based bytecode),
    • a mid-level IR mapping closely to VM internals designed for compilation (i.e., a fine-grained bytecode which almost all optimizations can be expressed in terms of; this can be used for multiple tiers of JIT by running different sequences of optimizations),
    • a low-level IR as a compilation target, potentially LLVM IR or B3 IR;
  • have a moving, precise GC (a combination of personal preference and the fact that it's easy to go from moving to non-moving and precise to conservative but not the other way);
  • avoid reimplementing everything in Rust from day 1 (aim to get something working fast);
  • not worry too much about SunSpider (i.e., very short-lived warmish code isn't a priority);
  • really not worry too much about SunSpider (i.e., I have no marketing department and I just don't give a damn);
  • implement as much as possible of the built-ins in JS;
  • be fast, without worrying too much about SunSpider (don't over-optimize for very short-lived code);
  • off-thread compilation;
  • target ES.latest + Annex B;
  • have all the features needed to be embedded in a browser (i.e., deal with weirdness around exotic objects).

Some more research-level goals (and yes, some of these could easily form a PhD thesis):

  • guarantee memory-safety of generated code,
  • guarantee memory-safety when calling back into the VM from generated code,
  • how well we can do tiering of the JIT by just using varying lists of optimizations (there was some talk about using IonMonkey as a baseline JIT by disabling most optimizations, though that never came to fruition I believe because of performance concerns),
  • demonstrate correctness of optimizations (and of AST -> HIR -> MIR -> LIR conversions),
  • how well we can use the memory safety guarantees we do have to move more off the main thread?

This undoubtedly leaves much out, but is potentially a useful starting point for discussions.

FAQ

Why Rust?

While a JITing VM inherently will have a big memory safety hole in the middle (i.e., generated code), Rust allows us to guarantee memory safety to a far bigger degree than we otherwise could. Also, well, there's little in the way of advantages of just reusing C/C++. Ultimately, I want to use the VM partly to throw ideas at and see what sticks.

A Production-level VM? Are you crazy?

Yes.

I don't have any expectation of it ever reaching comparable quality to SM, V8, JSC, or Chakra; the odds of some small open-source project ever having the resources to actually compete are miniscule. At the same time, we can make sure it has the API surface necessary and sufficient quality to be usable. Realistically, I'd expect to always trail in performance terms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment