From 31e4f22fe27bf896f37d454a0b7208d29638f49c Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Fri, 13 Mar 2026 00:54:04 +0200 Subject: [PATCH 1/3] feat(doc): Document all public APIs --- nova_vm/src/ecmascript.rs | 2 +- nova_vm/src/ecmascript/builtins/array.rs | 6 + .../src/ecmascript/builtins/array_buffer.rs | 2 + .../builtins/builtin_constructor.rs | 9 +- .../ecmascript/builtins/builtin_function.rs | 17 +- .../iteration/iterator_prototype.rs | 1 + nova_vm/src/ecmascript/builtins/data_view.rs | 4 + .../builtins/ecmascript_function.rs | 2 - .../builtins/finalization_registry/data.rs | 4 +- .../function_objects/function_prototype.rs | 2 +- .../finalization_registry_constructor.rs | 1 - nova_vm/src/ecmascript/builtins/regexp.rs | 9 + .../builtins/typed_array/any_typed_array.rs | 72 ++++++ .../typed_array/normal_typed_array.rs | 72 ++++++ .../typed_array/shared_typed_array.rs | 72 ++++++ nova_vm/src/ecmascript/execution/agent.rs | 22 +- .../ecmascript/execution/realm/intrinsics.rs | 165 +++++++++++++ nova_vm/src/ecmascript/execution/weak_key.rs | 10 +- .../src/ecmascript/types/language/bigint.rs | 4 + .../types/language/bigint/small_bigint.rs | 6 +- .../src/ecmascript/types/language/function.rs | 46 ++-- .../types/language/number/small_integer.rs | 8 + .../src/ecmascript/types/language/numeric.rs | 17 ++ .../src/ecmascript/types/language/object.rs | 150 ++++++++++-- .../types/language/object/property_key.rs | 19 ++ .../src/ecmascript/types/language/string.rs | 42 ++++ .../ecmascript/types/language/string/data.rs | 34 +-- .../src/ecmascript/types/language/value.rs | 219 +++++++++++++++--- .../ecmascript/types/language/value_vec.rs | 9 +- .../types/spec/property_descriptor.rs | 17 +- nova_vm/src/engine.rs | 3 + nova_vm/src/engine/bytecode/vm.rs | 1 - nova_vm/src/engine/rootable.rs | 4 - nova_vm/src/engine/rootable/scoped.rs | 13 +- nova_vm/src/heap.rs | 5 + nova_vm/src/heap/element_array.rs | 48 +++- nova_vm/src/heap/heap_bits.rs | 2 +- nova_vm/src/lib.rs | 60 +++++ 38 files changed, 1022 insertions(+), 157 deletions(-) diff --git a/nova_vm/src/ecmascript.rs b/nova_vm/src/ecmascript.rs index e574c2798..6ebfd92ec 100644 --- a/nova_vm/src/ecmascript.rs +++ b/nova_vm/src/ecmascript.rs @@ -2,7 +2,7 @@ // 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/. -//!# [ECMAScript language](https://tc39.es/ecma262/) +//! # [ECMAScript language](https://tc39.es/ecma262/) //! //! This module is the main entry point into the Nova JavaScript API and its //! implementation of the ECMAScript language specification. diff --git a/nova_vm/src/ecmascript/builtins/array.rs b/nova_vm/src/ecmascript/builtins/array.rs index 4171920f7..b18cdb0ab 100644 --- a/nova_vm/src/ecmascript/builtins/array.rs +++ b/nova_vm/src/ecmascript/builtins/array.rs @@ -38,6 +38,12 @@ use super::{ }; /// ### [10.4.2 Array Exotic Objects](https://tc39.es/ecma262/#sec-array-exotic-objects) +/// +/// ## Support status +/// +/// `Array` in Nova does not support sparse storage. This means that setting the +/// `length` property will grow the `Array`'s backing storage to the requested +/// size or larger. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct Array<'a>(BaseIndex<'a, ArrayHeapData<'static>>); diff --git a/nova_vm/src/ecmascript/builtins/array_buffer.rs b/nova_vm/src/ecmascript/builtins/array_buffer.rs index a0947335d..c649a2440 100644 --- a/nova_vm/src/ecmascript/builtins/array_buffer.rs +++ b/nova_vm/src/ecmascript/builtins/array_buffer.rs @@ -290,8 +290,10 @@ impl<'a> CreateHeapData, ArrayBuffer<'a>> for Heap { #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] #[repr(u8)] pub enum AnyArrayBuffer<'a> { + /// ## [25.1 ArrayBuffer Objects](https://tc39.es/ecma262/#sec-arraybuffer-objects) ArrayBuffer(ArrayBuffer<'a>) = ARRAY_BUFFER_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ## [25.2 SharedArrayBuffer Objects](https://tc39.es/ecma262/#sec-sharedarraybuffer-objects) SharedArrayBuffer(SharedArrayBuffer<'a>) = SHARED_ARRAY_BUFFER_DISCRIMINANT, } bindable_handle!(AnyArrayBuffer); diff --git a/nova_vm/src/ecmascript/builtins/builtin_constructor.rs b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs index 8362fb2e8..c6e2cab04 100644 --- a/nova_vm/src/ecmascript/builtins/builtin_constructor.rs +++ b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs @@ -24,7 +24,8 @@ use super::ArgumentsList; /// ### [4.4.36 built-in constructor](https://tc39.es/ecma262/#sec-built-in-constructor) /// -/// A class built-in default constructor created in step 14 of [ClassDefinitionEvaluation]. +/// A class built-in default constructor created in step 14 of +/// [ClassDefinitionEvaluation]. /// /// #### Examples /// @@ -45,12 +46,6 @@ arena_vec_access!( builtin_constructors ); -impl BuiltinConstructorFunction<'_> { - pub const fn is_constructor(self) -> bool { - true - } -} - impl<'a> FunctionInternalProperties<'a> for BuiltinConstructorFunction<'a> { fn get_name(self, agent: &Agent) -> &String<'a> { &self.get(agent).class_name diff --git a/nova_vm/src/ecmascript/builtins/builtin_function.rs b/nova_vm/src/ecmascript/builtins/builtin_function.rs index 4fa81a6e4..f42c14c3c 100644 --- a/nova_vm/src/ecmascript/builtins/builtin_function.rs +++ b/nova_vm/src/ecmascript/builtins/builtin_function.rs @@ -387,7 +387,10 @@ pub type ConstructorFn = for<'gc> fn( #[allow(unpredictable_function_pointer_comparisons)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Behaviour { + /// Regular JavaScript function not callable with the `new` keyword. Regular(RegularFn), + /// JavaScript function callable with the `new` keyword, and possibly + /// without it. Constructor(ConstructorFn), } @@ -446,27 +449,37 @@ pub(crate) trait BuiltinIntrinsic: Builtin { } /// Helper trait for defining builtin getter function properties. pub trait BuiltinGetter: Builtin { + /// Accessor property's getter function's `name` property value. const GETTER_NAME: String<'static> = Self::NAME; + /// Accessor property's getter function's call behaviour. const GETTER_BEHAVIOUR: Behaviour = Self::BEHAVIOUR; } /// Helper trait for defining builtin setter function properties. pub trait BuiltinSetter: Builtin { + /// Accessor property's setter function's `name` property value. const SETTER_NAME: String<'static> = Self::NAME; + /// Accessor property's setter function's call behaviour. const SETTER_BEHAVIOUR: Behaviour = Self::BEHAVIOUR; } /// Builtin function creation arguments. #[derive(Debug, Default)] pub struct BuiltinFunctionArgs<'a> { + /// The builtin function's `length` property initial value. pub length: u32, + /// The builtin function's `name` property initial value. pub name: &'static str, + /// The builtin function's Realm. Defaults to the current Realm. pub realm: Option>, + /// The builtin function's prototype. Defaults to the current Realm's + /// `Function.prototype` pub prototype: Option>, + /// An optional prefix for the builtin function's name. pub prefix: Option<&'static str>, } impl<'a> BuiltinFunctionArgs<'a> { - // Create new builtin function creation arguments with length and name. + /// Create new builtin function creation arguments with length and name. pub fn new(length: u32, name: &'static str) -> Self { Self { length, @@ -475,7 +488,7 @@ impl<'a> BuiltinFunctionArgs<'a> { } } - // Create new builtin function creation arguments with length, name, and a realm. + /// Create new builtin function creation arguments with length, name, and a realm. pub fn new_with_realm(length: u32, name: &'static str, realm: Realm<'a>) -> Self { Self { length, diff --git a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/iteration/iterator_prototype.rs b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/iteration/iterator_prototype.rs index f8c3c8967..4f22a77bb 100644 --- a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/iteration/iterator_prototype.rs +++ b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/iteration/iterator_prototype.rs @@ -81,6 +81,7 @@ impl Builtin for IteratorPrototypeToStringTag { const BEHAVIOUR: Behaviour = Behaviour::Regular(IteratorPrototype::get_to_string_tag); } impl BuiltinGetter for IteratorPrototypeToStringTag { + /// Accessor property's getter function's `name` property value. const GETTER_NAME: String<'static> = BUILTIN_STRING_MEMORY.get__Symbol_toStringTag_; } impl BuiltinSetter for IteratorPrototypeToStringTag { diff --git a/nova_vm/src/ecmascript/builtins/data_view.rs b/nova_vm/src/ecmascript/builtins/data_view.rs index 3145a82d2..ec108189d 100644 --- a/nova_vm/src/ecmascript/builtins/data_view.rs +++ b/nova_vm/src/ecmascript/builtins/data_view.rs @@ -366,8 +366,12 @@ impl HeapSweepWeakReference for SharedDataView<'static> { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(u8)] pub enum AnyDataView<'a> { + /// ## [25.3 DataView Objects](https://tc39.es/ecma262/#sec-dataview-objects) DataView(DataView<'a>) = DATA_VIEW_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ## [25.3 DataView Objects](https://tc39.es/ecma262/#sec-dataview-objects) + /// + /// A variant of DataView Objects viewing a SharedArrayBuffer. SharedDataView(SharedDataView<'a>) = SHARED_DATA_VIEW_DISCRIMINANT, } bindable_handle!(AnyDataView); diff --git a/nova_vm/src/ecmascript/builtins/ecmascript_function.rs b/nova_vm/src/ecmascript/builtins/ecmascript_function.rs index 117d8f533..d2ebc374b 100644 --- a/nova_vm/src/ecmascript/builtins/ecmascript_function.rs +++ b/nova_vm/src/ecmascript/builtins/ecmascript_function.rs @@ -969,7 +969,6 @@ pub(crate) fn make_constructor<'a>( Function::BuiltinConstructorFunction(_) | Function::BuiltinPromiseResolvingFunction(_) | Function::BuiltinPromiseFinallyFunction(_) - | Function::BuiltinPromiseCollectorFunction | Function::BuiltinProxyRevokerFunction => unreachable!(), } // 5. If prototype is not present, then @@ -1162,7 +1161,6 @@ pub(crate) fn set_function_name<'a>( Function::BuiltinConstructorFunction(_) | Function::BuiltinPromiseResolvingFunction(_) | Function::BuiltinPromiseFinallyFunction(_) - | Function::BuiltinPromiseCollectorFunction | Function::BuiltinProxyRevokerFunction => unreachable!(), } } diff --git a/nova_vm/src/ecmascript/builtins/finalization_registry/data.rs b/nova_vm/src/ecmascript/builtins/finalization_registry/data.rs index 82170c23a..846cc0c37 100644 --- a/nova_vm/src/ecmascript/builtins/finalization_registry/data.rs +++ b/nova_vm/src/ecmascript/builtins/finalization_registry/data.rs @@ -79,7 +79,7 @@ impl Default for CleanupRecord<'_> { Self { cleanup_queue: Default::default(), // Note: impossible value currently. - callback: Function::BuiltinPromiseCollectorFunction, + callback: Function::BuiltinProxyRevokerFunction, realm: Realm::_DEF, cleanup_requested: false, } @@ -102,7 +102,7 @@ impl<'fr> CleanupRecord<'fr> { /// FinalizationRegistry must be previously uninitialised. pub(super) unsafe fn initialise(&mut self, realm: Realm, cleanup_callback: Function) { debug_assert_eq!(self.realm, Realm::_DEF); - debug_assert_eq!(self.callback, Function::BuiltinPromiseCollectorFunction); + debug_assert_eq!(self.callback, Function::BuiltinProxyRevokerFunction); self.realm = realm.unbind(); self.callback = cleanup_callback.unbind(); } diff --git a/nova_vm/src/ecmascript/builtins/fundamental_objects/function_objects/function_prototype.rs b/nova_vm/src/ecmascript/builtins/fundamental_objects/function_objects/function_prototype.rs index 440aeaefb..754980064 100644 --- a/nova_vm/src/ecmascript/builtins/fundamental_objects/function_objects/function_prototype.rs +++ b/nova_vm/src/ecmascript/builtins/fundamental_objects/function_objects/function_prototype.rs @@ -416,7 +416,7 @@ impl FunctionPrototype { .unbind(), ) } - Function::BuiltinPromiseCollectorFunction | Function::BuiltinProxyRevokerFunction => { + Function::BuiltinProxyRevokerFunction => { unreachable!() } } diff --git a/nova_vm/src/ecmascript/builtins/managing_memory/finalization_registry_objects/finalization_registry_constructor.rs b/nova_vm/src/ecmascript/builtins/managing_memory/finalization_registry_objects/finalization_registry_constructor.rs index 27f757694..a0a5981b9 100644 --- a/nova_vm/src/ecmascript/builtins/managing_memory/finalization_registry_objects/finalization_registry_constructor.rs +++ b/nova_vm/src/ecmascript/builtins/managing_memory/finalization_registry_objects/finalization_registry_constructor.rs @@ -98,7 +98,6 @@ impl FinalizationRegistryConstructor { Function::BuiltinPromiseFinallyFunction(_) => { unreachable!("builtin promise finally function constructing FinalizationRegistry") } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), }; // 6. Set finalizationRegistry.[[CleanupCallback]] to diff --git a/nova_vm/src/ecmascript/builtins/regexp.rs b/nova_vm/src/ecmascript/builtins/regexp.rs index 81854e298..fdd55f95d 100644 --- a/nova_vm/src/ecmascript/builtins/regexp.rs +++ b/nova_vm/src/ecmascript/builtins/regexp.rs @@ -39,6 +39,15 @@ use super::ordinary::{ /// /// > NOTE: The form and functionality of regular expressions is modelled after /// > the regular expression facility in the Perl 5 programming language. +/// +/// ## Support status +/// +/// `RegExp` in Nova does not currently conform to the ECMAScript specification. +/// The 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. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct RegExp<'a>(BaseIndex<'a, RegExpHeapData<'static>>); diff --git a/nova_vm/src/ecmascript/builtins/typed_array/any_typed_array.rs b/nova_vm/src/ecmascript/builtins/typed_array/any_typed_array.rs index 5391eb4af..2abdcdd46 100644 --- a/nova_vm/src/ecmascript/builtins/typed_array/any_typed_array.rs +++ b/nova_vm/src/ecmascript/builtins/typed_array/any_typed_array.rs @@ -50,42 +50,114 @@ use crate::{ #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(u8)] pub enum AnyTypedArray<'a> { + /// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) + /// + /// An `i8` view into an ArrayBuffer. Int8Array(Int8Array<'a>) = INT_8_ARRAY_DISCRIMINANT, + /// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) + /// + /// A `u8` view into an ArrayBuffer. Uint8Array(Uint8Array<'a>) = UINT_8_ARRAY_DISCRIMINANT, + /// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) + /// + /// A `u8` view into an ArrayBuffer with clamping behaviour on assignment. Uint8ClampedArray(Uint8ClampedArray<'a>) = UINT_8_CLAMPED_ARRAY_DISCRIMINANT, + /// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) + /// + /// An `i16` view into an ArrayBuffer. Int16Array(Int16Array<'a>) = INT_16_ARRAY_DISCRIMINANT, + /// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) + /// + /// A `u16` view into an ArrayBuffer. Uint16Array(Uint16Array<'a>) = UINT_16_ARRAY_DISCRIMINANT, + /// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) + /// + /// An `i32` view into an ArrayBuffer. Int32Array(Int32Array<'a>) = INT_32_ARRAY_DISCRIMINANT, + /// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) + /// + /// A `u32` view into an ArrayBuffer. Uint32Array(Uint32Array<'a>) = UINT_32_ARRAY_DISCRIMINANT, + /// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) + /// + /// An `i64` view into an ArrayBuffer. BigInt64Array(BigInt64Array<'a>) = BIGINT_64_ARRAY_DISCRIMINANT, + /// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) + /// + /// A `u64` view into an ArrayBuffer. BigUint64Array(BigUint64Array<'a>) = BIGUINT_64_ARRAY_DISCRIMINANT, #[cfg(feature = "proposal-float16array")] + /// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) + /// + /// An `f16` view into an ArrayBuffer. Float16Array(Float16Array<'a>) = FLOAT_16_ARRAY_DISCRIMINANT, + /// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) + /// + /// An `f32` view into an ArrayBuffer. Float32Array(Float32Array<'a>) = FLOAT_32_ARRAY_DISCRIMINANT, + /// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) + /// + /// An `f64` view into an ArrayBuffer. Float64Array(Float64Array<'a>) = FLOAT_64_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) + /// + /// An `i8` view into a SharedArrayBuffer. SharedInt8Array(SharedInt8Array<'a>) = SHARED_INT_8_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) + /// + /// A `u8` view into a SharedArrayBuffer. SharedUint8Array(SharedUint8Array<'a>) = SHARED_UINT_8_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) + /// + /// A `u8` view into an ArrayBuffer with clamping behaviour o Sharedassignment. SharedUint8ClampedArray(SharedUint8ClampedArray<'a>) = SHARED_UINT_8_CLAMPED_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) + /// + /// An `i16` view into a SharedArrayBuffer. SharedInt16Array(SharedInt16Array<'a>) = SHARED_INT_16_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) + /// + /// A `u16` view into a SharedArrayBuffer. SharedUint16Array(SharedUint16Array<'a>) = SHARED_UINT_16_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) + /// + /// An `i32` view into a SharedArrayBuffer. SharedInt32Array(SharedInt32Array<'a>) = SHARED_INT_32_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) + /// + /// A `u32` view into a SharedArrayBuffer. SharedUint32Array(SharedUint32Array<'a>) = SHARED_UINT_32_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) + /// + /// An `i64` view into a SharedArrayBuffer. SharedBigInt64Array(SharedBigInt64Array<'a>) = SHARED_BIGINT_64_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) + /// + /// A `u64` view into a SharedArrayBuffer. SharedBigUint64Array(SharedBigUint64Array<'a>) = SHARED_BIGUINT_64_ARRAY_DISCRIMINANT, #[cfg(all(feature = "proposal-float16array", feature = "shared-array-buffer"))] + /// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) + /// + /// An `f16` view into a SharedArrayBuffer. SharedFloat16Array(SharedFloat16Array<'a>) = SHARED_FLOAT_16_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) + /// + /// An `f32` view into a SharedArrayBuffer. SharedFloat32Array(SharedFloat32Array<'a>) = SHARED_FLOAT_32_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) + /// + /// An `f64` view into a SharedArrayBuffer. SharedFloat64Array(SharedFloat64Array<'a>) = SHARED_FLOAT_64_ARRAY_DISCRIMINANT, } bindable_handle!(AnyTypedArray); diff --git a/nova_vm/src/ecmascript/builtins/typed_array/normal_typed_array.rs b/nova_vm/src/ecmascript/builtins/typed_array/normal_typed_array.rs index e115df0e5..f514dede0 100644 --- a/nova_vm/src/ecmascript/builtins/typed_array/normal_typed_array.rs +++ b/nova_vm/src/ecmascript/builtins/typed_array/normal_typed_array.rs @@ -297,18 +297,54 @@ impl<'gc> VoidArray<'gc> { } } +/// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) +/// +/// An `i8` view into an ArrayBuffer. pub type Uint8Array<'a> = GenericTypedArray<'a, u8>; +/// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) +/// +/// A `u8` view into an ArrayBuffer. pub type Uint8ClampedArray<'a> = GenericTypedArray<'a, U8Clamped>; +/// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) +/// +/// A `u8` view into an ArrayBuffer with clamping behaviour on assignment. pub type Int8Array<'a> = GenericTypedArray<'a, i8>; +/// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) +/// +/// An `i16` view into an ArrayBuffer. pub type Uint16Array<'a> = GenericTypedArray<'a, u16>; +/// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) +/// +/// A `u16` view into an ArrayBuffer. pub type Int16Array<'a> = GenericTypedArray<'a, i16>; +/// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) +/// +/// An `i32` view into an ArrayBuffer. pub type Uint32Array<'a> = GenericTypedArray<'a, u32>; +/// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) +/// +/// A `u32` view into an ArrayBuffer. pub type Int32Array<'a> = GenericTypedArray<'a, i32>; +/// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) +/// +/// An `i64` view into an ArrayBuffer. pub type BigUint64Array<'a> = GenericTypedArray<'a, u64>; +/// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) +/// +/// A `u64` view into an ArrayBuffer. pub type BigInt64Array<'a> = GenericTypedArray<'a, i64>; #[cfg(feature = "proposal-float16array")] +/// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) +/// +/// An `f16` view into an ArrayBuffer. pub type Float16Array<'a> = GenericTypedArray<'a, f16>; +/// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) +/// +/// An `f32` view into an ArrayBuffer. pub type Float32Array<'a> = GenericTypedArray<'a, f32>; +/// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) +/// +/// An `f64` view into an ArrayBuffer. pub type Float64Array<'a> = GenericTypedArray<'a, f64>; /// ## [23.2 TypedArray Objects](https://tc39.es/ecma262/#sec-typedarray-objects) @@ -322,18 +358,54 @@ pub type Float64Array<'a> = GenericTypedArray<'a, f64>; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(u8)] pub enum TypedArray<'a> { + /// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) + /// + /// An `i8` view into an ArrayBuffer. Int8Array(Int8Array<'a>) = INT_8_ARRAY_DISCRIMINANT, + /// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) + /// + /// A `u8` view into an ArrayBuffer. Uint8Array(Uint8Array<'a>) = UINT_8_ARRAY_DISCRIMINANT, + /// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) + /// + /// A `u8` view into an ArrayBuffer with clamping behaviour on assignment. Uint8ClampedArray(Uint8ClampedArray<'a>) = UINT_8_CLAMPED_ARRAY_DISCRIMINANT, + /// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) + /// + /// An `i16` view into an ArrayBuffer. Int16Array(Int16Array<'a>) = INT_16_ARRAY_DISCRIMINANT, + /// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) + /// + /// A `u16` view into an ArrayBuffer. Uint16Array(Uint16Array<'a>) = UINT_16_ARRAY_DISCRIMINANT, + /// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) + /// + /// An `i32` view into an ArrayBuffer. Int32Array(Int32Array<'a>) = INT_32_ARRAY_DISCRIMINANT, + /// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) + /// + /// A `u32` view into an ArrayBuffer. Uint32Array(Uint32Array<'a>) = UINT_32_ARRAY_DISCRIMINANT, + /// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) + /// + /// An `i64` view into an ArrayBuffer. BigInt64Array(BigInt64Array<'a>) = BIGINT_64_ARRAY_DISCRIMINANT, + /// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) + /// + /// A `u64` view into an ArrayBuffer. BigUint64Array(BigUint64Array<'a>) = BIGUINT_64_ARRAY_DISCRIMINANT, #[cfg(feature = "proposal-float16array")] + /// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) + /// + /// An `f16` view into an ArrayBuffer. Float16Array(Float16Array<'a>) = FLOAT_16_ARRAY_DISCRIMINANT, + /// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) + /// + /// An `f32` view into an ArrayBuffer. Float32Array(Float32Array<'a>) = FLOAT_32_ARRAY_DISCRIMINANT, + /// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) + /// + /// An `f64` view into an ArrayBuffer. Float64Array(Float64Array<'a>) = FLOAT_64_ARRAY_DISCRIMINANT, } bindable_handle!(TypedArray); diff --git a/nova_vm/src/ecmascript/builtins/typed_array/shared_typed_array.rs b/nova_vm/src/ecmascript/builtins/typed_array/shared_typed_array.rs index dc7cf0191..cdde6a21f 100644 --- a/nova_vm/src/ecmascript/builtins/typed_array/shared_typed_array.rs +++ b/nova_vm/src/ecmascript/builtins/typed_array/shared_typed_array.rs @@ -264,18 +264,54 @@ pub(crate) type SharedVoidArray<'a> = GenericSharedTypedArray<'a, ()>; impl<'gc> SharedVoidArray<'gc> {} +/// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) +/// +/// An `i8` view into a SharedArrayBuffer. pub type SharedUint8Array<'a> = GenericSharedTypedArray<'a, u8>; +/// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) +/// +/// A `u8` view into a SharedArrayBuffer. pub type SharedUint8ClampedArray<'a> = GenericSharedTypedArray<'a, U8Clamped>; +/// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) +/// +/// A `u8` view into an ArrayBuffer with clamping behaviour o Sharedassignment. pub type SharedInt8Array<'a> = GenericSharedTypedArray<'a, i8>; +/// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) +/// +/// An `i16` view into a SharedArrayBuffer. pub type SharedUint16Array<'a> = GenericSharedTypedArray<'a, u16>; +/// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) +/// +/// A `u16` view into a SharedArrayBuffer. pub type SharedInt16Array<'a> = GenericSharedTypedArray<'a, i16>; +/// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) +/// +/// An `i32` view into a SharedArrayBuffer. pub type SharedUint32Array<'a> = GenericSharedTypedArray<'a, u32>; +/// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) +/// +/// A `u32` view into a SharedArrayBuffer. pub type SharedInt32Array<'a> = GenericSharedTypedArray<'a, i32>; +/// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) +/// +/// An `i64` view into a SharedArrayBuffer. pub type SharedBigUint64Array<'a> = GenericSharedTypedArray<'a, u64>; +/// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) +/// +/// A `u64` view into a SharedArrayBuffer. pub type SharedBigInt64Array<'a> = GenericSharedTypedArray<'a, i64>; #[cfg(feature = "proposal-float16array")] +/// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) +/// +/// An `f16` view into a SharedArrayBuffer. pub type SharedFloat16Array<'a> = GenericSharedTypedArray<'a, f16>; +/// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) +/// +/// An `f32` view into a SharedArrayBuffer. pub type SharedFloat32Array<'a> = GenericSharedTypedArray<'a, f32>; +/// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) +/// +/// An `f64` view into a SharedArrayBuffer. pub type SharedFloat64Array<'a> = GenericSharedTypedArray<'a, f64>; macro_rules! shared_typed_array_delegate { @@ -599,18 +635,54 @@ impl<'a> InternalMethods<'a> for SharedTypedArray<'a> { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(u8)] pub enum SharedTypedArray<'a> { + /// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) + /// + /// An `i8` view into a SharedArrayBuffer. SharedInt8Array(SharedInt8Array<'a>) = SHARED_INT_8_ARRAY_DISCRIMINANT, + /// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) + /// + /// A `u8` view into a SharedArrayBuffer. SharedUint8Array(SharedUint8Array<'a>) = SHARED_UINT_8_ARRAY_DISCRIMINANT, + /// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) + /// + /// A `u8` view into an ArrayBuffer with clamping behaviour o Sharedassignment. SharedUint8ClampedArray(SharedUint8ClampedArray<'a>) = SHARED_UINT_8_CLAMPED_ARRAY_DISCRIMINANT, + /// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) + /// + /// An `i16` view into a SharedArrayBuffer. SharedInt16Array(SharedInt16Array<'a>) = SHARED_INT_16_ARRAY_DISCRIMINANT, + /// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) + /// + /// A `u16` view into a SharedArrayBuffer. SharedUint16Array(SharedUint16Array<'a>) = SHARED_UINT_16_ARRAY_DISCRIMINANT, + /// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) + /// + /// An `i32` view into a SharedArrayBuffer. SharedInt32Array(SharedInt32Array<'a>) = SHARED_INT_32_ARRAY_DISCRIMINANT, + /// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) + /// + /// A `u32` view into a SharedArrayBuffer. SharedUint32Array(SharedUint32Array<'a>) = SHARED_UINT_32_ARRAY_DISCRIMINANT, + /// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) + /// + /// An `i64` view into a SharedArrayBuffer. SharedBigInt64Array(SharedBigInt64Array<'a>) = SHARED_BIGINT_64_ARRAY_DISCRIMINANT, + /// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) + /// + /// A `u64` view into a SharedArrayBuffer. SharedBigUint64Array(SharedBigUint64Array<'a>) = SHARED_BIGUINT_64_ARRAY_DISCRIMINANT, #[cfg(feature = "proposal-float16array")] + /// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) + /// + /// An `f16` view into a SharedArrayBuffer. SharedFloat16Array(SharedFloat16Array<'a>) = SHARED_FLOAT_16_ARRAY_DISCRIMINANT, + /// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) + /// + /// An `f32` view into a SharedArrayBuffer. SharedFloat32Array(SharedFloat32Array<'a>) = SHARED_FLOAT_32_ARRAY_DISCRIMINANT, + /// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) + /// + /// An `f64` view into a SharedArrayBuffer. SharedFloat64Array(SharedFloat64Array<'a>) = SHARED_FLOAT_64_ARRAY_DISCRIMINANT, } bindable_handle!(SharedTypedArray); diff --git a/nova_vm/src/ecmascript/execution/agent.rs b/nova_vm/src/ecmascript/execution/agent.rs index edf4980ea..0125a2adf 100644 --- a/nova_vm/src/ecmascript/execution/agent.rs +++ b/nova_vm/src/ecmascript/execution/agent.rs @@ -278,7 +278,7 @@ pub struct Job { } impl Job { - // Returns `true` if the Job has finished and can be run. + /// Returns `true` if the Job has finished and can be run. pub fn is_finished(&self) -> bool { match &self.inner { #[cfg(feature = "atomics")] @@ -332,16 +332,28 @@ impl Job { } } +/// Parameter to [HostPromiseRejectionTracker] embedder hook. +/// +/// [HostPromiseRejectionTracker]: https://tc39.es/ecma262/#sec-host-promise-rejection-tracker +#[derive(Clone, Copy, PartialEq, Eq)] pub enum PromiseRejectionTrackerOperation { + /// A Promise was rejected without any handlers. Reject, + /// A handler was added to a rejected Promise for the first time. Handle, } #[derive(Clone, Copy, Default, PartialEq, Eq)] #[cfg(feature = "shared-array-buffer")] +/// Parameter to [HostGrowSharedArrayBuffer] embedder hook. +/// +/// [HostGrowSharedArrayBuffer]: https://tc39.es/ecma262/#sec-hostgrowsharedarraybuffer pub enum GrowSharedArrayBufferResult { + /// Returned when the embedder does not handle growing of this + /// SharedArrayBuffer. #[default] Unhandled = 0, + /// Returned when the embedder did handle growing of this SharedArrayBuffer. Handled = 1, } @@ -1560,13 +1572,21 @@ pub(crate) fn resolve_binding<'a, 'b>( /// Native error types. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ExceptionType { + /// ### [19.3.10 Error ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-error) Error, + /// ### [19.3.1 AggregateError ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-aggregate-error) AggregateError, + /// ### [19.3.11 EvalError ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-evalerror) EvalError, + /// ### [19.3.26 RangeError ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-rangeerror) RangeError, + /// ### [19.3.27 ReferenceError ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-referenceerror) ReferenceError, + /// ### [19.3.33 SyntaxError ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-syntaxerror) SyntaxError, + /// ### [19.3.34 TypeError ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-typeerror) TypeError, + /// ### [19.3.39 URIError ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-urierror) UriError, } diff --git a/nova_vm/src/ecmascript/execution/realm/intrinsics.rs b/nova_vm/src/ecmascript/execution/realm/intrinsics.rs index 42a4410f3..5dc347177 100644 --- a/nova_vm/src/ecmascript/execution/realm/intrinsics.rs +++ b/nova_vm/src/ecmascript/execution/realm/intrinsics.rs @@ -77,87 +77,252 @@ pub(crate) struct Intrinsics { #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[non_exhaustive] pub enum ProtoIntrinsics { + /// ```javascript + /// AggregateError.prototype + /// ``` AggregateError, + /// ```javascript + /// Array.prototype + /// ``` Array, #[cfg(feature = "array-buffer")] + /// ```javascript + /// ArrayBuffer.prototype + /// ``` ArrayBuffer, + /// ```javascript + /// Object.getPrototypeOf([].values()) + /// ``` ArrayIterator, + /// ```javascript + /// Object.getPrototypeOf(async () => {}) + /// ``` AsyncFunction, + /// ```javascript + /// Object.getPrototypeOf(Object.getPrototypeOf(async function*() {}())) + /// ``` AsyncGenerator, + /// ```javascript + /// Object.getPrototypeOf(async function*() {}) + /// ``` AsyncGeneratorFunction, + /// ```javascript + /// BigInt.prototype + /// ``` BigInt, #[cfg(feature = "array-buffer")] + /// ```javascript + /// BigInt64Array.prototype + /// ``` BigInt64Array, #[cfg(feature = "array-buffer")] + /// ```javascript + /// BigUint64Array.prototype + /// ``` BigUint64Array, + /// ```javascript + /// Boolean.prototype + /// ``` Boolean, #[cfg(feature = "array-buffer")] + /// ```javascript + /// DataView.prototype + /// ``` DataView, #[cfg(feature = "shared-array-buffer")] + /// ```javascript + /// DataView.prototype + /// ``` SharedDataView, #[cfg(feature = "date")] + /// ```javascript + /// Date.prototype + /// ``` Date, + /// ```javascript + /// Error.prototype + /// ``` Error, + /// ```javascript + /// EvalError.prototype + /// ``` EvalError, + /// ```javascript + /// FinalizationRegistry.prototype + /// ``` FinalizationRegistry, #[cfg(feature = "proposal-float16array")] + /// ```javascript + /// Float16Array.prototype + /// ``` Float16Array, #[cfg(feature = "array-buffer")] + /// ```javascript + /// Float32Array.prototype + /// ``` Float32Array, #[cfg(feature = "array-buffer")] + /// ```javascript + /// Float64Array.prototype + /// ``` Float64Array, + /// ```javascript + /// Function.prototype + /// ``` Function, + /// ```javascript + /// Generator.prototype + /// ``` Generator, + /// ```javascript + /// GeneratorFunction.prototype + /// ``` GeneratorFunction, #[cfg(feature = "array-buffer")] + /// ```javascript + /// Int16Array.prototype + /// ``` Int16Array, #[cfg(feature = "array-buffer")] + /// ```javascript + /// Int32Array.prototype + /// ``` Int32Array, #[cfg(feature = "array-buffer")] + /// ```javascript + /// Int8Array.prototype + /// ``` Int8Array, + /// ```javascript + /// Iterator.prototype + /// ``` Iterator, + /// ```javascript + /// Map.prototype + /// ``` Map, + /// ```javascript + /// Object.getPrototypeOf(new Map().values()) + /// ``` MapIterator, + /// ```javascript + /// Number.prototype + /// ``` Number, + /// ```javascript + /// Object.prototype + /// ``` Object, + /// ```javascript + /// Promise.prototype + /// ``` Promise, + /// ```javascript + /// RangeError.prototype + /// ``` RangeError, + /// ```javascript + /// ReferenceError.prototype + /// ``` ReferenceError, #[cfg(feature = "regexp")] + /// ```javascript + /// RegExp.prototype + /// ``` RegExp, #[cfg(feature = "set")] + /// ```javascript + /// Set.prototype + /// ``` Set, #[cfg(feature = "set")] + /// ```javascript + /// Object.getPrototypeOf(new Set().values()) + /// ``` SetIterator, #[cfg(feature = "shared-array-buffer")] + /// ```javascript + /// SharedArrayBuffer.prototype + /// ``` SharedArrayBuffer, + /// ```javascript + /// String.prototype + /// ``` String, + /// ```javascript + /// Object.getPrototypeOf(""[Symbol.iterator]()) + /// ``` StringIterator, #[cfg(feature = "regexp")] + /// ```javascript + /// Object.getPrototypeOf("".matchAll(/./g)) + /// ``` RegExpStringIterator, + /// ```javascript + /// Symbol.prototype + /// ``` Symbol, + /// ```javascript + /// SyntaxError.prototype + /// ``` SyntaxError, #[cfg(feature = "temporal")] + /// ```javascript + /// TemporalInstant.prototype + /// ``` TemporalInstant, #[cfg(feature = "temporal")] + /// ```javascript + /// TemporalDuration.prototype + /// ``` TemporalDuration, #[cfg(feature = "temporal")] + /// ```javascript + /// TemporalPlainTime.prototype + /// ``` TemporalPlainTime, + /// ```javascript + /// TypeError.prototype + /// ``` TypeError, #[cfg(feature = "array-buffer")] + /// ```javascript + /// Uint16Array.prototype + /// ``` Uint16Array, #[cfg(feature = "array-buffer")] + /// ```javascript + /// Uint32Array.prototype + /// ``` Uint32Array, #[cfg(feature = "array-buffer")] + /// ```javascript + /// Uint8Array.prototype + /// ``` Uint8Array, #[cfg(feature = "array-buffer")] + /// ```javascript + /// Uint8ClampedArray.prototype + /// ``` Uint8ClampedArray, + /// ```javascript + /// URIError.prototype + /// ``` URIError, #[cfg(feature = "weak-refs")] + /// ```javascript + /// WeakMap.prototype + /// ``` WeakMap, #[cfg(feature = "weak-refs")] + /// ```javascript + /// WeakRef.prototype + /// ``` WeakRef, #[cfg(feature = "weak-refs")] + /// ```javascript + /// WeakSet.prototype + /// ``` WeakSet, } diff --git a/nova_vm/src/ecmascript/execution/weak_key.rs b/nova_vm/src/ecmascript/execution/weak_key.rs index 7ba997f2d..af93af89b 100644 --- a/nova_vm/src/ecmascript/execution/weak_key.rs +++ b/nova_vm/src/ecmascript/execution/weak_key.rs @@ -64,8 +64,7 @@ use crate::{ ARGUMENTS_DISCRIMINANT, ARRAY_DISCRIMINANT, ARRAY_ITERATOR_DISCRIMINANT, ASYNC_GENERATOR_DISCRIMINANT, Array, ArrayIterator, AsyncGenerator, BOUND_FUNCTION_DISCRIMINANT, BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, - BUILTIN_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, - BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, + BUILTIN_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BUILTIN_PROXY_REVOKER_FUNCTION, BoundFunction, BuiltinConstructorFunction, BuiltinFunction, BuiltinPromiseFinallyFunction, BuiltinPromiseResolvingFunction, ECMASCRIPT_FUNCTION_DISCRIMINANT, ECMAScriptFunction, @@ -98,7 +97,6 @@ pub(crate) enum WeakKey<'a> { BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BuiltinPromiseFinallyFunction(BuiltinPromiseFinallyFunction<'a>) = BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, - BuiltinPromiseCollectorFunction = BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, BuiltinProxyRevokerFunction = BUILTIN_PROXY_REVOKER_FUNCTION, PrimitiveObject(PrimitiveObject<'a>) = PRIMITIVE_OBJECT_DISCRIMINANT, Arguments(UnmappedArguments<'a>) = ARGUMENTS_DISCRIMINANT, @@ -218,7 +216,6 @@ impl<'a> From> for Value<'a> { WeakKey::BuiltinConstructorFunction(d) => Self::BuiltinConstructorFunction(d), WeakKey::BuiltinPromiseResolvingFunction(d) => Self::BuiltinPromiseResolvingFunction(d), WeakKey::BuiltinPromiseFinallyFunction(d) => Self::BuiltinPromiseFinallyFunction(d), - WeakKey::BuiltinPromiseCollectorFunction => Self::BuiltinPromiseCollectorFunction, WeakKey::BuiltinProxyRevokerFunction => Self::BuiltinProxyRevokerFunction, WeakKey::PrimitiveObject(d) => Self::PrimitiveObject(d), WeakKey::Arguments(d) => Self::Arguments(d), @@ -331,7 +328,6 @@ impl<'a> From> for WeakKey<'a> { Object::BuiltinConstructorFunction(d) => Self::BuiltinConstructorFunction(d), Object::BuiltinPromiseResolvingFunction(d) => Self::BuiltinPromiseResolvingFunction(d), Object::BuiltinPromiseFinallyFunction(d) => Self::BuiltinPromiseFinallyFunction(d), - Object::BuiltinPromiseCollectorFunction => Self::BuiltinPromiseCollectorFunction, Object::BuiltinProxyRevokerFunction => Self::BuiltinProxyRevokerFunction, Object::PrimitiveObject(d) => Self::PrimitiveObject(d), Object::Arguments(d) => Self::Arguments(d), @@ -448,7 +444,6 @@ impl<'a> TryFrom> for Object<'a> { Ok(Self::BuiltinPromiseResolvingFunction(d)) } WeakKey::BuiltinPromiseFinallyFunction(d) => Ok(Self::BuiltinPromiseFinallyFunction(d)), - WeakKey::BuiltinPromiseCollectorFunction => Ok(Self::BuiltinPromiseCollectorFunction), WeakKey::BuiltinProxyRevokerFunction => Ok(Self::BuiltinProxyRevokerFunction), WeakKey::PrimitiveObject(d) => Ok(Self::PrimitiveObject(d)), WeakKey::Arguments(d) => Ok(Self::Arguments(d)), @@ -612,7 +607,6 @@ impl HeapMarkAndSweep for WeakKey<'static> { Self::BuiltinConstructorFunction(d) => d.mark_values(queues), Self::BuiltinPromiseResolvingFunction(d) => d.mark_values(queues), Self::BuiltinPromiseFinallyFunction(d) => d.mark_values(queues), - Self::BuiltinPromiseCollectorFunction => {} Self::BuiltinProxyRevokerFunction => {} Self::PrimitiveObject(d) => d.mark_values(queues), Self::Arguments(d) => d.mark_values(queues), @@ -723,7 +717,6 @@ impl HeapMarkAndSweep for WeakKey<'static> { Self::BuiltinConstructorFunction(d) => d.sweep_values(compactions), Self::BuiltinPromiseResolvingFunction(d) => d.sweep_values(compactions), Self::BuiltinPromiseFinallyFunction(d) => d.sweep_values(compactions), - Self::BuiltinPromiseCollectorFunction => {} Self::BuiltinProxyRevokerFunction => {} Self::PrimitiveObject(d) => d.sweep_values(compactions), Self::Arguments(d) => d.sweep_values(compactions), @@ -848,7 +841,6 @@ impl HeapSweepWeakReference for WeakKey<'static> { Self::BuiltinPromiseFinallyFunction(data) => data .sweep_weak_reference(compactions) .map(Self::BuiltinPromiseFinallyFunction), - Self::BuiltinPromiseCollectorFunction => Some(Self::BuiltinPromiseCollectorFunction), Self::BuiltinProxyRevokerFunction => Some(Self::BuiltinProxyRevokerFunction), Self::PrimitiveObject(data) => data .sweep_weak_reference(compactions) diff --git a/nova_vm/src/ecmascript/types/language/bigint.rs b/nova_vm/src/ecmascript/types/language/bigint.rs index 9ac101ef2..64e9b3337 100644 --- a/nova_vm/src/ecmascript/types/language/bigint.rs +++ b/nova_vm/src/ecmascript/types/language/bigint.rs @@ -132,7 +132,10 @@ impl TryFrom<&num_bigint::BigInt> for SmallBigInt { #[derive(Debug, Clone, Copy)] #[repr(u8)] pub enum BigInt<'a> { + /// Unlimited size integer data on the heap. Accessing the data can only be + /// done through the Agent. BigInt(HeapBigInt<'a>) = BIGINT_DISCRIMINANT, + /// 56-bit signed integer on the stack. SmallBigInt(SmallBigInt) = SMALL_BIGINT_DISCRIMINANT, } @@ -156,6 +159,7 @@ impl<'a> BigInt<'a> { } } + /// Returns the `0n` value. pub const fn zero() -> Self { Self::SmallBigInt(SmallBigInt::zero()) } diff --git a/nova_vm/src/ecmascript/types/language/bigint/small_bigint.rs b/nova_vm/src/ecmascript/types/language/bigint/small_bigint.rs index 4ca2a07c0..5af137126 100644 --- a/nova_vm/src/ecmascript/types/language/bigint/small_bigint.rs +++ b/nova_vm/src/ecmascript/types/language/bigint/small_bigint.rs @@ -26,10 +26,12 @@ impl core::hash::Hash for SmallBigInt { } impl SmallBigInt { + /// Minimum value that can be represented as a SmallBigInt. pub const MIN: i64 = -(2i64.pow(55)); + /// Maximum value that can be represented as a SmallBigInt pub const MAX: i64 = 2i64.pow(55) - 1; - // Returns true if SmallBigInt equals zero. + /// Returns true if SmallBigInt equals zero. pub const fn is_zero(self) -> bool { let Self { data: [a, b, c, d, e, f, g], @@ -37,6 +39,7 @@ impl SmallBigInt { a == 0 && b == 0 && c == 0 && d == 0 && e == 0 && f == 0 && g == 0 } + /// Returns the contained value as an i64. #[inline] pub const fn into_i64(self) -> i64 { let SmallBigInt { data } = self; @@ -57,6 +60,7 @@ impl SmallBigInt { } } + /// Returns the `0n` value. pub const fn zero() -> SmallBigInt { Self { data: [0, 0, 0, 0, 0, 0, 0], diff --git a/nova_vm/src/ecmascript/types/language/function.rs b/nova_vm/src/ecmascript/types/language/function.rs index ce5400dc9..46be6a6db 100644 --- a/nova_vm/src/ecmascript/types/language/function.rs +++ b/nova_vm/src/ecmascript/types/language/function.rs @@ -12,7 +12,6 @@ use crate::{ ecmascript::{ Agent, ArgumentsList, BOUND_FUNCTION_DISCRIMINANT, BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, BUILTIN_FUNCTION_DISCRIMINANT, - BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BUILTIN_PROXY_REVOKER_FUNCTION, BoundFunction, BuiltinConstructorFunction, BuiltinFunction, BuiltinPromiseFinallyFunction, @@ -34,16 +33,28 @@ use crate::{ #[derive(Clone, Copy, PartialEq, Eq)] #[repr(u8)] pub enum Function<'a> { + /// ### [10.4.1 Bound Function Exotic Objects](https://tc39.es/ecma262/#sec-bound-function-exotic-objects) BoundFunction(BoundFunction<'a>) = BOUND_FUNCTION_DISCRIMINANT, + /// ## [10.3 Built-in Function Objects](https://tc39.es/ecma262/#sec-built-in-function-objects) BuiltinFunction(BuiltinFunction<'a>) = BUILTIN_FUNCTION_DISCRIMINANT, + /// ## [10.2 ECMAScript Function Objects](https://tc39.es/ecma262/#sec-ecmascript-function-objects) ECMAScriptFunction(ECMAScriptFunction<'a>) = ECMASCRIPT_FUNCTION_DISCRIMINANT, + /// ### [4.4.36 built-in constructor](https://tc39.es/ecma262/#sec-built-in-constructor) + /// + /// A class built-in default constructor created in step 14 of + /// ClassDefinitionEvaluation. BuiltinConstructorFunction(BuiltinConstructorFunction<'a>) = BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, + /// Special built-in functions created to resolve or reject native [`Promise`] + /// objects. + /// + /// [`Promise`]: crate::ecmascript::Promise BuiltinPromiseResolvingFunction(BuiltinPromiseResolvingFunction<'a>) = BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, + /// Special functions created as part of `Promise.prototype.finally`. BuiltinPromiseFinallyFunction(BuiltinPromiseFinallyFunction<'a>) = BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, - BuiltinPromiseCollectorFunction = BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, + /// Placeholder. BuiltinProxyRevokerFunction = BUILTIN_PROXY_REVOKER_FUNCTION, } bindable_handle!(Function); @@ -74,7 +85,6 @@ impl Function<'_> { Function::BuiltinPromiseResolvingFunction(_) => false, Function::BuiltinPromiseFinallyFunction(_) => false, Function::BuiltinConstructorFunction(_) => true, - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -108,7 +118,6 @@ impl core::fmt::Debug for Function<'_> { Self::BuiltinPromiseFinallyFunction(d) => { write!(f, "BuiltinPromiseFinallyFunction({d:?})") } - Self::BuiltinPromiseCollectorFunction => todo!(), Self::BuiltinProxyRevokerFunction => todo!(), } } @@ -134,7 +143,6 @@ impl<'a> InternalSlots<'a> for Function<'a> { Function::BuiltinConstructorFunction(d) => d.get_backing_object(agent), Function::BuiltinPromiseResolvingFunction(d) => d.get_backing_object(agent), Function::BuiltinPromiseFinallyFunction(d) => d.get_backing_object(agent), - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -161,7 +169,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinConstructorFunction(x) => x.try_get_prototype_of(agent, gc), Function::BuiltinPromiseResolvingFunction(x) => x.try_get_prototype_of(agent, gc), Function::BuiltinPromiseFinallyFunction(x) => x.try_get_prototype_of(agent, gc), - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -183,7 +190,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.try_set_prototype_of(agent, prototype, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -200,7 +206,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinConstructorFunction(x) => x.try_is_extensible(agent, gc), Function::BuiltinPromiseResolvingFunction(x) => x.try_is_extensible(agent, gc), Function::BuiltinPromiseFinallyFunction(x) => x.try_is_extensible(agent, gc), - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -217,7 +222,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinConstructorFunction(x) => x.try_prevent_extensions(agent, gc), Function::BuiltinPromiseResolvingFunction(x) => x.try_prevent_extensions(agent, gc), Function::BuiltinPromiseFinallyFunction(x) => x.try_prevent_extensions(agent, gc), - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -244,7 +248,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.try_get_own_property(agent, property_key, cache, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -276,7 +279,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.try_define_own_property(agent, property_key, property_descriptor, cache, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -301,7 +303,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.try_has_property(agent, property_key, cache, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -325,7 +326,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.internal_has_property(agent, property_key, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -351,7 +351,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.try_get(agent, property_key, receiver, cache, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -376,7 +375,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.internal_get(agent, property_key, receiver, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -409,7 +407,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.try_set(agent, property_key, value, receiver, cache, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -439,7 +436,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.internal_set(agent, property_key, value, receiver, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -457,7 +453,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinConstructorFunction(x) => x.try_delete(agent, property_key, gc), Function::BuiltinPromiseResolvingFunction(x) => x.try_delete(agent, property_key, gc), Function::BuiltinPromiseFinallyFunction(x) => x.try_delete(agent, property_key, gc), - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -474,7 +469,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinConstructorFunction(x) => x.try_own_property_keys(agent, gc), Function::BuiltinPromiseResolvingFunction(x) => x.try_own_property_keys(agent, gc), Function::BuiltinPromiseFinallyFunction(x) => x.try_own_property_keys(agent, gc), - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -498,7 +492,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(f) => { f.get_own_property_at_offset(agent, offset, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -519,7 +512,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { f.set_at_offset(agent, props, offset, gc) } Function::BuiltinPromiseFinallyFunction(f) => f.set_at_offset(agent, props, offset, gc), - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -544,7 +536,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.internal_call(agent, this_argument, arguments, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -571,7 +562,6 @@ impl<'a> InternalMethods<'a> for Function<'a> { Function::BuiltinPromiseFinallyFunction(x) => { x.internal_construct(agent, arguments, new_target, gc) } - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -586,7 +576,6 @@ impl HeapMarkAndSweep for Function<'static> { Function::BuiltinConstructorFunction(x) => x.mark_values(queues), Function::BuiltinPromiseResolvingFunction(x) => x.mark_values(queues), Function::BuiltinPromiseFinallyFunction(x) => x.mark_values(queues), - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -599,7 +588,6 @@ impl HeapMarkAndSweep for Function<'static> { Function::BuiltinConstructorFunction(x) => x.sweep_values(compactions), Function::BuiltinPromiseResolvingFunction(x) => x.sweep_values(compactions), Function::BuiltinPromiseFinallyFunction(x) => x.sweep_values(compactions), - Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } } @@ -618,7 +606,6 @@ impl<'a> From> for Value<'a> { Self::BuiltinPromiseResolvingFunction(d) } Function::BuiltinPromiseFinallyFunction(d) => Self::BuiltinPromiseFinallyFunction(d), - Function::BuiltinPromiseCollectorFunction => Self::BuiltinPromiseCollectorFunction, Function::BuiltinProxyRevokerFunction => Self::BuiltinProxyRevokerFunction, } } @@ -633,7 +620,6 @@ impl<'a> From> for HeapRootData { Function::BuiltinConstructorFunction(d) => Self::from(d), Function::BuiltinPromiseResolvingFunction(d) => Self::from(d), Function::BuiltinPromiseFinallyFunction(d) => Self::from(d), - Function::BuiltinPromiseCollectorFunction => Self::BuiltinPromiseCollectorFunction, Function::BuiltinProxyRevokerFunction => Self::BuiltinProxyRevokerFunction, } } @@ -649,7 +635,6 @@ impl<'a> TryFrom> for Function<'a> { Value::BuiltinPromiseResolvingFunction(data) => { Ok(Self::BuiltinPromiseResolvingFunction(data)) } - Value::BuiltinPromiseCollectorFunction => Ok(Self::BuiltinPromiseCollectorFunction), Value::BuiltinProxyRevokerFunction => Ok(Self::BuiltinProxyRevokerFunction), _ => Err(()), } @@ -669,9 +654,6 @@ impl TryFrom for Function<'_> { HeapRootData::BuiltinPromiseResolvingFunction(data) => { Ok(Self::BuiltinPromiseResolvingFunction(data)) } - HeapRootData::BuiltinPromiseCollectorFunction => { - Ok(Self::BuiltinPromiseCollectorFunction) - } HeapRootData::BuiltinProxyRevokerFunction => Ok(Self::BuiltinProxyRevokerFunction), _ => Err(()), } @@ -688,7 +670,6 @@ impl<'a> From> for Object<'a> { Self::BuiltinPromiseResolvingFunction(f) } Function::BuiltinPromiseFinallyFunction(f) => Self::BuiltinPromiseFinallyFunction(f), - Function::BuiltinPromiseCollectorFunction => Self::BuiltinPromiseCollectorFunction, Function::BuiltinProxyRevokerFunction => Self::BuiltinProxyRevokerFunction, } } @@ -704,7 +685,6 @@ impl<'a> TryFrom> for Function<'a> { Object::BuiltinPromiseResolvingFunction(data) => { Ok(Self::BuiltinPromiseResolvingFunction(data)) } - Object::BuiltinPromiseCollectorFunction => Ok(Self::BuiltinPromiseCollectorFunction), Object::BuiltinProxyRevokerFunction => Ok(Self::BuiltinProxyRevokerFunction), _ => Err(()), } diff --git a/nova_vm/src/ecmascript/types/language/number/small_integer.rs b/nova_vm/src/ecmascript/types/language/number/small_integer.rs index 265c89c8a..ebc3b0969 100644 --- a/nova_vm/src/ecmascript/types/language/number/small_integer.rs +++ b/nova_vm/src/ecmascript/types/language/number/small_integer.rs @@ -29,9 +29,16 @@ impl core::hash::Hash for SmallInteger { } impl SmallInteger { + /// Minimum value that can be represented as a SmallInteger. + /// + /// This corresponds with `Number.MIN_SAFE_INTEGER`. pub const MIN: i64 = -(2i64.pow(53)) + 1; + /// Maximum value that can be represented as a SmallInteger. + /// + /// This corresponds with `Number.MAX_SAFE_INTEGER`. pub const MAX: i64 = 2i64.pow(53) - 1; + /// Returns the contained value as an i64. #[inline] pub const fn into_i64(self) -> i64 { let SmallInteger { data } = self; @@ -52,6 +59,7 @@ impl SmallInteger { } } + /// Returns the `0` value. pub const fn zero() -> Self { Self { data: [0, 0, 0, 0, 0, 0, 0], diff --git a/nova_vm/src/ecmascript/types/language/numeric.rs b/nova_vm/src/ecmascript/types/language/numeric.rs index afadaf5e3..0615130c0 100644 --- a/nova_vm/src/ecmascript/types/language/numeric.rs +++ b/nova_vm/src/ecmascript/types/language/numeric.rs @@ -24,10 +24,27 @@ use crate::{ #[derive(Debug, Clone, Copy, PartialEq)] #[repr(u8)] pub enum Numeric<'a> { + /// ### [6.1.6.1 The Number Type](https://tc39.es/ecma262/#sec-ecmascript-language-types-number-type) + /// + /// f64 on the heap. Accessing the data can only be done through the Agent. Number(HeapNumber<'a>) = NUMBER_DISCRIMINANT, + /// ### [6.1.6.1 The Number Type](https://tc39.es/ecma262/#sec-ecmascript-language-types-number-type) + /// + /// 54-bit signed integer on the stack. Integer(SmallInteger) = INTEGER_DISCRIMINANT, + /// ### [6.1.6.1 The Number Type](https://tc39.es/ecma262/#sec-ecmascript-language-types-number-type) + /// + /// f64 with 8 trailing zeroes on the stack that are cut off to produce a + /// 56-bit value. SmallF64(SmallF64) = FLOAT_DISCRIMINANT, + /// ### [6.1.6.2 The BigInt Type](https://tc39.es/ecma262/#sec-ecmascript-language-types-bigint-type) + /// + /// Unlimited size integer data on the heap. Accessing the data can only be + /// done through the Agent. BigInt(HeapBigInt<'a>) = BIGINT_DISCRIMINANT, + /// ### [6.1.6.2 The BigInt Type](https://tc39.es/ecma262/#sec-ecmascript-language-types-bigint-type) + /// + /// 56-bit signed integer on the stack. SmallBigInt(SmallBigInt) = SMALL_BIGINT_DISCRIMINANT, } diff --git a/nova_vm/src/ecmascript/types/language/object.rs b/nova_vm/src/ecmascript/types/language/object.rs index 6c2cdf488..7a38b6c98 100644 --- a/nova_vm/src/ecmascript/types/language/object.rs +++ b/nova_vm/src/ecmascript/types/language/object.rs @@ -22,11 +22,10 @@ use crate::ecmascript::{ ARGUMENTS_DISCRIMINANT, ARRAY_DISCRIMINANT, ARRAY_ITERATOR_DISCRIMINANT, ASYNC_GENERATOR_DISCRIMINANT, BOUND_FUNCTION_DISCRIMINANT, BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, BUILTIN_FUNCTION_DISCRIMINANT, - BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, - BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BUILTIN_PROXY_REVOKER_FUNCTION, - ECMASCRIPT_FUNCTION_DISCRIMINANT, EMBEDDER_OBJECT_DISCRIMINANT, ERROR_DISCRIMINANT, - FINALIZATION_REGISTRY_DISCRIMINANT, Function, GENERATOR_DISCRIMINANT, MAP_DISCRIMINANT, - MAP_ITERATOR_DISCRIMINANT, MODULE_DISCRIMINANT, OBJECT_DISCRIMINANT, + BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, + BUILTIN_PROXY_REVOKER_FUNCTION, ECMASCRIPT_FUNCTION_DISCRIMINANT, EMBEDDER_OBJECT_DISCRIMINANT, + ERROR_DISCRIMINANT, FINALIZATION_REGISTRY_DISCRIMINANT, Function, GENERATOR_DISCRIMINANT, + MAP_DISCRIMINANT, MAP_ITERATOR_DISCRIMINANT, MODULE_DISCRIMINANT, OBJECT_DISCRIMINANT, PRIMITIVE_OBJECT_DISCRIMINANT, PROMISE_DISCRIMINANT, PROXY_DISCRIMINANT, STRING_ITERATOR_DISCRIMINANT, UnmappedArguments, Value, }; @@ -107,124 +106,240 @@ use std::collections::TryReserveError; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(u8)] pub enum Object<'a> { + /// ### [6.1.7 The Object Type](https://tc39.es/ecma262/#sec-object-type) Object(OrdinaryObject<'a>) = OBJECT_DISCRIMINANT, + /// ### [10.4.1 Bound Function Exotic Objects](https://tc39.es/ecma262/#sec-bound-function-exotic-objects) BoundFunction(BoundFunction<'a>) = BOUND_FUNCTION_DISCRIMINANT, + /// ## [10.3 Built-in Function Objects](https://tc39.es/ecma262/#sec-built-in-function-objects) BuiltinFunction(BuiltinFunction<'a>) = BUILTIN_FUNCTION_DISCRIMINANT, + /// ## [10.2 ECMAScript Function Objects](https://tc39.es/ecma262/#sec-ecmascript-function-objects) ECMAScriptFunction(ECMAScriptFunction<'a>) = ECMASCRIPT_FUNCTION_DISCRIMINANT, + /// ### [4.4.36 built-in constructor](https://tc39.es/ecma262/#sec-built-in-constructor) + /// + /// A class built-in default constructor created in step 14 of + /// ClassDefinitionEvaluation. BuiltinConstructorFunction(BuiltinConstructorFunction<'a>) = BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, + /// Special built-in functions created to resolve or reject native [`Promise`] + /// objects. + /// + /// [`Promise`]: crate::ecmascript::Promise BuiltinPromiseResolvingFunction(BuiltinPromiseResolvingFunction<'a>) = BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, + /// Special functions created as part of `Promise.prototype.finally`. BuiltinPromiseFinallyFunction(BuiltinPromiseFinallyFunction<'a>) = BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, - BuiltinPromiseCollectorFunction = BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, + /// Placeholder. BuiltinProxyRevokerFunction = BUILTIN_PROXY_REVOKER_FUNCTION, + /// Primitive objects are special objects that hold a primitive value in their + /// internal data. PrimitiveObject(PrimitiveObject<'a>) = PRIMITIVE_OBJECT_DISCRIMINANT, + /// ### [10.4.4 Arguments Exotic Objects](https://tc39.es/ecma262/#sec-arguments-exotic-objects) + /// + /// An unmapped arguments object is an ordinary object with an additional + /// internal slot \[\[ParameterMap]] whose value is always **undefined**. Arguments(UnmappedArguments<'a>) = ARGUMENTS_DISCRIMINANT, + /// ### [10.4.2 Array Exotic Objects](https://tc39.es/ecma262/#sec-array-exotic-objects) Array(Array<'a>) = ARRAY_DISCRIMINANT, #[cfg(feature = "date")] + /// ## [21.4 Date Objects](https://tc39.es/ecma262/#sec-date-objects) Date(Date<'a>) = DATE_DISCRIMINANT, #[cfg(feature = "temporal")] + /// # [8 Temporal.Instant Objects](https://tc39.es/proposal-temporal/#sec-temporal-instant-objects) Instant(TemporalInstant<'a>) = INSTANT_DISCRIMINANT, #[cfg(feature = "temporal")] + /// # [7 Temporal.Duration Objects](https://tc39.es/proposal-temporal/#sec-temporal-duration-objects) Duration(TemporalDuration<'a>) = DURATION_DISCRIMINANT, #[cfg(feature = "temporal")] + /// # [4 Temporal.PlainTime Objects](https://tc39.es/proposal-temporal/#sec-temporal-plaintime-objects) PlainTime(TemporalPlainTime<'a>) = PLAIN_TIME_DISCRIMINANT, + /// ## [20.5 Error Objects](https://tc39.es/ecma262/#sec-error-objects) Error(Error<'a>) = ERROR_DISCRIMINANT, + /// ## [26.2 FinalizationRegistry Objects](https://tc39.es/ecma262/#sec-finalization-registry-objects) FinalizationRegistry(FinalizationRegistry<'a>) = FINALIZATION_REGISTRY_DISCRIMINANT, + /// ## [24.1 Map Objects](https://tc39.es/ecma262/#sec-map-objects) Map(Map<'a>) = MAP_DISCRIMINANT, + /// ## [27.2 Promise Objects](https://tc39.es/ecma262/#sec-promise-objects) Promise(Promise<'a>) = PROMISE_DISCRIMINANT, + /// ## [28.2 Proxy Objects](https://tc39.es/ecma262/#sec-proxy-objects) Proxy(Proxy<'a>) = PROXY_DISCRIMINANT, #[cfg(feature = "regexp")] + /// ## [22.2 RegExp (Regular Expression) Objects](https://tc39.es/ecma262/#sec-regexp-regular-expression-objects) RegExp(RegExp<'a>) = REGEXP_DISCRIMINANT, #[cfg(feature = "set")] + /// ## [24.2 Set Objects](https://tc39.es/ecma262/#sec-set-objects) Set(Set<'a>) = SET_DISCRIMINANT, #[cfg(feature = "weak-refs")] + /// ## [24.3 WeakMap Objects](https://tc39.es/ecma262/#sec-weakmap-objects) WeakMap(WeakMap<'a>) = WEAK_MAP_DISCRIMINANT, #[cfg(feature = "weak-refs")] + /// ## [26.1 WeakRef Objects](https://tc39.es/ecma262/#sec-weak-ref-objects) WeakRef(WeakRef<'a>) = WEAK_REF_DISCRIMINANT, #[cfg(feature = "weak-refs")] + /// ## [24.4 WeakSet Objects](https://tc39.es/ecma262/#sec-weakset-objects) WeakSet(WeakSet<'a>) = WEAK_SET_DISCRIMINANT, /// ## [25.1 ArrayBuffer Objects](https://tc39.es/ecma262/#sec-arraybuffer-objects) #[cfg(feature = "array-buffer")] ArrayBuffer(ArrayBuffer<'a>) = ARRAY_BUFFER_DISCRIMINANT, + /// ## [25.2 SharedArrayBuffer Objects](https://tc39.es/ecma262/#sec-sharedarraybuffer-objects) + #[cfg(feature = "shared-array-buffer")] + SharedArrayBuffer(SharedArrayBuffer<'a>) = SHARED_ARRAY_BUFFER_DISCRIMINANT, /// ## [25.3 DataView Objects](https://tc39.es/ecma262/#sec-dataview-objects) #[cfg(feature = "array-buffer")] DataView(DataView<'a>) = DATA_VIEW_DISCRIMINANT, + /// ## [25.3 DataView Objects](https://tc39.es/ecma262/#sec-dataview-objects) + /// + /// A variant of DataView Objects viewing a SharedArrayBuffer. + #[cfg(feature = "shared-array-buffer")] + SharedDataView(SharedDataView<'a>) = SHARED_DATA_VIEW_DISCRIMINANT, // ### [23.2 TypedArray Objects](https://tc39.es/ecma262/#sec-typedarray-objects) #[cfg(feature = "array-buffer")] + /// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) + /// + /// An `i8` view into an ArrayBuffer. Int8Array(Int8Array<'a>) = INT_8_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) + /// + /// A `u8` view into an ArrayBuffer. Uint8Array(Uint8Array<'a>) = UINT_8_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) + /// + /// A `u8` view into an ArrayBuffer with clamping behaviour on assignment. Uint8ClampedArray(Uint8ClampedArray<'a>) = UINT_8_CLAMPED_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) + /// + /// An `i16` view into an ArrayBuffer. Int16Array(Int16Array<'a>) = INT_16_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) + /// + /// A `u16` view into an ArrayBuffer. Uint16Array(Uint16Array<'a>) = UINT_16_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) + /// + /// An `i32` view into an ArrayBuffer. Int32Array(Int32Array<'a>) = INT_32_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) + /// + /// A `u32` view into an ArrayBuffer. Uint32Array(Uint32Array<'a>) = UINT_32_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) + /// + /// An `i64` view into an ArrayBuffer. BigInt64Array(BigInt64Array<'a>) = BIGINT_64_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) + /// + /// A `u64` view into an ArrayBuffer. BigUint64Array(BigUint64Array<'a>) = BIGUINT_64_ARRAY_DISCRIMINANT, #[cfg(feature = "proposal-float16array")] + /// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) + /// + /// An `f16` view into an ArrayBuffer. Float16Array(Float16Array<'a>) = FLOAT_16_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) + /// + /// An `f32` view into an ArrayBuffer. Float32Array(Float32Array<'a>) = FLOAT_32_ARRAY_DISCRIMINANT, #[cfg(feature = "array-buffer")] + /// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) + /// + /// An `f64` view into an ArrayBuffer. Float64Array(Float64Array<'a>) = FLOAT_64_ARRAY_DISCRIMINANT, - /// ## [25.2 SharedArrayBuffer Objects](https://tc39.es/ecma262/#sec-sharedarraybuffer-objects) - #[cfg(feature = "shared-array-buffer")] - SharedArrayBuffer(SharedArrayBuffer<'a>) = SHARED_ARRAY_BUFFER_DISCRIMINANT, - /// ## [25.3 DataView Objects](https://tc39.es/ecma262/#sec-dataview-objects) - /// - /// A variant of DataView Objects viewing a SharedArrayBuffer. - #[cfg(feature = "shared-array-buffer")] - SharedDataView(SharedDataView<'a>) = SHARED_DATA_VIEW_DISCRIMINANT, // ### [23.2 TypedArray Objects](https://tc39.es/ecma262/#sec-typedarray-objects) // // Variants of TypedArray Objects viewing a SharedArrayBuffer. #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) + /// + /// An `i8` view into a SharedArrayBuffer. SharedInt8Array(SharedInt8Array<'a>) = SHARED_INT_8_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) + /// + /// A `u8` view into a SharedArrayBuffer. SharedUint8Array(SharedUint8Array<'a>) = SHARED_UINT_8_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) + /// + /// A `u8` view into an ArrayBuffer with clamping behaviour o Sharedassignment. SharedUint8ClampedArray(SharedUint8ClampedArray<'a>) = SHARED_UINT_8_CLAMPED_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) + /// + /// An `i16` view into a SharedArrayBuffer. SharedInt16Array(SharedInt16Array<'a>) = SHARED_INT_16_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) + /// + /// A `u16` view into a SharedArrayBuffer. SharedUint16Array(SharedUint16Array<'a>) = SHARED_UINT_16_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) + /// + /// An `i32` view into a SharedArrayBuffer. SharedInt32Array(SharedInt32Array<'a>) = SHARED_INT_32_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) + /// + /// A `u32` view into a SharedArrayBuffer. SharedUint32Array(SharedUint32Array<'a>) = SHARED_UINT_32_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) + /// + /// An `i64` view into a SharedArrayBuffer. SharedBigInt64Array(SharedBigInt64Array<'a>) = SHARED_BIGINT_64_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) + /// + /// A `u64` view into a SharedArrayBuffer. SharedBigUint64Array(SharedBigUint64Array<'a>) = SHARED_BIGUINT_64_ARRAY_DISCRIMINANT, #[cfg(all(feature = "proposal-float16array", feature = "shared-array-buffer"))] + /// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) + /// + /// An `f16` view into a SharedArrayBuffer. SharedFloat16Array(SharedFloat16Array<'a>) = SHARED_FLOAT_16_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) + /// + /// An `f32` view into a SharedArrayBuffer. SharedFloat32Array(SharedFloat32Array<'a>) = SHARED_FLOAT_32_ARRAY_DISCRIMINANT, #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) + /// + /// An `f64` view into a SharedArrayBuffer. SharedFloat64Array(SharedFloat64Array<'a>) = SHARED_FLOAT_64_ARRAY_DISCRIMINANT, + /// ## [27.6 AsyncGenerator Objects](https://tc39.es/ecma262/#sec-asyncgenerator-objects) AsyncGenerator(AsyncGenerator<'a>) = ASYNC_GENERATOR_DISCRIMINANT, + /// ### [23.1.5 Array Iterator Objects](https://tc39.es/ecma262/#sec-array-iterator-objects) ArrayIterator(ArrayIterator<'a>) = ARRAY_ITERATOR_DISCRIMINANT, #[cfg(feature = "set")] + /// ### [24.2.6 Set Iterator Objects](https://tc39.es/ecma262/#sec-set-iterator-objects) SetIterator(SetIterator<'a>) = SET_ITERATOR_DISCRIMINANT, #[cfg(feature = "set")] + /// ### [24.1.5 Map Iterator Objects](https://tc39.es/ecma262/#sec-map-iterator-objects) MapIterator(MapIterator<'a>) = MAP_ITERATOR_DISCRIMINANT, + /// ### [22.1.5 String Iterator Objects](https://tc39.es/ecma262/#sec-string-iterator-objects) StringIterator(StringIterator<'a>) = STRING_ITERATOR_DISCRIMINANT, #[cfg(feature = "regexp")] + ///### [22.2.9 RegExp String Iterator Objects](https://tc39.es/ecma262/#sec-regexp-string-iterator-objects) RegExpStringIterator(RegExpStringIterator<'a>) = REGEXP_STRING_ITERATOR_DISCRIMINANT, + /// ## [27.5 Generator Objects](https://tc39.es/ecma262/#sec-generator-objects) Generator(Generator<'a>) = GENERATOR_DISCRIMINANT, + /// ### [10.4.6 Module Namespace Exotic Objects](https://tc39.es/ecma262/#sec-module-namespace-exotic-objects) Module(Module<'a>) = MODULE_DISCRIMINANT, + /// Embedder objects are intended for embedders to create objects with + /// native data embedded into them. EmbedderObject(EmbedderObject<'a>) = EMBEDDER_OBJECT_DISCRIMINANT, } @@ -668,7 +783,6 @@ impl<'a> From> for Value<'a> { Object::BuiltinPromiseFinallyFunction(data) => { Self::BuiltinPromiseFinallyFunction(data) } - Object::BuiltinPromiseCollectorFunction => Self::BuiltinPromiseCollectorFunction, Object::BuiltinProxyRevokerFunction => Self::BuiltinProxyRevokerFunction, Object::PrimitiveObject(data) => Self::PrimitiveObject(data), Object::Arguments(data) => Self::Arguments(data), @@ -818,7 +932,6 @@ macro_rules! object_delegate { Self::BuiltinConstructorFunction(data) => data.$method($($arg),+), Self::BuiltinPromiseResolvingFunction(data) => data.$method($($arg),+), Self::BuiltinPromiseFinallyFunction(data) => data.$method($($arg),+), - Self::BuiltinPromiseCollectorFunction => todo!(), Self::BuiltinProxyRevokerFunction => todo!(), Self::PrimitiveObject(data) => data.$method($($arg),+), Self::Arguments(data) => data.$method($($arg),+), @@ -1266,7 +1379,6 @@ impl HeapSweepWeakReference for Object<'static> { Self::BuiltinPromiseFinallyFunction(data) => data .sweep_weak_reference(compactions) .map(Self::BuiltinPromiseFinallyFunction), - Self::BuiltinPromiseCollectorFunction => todo!(), Self::BuiltinProxyRevokerFunction => todo!(), Self::PrimitiveObject(data) => data .sweep_weak_reference(compactions) @@ -1442,7 +1554,6 @@ impl From> for HeapRootData { Object::BuiltinConstructorFunction(d) => Self::from(d), Object::BuiltinPromiseResolvingFunction(d) => Self::from(d), Object::BuiltinPromiseFinallyFunction(d) => Self::from(d), - Object::BuiltinPromiseCollectorFunction => Self::BuiltinPromiseCollectorFunction, Object::BuiltinProxyRevokerFunction => Self::BuiltinProxyRevokerFunction, Object::PrimitiveObject(d) => Self::from(d), Object::Arguments(d) => Self::from(d), @@ -1561,9 +1672,6 @@ impl TryFrom for Object<'_> { HeapRootData::BuiltinConstructorFunction(f) => Ok(Self::BuiltinConstructorFunction(f)), HeapRootData::BuiltinPromiseResolvingFunction(f) => Ok(Self::from(f)), HeapRootData::BuiltinPromiseFinallyFunction(f) => Ok(Self::from(f)), - HeapRootData::BuiltinPromiseCollectorFunction => { - Ok(Self::BuiltinPromiseCollectorFunction) - } HeapRootData::BuiltinProxyRevokerFunction => Ok(Self::BuiltinProxyRevokerFunction), HeapRootData::PrimitiveObject(o) => Ok(Self::from(o)), HeapRootData::Arguments(o) => Ok(Self::from(o)), diff --git a/nova_vm/src/ecmascript/types/language/object/property_key.rs b/nova_vm/src/ecmascript/types/language/object/property_key.rs index 59b4e6e15..d4c7ecdeb 100644 --- a/nova_vm/src/ecmascript/types/language/object/property_key.rs +++ b/nova_vm/src/ecmascript/types/language/object/property_key.rs @@ -39,14 +39,33 @@ const PRIVATE_NAME_DISCRIMINANT: u8 = SYMBOL_DISCRIMINANT + 0b1000_0000; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[repr(u8)] pub enum PropertyKey<'a> { + /// ### [6.1.6.1 The Number Type](https://tc39.es/ecma262/#sec-ecmascript-language-types-number-type) + /// + /// 54-bit signed integer on the stack. Integer(SmallInteger) = INTEGER_DISCRIMINANT, + /// ### [6.1.4 The String Type](https://tc39.es/ecma262/#sec-ecmascript-language-types-string-type) + /// + /// 7-byte WTF-8 string on the stack. End of the string is determined by the + /// first 0xFF byte in the data. WTF-16 indexing is calculated on demand + /// from the data. SmallString(SmallString) = SMALL_STRING_DISCRIMINANT, + /// ### [6.1.4 The String Type](https://tc39.es/ecma262/#sec-ecmascript-language-types-string-type) + /// + /// WTF-8 string on the heap. Accessing the data can only be done through + /// the Agent. ECMAScript specification compliant WTF-16 indexing is + /// implemented through an index mapping. String(HeapString<'a>) = STRING_DISCRIMINANT, + /// ### [6.1.5 The Symbol Type](https://tc39.es/ecma262/#sec-ecmascript-language-types-symbol-type) Symbol(Symbol<'a>) = SYMBOL_DISCRIMINANT, + /// ### [6.2.12 Private Names](https://tc39.es/ecma262/#sec-private-names) PrivateName(PrivateName) = PRIVATE_NAME_DISCRIMINANT, } impl<'a> PropertyKey<'a> { + /// Perform a dummy scoping operation on a stack-allocated PropertyKey. + /// + /// This is useful when types dictate that scoping must be performed, but + /// the value is known to be stack-allocated. pub const fn scope_static(self) -> Scoped<'static, PropertyKey<'static>> { let key_root_repr = match self { PropertyKey::Integer(small_integer) => PropertyKeyRootRepr::Integer(small_integer), diff --git a/nova_vm/src/ecmascript/types/language/string.rs b/nova_vm/src/ecmascript/types/language/string.rs index d20edc47b..713be63c9 100644 --- a/nova_vm/src/ecmascript/types/language/string.rs +++ b/nova_vm/src/ecmascript/types/language/string.rs @@ -44,14 +44,17 @@ primitive_value!(SmallString); arena_vec_access!(HeapString, StringRecord, strings, StringRecord); impl HeapString<'_> { + /// Get the byte length of the heap-allocated String. pub fn len(self, agent: &Agent) -> usize { self.get(agent).len() } + /// Covert the heap-allocated String into UTF-8. pub fn to_string_lossy(self, agent: &Agent) -> Cow<'_, str> { self.get(agent).to_string_lossy() } + /// Get the heap-allocated String as UTF-8 if it is valid. pub fn as_str(self, agent: &Agent) -> Option<&str> { self.get(agent).as_str() } @@ -90,7 +93,13 @@ impl HeapString<'_> { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] #[repr(u8)] pub enum String<'a> { + /// WTF-8 string on the heap. Accessing the data can only be done through + /// the Agent. ECMAScript specification compliant WTF-16 indexing is + /// implemented through an index mapping. String(HeapString<'a>) = STRING_DISCRIMINANT, + /// 7-byte WTF-8 string on the stack. End of the string is determined by the + /// first 0xFF byte in the data. WTF-16 indexing is calculated on demand + /// from the data. SmallString(SmallString) = SMALL_STRING_DISCRIMINANT, } bindable_handle!(String); @@ -214,6 +223,7 @@ impl<'a> TryFrom> for SmallString { } impl<'a> String<'a> { + /// The empty string `""`. pub const EMPTY_STRING: String<'static> = String::from_small_string(""); /// Scope a stack-only String. Stack-only Strings do not need to store any @@ -231,10 +241,15 @@ impl<'a> String<'a> { Scoped::from_root_repr(key_root_repr) } + /// Returns true if this is the empty string `""`. pub fn is_empty_string(self) -> bool { self == Self::EMPTY_STRING } + /// Converts the string into a PropertyKey without checking for numeric + /// strings. + /// + /// This will cause erroneous behaviour if the string is eg. `"0"`. pub const fn to_property_key(self) -> PropertyKey<'a> { match self { String::String(data) => PropertyKey::String(data), @@ -251,6 +266,7 @@ impl<'a> String<'a> { String::SmallString(unsafe { SmallString::from_str_unchecked(message) }) } + /// Concatenate a list of JavaScript strings together. pub fn concat<'gc>( agent: &mut Agent, strings: impl AsRef<[Self]>, @@ -377,6 +393,9 @@ impl<'a> String<'a> { } #[inline(always)] + /// Get the WTF-16 code unit at a given WTF-16 code unit index. + /// + /// This is equivalent to the JavaScript `string.charCodeAt(idx)` method. pub fn char_code_at(self, agent: &Agent, idx: usize) -> CodePoint { self.char_code_at_(agent, idx) } @@ -389,6 +408,9 @@ impl<'a> String<'a> { } #[inline(always)] + /// Get the CodePoint at a given WTF-16 code unit index. + /// + /// This is equivalent to the JavaScript `string.codePointAt(idx)` method. pub fn code_point_at(self, agent: &Agent, utf16_idx: usize) -> CodePoint { self.code_point_at_(agent, utf16_idx) } @@ -481,6 +503,9 @@ impl<'a> String<'a> { } } + /// Return the string as a UTF-8 `&str` slice. This does not copy the data. + /// + /// Returns `None` if the string is not valid UTF-8. #[inline(always)] pub fn as_str(&self, agent: &Agent) -> Option<&str> { self.as_str_(agent) @@ -500,6 +525,7 @@ impl<'a> String<'a> { } } + /// Get the String data as a WTF-8 slice. #[inline(always)] pub fn as_wtf8(&self, agent: &Agent) -> &Wtf8 { self.as_wtf8_(agent) @@ -519,6 +545,7 @@ impl<'a> String<'a> { } } + /// Get the String data as a byte slice. #[inline(always)] pub fn as_bytes(&self, agent: &Agent) -> &[u8] { self.as_bytes_(agent) @@ -619,10 +646,14 @@ impl<'a> String<'a> { } impl<'gc> String<'gc> { + /// Create a [String] from a UTF-8 string slice. + /// + /// This copies the string data. pub fn from_str(agent: &mut Agent, str: &str, _gc: NoGcScope<'gc, '_>) -> Self { agent.heap.create(str) } + /// Create a [String] from a [CodePoint]. pub const fn from_code_point(cp: CodePoint) -> Self { // UTF-8 ranges and tags for encoding characters // Copied from 48d5fe9ec560b53b1f5069219b0d62015e1de5ba^:src/libcore/char.rs @@ -725,6 +756,11 @@ impl<'gc> String<'gc> { .ok_or(hash) } + /// Create a [String] from an owned Rust [`String`]. + /// + /// This does not copy the string data. + /// + /// [`String`]: std::string::String pub fn from_string( agent: &mut Agent, string: std::string::String, @@ -733,10 +769,14 @@ impl<'gc> String<'gc> { agent.heap.create(string).bind(gc) } + /// Create a [String] from a WTF-8 buffer. pub fn from_wtf8_buf(agent: &mut Agent, string: Wtf8Buf, gc: NoGcScope<'gc, '_>) -> Self { agent.heap.create(string).bind(gc) } + /// Create a [String] from a statically allocated UTF-8 string slice. + /// + /// This does not copy the string data. pub fn from_static_str(agent: &mut Agent, str: &'static str, _gc: NoGcScope<'gc, '_>) -> Self { if let Ok(value) = String::try_from(str) { value @@ -748,6 +788,7 @@ impl<'gc> String<'gc> { } impl Scoped<'_, String<'static>> { + /// Returns true if this is the empty string (`""`). pub fn is_empty_string(&self) -> bool { match self.inner { StringRootRepr::SmallString(s) => s.is_empty(), @@ -755,6 +796,7 @@ impl Scoped<'_, String<'static>> { } } + /// Covert the heap-allocated String into UTF-8. pub fn to_string_lossy<'string, 'agent: 'string>( &'string self, agent: &'agent Agent, diff --git a/nova_vm/src/ecmascript/types/language/string/data.rs b/nova_vm/src/ecmascript/types/language/string/data.rs index 949eb5c45..2d7f5fea0 100644 --- a/nova_vm/src/ecmascript/types/language/string/data.rs +++ b/nova_vm/src/ecmascript/types/language/string/data.rs @@ -69,7 +69,7 @@ impl StringRecord { const MAX_UTF8_LENGTH: usize = 3 * Self::MAX_UTF16_LENGTH; /// Get the byte length of the string. - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { match &self.data { StringBuffer::Owned(buf) => buf.len(), StringBuffer::Static(buf) => buf.len(), @@ -139,14 +139,17 @@ impl StringRecord { } /// Get the WTF-16 length of the string. - pub fn utf16_len(&self) -> usize { + pub(crate) fn utf16_len(&self) -> usize { match self.index_mapping() { IndexMapping::Ascii => self.len(), IndexMapping::NonAscii { mapping } => mapping.len(), } } - pub fn char_code_at(&self, idx: usize) -> CodePoint { + /// Get the WTF-16 code unit at a given WTF-16 code unit index. + /// + /// This is equivalent to the JavaScript `string.charCodeAt(idx)` method. + pub(crate) fn char_code_at(&self, idx: usize) -> CodePoint { let (utf8_idx, take_latter_half): (usize, bool) = if idx != 0 { match self.index_mapping() { IndexMapping::Ascii => { @@ -193,7 +196,7 @@ impl StringRecord { unsafe { CodePoint::from_u32_unchecked(surrogate as u32) } } - pub fn utf8_index(&self, utf16_idx: usize) -> Option { + pub(crate) fn utf8_index(&self, utf16_idx: usize) -> Option { if utf16_idx == 0 { Some(0) } else { @@ -213,7 +216,7 @@ impl StringRecord { } } - pub fn utf16_index(&self, utf8_idx: usize) -> usize { + pub(crate) fn utf16_index(&self, utf8_idx: usize) -> usize { if utf8_idx == 0 { 0 } else { @@ -275,7 +278,10 @@ impl StringRecord { } } - pub fn code_point_at(&self, utf16_idx: usize) -> CodePoint { + /// Get the CodePoint at a given WTF-16 code unit index. + /// + /// This is equivalent to the JavaScript `string.codePointAt(idx)` method. + pub(crate) fn code_point_at(&self, utf16_idx: usize) -> CodePoint { assert!(utf16_idx <= self.utf16_len()); let mapping = match self.index_mapping() { // SAFETY: ASCII is all valid CodePoints. @@ -327,7 +333,7 @@ impl StringRecord { /// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”). /// /// This only copies the data if necessary (if it contains any surrogate). - pub fn to_string_lossy(&self) -> Cow<'_, str> { + pub(crate) fn to_string_lossy(&self) -> Cow<'_, str> { self.as_wtf8().to_string_lossy() } @@ -337,24 +343,24 @@ impl StringRecord { /// /// This does not copy the data. #[inline] - pub fn as_str(&self) -> Option<&str> { + pub(crate) fn as_str(&self) -> Option<&str> { self.as_wtf8().as_str() } - pub fn as_bytes(&self) -> &[u8] { + pub(crate) fn as_bytes(&self) -> &[u8] { let buf = self.as_wtf8(); // SAFETY: converting to backing store data. unsafe { core::mem::transmute::<&Wtf8, &[u8]>(buf) } } - pub fn as_wtf8(&self) -> &Wtf8 { + pub(crate) fn as_wtf8(&self) -> &Wtf8 { match &self.data { StringBuffer::Owned(buf) => buf, StringBuffer::Static(buf) => buf, } } - pub fn from_str(str: &str) -> Self { + pub(crate) fn from_str(str: &str) -> Self { debug_assert!(str.len() > 7); assert!(str.len() <= Self::MAX_UTF8_LENGTH, "String is too long."); StringRecord { @@ -363,7 +369,7 @@ impl StringRecord { } } - pub fn from_static_str(str: &'static str) -> Self { + pub(crate) fn from_static_str(str: &'static str) -> Self { debug_assert!(str.len() > 7); assert!(str.len() <= Self::MAX_UTF8_LENGTH, "String is too long."); StringRecord { @@ -372,7 +378,7 @@ impl StringRecord { } } - pub fn from_string(str: String) -> Self { + pub(crate) fn from_string(str: String) -> Self { debug_assert!(str.len() > 7); assert!(str.len() <= Self::MAX_UTF8_LENGTH, "String is too long."); StringRecord { @@ -381,7 +387,7 @@ impl StringRecord { } } - pub fn from_wtf8_buf(str: Wtf8Buf) -> Self { + pub(crate) fn from_wtf8_buf(str: Wtf8Buf) -> Self { debug_assert!(str.len() > 7); assert!(str.len() <= Self::MAX_UTF8_LENGTH, "String is too long."); StringRecord { diff --git a/nova_vm/src/ecmascript/types/language/value.rs b/nova_vm/src/ecmascript/types/language/value.rs index e67358b93..3d71e667c 100644 --- a/nova_vm/src/ecmascript/types/language/value.rs +++ b/nova_vm/src/ecmascript/types/language/value.rs @@ -32,12 +32,12 @@ use crate::{ Agent, Array, ArrayIterator, AsyncGenerator, BUILTIN_STRING_MEMORY, BigInt, BoundFunction, BuiltinConstructorFunction, BuiltinFunction, BuiltinPromiseFinallyFunction, BuiltinPromiseResolvingFunction, ECMAScriptFunction, EmbedderObject, Error, - FinalizationRegistry, Generator, HeapBigInt, HeapNumber, HeapString, JsResult, Map, - MapIterator, Module, Number, Numeric, Object, OrdinaryObject, Primitive, PrimitiveObject, - Promise, Proxy, SmallBigInt, SmallF64, SmallInteger, SmallString, String, StringIterator, - Symbol, TryResult, UnmappedArguments, to_big_int, to_big_int64, to_big_uint64, to_int8, - to_int16, to_int32, to_number, to_numeric, to_string, to_uint8, to_uint8_clamp, to_uint16, - to_uint32, try_result_into_js, try_to_string, + FinalizationRegistry, Function, Generator, HeapBigInt, HeapNumber, HeapString, JsResult, + Map, MapIterator, Module, Number, Numeric, Object, OrdinaryObject, Primitive, + PrimitiveObject, Promise, Proxy, SmallBigInt, SmallF64, SmallInteger, SmallString, String, + StringIterator, Symbol, TryResult, UnmappedArguments, to_big_int, to_big_int64, + to_big_uint64, to_int8, to_int16, to_int32, to_number, to_numeric, to_string, to_uint8, + to_uint8_clamp, to_uint16, to_uint32, try_result_into_js, try_to_string, }, engine::{ Bindable, GcScope, HeapRootData, HeapRootRef, NoGcScope, Rootable, Scoped, bindable_handle, @@ -150,18 +150,29 @@ pub enum Value<'a> { Object(OrdinaryObject<'a>), // Functions + /// ### [10.4.1 Bound Function Exotic Objects](https://tc39.es/ecma262/#sec-bound-function-exotic-objects) BoundFunction(BoundFunction<'a>), + /// ## [10.3 Built-in Function Objects](https://tc39.es/ecma262/#sec-built-in-function-objects) BuiltinFunction(BuiltinFunction<'a>), + /// ## [10.2 ECMAScript Function Objects](https://tc39.es/ecma262/#sec-ecmascript-function-objects) ECMAScriptFunction(ECMAScriptFunction<'a>), - /// Default class constructor created in step 14 of - ///# [ClassDefinitionEvaluation](https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation). + /// ### [4.4.36 built-in constructor](https://tc39.es/ecma262/#sec-built-in-constructor) + /// + /// A class built-in default constructor created in step 14 of + /// ClassDefinitionEvaluation. BuiltinConstructorFunction(BuiltinConstructorFunction<'a>), + /// Special built-in functions created to resolve or reject native [`Promise`] + /// objects. + /// + /// [`Promise`]: crate::ecmascript::Promise BuiltinPromiseResolvingFunction(BuiltinPromiseResolvingFunction<'a>), + /// Special functions created as part of `Promise.prototype.finally`. BuiltinPromiseFinallyFunction(BuiltinPromiseFinallyFunction<'a>), - BuiltinPromiseCollectorFunction, + /// Placeholder. BuiltinProxyRevokerFunction, - // Boolean, Number, String, Symbol, BigInt objects + /// Primitive objects are special objects that hold a primitive value in their + /// internal data. PrimitiveObject(PrimitiveObject<'a>), // Well-known object types @@ -175,115 +186,210 @@ pub enum Value<'a> { /// internal slot \[\[ParameterMap]] whose value is always **undefined**. Arguments(UnmappedArguments<'a>), // TODO: MappedArguments(MappedArgumentsObject), + /// ### [10.4.2 Array Exotic Objects](https://tc39.es/ecma262/#sec-array-exotic-objects) Array(Array<'a>), #[cfg(feature = "date")] + /// ## [21.4 Date Objects](https://tc39.es/ecma262/#sec-date-objects) Date(Date<'a>), #[cfg(feature = "temporal")] + /// # [8 Temporal.Instant Objects](https://tc39.es/proposal-temporal/#sec-temporal-instant-objects) Instant(TemporalInstant<'a>), #[cfg(feature = "temporal")] + /// # [7 Temporal.Duration Objects](https://tc39.es/proposal-temporal/#sec-temporal-duration-objects) Duration(TemporalDuration<'a>), #[cfg(feature = "temporal")] + /// # [4 Temporal.PlainTime Objects](https://tc39.es/proposal-temporal/#sec-temporal-plaintime-objects) PlainTime(TemporalPlainTime<'a>), + /// ## [20.5 Error Objects](https://tc39.es/ecma262/#sec-error-objects) Error(Error<'a>), + /// ## [26.2 FinalizationRegistry Objects](https://tc39.es/ecma262/#sec-finalization-registry-objects) FinalizationRegistry(FinalizationRegistry<'a>), + /// ## [24.1 Map Objects](https://tc39.es/ecma262/#sec-map-objects) Map(Map<'a>), + /// ## [27.2 Promise Objects](https://tc39.es/ecma262/#sec-promise-objects) Promise(Promise<'a>), + /// ## [28.2 Proxy Objects](https://tc39.es/ecma262/#sec-proxy-objects) Proxy(Proxy<'a>), #[cfg(feature = "regexp")] + /// ## [22.2 RegExp (Regular Expression) Objects](https://tc39.es/ecma262/#sec-regexp-regular-expression-objects) RegExp(RegExp<'a>), #[cfg(feature = "set")] + /// ## [24.2 Set Objects](https://tc39.es/ecma262/#sec-set-objects) Set(Set<'a>), #[cfg(feature = "weak-refs")] + /// ## [24.3 WeakMap Objects](https://tc39.es/ecma262/#sec-weakmap-objects) WeakMap(WeakMap<'a>), #[cfg(feature = "weak-refs")] + /// ## [26.1 WeakRef Objects](https://tc39.es/ecma262/#sec-weak-ref-objects) WeakRef(WeakRef<'a>), #[cfg(feature = "weak-refs")] + /// ## [24.4 WeakSet Objects](https://tc39.es/ecma262/#sec-weakset-objects) WeakSet(WeakSet<'a>), /// ## [25.1 ArrayBuffer Objects](https://tc39.es/ecma262/#sec-arraybuffer-objects) #[cfg(feature = "array-buffer")] ArrayBuffer(ArrayBuffer<'a>), + /// ## [25.2 SharedArrayBuffer Objects](https://tc39.es/ecma262/#sec-sharedarraybuffer-objects) + #[cfg(feature = "shared-array-buffer")] + SharedArrayBuffer(SharedArrayBuffer<'a>), /// ## [25.3 DataView Objects](https://tc39.es/ecma262/#sec-dataview-objects) #[cfg(feature = "array-buffer")] DataView(DataView<'a>), + /// ## [25.3 DataView Objects](https://tc39.es/ecma262/#sec-dataview-objects) + /// + /// A variant of DataView Objects viewing a SharedArrayBuffer. + #[cfg(feature = "shared-array-buffer")] + SharedDataView(SharedDataView<'a>), // ### [23.2 TypedArray Objects](https://tc39.es/ecma262/#sec-typedarray-objects) #[cfg(feature = "array-buffer")] + /// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) + /// + /// An `i8` view into an ArrayBuffer. Int8Array(Int8Array<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) + /// + /// A `u8` view into an ArrayBuffer. Uint8Array(Uint8Array<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) + /// + /// A `u8` view into an ArrayBuffer with clamping behaviour on assignment. Uint8ClampedArray(Uint8ClampedArray<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) + /// + /// An `i16` view into an ArrayBuffer. Int16Array(Int16Array<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) + /// + /// A `u16` view into an ArrayBuffer. Uint16Array(Uint16Array<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) + /// + /// An `i32` view into an ArrayBuffer. Int32Array(Int32Array<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) + /// + /// A `u32` view into an ArrayBuffer. Uint32Array(Uint32Array<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) + /// + /// An `i64` view into an ArrayBuffer. BigInt64Array(BigInt64Array<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) + /// + /// A `u64` view into an ArrayBuffer. BigUint64Array(BigUint64Array<'a>), #[cfg(feature = "proposal-float16array")] + /// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) + /// + /// An `f16` view into an ArrayBuffer. Float16Array(Float16Array<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) + /// + /// An `f32` view into an ArrayBuffer. Float32Array(Float32Array<'a>), #[cfg(feature = "array-buffer")] + /// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) + /// + /// An `f64` view into an ArrayBuffer. Float64Array(Float64Array<'a>), - /// ## [25.2 SharedArrayBuffer Objects](https://tc39.es/ecma262/#sec-sharedarraybuffer-objects) - #[cfg(feature = "shared-array-buffer")] - SharedArrayBuffer(SharedArrayBuffer<'a>), - /// ## [25.3 DataView Objects](https://tc39.es/ecma262/#sec-dataview-objects) - /// - /// A variant of DataView Objects viewing a SharedArrayBuffer. - #[cfg(feature = "shared-array-buffer")] - SharedDataView(SharedDataView<'a>), // ### [23.2 TypedArray Objects](https://tc39.es/ecma262/#sec-typedarray-objects) // // Variants of TypedArray Objects viewing a SharedArrayBuffer. #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.17 Int8Array ( . . . )](https://tc39.es/ecma262/#sec-int8array) + /// + /// An `i8` view into a SharedArrayBuffer. SharedInt8Array(SharedInt8Array<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.35 Uint8Array ( . . . )](https://tc39.es/ecma262/#sec-uint8array) + /// + /// A `u8` view into a SharedArrayBuffer. SharedUint8Array(SharedUint8Array<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.36 Uint8ClampedArray ( . . . )](https://tc39.es/ecma262/#sec-uint8clampedarray) + /// + /// A `u8` view into an ArrayBuffer with clamping behaviour o Sharedassignment. SharedUint8ClampedArray(SharedUint8ClampedArray<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.18 Int16Array ( . . . )](https://tc39.es/ecma262/#sec-int16array) + /// + /// An `i16` view into a SharedArrayBuffer. SharedInt16Array(SharedInt16Array<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.37 Uint16Array ( . . . )](https://tc39.es/ecma262/#sec-uint16array) + /// + /// A `u16` view into a SharedArrayBuffer. SharedUint16Array(SharedUint16Array<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.19 Int32Array ( . . . )](https://tc39.es/ecma262/#sec-int32array) + /// + /// An `i32` view into a SharedArrayBuffer. SharedInt32Array(SharedInt32Array<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.38 Uint32Array ( . . . )](https://tc39.es/ecma262/#sec-uint32array) + /// + /// A `u32` view into a SharedArrayBuffer. SharedUint32Array(SharedUint32Array<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.5 BigInt64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-bigint64array) + /// + /// An `i64` view into a SharedArrayBuffer. SharedBigInt64Array(SharedBigInt64Array<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.6 BigUint64Array ( . . . )](https://tc39.es/ecma262/#sec-constructor-properties-of-the-global-object-biguint64array) + /// + /// A `u64` view into a SharedArrayBuffer. SharedBigUint64Array(SharedBigUint64Array<'a>), #[cfg(all(feature = "proposal-float16array", feature = "shared-array-buffer"))] + /// ### [19.3.13 Float16Array ( . . . )](https://tc39.es/ecma262/#sec-float16array) + /// + /// An `f16` view into a SharedArrayBuffer. SharedFloat16Array(SharedFloat16Array<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.13 Float32Array ( . . . )](https://tc39.es/ecma262/#sec-float32array) + /// + /// An `f32` view into a SharedArrayBuffer. SharedFloat32Array(SharedFloat32Array<'a>), #[cfg(feature = "shared-array-buffer")] + /// ### [19.3.13 Float64Array ( . . . )](https://tc39.es/ecma262/#sec-float64array) + /// + /// An `f64` view into a SharedArrayBuffer. SharedFloat64Array(SharedFloat64Array<'a>), // Iterator objects + /// ## [27.6 AsyncGenerator Objects](https://tc39.es/ecma262/#sec-asyncgenerator-objects) AsyncGenerator(AsyncGenerator<'a>), + /// ### [23.1.5 Array Iterator Objects](https://tc39.es/ecma262/#sec-array-iterator-objects) ArrayIterator(ArrayIterator<'a>), #[cfg(feature = "set")] + /// ### [24.2.6 Set Iterator Objects](https://tc39.es/ecma262/#sec-set-iterator-objects) SetIterator(SetIterator<'a>), #[cfg(feature = "set")] + /// ### [24.1.5 Map Iterator Objects](https://tc39.es/ecma262/#sec-map-iterator-objects) MapIterator(MapIterator<'a>), + /// ### [22.1.5 String Iterator Objects](https://tc39.es/ecma262/#sec-string-iterator-objects) StringIterator(StringIterator<'a>), #[cfg(feature = "regexp")] + ///### [22.2.9 RegExp String Iterator Objects](https://tc39.es/ecma262/#sec-regexp-string-iterator-objects) RegExpStringIterator(RegExpStringIterator<'a>), + /// ## [27.5 Generator Objects](https://tc39.es/ecma262/#sec-generator-objects) Generator(Generator<'a>), - // ECMAScript Module + /// ### [10.4.6 Module Namespace Exotic Objects](https://tc39.es/ecma262/#sec-module-namespace-exotic-objects) Module(Module<'a>), - // Embedder objects + /// Embedder objects are intended for embedders to create objects with + /// native data embedded into them. EmbedderObject(EmbedderObject<'a>) = 0x7f, } @@ -347,8 +453,6 @@ pub(crate) const BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT: u8 = value_dis pub(crate) const BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT: u8 = value_discriminant( Value::BuiltinPromiseFinallyFunction(BuiltinPromiseFinallyFunction::_DEF), ); -pub(crate) const BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT: u8 = - value_discriminant(Value::BuiltinPromiseCollectorFunction); pub(crate) const BUILTIN_PROXY_REVOKER_FUNCTION: u8 = value_discriminant(Value::BuiltinProxyRevokerFunction); pub(crate) const PRIMITIVE_OBJECT_DISCRIMINANT: u8 = @@ -500,10 +604,18 @@ impl<'a> Value<'a> { Scoped::from_root_repr(key_root_repr) } + /// Create a [Value] from a UTF-8 string slice. + /// + /// This copies the string data. pub fn from_str(agent: &mut Agent, str: &str, gc: NoGcScope<'a, '_>) -> Value<'a> { String::from_str(agent, str, gc).into() } + /// Create a [Value] from an owned Rust [`String`]. + /// + /// This does not copy the string data. + /// + /// [`String`]: std::string::String pub fn from_string( agent: &mut Agent, string: std::string::String, @@ -512,6 +624,9 @@ impl<'a> Value<'a> { String::from_string(agent, string, gc).into() } + /// Create a [Value] from a statically allocated UTF-8 string slice. + /// + /// This does not copy the string data. pub fn from_static_str( agent: &mut Agent, str: &'static str, @@ -520,108 +635,129 @@ impl<'a> Value<'a> { String::from_static_str(agent, str, gc).into() } + /// Create a [Value] from an f64. pub fn from_f64(agent: &mut Agent, value: f64, gc: NoGcScope<'a, '_>) -> Value<'a> { Number::from_f64(agent, value, gc).into() } + /// Create a [Value] from an i64. pub fn from_i64(agent: &mut Agent, value: i64, gc: NoGcScope<'a, '_>) -> Value<'a> { Number::from_i64(agent, value, gc).into() } + /// Get the canonical `NaN` value. pub fn nan() -> Self { Number::nan().into() } + /// Get the `+Infinity` value. pub fn pos_inf() -> Self { Number::pos_inf().into() } + /// Get the `-Infinity` value. pub fn neg_inf() -> Self { Number::neg_inf().into() } + /// Get the `+0` value. pub fn pos_zero() -> Self { Number::pos_zero().into() } + /// Get the `-0` value. pub fn neg_zero() -> Self { Number::neg_zero().into() } + /// Returns `true` if this is the JavaScript boolean value `true`. pub fn is_true(self) -> bool { matches!(self, Value::Boolean(true)) } + /// Returns `true` if this is the JavaScript boolean value `false`. pub fn is_false(self) -> bool { matches!(self, Value::Boolean(false)) } + /// Returns `true` if this is a JavaScript object. pub fn is_object(self) -> bool { super::Object::try_from(self).is_ok() } + /// Returns `true` if this is a JavaScript function. pub fn is_function(self) -> bool { - matches!( - self, - Value::BoundFunction(_) | Value::BuiltinFunction(_) | Value::ECMAScriptFunction(_) - ) + Function::try_from(self).is_ok() } + /// Returns `true` if this is a primitive value. pub fn is_primitive(self) -> bool { Primitive::try_from(self).is_ok() } + /// Returns `true` if this is a String. pub fn is_string(self) -> bool { matches!(self, Value::String(_) | Value::SmallString(_)) } + /// Returns `true` if this is a boolean. pub fn is_boolean(self) -> bool { matches!(self, Value::Boolean(_)) } + /// Returns `true` if this is `null`. pub fn is_null(self) -> bool { matches!(self, Value::Null) } + /// Returns `true` if this is `undefined`. pub fn is_undefined(self) -> bool { matches!(self, Value::Undefined) } + /// Returns `true` if this is `+0`. pub fn is_pos_zero(self, agent: &Agent) -> bool { Number::try_from(self).is_ok_and(|n| n.is_pos_zero_(agent)) || BigInt::try_from(self).is_ok_and(|n| n.is_zero(agent)) } + /// Returns `true` if this is `-0`. pub fn is_neg_zero(self, agent: &Agent) -> bool { Number::try_from(self).is_ok_and(|n| n.is_neg_zero_(agent)) } + /// Returns `true` if this is `+Infinity`. pub fn is_pos_infinity(self, agent: &Agent) -> bool { Number::try_from(self) .map(|n| n.is_pos_infinity_(agent)) .unwrap_or(false) } + /// Returns `true` if this is `-Infinity`. pub fn is_neg_infinity(self, agent: &Agent) -> bool { Number::try_from(self) .map(|n| n.is_neg_infinity_(agent)) .unwrap_or(false) } + /// Returns `true` if this is `NaN`. pub fn is_nan(self, agent: &Agent) -> bool { Number::try_from(self) .map(|n| n.is_nan_(agent)) .unwrap_or(false) } + /// Returns `true` if this is a BigInt. pub fn is_bigint(self) -> bool { matches!(self, Value::BigInt(_) | Value::SmallBigInt(_)) } + /// Returns `true` if this is a Symbol. pub fn is_symbol(self) -> bool { matches!(self, Value::Symbol(_)) } + /// Returns `true` if this is a numeric Value. pub fn is_numeric(self) -> bool { matches!( self, @@ -633,6 +769,7 @@ impl<'a> Value<'a> { ) } + /// Returns `true` if this is a Number. pub fn is_number(self) -> bool { matches!( self, @@ -640,10 +777,12 @@ impl<'a> Value<'a> { ) } + /// Returns `true` if this is a safe integer. pub fn is_integer(self) -> bool { matches!(self, Value::Integer(_)) } + /// Returns `true` if this is the empty string (`""`). pub fn is_empty_string(self) -> bool { if let Value::SmallString(s) = self { s.is_empty() @@ -652,6 +791,7 @@ impl<'a> Value<'a> { } } + /// ### [7.1.4 ToNumber ( argument )](https://tc39.es/ecma262/#sec-tonumber) pub fn to_number<'gc>( self, agent: &mut Agent, @@ -660,6 +800,7 @@ impl<'a> Value<'a> { to_number(agent, self, gc) } + /// ### [7.1.13 ToBigInt ( argument )](https://tc39.es/ecma262/#sec-tobigint) pub fn to_bigint<'gc>( self, agent: &mut Agent, @@ -668,6 +809,7 @@ impl<'a> Value<'a> { to_big_int(agent, self, gc) } + /// ### [7.1.3 ToNumeric ( value )](https://tc39.es/ecma262/#sec-tonumeric) pub fn to_numeric<'gc>( self, agent: &mut Agent, @@ -677,50 +819,60 @@ impl<'a> Value<'a> { } #[inline] + /// ### [7.1.6 ToInt32 ( argument )](https://tc39.es/ecma262/#sec-toint32) pub fn to_int32<'gc>(self, agent: &mut Agent, gc: GcScope<'gc, '_>) -> JsResult<'gc, i32> { to_int32(agent, self, gc) } #[inline] + /// ### [7.1.7 ToUint32 ( argument )](https://tc39.es/ecma262/#sec-touint32) pub fn to_uint32<'gc>(self, agent: &mut Agent, gc: GcScope<'gc, '_>) -> JsResult<'gc, u32> { to_uint32(agent, self, gc) } #[inline] + /// ### [7.1.8 ToInt16 ( argument )](https://tc39.es/ecma262/#sec-toint16) pub fn to_int16<'gc>(self, agent: &mut Agent, gc: GcScope<'gc, '_>) -> JsResult<'gc, i16> { to_int16(agent, self, gc) } #[inline] + /// ### [7.1.9 ToUint16 ( argument )](https://tc39.es/ecma262/#sec-touint16) pub fn to_uint16<'gc>(self, agent: &mut Agent, gc: GcScope<'gc, '_>) -> JsResult<'gc, u16> { to_uint16(agent, self, gc) } #[inline] + /// ### [7.1.10 ToInt8 ( argument )](https://tc39.es/ecma262/#sec-toint8) pub fn to_int8<'gc>(self, agent: &mut Agent, gc: GcScope<'gc, '_>) -> JsResult<'gc, i8> { to_int8(agent, self, gc) } #[inline] + /// ### [7.1.11 ToUint8 ( argument )](https://tc39.es/ecma262/#sec-touint8) pub fn to_uint8<'gc>(self, agent: &mut Agent, gc: GcScope<'gc, '_>) -> JsResult<'gc, u8> { to_uint8(agent, self, gc) } #[inline] + /// ### [7.1.12 ToUint8Clamp ( argument )](https://tc39.es/ecma262/#sec-touint8clamp) pub fn to_uint8_clamp<'gc>(self, agent: &mut Agent, gc: GcScope<'gc, '_>) -> JsResult<'gc, u8> { to_uint8_clamp(agent, self, gc) } #[inline] + /// ### [7.1.15 ToBigInt64 ( argument )](https://tc39.es/ecma262/#sec-tobigint64) pub fn to_big_int64<'gc>(self, agent: &mut Agent, gc: GcScope<'gc, '_>) -> JsResult<'gc, i64> { to_big_int64(agent, self, gc) } #[inline] + /// ### [7.1.16 ToBigUint64 ( argument )](https://tc39.es/ecma262/#sec-tobiguint64) pub fn to_big_uint64<'gc>(self, agent: &mut Agent, gc: GcScope<'gc, '_>) -> JsResult<'gc, u64> { to_big_uint64(agent, self, gc) } + /// ### [7.1.17 ToString ( argument )](https://tc39.es/ecma262/#sec-tostring) pub fn to_string<'gc>( self, agent: &mut Agent, @@ -729,6 +881,10 @@ impl<'a> Value<'a> { to_string(agent, self, gc) } + /// ### [7.1.17 ToString ( argument )](https://tc39.es/ecma262/#sec-tostring) + /// + /// Variant of the `ToString` abstract operation that will never call into + /// JavaScript and therefore can never trigger garbage collection. pub fn try_to_string<'gc>( self, agent: &mut Agent, @@ -957,10 +1113,7 @@ impl Rootable for Value<'_> { Self::BuiltinPromiseFinallyFunction(builtin_promise_finally_function) => { Err(HeapRootData::from(builtin_promise_finally_function)) } - Self::BuiltinPromiseCollectorFunction => { - Err(HeapRootData::BuiltinPromiseCollectorFunction) - } - Self::BuiltinProxyRevokerFunction => Err(HeapRootData::BuiltinPromiseCollectorFunction), + Self::BuiltinProxyRevokerFunction => Err(HeapRootData::BuiltinProxyRevokerFunction), Self::PrimitiveObject(primitive_object) => Err(HeapRootData::from(primitive_object)), Self::Arguments(ordinary_object) => Err(HeapRootData::from(ordinary_object)), Self::Array(array) => Err(HeapRootData::from(array)), @@ -1093,9 +1246,6 @@ impl Rootable for Value<'_> { HeapRootData::BuiltinConstructorFunction(f) => Some(Self::from(f)), HeapRootData::BuiltinPromiseResolvingFunction(f) => Some(Self::from(f)), HeapRootData::BuiltinPromiseFinallyFunction(f) => Some(Self::from(f)), - HeapRootData::BuiltinPromiseCollectorFunction => { - Some(Self::BuiltinPromiseCollectorFunction) - } HeapRootData::BuiltinProxyRevokerFunction => Some(Self::BuiltinProxyRevokerFunction), HeapRootData::PrimitiveObject(o) => Some(Self::from(o)), HeapRootData::Arguments(o) => Some(Self::from(o)), @@ -1334,7 +1484,6 @@ impl HeapMarkAndSweep for Value<'static> { Self::BuiltinConstructorFunction(data) => data.mark_values(queues), Self::BuiltinPromiseResolvingFunction(data) => data.mark_values(queues), Self::BuiltinPromiseFinallyFunction(data) => data.mark_values(queues), - Self::BuiltinPromiseCollectorFunction => todo!(), Self::BuiltinProxyRevokerFunction => todo!(), Self::AsyncGenerator(data) => data.mark_values(queues), Self::ArrayIterator(data) => data.mark_values(queues), @@ -1457,7 +1606,6 @@ impl HeapMarkAndSweep for Value<'static> { Self::BuiltinConstructorFunction(data) => data.sweep_values(compactions), Self::BuiltinPromiseResolvingFunction(data) => data.sweep_values(compactions), Self::BuiltinPromiseFinallyFunction(data) => data.sweep_values(compactions), - Self::BuiltinPromiseCollectorFunction => todo!(), Self::BuiltinProxyRevokerFunction => todo!(), Self::AsyncGenerator(data) => data.sweep_values(compactions), Self::ArrayIterator(data) => data.sweep_values(compactions), @@ -1482,7 +1630,6 @@ fn map_object_to_static_string_repr(value: Value) -> String<'static> { | Object::BuiltinConstructorFunction(_) | Object::BuiltinPromiseResolvingFunction(_) | Object::BuiltinPromiseFinallyFunction(_) - | Object::BuiltinPromiseCollectorFunction | Object::BuiltinProxyRevokerFunction => BUILTIN_STRING_MEMORY._object_Function_, Object::Arguments(_) => BUILTIN_STRING_MEMORY._object_Arguments_, Object::Array(_) => BUILTIN_STRING_MEMORY._object_Array_, diff --git a/nova_vm/src/ecmascript/types/language/value_vec.rs b/nova_vm/src/ecmascript/types/language/value_vec.rs index 5073c71c6..3240892ee 100644 --- a/nova_vm/src/ecmascript/types/language/value_vec.rs +++ b/nova_vm/src/ecmascript/types/language/value_vec.rs @@ -46,23 +46,24 @@ impl ScopedCollection<'_, Vec>> { f(value_vec) } - /// Push a Value into the scoped vec. + /// Push a Value into the scoped Vec. pub fn push(&mut self, agent: &Agent, value: Value) { self.with_cb_mut(agent, |value_vec| value_vec.push(value.unbind())); } - /// Pop a Value from the scoped vec. + /// Pop a Value from the scoped Vec. pub fn pop<'a>(&mut self, agent: &Agent, gc: NoGcScope<'a, '_>) -> Option> { self.with_cb_mut(agent, |value_vec| value_vec.pop().bind(gc)) } + /// Copy the last Value from the scoped Vec if not empty. pub fn last<'a>(&self, agent: &Agent, gc: NoGcScope<'a, '_>) -> Option> { self.with_cb(agent, |value_vec| { value_vec.last().map(|value| value.bind(gc)) }) } - /// Returns `true` if the scoped vec contains a Value. + /// Returns `true` if the scoped Vec contains a Value. pub fn contains(&self, agent: &Agent, value: Value) -> bool { self.with_cb(agent, |value_vec| value_vec.contains(&value.unbind())) } @@ -74,10 +75,12 @@ impl ScopedCollection<'_, Vec>> { }) } + /// Returns `true` if the scoped Vec is empty. pub fn is_empty(&self, agent: &Agent) -> bool { self.with_cb(agent, |value_vec| value_vec.is_empty()) } + /// Returns the scoped Vec's length. pub fn len(&self, agent: &Agent) -> usize { self.with_cb(agent, |value_vec| value_vec.len()) } diff --git a/nova_vm/src/ecmascript/types/spec/property_descriptor.rs b/nova_vm/src/ecmascript/types/spec/property_descriptor.rs index 7f9a7be0d..baf00ae9c 100644 --- a/nova_vm/src/ecmascript/types/spec/property_descriptor.rs +++ b/nova_vm/src/ecmascript/types/spec/property_descriptor.rs @@ -125,6 +125,9 @@ impl<'a> PropertyDescriptor<'a> { } } + /// Creates a new data descriptor from a [Value]. + /// + /// Data descriptors are writable, enumerable, and configurable. pub fn new_data_descriptor(value: impl Into>) -> Self { Self { value: Some(value.into()), @@ -136,6 +139,7 @@ impl<'a> PropertyDescriptor<'a> { } } + /// Creates a new non-enumerable data descriptor from a [Value]. pub fn non_enumerable_data_descriptor(value: impl Into>) -> Self { Self { value: Some(value.into()), @@ -147,14 +151,9 @@ impl<'a> PropertyDescriptor<'a> { } } + /// Creates a new non-enumerable data descriptor from a [Function]. pub fn new_prototype_method_descriptor(function: impl Into>) -> Self { - Self { - value: Some(function.into().unbind().into()), - writable: Some(true), - enumerable: Some(false), - configurable: Some(true), - ..Default::default() - } + Self::non_enumerable_data_descriptor(function.into()) } /// ### [6.2.6.1 IsAccessorDescriptor ( Desc )](https://tc39.es/ecma262/#sec-isaccessordescriptor) @@ -717,6 +716,9 @@ impl<'a> PropertyDescriptor<'a> { Ok(()) } + /// Returns `true` if this property descriptor has been fully populated with + /// enumerable and configurable bits, and either a value and a writable bit + /// OR at least a getter or setter function. pub fn is_fully_populated(&self) -> bool { ((self.value.is_some() && self.writable.is_some()) // A property descriptor can contain just get or set. @@ -725,6 +727,7 @@ impl<'a> PropertyDescriptor<'a> { && self.configurable.is_some() } + /// Returns `true` if this property descriptor has any fields populated. pub fn has_fields(&self) -> bool { self.value.is_some() || self.writable.is_some() diff --git a/nova_vm/src/engine.rs b/nova_vm/src/engine.rs index 10d8b9392..698685a15 100644 --- a/nova_vm/src/engine.rs +++ b/nova_vm/src/engine.rs @@ -51,6 +51,9 @@ //! use-after-free, in JavaScript world this means that a value changes to //! another value of the same type without any assignment, or the engine crashes //! from an out-of-bounds memory access. +//! +//! [`Object`]: crate::ecmascript::Object +//! [`Value`]: crate::ecmascript::Value mod bytecode; mod context; diff --git a/nova_vm/src/engine/bytecode/vm.rs b/nova_vm/src/engine/bytecode/vm.rs index 510bc83b9..c7febba87 100644 --- a/nova_vm/src/engine/bytecode/vm.rs +++ b/nova_vm/src/engine/bytecode/vm.rs @@ -1313,7 +1313,6 @@ pub(crate) fn typeof_operator(agent: &Agent, val: Value, gc: NoGcScope) -> Strin Value::BuiltinConstructorFunction(_) | Value::BuiltinPromiseResolvingFunction(_) | Value::BuiltinPromiseFinallyFunction(_) | - Value::BuiltinPromiseCollectorFunction | Value::BuiltinProxyRevokerFunction => BUILTIN_STRING_MEMORY.function, Value::Proxy(proxy) => { if proxy.is_callable(agent, gc) { diff --git a/nova_vm/src/engine/rootable.rs b/nova_vm/src/engine/rootable.rs index 9c4874479..6271f0ba0 100644 --- a/nova_vm/src/engine/rootable.rs +++ b/nova_vm/src/engine/rootable.rs @@ -68,7 +68,6 @@ use crate::{ ASYNC_GENERATOR_DISCRIMINANT, Array, ArrayIterator, AsyncGenerator, AwaitReaction, BIGINT_DISCRIMINANT, BOUND_FUNCTION_DISCRIMINANT, BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, BUILTIN_FUNCTION_DISCRIMINANT, - BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BUILTIN_PROXY_REVOKER_FUNCTION, BoundFunction, BuiltinConstructorFunction, BuiltinFunction, BuiltinPromiseFinallyFunction, @@ -314,7 +313,6 @@ pub(crate) enum HeapRootData { BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BuiltinPromiseFinallyFunction(BuiltinPromiseFinallyFunction<'static>) = BUILTIN_PROMISE_FINALLY_FUNCTION_DISCRIMINANT, - BuiltinPromiseCollectorFunction = BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, BuiltinProxyRevokerFunction = BUILTIN_PROXY_REVOKER_FUNCTION, PrimitiveObject(PrimitiveObject<'static>), Arguments(UnmappedArguments<'static>) = ARGUMENTS_DISCRIMINANT, @@ -495,7 +493,6 @@ impl HeapMarkAndSweep for HeapRootData { Self::BuiltinPromiseFinallyFunction(builtin_promise_finally_function) => { builtin_promise_finally_function.mark_values(queues) } - Self::BuiltinPromiseCollectorFunction => todo!(), Self::BuiltinProxyRevokerFunction => todo!(), Self::PrimitiveObject(primitive_object) => primitive_object.mark_values(queues), Self::Arguments(ordinary_object) => ordinary_object.mark_values(queues), @@ -650,7 +647,6 @@ impl HeapMarkAndSweep for HeapRootData { Self::BuiltinPromiseFinallyFunction(builtin_promise_finally_function) => { builtin_promise_finally_function.sweep_values(compactions); } - Self::BuiltinPromiseCollectorFunction => todo!(), Self::BuiltinProxyRevokerFunction => todo!(), Self::PrimitiveObject(primitive_object) => primitive_object.sweep_values(compactions), Self::Arguments(ordinary_object) => ordinary_object.sweep_values(compactions), diff --git a/nova_vm/src/engine/rootable/scoped.rs b/nova_vm/src/engine/rootable/scoped.rs index d9ac1a165..0c1706ce8 100644 --- a/nova_vm/src/engine/rootable/scoped.rs +++ b/nova_vm/src/engine/rootable/scoped.rs @@ -79,6 +79,7 @@ impl<'scope, T: Rootable> Scoped<'scope, T> { self.inner } + /// Create a new `Scoped` from a scopable value. pub fn new(agent: &Agent, value: T, _gc: NoGcScope<'_, 'scope>) -> Self { let value = match T::to_root_repr(value) { Ok(stack_repr) => { @@ -111,8 +112,8 @@ impl<'scope, T: Rootable> Scoped<'scope, T> { /// /// ## Panics /// - /// If the scoped value has been taken by another caller already, the - /// method panics. + /// Panics if the `Scoped` has been cloned and the clone has been used to + /// call `take` already. #[must_use] pub unsafe fn take(self, agent: &Agent) -> T { match T::from_root_repr(&self.inner) { @@ -152,6 +153,14 @@ impl<'scope, T: Rootable> Scoped<'scope, T> { unsafe { stack_refs.set_len(last_non_empty_index) }; } + /// Get a copy of the contained scopable value from a `Scoped`. + /// + /// # Panics + /// + /// Panics if the `Scoped` has been cloned and the clone has been used to + /// [take] the value out of the slot. + /// + /// [take]: Scoped::take pub fn get(&self, agent: &Agent) -> T { match T::from_root_repr(&self.inner) { Ok(value) => value, diff --git a/nova_vm/src/heap.rs b/nova_vm/src/heap.rs index fee8e0fa0..905d500a5 100644 --- a/nova_vm/src/heap.rs +++ b/nova_vm/src/heap.rs @@ -2,6 +2,11 @@ // 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 engine heap structures +//! +//! This module contains internal details of how the Nova engine lays out its +//! heap. It is likely to go away in the future. + mod element_array; mod heap_bits; mod heap_constants; diff --git a/nova_vm/src/heap/element_array.rs b/nova_vm/src/heap/element_array.rs index 5d731ee2b..2df234a8f 100644 --- a/nova_vm/src/heap/element_array.rs +++ b/nova_vm/src/heap/element_array.rs @@ -500,61 +500,93 @@ pub enum ElementDescriptor<'a> { /// ```js /// { get, set: undefined, enumerable: true, configurable: true } /// ``` - ReadOnlyEnumerableConfigurableAccessor { get: Function<'a> }, + ReadOnlyEnumerableConfigurableAccessor { + /// Getter function of a read-only accessor property. + get: Function<'a>, + }, /// ```js /// { get, set: undefined, enumerable: true, configurable: false } /// ``` - ReadOnlyEnumerableUnconfigurableAccessor { get: Function<'a> }, + ReadOnlyEnumerableUnconfigurableAccessor { + /// Getter function of a read-only accessor property. + get: Function<'a>, + }, /// ```js /// { get, set: undefined, enumerable: false, configurable: true } /// ``` - ReadOnlyUnenumerableConfigurableAccessor { get: Function<'a> }, + ReadOnlyUnenumerableConfigurableAccessor { + /// Getter function of a read-only accessor property. + get: Function<'a>, + }, /// ```js /// { get, set: undefined, enumerable: false, configurable: false } /// ``` - ReadOnlyUnenumerableUnconfigurableAccessor { get: Function<'a> }, + ReadOnlyUnenumerableUnconfigurableAccessor { + /// Getter function of a read-only accessor property. + get: Function<'a>, + }, /// ```js /// { get: undefined, set, enumerable: true, configurable: true } /// ``` - WriteOnlyEnumerableConfigurableAccessor { set: Function<'a> }, + WriteOnlyEnumerableConfigurableAccessor { + /// Setter function of a write-only accessor property. + set: Function<'a>, + }, /// ```js /// { get: undefined, set, enumerable: true, configurable: false } /// ``` - WriteOnlyEnumerableUnconfigurableAccessor { set: Function<'a> }, + WriteOnlyEnumerableUnconfigurableAccessor { + /// Setter function of a write-only accessor property. + set: Function<'a>, + }, /// ```js /// { get: undefined, set, enumerable: false, configurable: true } /// ``` - WriteOnlyUnenumerableConfigurableAccessor { set: Function<'a> }, + WriteOnlyUnenumerableConfigurableAccessor { + /// Setter function of a write-only accessor property. + set: Function<'a>, + }, /// ```js /// { get: undefined, set, enumerable: false, configurable: false } /// ``` - WriteOnlyUnenumerableUnconfigurableAccessor { set: Function<'a> }, + WriteOnlyUnenumerableUnconfigurableAccessor { + /// Setter function of a write-only accessor property. + set: Function<'a>, + }, /// ```js /// { get, set, enumerable: true, configurable: true } /// ``` ReadWriteEnumerableConfigurableAccessor { + /// Getter function of a read-write accessor property. get: Function<'a>, + /// Setter function of a read-write accessor property. set: Function<'a>, }, /// ```js /// { get, set, enumerable: true, configurable: false } /// ``` ReadWriteEnumerableUnconfigurableAccessor { + /// Getter function of a read-write accessor property. get: Function<'a>, + /// Setter function of a read-write accessor property. set: Function<'a>, }, /// ```js /// { get, set, enumerable: false, configurable: true } /// ``` ReadWriteUnenumerableConfigurableAccessor { + /// Getter function of a read-write accessor property. get: Function<'a>, + /// Setter function of a read-write accessor property. set: Function<'a>, }, /// ```js /// { get, set, enumerable: false, configurable: false } /// ``` ReadWriteUnenumerableUnconfigurableAccessor { + /// Getter function of a read-write accessor property. get: Function<'a>, + /// Setter function of a read-write accessor property. set: Function<'a>, }, } diff --git a/nova_vm/src/heap/heap_bits.rs b/nova_vm/src/heap/heap_bits.rs index 901c9dcbd..0a9593d09 100644 --- a/nova_vm/src/heap/heap_bits.rs +++ b/nova_vm/src/heap/heap_bits.rs @@ -873,7 +873,7 @@ impl HeapBits { WeakKey::BuiltinPromiseFinallyFunction(d) => self .promise_finally_functions .get_bit(d.get_index(), &self.bits), - WeakKey::BuiltinPromiseCollectorFunction | WeakKey::BuiltinProxyRevokerFunction => { + WeakKey::BuiltinProxyRevokerFunction => { unreachable!() } WeakKey::PrimitiveObject(d) => { diff --git a/nova_vm/src/lib.rs b/nova_vm/src/lib.rs index 22a45de54..1a04a10ba 100644 --- a/nova_vm/src/lib.rs +++ b/nova_vm/src/lib.rs @@ -3,6 +3,66 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. #![cfg_attr(feature = "proposal-float16array", feature(f16))] +#![warn(missing_docs)] + +//! # Nova JavaScript engine +//! +//! Nova is a JavaScript engine aiming to be lightweight, easy to embed, and +//! close to the ECMAScript specification in form with the implementation +//! relying on idiomatic Rust rather than traditional JavaScript engine building +//! wisdom. Great performance is also an aspirational goal of the engine, but +//! not something that can be said to really be a reality today. +//! +//! ## API architecture +//! +//! The API of the engine relies on idiomatic Rust rather than traditional +//! JavaScript engine building wisdom. This is most apparent in the [`Value`] +//! type and its subtypes: 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 +//! 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`. +//! +//! ## Lightweight engine +//! +//! The engine's heap is set up to keep heap allocations small, trading speed +//! for a smaller memory footprint in the general case. This should make working +//! with large, regular datasets fairly low-impact on the memory usage of the +//! engine. +//! +//! ## Ease of embedding +//! +//! The engine has very little bells or whistles and is very easy to set up for +//! one-off script runs. The engine uses the [WTF-8] encoding internally for +//! [`String`] storage, making interfacing between the engine and normal Rust +//! code much nicer than one might expect. +//! +//! ## Shortcomings and unexpected edge cases +//! +//! Nova JavaScript engine has not been born 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 8 billion bytes. +//! +//! 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. +//! +//! [`Agent`]: crate::ecmascript::Agent +//! [`Array`]: crate::ecmascript::Array +//! [`RegExp`]: crate::ecmascript::RegExp +//! [`Promise`]: crate::ecmascript::Promise +//! [`String`]: crate::ecmascript::String +//! [`Value`]: crate::ecmascript::Value +//! [WTF-8]: https://wtf-8.codeberg.page/ pub mod ecmascript; pub mod engine; From 8a9e3d3fc23367e88c70f9d2d36aa600ed2481a1 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Fri, 13 Mar 2026 01:46:17 +0200 Subject: [PATCH 2/3] Fix doc fmt --- .../operations_on_objects.rs | 2 +- .../generator_objects.rs | 6 +++--- .../promise_capability_records.rs | 12 +++++------ .../abstract_operations.rs | 2 +- nova_vm/src/ecmascript/builtins/promise.rs | 6 +++++- .../builtins/reflection/reflect_object.rs | 20 +++++++++---------- .../builtins/structured_data/json_object.rs | 2 +- .../regexp_string_iterator_objects.rs | 2 +- nova_vm/src/ecmascript/execution.rs | 2 +- nova_vm/src/ecmascript/execution/agent.rs | 4 ++-- .../environments/module_environment.rs | 2 +- .../weak_ref_and_finalization_registry.rs | 2 +- nova_vm/src/ecmascript/types/language.rs | 2 +- .../src/ecmascript/types/language/object.rs | 2 +- .../src/ecmascript/types/language/value.rs | 2 +- nova_vm/src/ecmascript/types/spec.rs | 2 +- .../bytecode_compiler/template_literals.rs | 2 +- 17 files changed, 38 insertions(+), 34 deletions(-) diff --git a/nova_vm/src/ecmascript/abstract_operations/operations_on_objects.rs b/nova_vm/src/ecmascript/abstract_operations/operations_on_objects.rs index 69a956c11..69158b974 100644 --- a/nova_vm/src/ecmascript/abstract_operations/operations_on_objects.rs +++ b/nova_vm/src/ecmascript/abstract_operations/operations_on_objects.rs @@ -2683,7 +2683,7 @@ pub(crate) fn try_private_set<'gc>( } } -///### [7.3.33 InitializeInstanceElements ( O, constructor )](https://tc39.es/ecma262/#sec-initializeinstanceelements) +/// ### [7.3.33 InitializeInstanceElements ( O, constructor )](https://tc39.es/ecma262/#sec-initializeinstanceelements) /// /// The abstract operation InitializeInstanceElements takes arguments O (an /// Object) and constructor (an ECMAScript function object) and returns either diff --git a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/generator_objects.rs b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/generator_objects.rs index d6e687c54..c3d166e10 100644 --- a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/generator_objects.rs +++ b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/generator_objects.rs @@ -32,7 +32,7 @@ object_handle!(Generator); arena_vec_access!(Generator, 'a, GeneratorHeapData, generators); impl Generator<'_> { - ///### [27.5.3.3 GeneratorResume ( generator, value, generatorBrand )](https://tc39.es/ecma262/#sec-generatorresume) + /// ### [27.5.3.3 GeneratorResume ( generator, value, generatorBrand )](https://tc39.es/ecma262/#sec-generatorresume) pub(crate) fn resume<'a>( self, agent: &mut Agent, @@ -152,7 +152,7 @@ impl Generator<'_> { } } - ///### [27.5.3.4 GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )](https://tc39.es/ecma262/#sec-generatorresumeabrupt) + /// ### [27.5.3.4 GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )](https://tc39.es/ecma262/#sec-generatorresumeabrupt) /// NOTE: This method only accepts throw completions. pub(crate) fn resume_throw<'a>( self, @@ -262,7 +262,7 @@ impl Generator<'_> { } } - ///### [27.5.3.4 GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )](https://tc39.es/ecma262/#sec-generatorresumeabrupt) + /// ### [27.5.3.4 GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )](https://tc39.es/ecma262/#sec-generatorresumeabrupt) /// NOTE: This method only accepts return completions. pub(crate) fn resume_return<'a>( self, diff --git a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_abstract_operations/promise_capability_records.rs b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_abstract_operations/promise_capability_records.rs index f06043c68..83b605742 100644 --- a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_abstract_operations/promise_capability_records.rs +++ b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_abstract_operations/promise_capability_records.rs @@ -40,7 +40,7 @@ pub struct PromiseCapability<'a> { } impl<'a> PromiseCapability<'a> { - ///### [27.2.1.5 NewPromiseCapability ( C )](https://tc39.es/ecma262/#sec-newpromisecapability) + /// ### [27.2.1.5 NewPromiseCapability ( C )](https://tc39.es/ecma262/#sec-newpromisecapability) /// /// Create a new PromiseCapability /// @@ -84,7 +84,7 @@ impl<'a> PromiseCapability<'a> { } } - ///### [27.2.1.4 FulfillPromise ( promise, value )](https://tc39.es/ecma262/#sec-fulfillpromise) + /// ### [27.2.1.4 FulfillPromise ( promise, value )](https://tc39.es/ecma262/#sec-fulfillpromise) pub(crate) fn internal_fulfill(&self, agent: &mut Agent, value: Value, gc: NoGcScope) { // 1. Assert: The value of promise.[[PromiseState]] is pending. // 2. Let reactions be promise.[[PromiseFulfillReactions]]. @@ -108,7 +108,7 @@ impl<'a> PromiseCapability<'a> { } } - ///### [27.2.1.7 RejectPromise ( promise, reason )](https://tc39.es/ecma262/#sec-rejectpromise) + /// ### [27.2.1.7 RejectPromise ( promise, reason )](https://tc39.es/ecma262/#sec-rejectpromise) fn internal_reject(&self, agent: &mut Agent, reason: Value, gc: NoGcScope) { // 1. Assert: The value of promise.[[PromiseState]] is pending. // 2. Let reactions be promise.[[PromiseRejectReactions]]. @@ -141,7 +141,7 @@ impl<'a> PromiseCapability<'a> { } } - ///### [27.2.1.3.2 Promise Resolve Functions](https://tc39.es/ecma262/#sec-promise-resolve-functions) + /// ### [27.2.1.3.2 Promise Resolve Functions](https://tc39.es/ecma262/#sec-promise-resolve-functions) /// /// Resolve the associated [`Promise`] with a given value. Ignored if the /// [`Promise`] is already resolved. @@ -246,7 +246,7 @@ impl<'a> PromiseCapability<'a> { // 16. Return undefined. } - ///### [27.2.1.3.2 Promise Resolve Functions](https://tc39.es/ecma262/#sec-promise-resolve-functions) + /// ### [27.2.1.3.2 Promise Resolve Functions](https://tc39.es/ecma262/#sec-promise-resolve-functions) /// /// Try resolve the associated [`Promise`] with a given value. Fails if /// resolving would require calling into user-code. Ignored if the @@ -335,7 +335,7 @@ impl<'a> PromiseCapability<'a> { TryResult::Continue(()) } - ///### [27.2.1.3.1 Promise Reject Functions](https://tc39.es/ecma262/#sec-promise-reject-functions) + /// ### [27.2.1.3.1 Promise Reject Functions](https://tc39.es/ecma262/#sec-promise-reject-functions) /// /// Reject the associated [`Promise`] with a given value. Ignored if the /// [`Promise`] is already resolved. diff --git a/nova_vm/src/ecmascript/builtins/indexed_collections/typed_array_objects/abstract_operations.rs b/nova_vm/src/ecmascript/builtins/indexed_collections/typed_array_objects/abstract_operations.rs index b562c86c3..1a4f88566 100644 --- a/nova_vm/src/ecmascript/builtins/indexed_collections/typed_array_objects/abstract_operations.rs +++ b/nova_vm/src/ecmascript/builtins/indexed_collections/typed_array_objects/abstract_operations.rs @@ -485,7 +485,7 @@ pub(crate) trait TypedArrayAbstractOperations<'ta>: Copy + Sized { count: usize, ); - ///### [23.2.3.26.2 SetTypedArrayFromTypedArray ( target, targetOffset, source )](https://tc39.es/ecma262/#sec-settypedarrayfromtypedarray) + /// ### [23.2.3.26.2 SetTypedArrayFromTypedArray ( target, targetOffset, source )](https://tc39.es/ecma262/#sec-settypedarrayfromtypedarray) /// /// The abstract operation SetTypedArrayFromTypedArray takes arguments /// target (a TypedArray), targetOffset (a non-negative integer or +∞), and diff --git a/nova_vm/src/ecmascript/builtins/promise.rs b/nova_vm/src/ecmascript/builtins/promise.rs index b4bea3735..e07b5e0da 100644 --- a/nova_vm/src/ecmascript/builtins/promise.rs +++ b/nova_vm/src/ecmascript/builtins/promise.rs @@ -43,6 +43,10 @@ use crate::{ /// resolved. An unresolved promise is always in the pending state. A resolved /// promise may be pending, fulfilled or rejected. /// +/// ## Support status +/// +/// `Promise` in Nova does not currently support subclassing. +/// /// [Job]: crate::ecmascript::Job #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] @@ -98,7 +102,7 @@ impl<'a> Promise<'a> { }; } - ///### [27.2.4.7.1 PromiseResolve ( C, x )](https://tc39.es/ecma262/#sec-promise-resolve) + /// ### [27.2.4.7.1 PromiseResolve ( C, x )](https://tc39.es/ecma262/#sec-promise-resolve) pub(crate) fn resolve( agent: &mut Agent, x: Value, diff --git a/nova_vm/src/ecmascript/builtins/reflection/reflect_object.rs b/nova_vm/src/ecmascript/builtins/reflection/reflect_object.rs index 2f54e68de..034ee0f95 100644 --- a/nova_vm/src/ecmascript/builtins/reflection/reflect_object.rs +++ b/nova_vm/src/ecmascript/builtins/reflection/reflect_object.rs @@ -124,7 +124,7 @@ impl Builtin for ReflectObjectSetPrototypeOf { } impl ReflectObject { - ///### [28.1.1 Reflect.apply ( target, thisArgument, argumentsList )](https://tc39.es/ecma262/#sec-reflect.apply) + /// ### [28.1.1 Reflect.apply ( target, thisArgument, argumentsList )](https://tc39.es/ecma262/#sec-reflect.apply) fn apply<'gc>( agent: &mut Agent, _this_value: Value, @@ -214,7 +214,7 @@ impl ReflectObject { .map(|o| o.into()) } - ///### [28.1.3 Reflect.defineProperty ( target, propertyKey, attributes )](https://tc39.es/ecma262/#sec-reflect.defineproperty) + /// ### [28.1.3 Reflect.defineProperty ( target, propertyKey, attributes )](https://tc39.es/ecma262/#sec-reflect.defineproperty) fn define_property<'gc>( agent: &mut Agent, _this_value: Value, @@ -285,7 +285,7 @@ impl ReflectObject { Ok(ret.into()) } - ///### [28.1.4 Reflect.deleteProperty ( target, propertyKey )](https://tc39.es/ecma262/#sec-reflect.deleteproperty) + /// ### [28.1.4 Reflect.deleteProperty ( target, propertyKey )](https://tc39.es/ecma262/#sec-reflect.deleteproperty) fn delete_property<'gc>( agent: &mut Agent, _this_value: Value, @@ -373,7 +373,7 @@ impl ReflectObject { .internal_get(agent, key.unbind(), receiver.unbind(), gc) } - ///### [28.1.6 Reflect.getOwnPropertyDescriptor ( target, propertyKey )](https://tc39.es/ecma262/#sec-reflect.getownpropertydescriptor) + /// ### [28.1.6 Reflect.getOwnPropertyDescriptor ( target, propertyKey )](https://tc39.es/ecma262/#sec-reflect.getownpropertydescriptor) fn get_own_property_descriptor<'gc>( agent: &mut Agent, _this_value: Value, @@ -418,7 +418,7 @@ impl ReflectObject { } } - ///### [28.1.7 Reflect.getPrototypeOf ( target )](https://tc39.es/ecma262/#sec-reflect.getprototypeof) + /// ### [28.1.7 Reflect.getPrototypeOf ( target )](https://tc39.es/ecma262/#sec-reflect.getprototypeof) fn get_prototype_of<'gc>( agent: &mut Agent, _this_value: Value, @@ -444,7 +444,7 @@ impl ReflectObject { } } - ///### [28.1.8 Reflect.has ( target, propertyKey )](https://tc39.es/ecma262/#sec-reflect.has) + /// ### [28.1.8 Reflect.has ( target, propertyKey )](https://tc39.es/ecma262/#sec-reflect.has) fn has<'gc>( agent: &mut Agent, _this_value: Value, @@ -483,7 +483,7 @@ impl ReflectObject { Ok(ret.into()) } - ///### [28.1.9 Reflect.isExtensible ( target )](https://tc39.es/ecma262/#sec-reflect.isextensible) + /// ### [28.1.9 Reflect.isExtensible ( target )](https://tc39.es/ecma262/#sec-reflect.isextensible) fn is_extensible<'gc>( agent: &mut Agent, _this_value: Value, @@ -507,7 +507,7 @@ impl ReflectObject { Ok(ret.into()) } - ///### [28.1.10 Reflect.ownKeys ( target )](https://tc39.es/ecma262/#sec-reflect.ownkeys) + /// ### [28.1.10 Reflect.ownKeys ( target )](https://tc39.es/ecma262/#sec-reflect.ownkeys) fn own_keys<'gc>( agent: &mut Agent, _this_value: Value, @@ -538,7 +538,7 @@ impl ReflectObject { Ok(create_array_from_list(agent, &keys.unbind(), gc.into_nogc()).into()) } - ///### [28.1.11 Reflect.preventExtensions ( target )](https://tc39.es/ecma262/#sec-reflect.preventextensions) + /// ### [28.1.11 Reflect.preventExtensions ( target )](https://tc39.es/ecma262/#sec-reflect.preventextensions) fn prevent_extensions<'gc>( agent: &mut Agent, _this_value: Value, @@ -616,7 +616,7 @@ impl ReflectObject { Ok(ret.into()) } - ///### [28.1.13 Reflect.setPrototypeOf ( target, proto )](https://tc39.es/ecma262/#sec-reflect.setprototypeof) + /// ### [28.1.13 Reflect.setPrototypeOf ( target, proto )](https://tc39.es/ecma262/#sec-reflect.setprototypeof) fn set_prototype_of<'gc>( agent: &mut Agent, _this_value: Value, diff --git a/nova_vm/src/ecmascript/builtins/structured_data/json_object.rs b/nova_vm/src/ecmascript/builtins/structured_data/json_object.rs index 3d42c04f8..1d707972d 100644 --- a/nova_vm/src/ecmascript/builtins/structured_data/json_object.rs +++ b/nova_vm/src/ecmascript/builtins/structured_data/json_object.rs @@ -465,7 +465,7 @@ impl JSONObject { } } -///### [25.5.1.1 InternalizeJSONProperty ( holder, name, reviver )](https://tc39.es/ecma262/#sec-internalizejsonproperty) +/// ### [25.5.1.1 InternalizeJSONProperty ( holder, name, reviver )](https://tc39.es/ecma262/#sec-internalizejsonproperty) /// /// The abstract operation InternalizeJSONProperty takes arguments holder (an /// Object), name (a String), and reviver (a function object) and returns diff --git a/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_string_iterator_objects.rs b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_string_iterator_objects.rs index 6d5b4ab92..33c4bd319 100644 --- a/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_string_iterator_objects.rs +++ b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_string_iterator_objects.rs @@ -52,7 +52,7 @@ pub(crate) fn create_reg_exp_string_iterator<'gc>( }) } -///### [22.2.9 RegExp String Iterator Objects](https://tc39.es/ecma262/#sec-regexp-string-iterator-objects) +/// ### [22.2.9 RegExp String Iterator Objects](https://tc39.es/ecma262/#sec-regexp-string-iterator-objects) /// /// A _RegExp String Iterator_ is an object that represents a specific iteration /// over some specific String instance object, matching against some specific diff --git a/nova_vm/src/ecmascript/execution.rs b/nova_vm/src/ecmascript/execution.rs index 843c3de06..db36a8a60 100644 --- a/nova_vm/src/ecmascript/execution.rs +++ b/nova_vm/src/ecmascript/execution.rs @@ -2,7 +2,7 @@ // 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/. -//!# [9 Executable Code and Execution Contexts](https://tc39.es/ecma262/#sec-executable-code-and-execution-contexts) +//! # [9 Executable Code and Execution Contexts](https://tc39.es/ecma262/#sec-executable-code-and-execution-contexts) mod agent; mod default_host_hooks; diff --git a/nova_vm/src/ecmascript/execution/agent.rs b/nova_vm/src/ecmascript/execution/agent.rs index 0125a2adf..3cd0dad3e 100644 --- a/nova_vm/src/ecmascript/execution/agent.rs +++ b/nova_vm/src/ecmascript/execution/agent.rs @@ -5,10 +5,10 @@ //! ## [9.6 Agents](https://tc39.es/ecma262/#sec-agents) //! //! An _agent_ comprises a set of ECMAScript -//!# [execution contexts](https://tc39.es/ecma262/#sec-execution-contexts), an +//! # [execution contexts](https://tc39.es/ecma262/#sec-execution-contexts), an //! execution context stack, a running execution context, an _Agent Record_, //! and an _executing thread_. Except for the -//!# [executing thread](https://tc39.es/ecma262/#executing-thread), the +//! # [executing thread](https://tc39.es/ecma262/#executing-thread), the //! constituents of an agent belong exclusively to that agent. //! //! In Nova, the [`Agent Record`](Agent) is the main entry point into the diff --git a/nova_vm/src/ecmascript/execution/environments/module_environment.rs b/nova_vm/src/ecmascript/execution/environments/module_environment.rs index 56cce3e4c..86d50db42 100644 --- a/nova_vm/src/ecmascript/execution/environments/module_environment.rs +++ b/nova_vm/src/ecmascript/execution/environments/module_environment.rs @@ -29,7 +29,7 @@ use super::{ /// and share the same specifications for all of those methods except for /// GetBindingValue, DeleteBinding, HasThisBinding and GetThisBinding. In /// addition, Module Environment Records support the methods listed in -///# [Table 22](https://tc39.es/ecma262/#table-additional-methods-of-module-environment-records). +/// # [Table 22](https://tc39.es/ecma262/#table-additional-methods-of-module-environment-records). /// /// NOTE: There is no data-wise difference between a DeclarativeEnvironment and /// a ModuleEnvironment, so we treat them exactly the same way. diff --git a/nova_vm/src/ecmascript/execution/weak_ref_and_finalization_registry.rs b/nova_vm/src/ecmascript/execution/weak_ref_and_finalization_registry.rs index 4f1914fb1..76fb6c928 100644 --- a/nova_vm/src/ecmascript/execution/weak_ref_and_finalization_registry.rs +++ b/nova_vm/src/ecmascript/execution/weak_ref_and_finalization_registry.rs @@ -2,7 +2,7 @@ // 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/. -//!## [9.9 Processing Model of WeakRef and FinalizationRegistry Targets](https://tc39.es/ecma262/#sec-weakref-processing-model) +//! ## [9.9 Processing Model of WeakRef and FinalizationRegistry Targets](https://tc39.es/ecma262/#sec-weakref-processing-model) use crate::{ ecmascript::{ diff --git a/nova_vm/src/ecmascript/types/language.rs b/nova_vm/src/ecmascript/types/language.rs index 332cb0a0e..30a5c7452 100644 --- a/nova_vm/src/ecmascript/types/language.rs +++ b/nova_vm/src/ecmascript/types/language.rs @@ -2,7 +2,7 @@ // 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/. -//!## [6.1 ECMAScript Language Types](https://tc39.es/ecma262/#sec-ecmascript-language-types) +//! ## [6.1 ECMAScript Language Types](https://tc39.es/ecma262/#sec-ecmascript-language-types) mod bigint; mod function; diff --git a/nova_vm/src/ecmascript/types/language/object.rs b/nova_vm/src/ecmascript/types/language/object.rs index 7a38b6c98..66de5eadc 100644 --- a/nova_vm/src/ecmascript/types/language/object.rs +++ b/nova_vm/src/ecmascript/types/language/object.rs @@ -332,7 +332,7 @@ pub enum Object<'a> { /// ### [22.1.5 String Iterator Objects](https://tc39.es/ecma262/#sec-string-iterator-objects) StringIterator(StringIterator<'a>) = STRING_ITERATOR_DISCRIMINANT, #[cfg(feature = "regexp")] - ///### [22.2.9 RegExp String Iterator Objects](https://tc39.es/ecma262/#sec-regexp-string-iterator-objects) + /// ### [22.2.9 RegExp String Iterator Objects](https://tc39.es/ecma262/#sec-regexp-string-iterator-objects) RegExpStringIterator(RegExpStringIterator<'a>) = REGEXP_STRING_ITERATOR_DISCRIMINANT, /// ## [27.5 Generator Objects](https://tc39.es/ecma262/#sec-generator-objects) Generator(Generator<'a>) = GENERATOR_DISCRIMINANT, diff --git a/nova_vm/src/ecmascript/types/language/value.rs b/nova_vm/src/ecmascript/types/language/value.rs index 3d71e667c..2f14faab3 100644 --- a/nova_vm/src/ecmascript/types/language/value.rs +++ b/nova_vm/src/ecmascript/types/language/value.rs @@ -380,7 +380,7 @@ pub enum Value<'a> { /// ### [22.1.5 String Iterator Objects](https://tc39.es/ecma262/#sec-string-iterator-objects) StringIterator(StringIterator<'a>), #[cfg(feature = "regexp")] - ///### [22.2.9 RegExp String Iterator Objects](https://tc39.es/ecma262/#sec-regexp-string-iterator-objects) + /// ### [22.2.9 RegExp String Iterator Objects](https://tc39.es/ecma262/#sec-regexp-string-iterator-objects) RegExpStringIterator(RegExpStringIterator<'a>), /// ## [27.5 Generator Objects](https://tc39.es/ecma262/#sec-generator-objects) Generator(Generator<'a>), diff --git a/nova_vm/src/ecmascript/types/spec.rs b/nova_vm/src/ecmascript/types/spec.rs index 403eedb38..cbc94298f 100644 --- a/nova_vm/src/ecmascript/types/spec.rs +++ b/nova_vm/src/ecmascript/types/spec.rs @@ -2,7 +2,7 @@ // 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/. -//!## [6.2 ECMAScript Specification Types](https://tc39.es/ecma262/#sec-ecmascript-specification-types) +//! ## [6.2 ECMAScript Specification Types](https://tc39.es/ecma262/#sec-ecmascript-specification-types) #[cfg(feature = "array-buffer")] mod data_block; diff --git a/nova_vm/src/engine/bytecode/bytecode_compiler/template_literals.rs b/nova_vm/src/engine/bytecode/bytecode_compiler/template_literals.rs index 5810369ed..effb2174b 100644 --- a/nova_vm/src/engine/bytecode/bytecode_compiler/template_literals.rs +++ b/nova_vm/src/engine/bytecode/bytecode_compiler/template_literals.rs @@ -2,7 +2,7 @@ // 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/. -//!### [13.2.8 Template Literals](https://tc39.es/ecma262/#sec-template-literals) +//! ### [13.2.8 Template Literals](https://tc39.es/ecma262/#sec-template-literals) use std::ptr::NonNull; From f6bf33effd02b983b6cea05e1da502f182151e58 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Fri, 13 Mar 2026 02:33:51 +0200 Subject: [PATCH 3/3] fix --- nova_vm/src/lib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/nova_vm/src/lib.rs b/nova_vm/src/lib.rs index 1a04a10ba..a4f91d3ce 100644 --- a/nova_vm/src/lib.rs +++ b/nova_vm/src/lib.rs @@ -46,13 +46,14 @@ //! 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 8 billion bytes. +//! Calling `new Array(10 ** 9)` will request an allocation for 8 billion +//! bytes. //! //! 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. +//! 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. //!