Nova - Your favorite javascript and wasm engine
⚠️ This project is a Work In Progress, and is very far from being suitable for use ⚠️
Nova is a JavaScript and WebAssembly engine written in Rust.
The engine is exposed as a library with an API for implementation in Rust projects which themselves must serve as a runtime for JavaScript code. The execution model is currently greatly inspired by Kiesel and SerenityOS's LibJS. See the code for more details.
The core of our team is on our Discord server.
Heap structure
If you find yourself interested in what on earth is going on in the Heap, take a look at the Heap README.md. It gives a more thorough walkthrough of the Heap structure and what the idea there is.
List of active development ideas
This list serves as a "this is where you were" for returning developers as well as a potential easy jumping-into point for newcompers.
- Write implementations of more abstract operations
- See
nova_vm/src/ecmascript/abstract_operations
- Specifically eg.
operations_on_objects.rs
is missing multiple operations, even stubs.
- See
- Write implementations of class abstract operations
- String, Number, ...
- Start
nova_vm/src/syntax
folder for 8 Syntax-Directed Operations- This will serve as the bridge between oxc AST, Bytecode, and Bytecode interpretation
Some more long-term prospects and/or wild ideas:
- Reintroduce lifetimes to Heap if possible
Value<'gen>
lifetime that is "controlled" by a Heap generation number: Heap Values are valid while we can guarantee that the Heap generation number isn't mutably borrowed. This is basically completely equal to a scope basedLocal<'a, Value>
lifetime but the intended benefit is that theValue<'gen>
lifetimes can also be used during Heap compaction: When Heap GC and compaction occurs it can be written as a transformation fromHeap<'old>
toHeap<'new>
and the borrow checker would then help to make sure that any and allT<'new>
structs within the heap are properly transformed toT<'new>
.
- Add a
Reference
variant toValue
(or create aValueOrReference
enum that is the true root enum)- ReferenceRecords would (maybe?) move to Heap directly. This might make some syntax-directed operations simpler to implement.
- Add
DISCRIMINANT + 0x80
variants that work as thrown values of typeDISCRIMINANT
- As a result, eg. a thrown String would be just a String with the top bit set
true. This would stop Result usage which is a darn shame (can be fixed with
Nightly features). But it would mean that returning a (sort of)
Result<Value>
would fit in a register.
- As a result, eg. a thrown String would be just a String with the top bit set
true. This would stop Result usage which is a darn shame (can be fixed with
Nightly features). But it would mean that returning a (sort of)
- Consider a register based VM instead of going stack based