1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//! # 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.
//!
//! ```rust
//! 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.
//!
//! 1. The engine performance is acceptable, but it is not fast by any means.
//! 1. The [`Array`] implementation does not support sparse storage internally.
//! Calling `new Array(10 ** 9)` will request an allocation for 1 billion
//! JavaScript [`Value`]s.
//! 1. The [`RegExp`] implementation 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.
//! 1. [`Promise`] subclassing is currently not supported.
//! 1. The engine does not support [WebAssembly] execution.
//!
//! [`Agent`]: crate::ecmascript::Agent
//! [`Array`]: crate::ecmascript::Array
//! [`RegExp`]: crate::ecmascript::RegExp
//! [`Promise`]: crate::ecmascript::Promise
//! [`Object`]: crate::ecmascript::Object
//! [`String`]: crate::ecmascript::String
//! [`Value`]: crate::ecmascript::Value
//! [WebAssembly]: https://webassembly.org
//! [WTF-8]: https://wtf-8.codeberg.page/
//! [JavaScript]: https://tc39.es/ecma262
//! [Kiesel]: https://codeberg.org/kiesel-js/kiesel
//! [LibJS]: https://github.com/LadybirdBrowser/ladybird/tree/master/Libraries/LibJS
/// DTrace / SystemTap USDT probes in Nova VM.
/// 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.
///
/// ```rust
/// nova_vm::register_probes();
/// ```
///
/// # usdt documentation
pub use register_probes;