Expand description
§Nova JavaScript engine
Nova is a JavaScript engine focused on being lightweight, modular, and easy to embed. The engine’s architecture is built close to the ECMAScript specification in structure with the implementation relying on idiomatic Rust and data-oriented design over traditional JavaScript engine building strategies. Interpreter performance is also a goal, but not yet a high priority.
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 greatly inspired by Kiesel and LibJS.
§Basic usage
The engine has very little bells or whistles and is very easy to set up for
one-off script runs or simple call-and-return instances. The engine uses the
WTF-8 encoding internally for String storage, making interfacing with
JavaScript look and act similar to normal Rust code.
use nova_vm::{ecmascript::{DefaultHostHooks, GcAgent}, engine::GcScope};
let mut agent = GcAgent::new(Default::default(), &DefaultHostHooks);
let realm = agent.create_default_realm();
let _ = agent.run_in_realm(&realm, |_agent, _gc| {
// do work here
});§Architecture
The engine’s public API relies on idiomatic Rust over traditional JavaScript
engine building wisdom. This is most apparent in the Value type and its
subvariants such as Object: instead of using NaN-boxing, NuN-boxing, or
other traditional and known efficient strategies for building a dynamically
typed language, Nova uses normal Rust enums carrying either on-stack data or
a 32-bit handle to heap-allocated data. The only pointer that gets
consistently passed through call stacks is the Agent reference, and
handles are merely ways to access heap-allocated JavaScript data held inside
the Agent.
Internally, the architecture and structure of the engine follows the ECMAScript specification but uses data-oriented design for the actual implementation. Data on the heap is allocated in homogenous (containing data of only one type) arenas with hot data split apart from cold data, and optional data stored behind keyed indirections using the arena’s associated 32-bit handle as the key, thus using no memory to store the default null case. The arenas are additionally compacted during garbage collection, trading some extra collection time for better runtime cache locality for hot data.
§Shortcomings and unexpected edge cases
Nova JavaScript engine is not perfect and has many shortcomings.
- The engine performance is acceptable, but it is not fast by any means.
- The
Arrayimplementation does not support sparse storage internally. Callingnew Array(10 ** 9)will request an allocation for 1 billion JavaScriptValues. - The
RegExpimplementation does not support lookaheads, lookbehinds, or backreferences. It is always in UTF-8 / Unicode sets mode, does not support RegExp patterns containing unpaired surrogates, and its groups are slightly different from what the ECMAScript specification defines. In short: it is not compliant. Promisesubclassing is currently not supported.- The engine does not support WebAssembly execution.
Modules§
- ecmascript
- ECMAScript language
- engine
- Nova JavaScript engine
- heap
- Nova engine heap structures
Functions§
- register_
probes - Function that should be called as the very first thing in
fn main()of any application using Nova JavaScript engine. This function registers USDT probes with the DTrace kernel module on OS’s that have one and is required for them to work. On other OS’s this is a no-op.