diff --git a/nova_vm/Cargo.toml b/nova_vm/Cargo.toml index 36410849b..b08b1acf5 100644 --- a/nova_vm/Cargo.toml +++ b/nova_vm/Cargo.toml @@ -23,9 +23,10 @@ sonic-rs = { workspace = true, optional = true} wtf8 = { workspace = true } [features] -default = ["math", "json"] +default = ["math", "json", "date"] math = [] json = ["sonic-rs"] +date = [] typescript = [] diff --git a/nova_vm/src/ecmascript/builtins.rs b/nova_vm/src/ecmascript/builtins.rs index a05759160..34b86bb5c 100644 --- a/nova_vm/src/ecmascript/builtins.rs +++ b/nova_vm/src/ecmascript/builtins.rs @@ -16,6 +16,7 @@ mod builtin_constructor; mod builtin_function; pub(crate) mod control_abstraction_objects; pub(crate) mod data_view; +#[cfg(feature = "date")] pub mod date; mod ecmascript_function; pub(crate) mod embedder_object; diff --git a/nova_vm/src/ecmascript/builtins/fundamental_objects/object_objects/object_prototype.rs b/nova_vm/src/ecmascript/builtins/fundamental_objects/object_objects/object_prototype.rs index 803d25f82..0cc17ad3a 100644 --- a/nova_vm/src/ecmascript/builtins/fundamental_objects/object_objects/object_prototype.rs +++ b/nova_vm/src/ecmascript/builtins/fundamental_objects/object_objects/object_prototype.rs @@ -165,6 +165,7 @@ impl ObjectPrototype { // 5. If isArray is true, let builtinTag be "Array". Value::Array(_) => Ok(BUILTIN_STRING_MEMORY._object_Array_.into_value()), // 12. Else if O has a [[DateValue]] internal slot, let builtinTag be "Date". + #[cfg(feature = "date")] Value::Date(_) => Ok(BUILTIN_STRING_MEMORY._object_Date_.into_value()), // 8. Else if O has an [[ErrorData]] internal slot, let builtinTag be "Error". Value::Error(_) => Ok(BUILTIN_STRING_MEMORY._object_Error_.into_value()), diff --git a/nova_vm/src/ecmascript/builtins/numbers_and_dates.rs b/nova_vm/src/ecmascript/builtins/numbers_and_dates.rs index 1a8d0c288..d6938518f 100644 --- a/nova_vm/src/ecmascript/builtins/numbers_and_dates.rs +++ b/nova_vm/src/ecmascript/builtins/numbers_and_dates.rs @@ -3,6 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. pub mod bigint_objects; +#[cfg(feature = "date")] pub mod date_objects; #[cfg(feature = "math")] pub mod math_object; diff --git a/nova_vm/src/ecmascript/builtins/ordinary.rs b/nova_vm/src/ecmascript/builtins/ordinary.rs index 2236d9eab..93862cfca 100644 --- a/nova_vm/src/ecmascript/builtins/ordinary.rs +++ b/nova_vm/src/ecmascript/builtins/ordinary.rs @@ -24,10 +24,11 @@ use crate::{ heap::{CompactionLists, CreateHeapData, HeapMarkAndSweep, WellKnownSymbolIndexes, WorkQueues}, }; +#[cfg(feature = "date")] +use super::date::data::DateHeapData; use super::{ control_abstraction_objects::generator_objects::GeneratorHeapData, data_view::data::DataViewHeapData, - date::data::DateHeapData, error::ErrorHeapData, finalization_registry::data::FinalizationRegistryHeapData, indexed_collections::array_objects::array_iterator_objects::array_iterator::ArrayIteratorHeapData, @@ -824,6 +825,7 @@ pub(crate) fn ordinary_object_create_with_intrinsics( .heap .create(ErrorHeapData::new(ExceptionType::EvalError, None, None)) .into_object(), + #[cfg(feature = "date")] ProtoIntrinsics::Date => agent.heap.create(DateHeapData::new_invalid()).into_object(), ProtoIntrinsics::Function => todo!(), ProtoIntrinsics::Number => agent @@ -1041,6 +1043,7 @@ pub(crate) fn get_prototype_from_constructor( ProtoIntrinsics::BigUint64Array => Some(intrinsics.big_uint64_array().into_function()), ProtoIntrinsics::Boolean => Some(intrinsics.boolean().into_function()), ProtoIntrinsics::DataView => Some(intrinsics.data_view().into_function()), + #[cfg(feature = "date")] ProtoIntrinsics::Date => Some(intrinsics.date().into_function()), ProtoIntrinsics::Error => Some(intrinsics.error().into_function()), ProtoIntrinsics::EvalError => Some(intrinsics.eval_error().into_function()), diff --git a/nova_vm/src/ecmascript/execution/realm.rs b/nova_vm/src/ecmascript/execution/realm.rs index f4442b144..22618ac0d 100644 --- a/nova_vm/src/ecmascript/execution/realm.rs +++ b/nova_vm/src/ecmascript/execution/realm.rs @@ -574,18 +574,20 @@ pub(crate) fn set_default_global_bindings( }; define_property_or_throw(agent, global, name, desc)?; - // 19.3.9 Date ( . . . ) - let name = PropertyKey::from(BUILTIN_STRING_MEMORY.Date); - let value = agent.get_realm(realm_id).intrinsics().date(); - let desc = PropertyDescriptor { - value: Some(value.into_value()), - writable: Some(true), - enumerable: Some(false), - configurable: Some(true), - ..Default::default() - }; - define_property_or_throw(agent, global, name, desc)?; - + #[cfg(feature = "date")] + { + // 19.3.9 Date ( . . . ) + let name = PropertyKey::from(BUILTIN_STRING_MEMORY.Date); + let value = agent.get_realm(realm_id).intrinsics().date(); + let desc = PropertyDescriptor { + value: Some(value.into_value()), + writable: Some(true), + enumerable: Some(false), + configurable: Some(true), + ..Default::default() + }; + define_property_or_throw(agent, global, name, desc)?; + } // 19.3.10 Error ( . . . ) let name = PropertyKey::from(BUILTIN_STRING_MEMORY.Error); let value = agent.get_realm(realm_id).intrinsics().error(); @@ -1171,6 +1173,7 @@ mod test { if let Some((missing_builtin_index, _)) = missing_builtin { panic_builtin_function_missing(missing_builtin_index); } + #[cfg(feature = "date")] assert!(agent.heap.dates.is_empty()); assert!(agent.heap.ecmascript_functions.is_empty()); assert_eq!(agent.heap.environments.declarative.len(), 1); diff --git a/nova_vm/src/ecmascript/execution/realm/intrinsics.rs b/nova_vm/src/ecmascript/execution/realm/intrinsics.rs index cbf6b7f69..bfc16bf4f 100644 --- a/nova_vm/src/ecmascript/execution/realm/intrinsics.rs +++ b/nova_vm/src/ecmascript/execution/realm/intrinsics.rs @@ -126,7 +126,6 @@ use crate::{ bigint_objects::{ bigint_constructor::BigIntConstructor, bigint_prototype::BigIntPrototype, }, - date_objects::{date_constructor::DateConstructor, date_prototype::DatePrototype}, number_objects::{ number_constructor::NumberConstructor, number_prototype::NumberPrototype, }, @@ -142,6 +141,11 @@ use crate::{ }; use super::RealmIdentifier; + +#[cfg(feature = "date")] +use crate::ecmascript::builtins::numbers_and_dates::date_objects::{ + date_constructor::DateConstructor, date_prototype::DatePrototype, +}; #[cfg(feature = "math")] use crate::ecmascript::builtins::numbers_and_dates::math_object::MathObject; #[cfg(feature = "json")] @@ -172,6 +176,7 @@ pub enum ProtoIntrinsics { BigUint64Array, Boolean, DataView, + #[cfg(feature = "date")] Date, Error, EvalError, @@ -262,7 +267,9 @@ impl Intrinsics { BigIntConstructor::create_intrinsic(agent, realm); #[cfg(feature = "math")] MathObject::create_intrinsic(agent, realm); + #[cfg(feature = "date")] DatePrototype::create_intrinsic(agent, realm); + #[cfg(feature = "date")] DateConstructor::create_intrinsic(agent, realm); StringPrototype::create_intrinsic(agent, realm); StringConstructor::create_intrinsic(agent, realm); @@ -331,6 +338,7 @@ impl Intrinsics { ProtoIntrinsics::BigInt => self.big_int_prototype().into(), ProtoIntrinsics::Boolean => self.boolean_prototype().into(), ProtoIntrinsics::Error => self.error_prototype().into(), + #[cfg(feature = "date")] ProtoIntrinsics::Date => self.date_prototype().into(), ProtoIntrinsics::EvalError => self.eval_error_prototype().into(), ProtoIntrinsics::Function => self.function_prototype().into(), @@ -652,6 +660,7 @@ impl Intrinsics { IntrinsicConstructorIndexes::DataView.get_object_index(self.object_index_base) } + #[cfg(feature = "date")] /// %Date.prototype.toUTCString% pub(crate) fn date_prototype_to_utcstring(&self) -> BuiltinFunction { IntrinsicFunctionIndexes::DatePrototypeToUTCString @@ -659,6 +668,7 @@ impl Intrinsics { .into() } + #[cfg(feature = "date")] /// %Date.prototype% pub(crate) fn date_prototype(&self) -> OrdinaryObject { IntrinsicObjectIndexes::DatePrototype @@ -666,6 +676,7 @@ impl Intrinsics { .into() } + #[cfg(feature = "date")] /// %Date% pub(crate) fn date(&self) -> BuiltinFunction { IntrinsicConstructorIndexes::Date @@ -673,6 +684,7 @@ impl Intrinsics { .into() } + #[cfg(feature = "date")] pub(crate) fn date_base_object(&self) -> ObjectIndex { IntrinsicConstructorIndexes::Date.get_object_index(self.object_index_base) } @@ -1513,8 +1525,11 @@ impl HeapMarkAndSweep for Intrinsics { self.boolean().mark_values(queues); self.data_view_prototype().mark_values(queues); self.data_view().mark_values(queues); + #[cfg(feature = "date")] self.date_prototype_to_utcstring().mark_values(queues); + #[cfg(feature = "date")] self.date_prototype().mark_values(queues); + #[cfg(feature = "date")] self.date().mark_values(queues); self.decode_uri().mark_values(queues); self.decode_uri_component().mark_values(queues); diff --git a/nova_vm/src/ecmascript/types/language/object.rs b/nova_vm/src/ecmascript/types/language/object.rs index 7a16d2d8b..e9838396d 100644 --- a/nova_vm/src/ecmascript/types/language/object.rs +++ b/nova_vm/src/ecmascript/types/language/object.rs @@ -11,6 +11,8 @@ mod property_storage; use std::hash::Hash; +#[cfg(feature = "date")] +use super::value::DATE_DISCRIMINANT; use super::{ value::{ ARGUMENTS_DISCRIMINANT, ARRAY_BUFFER_DISCRIMINANT, ARRAY_DISCRIMINANT, @@ -20,19 +22,22 @@ use super::{ BUILTIN_FUNCTION_DISCRIMINANT, BUILTIN_GENERATOR_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BUILTIN_PROXY_REVOKER_FUNCTION, - DATA_VIEW_DISCRIMINANT, DATE_DISCRIMINANT, ECMASCRIPT_FUNCTION_DISCRIMINANT, - EMBEDDER_OBJECT_DISCRIMINANT, ERROR_DISCRIMINANT, FINALIZATION_REGISTRY_DISCRIMINANT, - FLOAT_32_ARRAY_DISCRIMINANT, FLOAT_64_ARRAY_DISCRIMINANT, GENERATOR_DISCRIMINANT, - INT_16_ARRAY_DISCRIMINANT, INT_32_ARRAY_DISCRIMINANT, INT_8_ARRAY_DISCRIMINANT, - ITERATOR_DISCRIMINANT, MAP_DISCRIMINANT, MAP_ITERATOR_DISCRIMINANT, MODULE_DISCRIMINANT, - OBJECT_DISCRIMINANT, PRIMITIVE_OBJECT_DISCRIMINANT, PROMISE_DISCRIMINANT, - PROXY_DISCRIMINANT, REGEXP_DISCRIMINANT, SET_DISCRIMINANT, SET_ITERATOR_DISCRIMINANT, + DATA_VIEW_DISCRIMINANT, ECMASCRIPT_FUNCTION_DISCRIMINANT, EMBEDDER_OBJECT_DISCRIMINANT, + ERROR_DISCRIMINANT, FINALIZATION_REGISTRY_DISCRIMINANT, FLOAT_32_ARRAY_DISCRIMINANT, + FLOAT_64_ARRAY_DISCRIMINANT, GENERATOR_DISCRIMINANT, INT_16_ARRAY_DISCRIMINANT, + INT_32_ARRAY_DISCRIMINANT, INT_8_ARRAY_DISCRIMINANT, ITERATOR_DISCRIMINANT, + MAP_DISCRIMINANT, MAP_ITERATOR_DISCRIMINANT, MODULE_DISCRIMINANT, OBJECT_DISCRIMINANT, + PRIMITIVE_OBJECT_DISCRIMINANT, PROMISE_DISCRIMINANT, PROXY_DISCRIMINANT, + REGEXP_DISCRIMINANT, SET_DISCRIMINANT, SET_ITERATOR_DISCRIMINANT, SHARED_ARRAY_BUFFER_DISCRIMINANT, UINT_16_ARRAY_DISCRIMINANT, UINT_32_ARRAY_DISCRIMINANT, UINT_8_ARRAY_DISCRIMINANT, UINT_8_CLAMPED_ARRAY_DISCRIMINANT, WEAK_MAP_DISCRIMINANT, WEAK_REF_DISCRIMINANT, WEAK_SET_DISCRIMINANT, }, Function, IntoValue, Value, }; + +#[cfg(feature = "date")] +use crate::ecmascript::builtins::date::Date; use crate::{ ecmascript::{ builtins::{ @@ -42,7 +47,6 @@ use crate::{ promise_objects::promise_abstract_operations::promise_resolving_functions::BuiltinPromiseResolvingFunction, }, data_view::DataView, - date::Date, embedder_object::EmbedderObject, error::Error, finalization_registry::FinalizationRegistry, @@ -104,6 +108,7 @@ pub enum Object { Array(Array) = ARRAY_DISCRIMINANT, ArrayBuffer(ArrayBuffer) = ARRAY_BUFFER_DISCRIMINANT, DataView(DataView) = DATA_VIEW_DISCRIMINANT, + #[cfg(feature = "date")] Date(Date) = DATE_DISCRIMINANT, Error(Error) = ERROR_DISCRIMINANT, FinalizationRegistry(FinalizationRegistry) = FINALIZATION_REGISTRY_DISCRIMINANT, @@ -160,6 +165,7 @@ impl IntoValue for Object { Object::Array(data) => Value::Array(data), Object::ArrayBuffer(data) => Value::ArrayBuffer(data), Object::DataView(data) => Value::DataView(data), + #[cfg(feature = "date")] Object::Date(data) => Value::Date(data), Object::Error(data) => Value::Error(data), Object::FinalizationRegistry(data) => Value::FinalizationRegistry(data), @@ -336,6 +342,7 @@ impl From for Value { Object::Array(data) => Value::Array(data), Object::ArrayBuffer(data) => Value::ArrayBuffer(data), Object::DataView(data) => Value::DataView(data), + #[cfg(feature = "date")] Object::Date(data) => Value::Date(data), Object::Error(data) => Value::Error(data), Object::FinalizationRegistry(data) => Value::FinalizationRegistry(data), @@ -389,6 +396,7 @@ impl TryFrom for Object { | Value::SmallBigInt(_) => Err(()), Value::Object(x) => Ok(Object::from(x)), Value::Array(x) => Ok(Object::from(x)), + #[cfg(feature = "date")] Value::Date(x) => Ok(Object::Date(x)), Value::Error(x) => Ok(Object::from(x)), Value::BoundFunction(x) => Ok(Object::from(x)), @@ -467,6 +475,7 @@ impl Hash for Object { Object::Array(data) => data.get_index().hash(state), Object::ArrayBuffer(data) => data.get_index().hash(state), Object::DataView(data) => data.get_index().hash(state), + #[cfg(feature = "date")] Object::Date(data) => data.get_index().hash(state), Object::Error(data) => data.get_index().hash(state), Object::FinalizationRegistry(data) => data.get_index().hash(state), @@ -521,6 +530,7 @@ impl InternalSlots for Object { Object::Object(data) => data.internal_extensible(agent), Object::Array(data) => data.internal_extensible(agent), Object::ArrayBuffer(data) => data.internal_extensible(agent), + #[cfg(feature = "date")] Object::Date(data) => data.internal_extensible(agent), Object::Error(data) => data.internal_extensible(agent), Object::BoundFunction(data) => data.internal_extensible(agent), @@ -578,6 +588,7 @@ impl InternalSlots for Object { Object::Object(data) => data.internal_set_extensible(agent, value), Object::Array(data) => data.internal_set_extensible(agent, value), Object::ArrayBuffer(data) => data.internal_set_extensible(agent, value), + #[cfg(feature = "date")] Object::Date(data) => data.internal_set_extensible(agent, value), Object::Error(data) => data.internal_set_extensible(agent, value), Object::BoundFunction(data) => data.internal_set_extensible(agent, value), @@ -653,6 +664,7 @@ impl InternalSlots for Object { Object::Object(data) => data.internal_prototype(agent), Object::Array(data) => data.internal_prototype(agent), Object::ArrayBuffer(data) => data.internal_prototype(agent), + #[cfg(feature = "date")] Object::Date(data) => data.internal_prototype(agent), Object::Error(data) => data.internal_prototype(agent), Object::BoundFunction(data) => data.internal_prototype(agent), @@ -710,6 +722,7 @@ impl InternalSlots for Object { Object::Object(data) => data.internal_set_prototype(agent, prototype), Object::Array(data) => data.internal_set_prototype(agent, prototype), Object::ArrayBuffer(data) => data.internal_set_prototype(agent, prototype), + #[cfg(feature = "date")] Object::Date(data) => data.internal_set_prototype(agent, prototype), Object::Error(data) => data.internal_set_prototype(agent, prototype), Object::BoundFunction(data) => data.internal_set_prototype(agent, prototype), @@ -789,6 +802,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_get_prototype_of(agent), Object::Array(data) => data.internal_get_prototype_of(agent), Object::ArrayBuffer(data) => data.internal_get_prototype_of(agent), + #[cfg(feature = "date")] Object::Date(data) => data.internal_get_prototype_of(agent), Object::Error(data) => data.internal_get_prototype_of(agent), Object::BoundFunction(data) => data.internal_get_prototype_of(agent), @@ -864,6 +878,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_set_prototype_of(agent, prototype), Object::Array(data) => data.internal_set_prototype_of(agent, prototype), Object::ArrayBuffer(data) => data.internal_set_prototype_of(agent, prototype), + #[cfg(feature = "date")] Object::Date(data) => data.internal_set_prototype_of(agent, prototype), Object::Error(data) => data.internal_set_prototype_of(agent, prototype), Object::BoundFunction(data) => data.internal_set_prototype_of(agent, prototype), @@ -941,6 +956,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_is_extensible(agent), Object::Array(data) => data.internal_is_extensible(agent), Object::ArrayBuffer(data) => data.internal_is_extensible(agent), + #[cfg(feature = "date")] Object::Date(data) => data.internal_is_extensible(agent), Object::Error(data) => data.internal_is_extensible(agent), Object::BoundFunction(data) => data.internal_is_extensible(agent), @@ -1006,6 +1022,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_prevent_extensions(agent), Object::Array(data) => data.internal_prevent_extensions(agent), Object::ArrayBuffer(data) => data.internal_prevent_extensions(agent), + #[cfg(feature = "date")] Object::Date(data) => data.internal_prevent_extensions(agent), Object::Error(data) => data.internal_prevent_extensions(agent), Object::BoundFunction(data) => data.internal_prevent_extensions(agent), @@ -1085,6 +1102,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_get_own_property(agent, property_key), Object::Array(data) => data.internal_get_own_property(agent, property_key), Object::ArrayBuffer(data) => data.internal_get_own_property(agent, property_key), + #[cfg(feature = "date")] Object::Date(data) => data.internal_get_own_property(agent, property_key), Object::Error(data) => data.internal_get_own_property(agent, property_key), Object::BoundFunction(data) => data.internal_get_own_property(agent, property_key), @@ -1175,6 +1193,7 @@ impl InternalMethods for Object { Object::ArrayBuffer(idx) => { idx.internal_define_own_property(agent, property_key, property_descriptor) } + #[cfg(feature = "date")] Object::Date(idx) => { idx.internal_define_own_property(agent, property_key, property_descriptor) } @@ -1301,6 +1320,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_has_property(agent, property_key), Object::Array(data) => data.internal_has_property(agent, property_key), Object::ArrayBuffer(data) => data.internal_has_property(agent, property_key), + #[cfg(feature = "date")] Object::Date(data) => data.internal_has_property(agent, property_key), Object::Error(data) => data.internal_has_property(agent, property_key), Object::BoundFunction(data) => data.internal_has_property(agent, property_key), @@ -1383,6 +1403,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_get(agent, property_key, receiver), Object::Array(data) => data.internal_get(agent, property_key, receiver), Object::ArrayBuffer(data) => data.internal_get(agent, property_key, receiver), + #[cfg(feature = "date")] Object::Date(data) => data.internal_get(agent, property_key, receiver), Object::Error(data) => data.internal_get(agent, property_key, receiver), Object::BoundFunction(data) => data.internal_get(agent, property_key, receiver), @@ -1466,6 +1487,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_set(agent, property_key, value, receiver), Object::Array(data) => data.internal_set(agent, property_key, value, receiver), Object::ArrayBuffer(data) => data.internal_set(agent, property_key, value, receiver), + #[cfg(feature = "date")] Object::Date(data) => data.internal_set(agent, property_key, value, receiver), Object::Error(data) => data.internal_set(agent, property_key, value, receiver), Object::BoundFunction(data) => data.internal_set(agent, property_key, value, receiver), @@ -1556,6 +1578,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_delete(agent, property_key), Object::Array(data) => data.internal_delete(agent, property_key), Object::ArrayBuffer(data) => data.internal_delete(agent, property_key), + #[cfg(feature = "date")] Object::Date(data) => data.internal_delete(agent, property_key), Object::Error(data) => data.internal_delete(agent, property_key), Object::BoundFunction(data) => data.internal_delete(agent, property_key), @@ -1631,6 +1654,7 @@ impl InternalMethods for Object { Object::Object(data) => data.internal_own_property_keys(agent), Object::Array(data) => data.internal_own_property_keys(agent), Object::ArrayBuffer(data) => data.internal_own_property_keys(agent), + #[cfg(feature = "date")] Object::Date(data) => data.internal_own_property_keys(agent), Object::Error(data) => data.internal_own_property_keys(agent), Object::BoundFunction(data) => data.internal_own_property_keys(agent), @@ -1743,6 +1767,7 @@ impl HeapMarkAndSweep for Object { Object::Object(data) => data.mark_values(queues), Object::Array(data) => data.mark_values(queues), Object::ArrayBuffer(data) => data.mark_values(queues), + #[cfg(feature = "date")] Object::Date(data) => data.mark_values(queues), Object::Error(data) => data.mark_values(queues), Object::BoundFunction(data) => data.mark_values(queues), @@ -1805,6 +1830,7 @@ impl HeapMarkAndSweep for Object { Object::Array(data) => data.sweep_values(compactions), Object::ArrayBuffer(data) => data.sweep_values(compactions), Object::DataView(data) => data.sweep_values(compactions), + #[cfg(feature = "date")] Object::Date(data) => data.sweep_values(compactions), Object::Error(data) => data.sweep_values(compactions), Object::FinalizationRegistry(data) => data.sweep_values(compactions), diff --git a/nova_vm/src/ecmascript/types/language/value.rs b/nova_vm/src/ecmascript/types/language/value.rs index 856b9c63e..f25548f44 100644 --- a/nova_vm/src/ecmascript/types/language/value.rs +++ b/nova_vm/src/ecmascript/types/language/value.rs @@ -9,6 +9,8 @@ use super::{ BigInt, BigIntHeapData, IntoValue, Number, Numeric, OrdinaryObject, String, StringHeapData, Symbol, }; +#[cfg(feature = "date")] +use crate::ecmascript::builtins::date::Date; use crate::{ ecmascript::{ abstract_operations::type_conversion::{ @@ -21,7 +23,6 @@ use crate::{ promise_objects::promise_abstract_operations::promise_resolving_functions::BuiltinPromiseResolvingFunction, }, data_view::DataView, - date::Date, embedder_object::EmbedderObject, error::Error, finalization_registry::FinalizationRegistry, @@ -50,6 +51,7 @@ use crate::{ heap::{indexes::TypedArrayIndex, CompactionLists, HeapMarkAndSweep, WorkQueues}, SmallInteger, SmallString, }; + use std::{ hash::{Hash, Hasher}, mem::size_of, @@ -144,6 +146,7 @@ pub enum Value { Array(Array), ArrayBuffer(ArrayBuffer), DataView(DataView), + #[cfg(feature = "date")] Date(Date), Error(Error), FinalizationRegistry(FinalizationRegistry), @@ -225,6 +228,7 @@ pub(crate) const OBJECT_DISCRIMINANT: u8 = pub(crate) const ARRAY_DISCRIMINANT: u8 = value_discriminant(Value::Array(Array::_def())); pub(crate) const ARRAY_BUFFER_DISCRIMINANT: u8 = value_discriminant(Value::ArrayBuffer(ArrayBuffer::_def())); +#[cfg(feature = "date")] pub(crate) const DATE_DISCRIMINANT: u8 = value_discriminant(Value::Date(Date::_def())); pub(crate) const ERROR_DISCRIMINANT: u8 = value_discriminant(Value::Error(Error::_def())); pub(crate) const BUILTIN_FUNCTION_DISCRIMINANT: u8 = @@ -576,6 +580,7 @@ impl Value { discriminant.hash(hasher); data.get_index().hash(hasher); } + #[cfg(feature = "date")] Value::Date(data) => { discriminant.hash(hasher); data.get_index().hash(hasher); @@ -778,6 +783,7 @@ impl Value { discriminant.hash(hasher); data.get_index().hash(hasher); } + #[cfg(feature = "date")] Value::Date(data) => { discriminant.hash(hasher); data.get_index().hash(hasher); @@ -1008,6 +1014,7 @@ impl HeapMarkAndSweep for Value { Value::Object(data) => data.mark_values(queues), Value::Array(data) => data.mark_values(queues), Value::ArrayBuffer(data) => data.mark_values(queues), + #[cfg(feature = "date")] Value::Date(data) => data.mark_values(queues), Value::Error(data) => data.mark_values(queues), Value::BoundFunction(data) => data.mark_values(queues), @@ -1072,6 +1079,7 @@ impl HeapMarkAndSweep for Value { Value::Object(data) => data.sweep_values(compactions), Value::Array(data) => data.sweep_values(compactions), Value::ArrayBuffer(data) => data.sweep_values(compactions), + #[cfg(feature = "date")] Value::Date(data) => data.sweep_values(compactions), Value::Error(data) => data.sweep_values(compactions), Value::BoundFunction(data) => data.sweep_values(compactions), diff --git a/nova_vm/src/engine/bytecode/vm.rs b/nova_vm/src/engine/bytecode/vm.rs index c3d0309a1..3b5b3dd34 100644 --- a/nova_vm/src/engine/bytecode/vm.rs +++ b/nova_vm/src/engine/bytecode/vm.rs @@ -2090,7 +2090,6 @@ fn typeof_operator(_: &mut Agent, val: Value) -> String { Value::Object(_) | Value::Array(_) | Value::ArrayBuffer(_) | - Value::Date(_) | Value::Error(_) | // 14. Return "object". Value::PrimitiveObject(_) | @@ -2125,6 +2124,8 @@ fn typeof_operator(_: &mut Agent, val: Value) -> String { Value::Generator(_) | Value::Module(_) | Value::EmbedderObject(_) => BUILTIN_STRING_MEMORY.object, + #[cfg(feature = "date")] + Value::Date(_) => BUILTIN_STRING_MEMORY.object, // 13. If val has a [[Call]] internal slot, return "function". Value::BoundFunction(_) | Value::BuiltinFunction(_) | Value::ECMAScriptFunction(_) | Value::BuiltinGeneratorFunction | diff --git a/nova_vm/src/heap.rs b/nova_vm/src/heap.rs index 8ea620107..3348e5941 100644 --- a/nova_vm/src/heap.rs +++ b/nova_vm/src/heap.rs @@ -40,7 +40,6 @@ use crate::ecmascript::{ }, }, data_view::data::DataViewHeapData, - date::data::DateHeapData, embedder_object::data::EmbedderObjectHeapData, error::ErrorHeapData, finalization_registry::data::FinalizationRegistryHeapData, @@ -68,6 +67,10 @@ use crate::ecmascript::{ BUILTIN_STRINGS_LIST, }, }; + +#[cfg(feature = "date")] +use crate::ecmascript::builtins::date::data::DateHeapData; + use crate::ecmascript::{ builtins::{ArrayBufferHeapData, ArrayHeapData}, execution::{Environments, Realm, RealmIdentifier}, @@ -93,6 +96,7 @@ pub struct Heap { pub builtin_constructors: Vec>, pub builtin_functions: Vec>, pub data_views: Vec>, + #[cfg(feature = "date")] pub dates: Vec>, pub ecmascript_functions: Vec>, /// ElementsArrays is where all element arrays live; @@ -174,6 +178,7 @@ impl Heap { builtin_constructors: Vec::with_capacity(256), builtin_functions: Vec::with_capacity(1024), data_views: Vec::with_capacity(0), + #[cfg(feature = "date")] dates: Vec::with_capacity(1024), ecmascript_functions: Vec::with_capacity(1024), elements: ElementArrays { diff --git a/nova_vm/src/heap/heap_bits.rs b/nova_vm/src/heap/heap_bits.rs index aebfb668f..be780789a 100644 --- a/nova_vm/src/heap/heap_bits.rs +++ b/nova_vm/src/heap/heap_bits.rs @@ -8,6 +8,8 @@ use super::{ indexes::{BaseIndex, ElementIndex, TypedArrayIndex}, Heap, }; +#[cfg(feature = "date")] +use crate::ecmascript::builtins::date::Date; use crate::ecmascript::{ builtins::{ bound_function::BoundFunction, @@ -20,7 +22,6 @@ use crate::ecmascript::{ }, }, data_view::DataView, - date::Date, embedder_object::EmbedderObject, error::Error, finalization_registry::FinalizationRegistry, @@ -64,6 +65,7 @@ pub struct HeapBits { pub builtin_constructors: Box<[bool]>, pub builtin_functions: Box<[bool]>, pub data_views: Box<[bool]>, + #[cfg(feature = "date")] pub dates: Box<[bool]>, pub declarative_environments: Box<[bool]>, pub e_2_10: Box<[(bool, u16)]>, @@ -118,6 +120,7 @@ pub(crate) struct WorkQueues { pub builtin_constructors: Vec, pub builtin_functions: Vec, pub data_views: Vec, + #[cfg(feature = "date")] pub dates: Vec, pub declarative_environments: Vec, pub e_2_10: Vec<(ElementIndex, u32)>, @@ -172,6 +175,7 @@ impl HeapBits { let builtin_constructors = vec![false; heap.builtin_constructors.len()]; let builtin_functions = vec![false; heap.builtin_functions.len()]; let data_views = vec![false; heap.data_views.len()]; + #[cfg(feature = "date")] let dates = vec![false; heap.dates.len()]; let declarative_environments = vec![false; heap.environments.declarative.len()]; let e_2_10 = vec![(false, 0u16); heap.elements.e2pow10.values.len()]; @@ -223,6 +227,7 @@ impl HeapBits { builtin_constructors: builtin_constructors.into_boxed_slice(), builtin_functions: builtin_functions.into_boxed_slice(), data_views: data_views.into_boxed_slice(), + #[cfg(feature = "date")] dates: dates.into_boxed_slice(), declarative_environments: declarative_environments.into_boxed_slice(), e_2_10: e_2_10.into_boxed_slice(), @@ -280,6 +285,7 @@ impl WorkQueues { builtin_constructors: Vec::with_capacity(heap.builtin_constructors.len() / 4), builtin_functions: Vec::with_capacity(heap.builtin_functions.len() / 4), data_views: Vec::with_capacity(heap.data_views.len() / 4), + #[cfg(feature = "date")] dates: Vec::with_capacity(heap.dates.len() / 4), declarative_environments: Vec::with_capacity(heap.environments.declarative.len() / 4), e_2_10: Vec::with_capacity(heap.elements.e2pow10.values.len() / 4), @@ -360,6 +366,7 @@ impl WorkQueues { builtin_constructors, builtin_functions, data_views, + #[cfg(feature = "date")] dates, declarative_environments, e_2_10, @@ -402,6 +409,10 @@ impl WorkQueues { weak_refs, weak_sets, } = self; + + #[cfg(not(feature = "date"))] + let dates: &[bool; 0] = &[]; + array_buffers.is_empty() && arrays.is_empty() && array_iterators.is_empty() @@ -603,6 +614,7 @@ pub(crate) struct CompactionLists { pub builtin_constructors: CompactionList, pub builtin_functions: CompactionList, pub data_views: CompactionList, + #[cfg(feature = "date")] pub dates: CompactionList, pub declarative_environments: CompactionList, pub e_2_10: CompactionList, @@ -687,6 +699,7 @@ impl CompactionLists { embedder_objects: CompactionList::from_mark_bits(&bits.embedder_objects), generators: CompactionList::from_mark_bits(&bits.generators), source_codes: CompactionList::from_mark_bits(&bits.source_codes), + #[cfg(feature = "date")] dates: CompactionList::from_mark_bits(&bits.dates), errors: CompactionList::from_mark_bits(&bits.errors), maps: CompactionList::from_mark_bits(&bits.maps), diff --git a/nova_vm/src/heap/heap_constants.rs b/nova_vm/src/heap/heap_constants.rs index 45c3b3376..e49278a08 100644 --- a/nova_vm/src/heap/heap_constants.rs +++ b/nova_vm/src/heap/heap_constants.rs @@ -27,6 +27,7 @@ pub(crate) enum IntrinsicObjectIndexes { // Numbers and dates BigIntPrototype, MathObject, + #[cfg(feature = "date")] DatePrototype, // Text processing @@ -132,6 +133,7 @@ pub(crate) enum IntrinsicConstructorIndexes { // Numbers and dates Number, BigInt, + #[cfg(feature = "date")] Date, // Text processing @@ -200,6 +202,7 @@ pub(crate) enum IntrinsicFunctionIndexes { ArrayPrototypeSort, ArrayPrototypeToString, ArrayPrototypeValues, + #[cfg(feature = "date")] DatePrototypeToUTCString, DecodeURI, DecodeURIComponent, diff --git a/nova_vm/src/heap/heap_gc.rs b/nova_vm/src/heap/heap_gc.rs index bf43e555d..0d2b911b4 100644 --- a/nova_vm/src/heap/heap_gc.rs +++ b/nova_vm/src/heap/heap_gc.rs @@ -15,6 +15,8 @@ use super::{ indexes::{ElementIndex, StringIndex, TypedArrayIndex}, Heap, WellKnownSymbolIndexes, }; +#[cfg(feature = "date")] +use crate::ecmascript::builtins::date::Date; use crate::ecmascript::{ builtins::{ bound_function::BoundFunction, @@ -27,7 +29,6 @@ use crate::ecmascript::{ }, }, data_view::DataView, - date::Date, embedder_object::EmbedderObject, error::Error, finalization_registry::FinalizationRegistry, @@ -111,6 +112,7 @@ pub fn heap_gc(heap: &mut Heap, root_realms: &mut [Option]) { builtin_constructors, builtin_functions, data_views, + #[cfg(feature = "date")] dates, ecmascript_functions, elements, @@ -420,19 +422,22 @@ pub fn heap_gc(heap: &mut Heap, root_realms: &mut [Option]) { data_views.get(index).mark_values(&mut queues); } }); - let mut date_marks: Box<[Date]> = queues.dates.drain(..).collect(); - date_marks.sort(); - date_marks.iter().for_each(|&idx| { - let index = idx.get_index(); - if let Some(marked) = bits.dates.get_mut(index) { - if *marked { - // Already marked, ignore - return; + #[cfg(feature = "date")] + { + let mut date_marks: Box<[Date]> = queues.dates.drain(..).collect(); + date_marks.sort(); + date_marks.iter().for_each(|&idx| { + let index = idx.get_index(); + if let Some(marked) = bits.dates.get_mut(index) { + if *marked { + // Already marked, ignore + return; + } + *marked = true; + dates.get(index).mark_values(&mut queues); } - *marked = true; - dates.get(index).mark_values(&mut queues); - } - }); + }); + } let mut embedder_object_marks: Box<[EmbedderObject]> = queues.embedder_objects.drain(..).collect(); embedder_object_marks.sort(); @@ -919,6 +924,7 @@ fn sweep(heap: &mut Heap, bits: &HeapBits, root_realms: &mut [Option; pub type BuiltinFunctionIndex = BaseIndex; pub type BuiltinConstructorIndex = BaseIndex; pub type DataViewIndex = BaseIndex; +#[cfg(feature = "date")] pub type DateIndex = BaseIndex; pub type ECMAScriptFunctionIndex = BaseIndex; pub type ElementIndex = BaseIndex<[Option]>;