|
4 | 4 |
|
5 | 5 | #![cfg_attr(feature = "proposal-float16array", feature(f16))] |
6 | 6 | #![warn(missing_docs)] |
7 | | -#![doc = include_str!("../../README.md")] |
| 7 | + |
| 8 | +//! # Nova JavaScript engine |
| 9 | +//! |
| 10 | +//! Nova is a [JavaScript] engine focused on being lightweight, modular, and |
| 11 | +//! easy to embed. The engine's architecture is built close to the ECMAScript |
| 12 | +//! specification in structure with the implementation relying on idiomatic Rust |
| 13 | +//! and data-oriented design over traditional JavaScript engine building |
| 14 | +//! strategies. Interpreter performance is also a goal, but not yet a high |
| 15 | +//! priority. |
| 16 | +//! |
| 17 | +//! The engine is exposed as a library with an API for implementation in Rust |
| 18 | +//! projects which themselves must serve as a runtime for JavaScript code. The |
| 19 | +//! execution model is greatly inspired by [Kiesel] and [LibJS]. |
| 20 | +//! |
| 21 | +//! ## Basic usage |
| 22 | +//! |
| 23 | +//! The engine has very little bells or whistles and is very easy to set up for |
| 24 | +//! one-off script runs or simple call-and-return instances. The engine uses the |
| 25 | +//! [WTF-8] encoding internally for [`String`] storage, making interfacing with |
| 26 | +//! JavaScript look and act similar to normal Rust code. |
| 27 | +//! |
| 28 | +//! ```rust |
| 29 | +//! use nova_vm::{ecmascript::{DefaultHostHooks, GcAgent}, engine::GcScope}; |
| 30 | +//! let mut agent = GcAgent::new(Default::default(), &DefaultHostHooks); |
| 31 | +//! let realm = agent.create_default_realm(); |
| 32 | +//! let _ = agent.run_in_realm(&realm, |_agent, _gc| { |
| 33 | +//! // do work here |
| 34 | +//! }); |
| 35 | +//! ``` |
| 36 | +//! |
| 37 | +//! ## Architecture |
| 38 | +//! |
| 39 | +//! The engine's public API relies on idiomatic Rust over traditional JavaScript |
| 40 | +//! engine building wisdom. This is most apparent in the [`Value`] type and its |
| 41 | +//! subvariants such as [`Object`]: instead of using NaN-boxing, NuN-boxing, or |
| 42 | +//! other traditional and known efficient strategies for building a dynamically |
| 43 | +//! typed language, Nova uses normal Rust enums carrying either on-stack data or |
| 44 | +//! a 32-bit handle to heap-allocated data. The only pointer that gets |
| 45 | +//! consistently passed through call stacks is the [`Agent`] reference, and |
| 46 | +//! handles are merely ways to access heap-allocated JavaScript data held inside |
| 47 | +//! the `Agent`. |
| 48 | +//! |
| 49 | +//! Internally, the architecture and structure of the engine follows the |
| 50 | +//! ECMAScript specification but uses data-oriented design for the actual |
| 51 | +//! implementation. Data on the heap is allocated in homogenous (containing data |
| 52 | +//! of only one type) arenas with hot data split apart from cold data, and |
| 53 | +//! optional data stored behind keyed indirections using the arena's associated |
| 54 | +//! 32-bit handle as the key, thus using no memory to store the default null |
| 55 | +//! case. The arenas are additionally compacted during garbage collection, |
| 56 | +//! trading some extra collection time for better runtime cache locality for hot |
| 57 | +//! data. |
| 58 | +//! |
| 59 | +//! ## Shortcomings and unexpected edge cases |
| 60 | +//! |
| 61 | +//! Nova JavaScript engine is not perfect and has many shortcomings. |
| 62 | +//! |
| 63 | +//! 1. The engine performance is acceptable, but it is not fast by any means. |
| 64 | +//! 1. The [`Array`] implementation does not support sparse storage internally. |
| 65 | +//! Calling `new Array(10 ** 9)` will request an allocation for 1 billion |
| 66 | +//! JavaScript [`Value`]s. |
| 67 | +//! 1. The [`RegExp`] implementation does not support lookaheads, lookbehinds, |
| 68 | +//! or backreferences. It is always in UTF-8 / Unicode sets mode, does not |
| 69 | +//! support RegExp patterns containing unpaired surrogates, and its groups |
| 70 | +//! are slightly different from what the ECMAScript specification defines. In |
| 71 | +//! short: it is not compliant. |
| 72 | +//! 1. [`Promise`] subclassing is currently not supported. |
| 73 | +//! 1. The engine does not support [WebAssembly] execution. |
| 74 | +//! |
| 75 | +//! [`Agent`]: crate::ecmascript::Agent |
| 76 | +//! [`Array`]: crate::ecmascript::Array |
| 77 | +//! [`RegExp`]: crate::ecmascript::RegExp |
| 78 | +//! [`Promise`]: crate::ecmascript::Promise |
| 79 | +//! [`Object`]: crate::ecmascript::Object |
| 80 | +//! [`String`]: crate::ecmascript::String |
| 81 | +//! [`Value`]: crate::ecmascript::Value |
| 82 | +//! [WebAssembly]: https://webassembly.org |
| 83 | +//! [WTF-8]: https://wtf-8.codeberg.page/ |
| 84 | +//! [JavaScript]: https://tc39.es/ecma262 |
| 85 | +//! [Kiesel]: https://codeberg.org/kiesel-js/kiesel |
| 86 | +//! [LibJS]: https://github.com/LadybirdBrowser/ladybird/tree/master/Libraries/LibJS |
8 | 87 |
|
9 | 88 | pub mod ecmascript; |
10 | 89 | pub mod engine; |
|
0 commit comments