diff --git a/nova_vm/src/builtin_strings b/nova_vm/src/builtin_strings index bcfb1babc..b98a1b9e8 100644 --- a/nova_vm/src/builtin_strings +++ b/nova_vm/src/builtin_strings @@ -9,6 +9,12 @@ [object String] [object Undefined] [Symbol.hasInstance] +[Symbol.iterator] +[Symbol.match] +[Symbol.matchAll] +[Symbol.replace] +[Symbol.search] +[Symbol.split] [Symbol.toPrimitive] abs acos @@ -42,7 +48,11 @@ caller cause cbrt ceil +charAt +charCodeAt clz32 +codePointAt +concat constructor copyWithin cos @@ -55,11 +65,14 @@ defineProperties defineProperty description done +dotAll E +endsWith entries EPSILON Error EvalError +exec exp expm1 false @@ -69,6 +82,7 @@ find findIndex findLast findLastIndex +flags flat flatMap Float32Array @@ -76,6 +90,8 @@ Float64Array floor for freeze +fromCharCode +fromCodePoint fromEntries fround function @@ -83,6 +99,16 @@ Function get [Symbol.species] get byteLength get description +get dotAll +get flags +get global +get hasIndices +get ignoreCase +get multiline +get source +get stricky +get unicode +get unicodeSets getDate getDay getFullYear @@ -106,14 +132,18 @@ getUTCMilliseconds getUTCMinutes getUTCMonth getUTCSeconds +global globalThis groupBy +hasIndices hasInstance hasOwn hasOwnProperty hypot +ignoreCase imul includes +indexOf Infinity Int16Array Int32Array @@ -128,12 +158,15 @@ isNaN isPrototypeOf isSafeInteger isSealed +isWellFormed iterator keyFor keys +lastIndexOf length LN10 LN2 +localeCompare log log10 LOG10E @@ -152,16 +185,20 @@ message min MIN_SAFE_INTEGER MIN_VALUE +multiline name NaN NEGATIVE_INFINITY next +normalize now null number Number object Object +padEnd +padStart parse parseFloat parseInt @@ -175,9 +212,13 @@ prototype Proxy random RangeError +raw ReferenceError RegExp +RegExp String Iterator +repeat replace +replaceAll round seal search @@ -202,26 +243,35 @@ SharedArrayBuffer sign sin sinh +slice +source species split sqrt SQRT1_2 SQRT2 +startsWith +stricky string String +String Iterator symbol Symbol SyntaxError tan tanh +test toDateString toExponential toFixed toISOString toJSON toLocaleDateString +toLocaleLowerCase toLocaleString toLocaleTimeString +toLocaleUpperCase +toLowerCase toPrecision toPrimitive toReversed @@ -230,7 +280,12 @@ toSpliced toString toStringTag toTimeString +toUpperCase toUTCString +toWellFormed +trim +trimEnd +trimStart true trunc TypeError @@ -239,6 +294,8 @@ Uint32Array Uint8Array Uint8ClampedArray undefined +unicode +unicodeSets unscopables URIError utc diff --git a/nova_vm/src/ecmascript/builders/builtin_function_builder.rs b/nova_vm/src/ecmascript/builders/builtin_function_builder.rs index bcdc676cd..66bfc5d2f 100644 --- a/nova_vm/src/ecmascript/builders/builtin_function_builder.rs +++ b/nova_vm/src/ecmascript/builders/builtin_function_builder.rs @@ -19,7 +19,7 @@ use super::property_builder::{self, PropertyBuilder}; pub struct NoPrototype; #[derive(Clone, Copy)] -pub struct CreatorPrototype(Object); +pub struct CreatorPrototype(Option); #[derive(Default, Clone, Copy)] pub struct NoLength; @@ -162,7 +162,30 @@ impl<'agent, L, N, B, Pr> BuiltinFunctionBuilder<'agent, NoPrototype, L, N, B, P this: self.this, object_index, realm: self.realm, - prototype: CreatorPrototype(prototype), + prototype: CreatorPrototype(Some(prototype)), + length: self.length, + name: self.name, + behaviour: self.behaviour, + properties: self.properties, + } + } + + #[must_use] + pub fn with_null_prototype( + self, + ) -> BuiltinFunctionBuilder<'agent, CreatorPrototype, L, N, B, Pr> { + let object_index = if self.object_index.is_none() { + self.agent.heap.objects.push(None); + Some(ObjectIndex::last(&self.agent.heap.objects)) + } else { + self.object_index + }; + BuiltinFunctionBuilder { + agent: self.agent, + this: self.this, + object_index, + realm: self.realm, + prototype: CreatorPrototype(None), length: self.length, name: self.name, behaviour: self.behaviour, @@ -518,7 +541,7 @@ impl<'agent> assert!(slot.is_none()); *slot = Some(ObjectHeapData { extensible: true, - prototype: Some(prototype.0), + prototype: prototype.0, keys, values, }); diff --git a/nova_vm/src/ecmascript/builtins.rs b/nova_vm/src/ecmascript/builtins.rs index 2adcfbca3..329359f51 100644 --- a/nova_vm/src/ecmascript/builtins.rs +++ b/nova_vm/src/ecmascript/builtins.rs @@ -14,6 +14,8 @@ pub mod error; pub(crate) mod fundamental_objects; pub(crate) mod numbers_and_dates; pub mod ordinary; +pub(crate) mod regexp; +pub(crate) mod text_processing; pub(crate) use arguments::*; pub(crate) use array::abstract_operations::*; 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 220120bd9..e1c8b69f1 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 @@ -204,6 +204,7 @@ impl FunctionPrototype { Some(this_object_index), ) .with_property_capacity(8) + .with_null_prototype() // 10.2.4 AddRestrictedFunctionProperties ( F, realm ) .with_property(|builder| { builder diff --git a/nova_vm/src/ecmascript/builtins/numbers_and_dates/date_objects/date_prototype.rs b/nova_vm/src/ecmascript/builtins/numbers_and_dates/date_objects/date_prototype.rs index b45eb7652..3bea09cc7 100644 --- a/nova_vm/src/ecmascript/builtins/numbers_and_dates/date_objects/date_prototype.rs +++ b/nova_vm/src/ecmascript/builtins/numbers_and_dates/date_objects/date_prototype.rs @@ -577,7 +577,7 @@ impl DatePrototype { let date_constructor = intrinsics.date(); OrdinaryObjectBuilder::new_intrinsic_object(agent, realm, this) - .with_property_capacity(7) + .with_property_capacity(45) .with_constructor_property(date_constructor) .with_builtin_function_property::() .with_builtin_function_property::() diff --git a/nova_vm/src/ecmascript/builtins/regexp.rs b/nova_vm/src/ecmascript/builtins/regexp.rs new file mode 100644 index 000000000..5f3ae1cdd --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/regexp.rs @@ -0,0 +1,7 @@ +use crate::heap::indexes::ObjectIndex; + +#[derive(Debug, Clone, Copy)] +pub struct RegExpHeapData { + pub(crate) object_index: ObjectIndex, + // _regex: RegExp, +} diff --git a/nova_vm/src/ecmascript/builtins/text_processing.rs b/nova_vm/src/ecmascript/builtins/text_processing.rs new file mode 100644 index 000000000..e7d038b15 --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/text_processing.rs @@ -0,0 +1,2 @@ +pub(crate) mod regexp_objects; +pub(crate) mod string_objects; diff --git a/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects.rs b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects.rs new file mode 100644 index 000000000..8cf0a0c16 --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects.rs @@ -0,0 +1,3 @@ +pub(crate) mod regexp_constructor; +pub(crate) mod regexp_prototype; +pub(crate) mod regexp_string_iterator_prototype; diff --git a/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_constructor.rs b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_constructor.rs new file mode 100644 index 000000000..95721eb72 --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_constructor.rs @@ -0,0 +1,75 @@ +use crate::ecmascript::builders::builtin_function_builder::BuiltinFunctionBuilder; +use crate::ecmascript::builtins::ArgumentsList; +use crate::ecmascript::builtins::Behaviour; +use crate::ecmascript::builtins::Builtin; +use crate::ecmascript::execution::Agent; +use crate::ecmascript::execution::JsResult; +use crate::ecmascript::execution::RealmIdentifier; +use crate::ecmascript::types::IntoFunction; +use crate::ecmascript::types::IntoObject; +use crate::ecmascript::types::Object; +use crate::ecmascript::types::String; +use crate::ecmascript::types::Value; +use crate::ecmascript::types::BUILTIN_STRING_MEMORY; +use crate::heap::WellKnownSymbolIndexes; + +pub struct RegExpConstructor; + +impl Builtin for RegExpConstructor { + const BEHAVIOUR: Behaviour = Behaviour::Constructor(Self::behaviour); + const LENGTH: u8 = 1; + const NAME: String = BUILTIN_STRING_MEMORY.RegExp; +} + +struct RegExpSpecies; +impl Builtin for RegExpSpecies { + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpConstructor::species); + const LENGTH: u8 = 0; + const NAME: String = BUILTIN_STRING_MEMORY.get__Symbol_species_; +} +impl RegExpConstructor { + fn behaviour( + _agent: &mut Agent, + _this_value: Value, + _arguments: ArgumentsList, + _new_target: Option, + ) -> JsResult { + todo!(); + } + + fn species( + _agent: &mut Agent, + _this_value: Value, + _arguments: ArgumentsList, + ) -> JsResult { + todo!(); + } + + pub(crate) fn create_intrinsic(agent: &mut Agent, realm: RealmIdentifier) { + let intrinsics = agent.get_realm(realm).intrinsics(); + let regexp_prototype = intrinsics.reg_exp_prototype(); + let this = intrinsics.reg_exp(); + let this_object_index = intrinsics.reg_exp_base_object(); + + BuiltinFunctionBuilder::new_intrinsic_constructor::( + agent, + realm, + this, + Some(this_object_index), + ) + .with_property_capacity(2) + .with_prototype_property(regexp_prototype.into_object()) + .with_property(|builder| { + builder + .with_key(WellKnownSymbolIndexes::Species.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .build(); + } +} diff --git a/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_prototype.rs b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_prototype.rs new file mode 100644 index 000000000..6bab66145 --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_prototype.rs @@ -0,0 +1,388 @@ +use crate::{ + ecmascript::{ + builders::{ + builtin_function_builder::BuiltinFunctionBuilder, + ordinary_object_builder::OrdinaryObjectBuilder, + }, + builtins::{ArgumentsList, Behaviour, Builtin}, + execution::{Agent, JsResult, RealmIdentifier}, + types::{IntoFunction, IntoValue, String, Value, BUILTIN_STRING_MEMORY}, + }, + heap::WellKnownSymbolIndexes, +}; + +pub(crate) struct RegExpPrototype; + +struct RegExpPrototypeExec; +impl Builtin for RegExpPrototypeExec { + const NAME: String = BUILTIN_STRING_MEMORY.exec; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::exec); +} +struct RegExpPrototypeDotAll; +impl Builtin for RegExpPrototypeDotAll { + const NAME: String = BUILTIN_STRING_MEMORY.get_dotAll; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_dot_all); +} +struct RegExpPrototypeFlags; +impl Builtin for RegExpPrototypeFlags { + const NAME: String = BUILTIN_STRING_MEMORY.get_flags; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_flags); +} +struct RegExpPrototypeGlobal; +impl Builtin for RegExpPrototypeGlobal { + const NAME: String = BUILTIN_STRING_MEMORY.get_global; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_global); +} +struct RegExpPrototypeHasIndices; +impl Builtin for RegExpPrototypeHasIndices { + const NAME: String = BUILTIN_STRING_MEMORY.get_hasIndices; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_has_indices); +} +struct RegExpPrototypeIgnoreCase; +impl Builtin for RegExpPrototypeIgnoreCase { + const NAME: String = BUILTIN_STRING_MEMORY.get_ignoreCase; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_ignore_case); +} +struct RegExpPrototypeMatch; +impl Builtin for RegExpPrototypeMatch { + const NAME: String = BUILTIN_STRING_MEMORY._Symbol_match_; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::r#match); +} +struct RegExpPrototypeMatchAll; +impl Builtin for RegExpPrototypeMatchAll { + const NAME: String = BUILTIN_STRING_MEMORY._Symbol_matchAll_; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::match_all); +} +struct RegExpPrototypeMultiline; +impl Builtin for RegExpPrototypeMultiline { + const NAME: String = BUILTIN_STRING_MEMORY.get_multiline; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_multiline); +} +struct RegExpPrototypeReplace; +impl Builtin for RegExpPrototypeReplace { + const NAME: String = BUILTIN_STRING_MEMORY._Symbol_replace_; + const LENGTH: u8 = 2; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::replace); +} +struct RegExpPrototypeSearch; +impl Builtin for RegExpPrototypeSearch { + const NAME: String = BUILTIN_STRING_MEMORY._Symbol_search_; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::search); +} +struct RegExpPrototypeSource; +impl Builtin for RegExpPrototypeSource { + const NAME: String = BUILTIN_STRING_MEMORY.get_source; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_source); +} +struct RegExpPrototypeSplit; +impl Builtin for RegExpPrototypeSplit { + const NAME: String = BUILTIN_STRING_MEMORY._Symbol_split_; + const LENGTH: u8 = 2; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::split); +} +struct RegExpPrototypeStricky; +impl Builtin for RegExpPrototypeStricky { + const NAME: String = BUILTIN_STRING_MEMORY.get_stricky; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_sticky); +} +struct RegExpPrototypeTest; +impl Builtin for RegExpPrototypeTest { + const NAME: String = BUILTIN_STRING_MEMORY.test; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::test); +} +struct RegExpPrototypeToString; +impl Builtin for RegExpPrototypeToString { + const NAME: String = BUILTIN_STRING_MEMORY.toString; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::to_string); +} +struct RegExpPrototypeUnicode; +impl Builtin for RegExpPrototypeUnicode { + const NAME: String = BUILTIN_STRING_MEMORY.get_unicode; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_unicode); +} +struct RegExpPrototypeUnicodeSets; +impl Builtin for RegExpPrototypeUnicodeSets { + const NAME: String = BUILTIN_STRING_MEMORY.get_unicodeSets; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(RegExpPrototype::get_unicode_sets); +} + +impl RegExpPrototype { + fn exec(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_dot_all(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_flags(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_global(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_has_indices( + _agent: &mut Agent, + _this_value: Value, + _: ArgumentsList, + ) -> JsResult { + todo!() + } + + fn get_ignore_case( + _agent: &mut Agent, + _this_value: Value, + _: ArgumentsList, + ) -> JsResult { + todo!() + } + + fn r#match(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn match_all(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_multiline(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn replace(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn search(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_source(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn split(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_sticky(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn test(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn to_string(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_unicode(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_unicode_sets( + _agent: &mut Agent, + _this_value: Value, + _: ArgumentsList, + ) -> JsResult { + todo!() + } + + pub(crate) fn create_intrinsic(agent: &mut Agent, realm: RealmIdentifier) { + let intrinsics = agent.get_realm(realm).intrinsics(); + let this = intrinsics.reg_exp_prototype(); + let reg_exp_constructor = intrinsics.reg_exp(); + + OrdinaryObjectBuilder::new_intrinsic_object(agent, realm, this) + .with_property_capacity(19) + .with_constructor_property(reg_exp_constructor) + .with_builtin_function_property::() + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.dotAll.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.flags.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.global.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.hasIndices.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.ignoreCase.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(WellKnownSymbolIndexes::Match.into()) + .with_value_creator_readonly(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_value() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(WellKnownSymbolIndexes::MatchAll.into()) + .with_value_creator_readonly(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_value() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.multiline.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(WellKnownSymbolIndexes::Replace.into()) + .with_value_creator_readonly(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_value() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(WellKnownSymbolIndexes::Search.into()) + .with_value_creator_readonly(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_value() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.source.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(WellKnownSymbolIndexes::Split.into()) + .with_value_creator_readonly(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_value() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.stricky.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.unicode.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .with_property(|builder| { + builder + .with_key(BUILTIN_STRING_MEMORY.unicodeSets.into()) + .with_getter(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_function() + }) + .with_enumerable(false) + .build() + }) + .build(); + } +} diff --git a/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_string_iterator_prototype.rs b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_string_iterator_prototype.rs new file mode 100644 index 000000000..e976f7954 --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/text_processing/regexp_objects/regexp_string_iterator_prototype.rs @@ -0,0 +1,44 @@ +use crate::{ + ecmascript::{ + builders::ordinary_object_builder::OrdinaryObjectBuilder, + builtins::{ArgumentsList, Builtin}, + execution::{Agent, JsResult, RealmIdentifier}, + types::{String, Value, BUILTIN_STRING_MEMORY}, + }, + heap::WellKnownSymbolIndexes, +}; + +pub(crate) struct RegExpStringIteratorPrototype; + +struct RegExpStringIteratorPrototypeNext; +impl Builtin for RegExpStringIteratorPrototypeNext { + const NAME: String = BUILTIN_STRING_MEMORY.next; + + const LENGTH: u8 = 0; + + const BEHAVIOUR: crate::ecmascript::builtins::Behaviour = + crate::ecmascript::builtins::Behaviour::Regular(RegExpStringIteratorPrototype::next); +} + +impl RegExpStringIteratorPrototype { + fn next(_agent: &mut Agent, _this_value: Value, _arguments: ArgumentsList) -> JsResult { + todo!(); + } + + pub(crate) fn create_intrinsic(agent: &mut Agent, realm: RealmIdentifier) { + let intrinsics = agent.get_realm(realm).intrinsics(); + let this = intrinsics.reg_exp_string_iterator_prototype(); + + OrdinaryObjectBuilder::new_intrinsic_object(agent, realm, this) + .with_property_capacity(2) + .with_builtin_function_property::() + .with_property(|builder| { + builder + .with_key(WellKnownSymbolIndexes::ToStringTag.into()) + .with_value_readonly(BUILTIN_STRING_MEMORY.RegExp_String_Iterator.into_value()) + .with_enumerable(false) + .build() + }) + .build(); + } +} diff --git a/nova_vm/src/ecmascript/builtins/text_processing/string_objects.rs b/nova_vm/src/ecmascript/builtins/text_processing/string_objects.rs new file mode 100644 index 000000000..c0f680ce3 --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/text_processing/string_objects.rs @@ -0,0 +1,3 @@ +pub(crate) mod string_constructor; +pub(crate) mod string_iterator_objects; +pub(crate) mod string_prototype; diff --git a/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_constructor.rs b/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_constructor.rs new file mode 100644 index 000000000..e1f0cbf5b --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_constructor.rs @@ -0,0 +1,117 @@ +use crate::ecmascript::abstract_operations::type_conversion::to_string; +use crate::ecmascript::builders::builtin_function_builder::BuiltinFunctionBuilder; +use crate::ecmascript::builtins::ordinary::get_prototype_from_constructor; +use crate::ecmascript::builtins::ArgumentsList; +use crate::ecmascript::builtins::Behaviour; +use crate::ecmascript::builtins::Builtin; +use crate::ecmascript::execution::Agent; +use crate::ecmascript::execution::JsResult; +use crate::ecmascript::execution::ProtoIntrinsics; +use crate::ecmascript::execution::RealmIdentifier; +use crate::ecmascript::types::Function; +use crate::ecmascript::types::IntoObject; +use crate::ecmascript::types::Object; +use crate::ecmascript::types::String; +use crate::ecmascript::types::Value; +use crate::ecmascript::types::BUILTIN_STRING_MEMORY; + +pub struct StringConstructor; + +impl Builtin for StringConstructor { + const BEHAVIOUR: Behaviour = Behaviour::Constructor(Self::behaviour); + const LENGTH: u8 = 1; + const NAME: String = BUILTIN_STRING_MEMORY.String; +} + +struct StringFromCharCode; +impl Builtin for StringFromCharCode { + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringConstructor::from_char_code); + const LENGTH: u8 = 0; + const NAME: String = BUILTIN_STRING_MEMORY.fromCharCode; +} +struct StringFromCodePoint; +impl Builtin for StringFromCodePoint { + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringConstructor::from_code_point); + const LENGTH: u8 = 1; + const NAME: String = BUILTIN_STRING_MEMORY.fromCodePoint; +} +struct StringRaw; +impl Builtin for StringRaw { + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringConstructor::raw); + const LENGTH: u8 = 1; + const NAME: String = BUILTIN_STRING_MEMORY.raw; +} +impl StringConstructor { + fn behaviour( + agent: &mut Agent, + _this_value: Value, + arguments: ArgumentsList, + new_target: Option, + ) -> JsResult { + let value = arguments.get(0); + // 1. If value is not present, then + let s = if value.is_undefined() { + // a. Let s be the empty String. + String::EMPTY_STRING + } else { + // 2. Else, + // a. If NewTarget is undefined and value is a Symbol, return SymbolDescriptiveString(value). + if new_target.is_none() && value.is_symbol() { + todo!("return SymbolDescriptiveString(value);"); + } + // b. Let s be ? ToString(value). + to_string(agent, value)? + }; + // 3. If NewTarget is undefined, return s. + let Some(new_target) = new_target else { + return Ok(s.into_value()); + }; + // 4. Return StringCreate(s, ? GetPrototypeFromConstructor(NewTarget, "%String.prototype%")). + let _prototype = get_prototype_from_constructor( + agent, + Function::try_from(new_target).unwrap(), + ProtoIntrinsics::String, + )?; + todo!("StringCreate(s, ? GetPrototypeFromConstructor(NewTarget, \"%String.prototype%\"))"); + } + + fn from_char_code( + _agent: &mut Agent, + _this_value: Value, + _arguments: ArgumentsList, + ) -> JsResult { + todo!(); + } + + fn from_code_point( + _agent: &mut Agent, + _this_value: Value, + _arguments: ArgumentsList, + ) -> JsResult { + todo!(); + } + + fn raw(_agent: &mut Agent, _this_value: Value, _arguments: ArgumentsList) -> JsResult { + todo!(); + } + + pub(crate) fn create_intrinsic(agent: &mut Agent, realm: RealmIdentifier) { + let intrinsics = agent.get_realm(realm).intrinsics(); + let string_prototype = intrinsics.string_prototype(); + let this = intrinsics.string(); + let this_object_index = intrinsics.string_base_object(); + + BuiltinFunctionBuilder::new_intrinsic_constructor::( + agent, + realm, + this, + Some(this_object_index), + ) + .with_property_capacity(4) + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_prototype_property(string_prototype.into_object()) + .with_builtin_function_property::() + .build(); + } +} diff --git a/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_iterator_objects.rs b/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_iterator_objects.rs new file mode 100644 index 000000000..eb04b2aad --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_iterator_objects.rs @@ -0,0 +1,44 @@ +use crate::{ + ecmascript::{ + builders::ordinary_object_builder::OrdinaryObjectBuilder, + builtins::{ArgumentsList, Builtin}, + execution::{Agent, JsResult, RealmIdentifier}, + types::{String, Value, BUILTIN_STRING_MEMORY}, + }, + heap::WellKnownSymbolIndexes, +}; + +pub(crate) struct StringIteratorPrototype; + +struct StringIteratorPrototypeNext; +impl Builtin for StringIteratorPrototypeNext { + const NAME: String = BUILTIN_STRING_MEMORY.next; + + const LENGTH: u8 = 0; + + const BEHAVIOUR: crate::ecmascript::builtins::Behaviour = + crate::ecmascript::builtins::Behaviour::Regular(StringIteratorPrototype::next); +} + +impl StringIteratorPrototype { + fn next(_agent: &mut Agent, _this_value: Value, _arguments: ArgumentsList) -> JsResult { + todo!(); + } + + pub(crate) fn create_intrinsic(agent: &mut Agent, realm: RealmIdentifier) { + let intrinsics = agent.get_realm(realm).intrinsics(); + let this = intrinsics.string_iterator_prototype(); + + OrdinaryObjectBuilder::new_intrinsic_object(agent, realm, this) + .with_property_capacity(2) + .with_builtin_function_property::() + .with_property(|builder| { + builder + .with_key(WellKnownSymbolIndexes::ToStringTag.into()) + .with_value_readonly(BUILTIN_STRING_MEMORY.String_Iterator.into_value()) + .with_enumerable(false) + .build() + }) + .build(); + } +} diff --git a/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_prototype.rs b/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_prototype.rs new file mode 100644 index 000000000..8c44372a7 --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/text_processing/string_objects/string_prototype.rs @@ -0,0 +1,436 @@ +use crate::{ + ecmascript::{ + builders::{ + builtin_function_builder::BuiltinFunctionBuilder, + ordinary_object_builder::OrdinaryObjectBuilder, + }, + builtins::{ArgumentsList, Behaviour, Builtin}, + execution::{Agent, JsResult, RealmIdentifier}, + types::{IntoValue, String, Value, BUILTIN_STRING_MEMORY}, + }, + heap::WellKnownSymbolIndexes, +}; + +pub(crate) struct StringPrototype; + +struct StringPrototypeGetAt; +impl Builtin for StringPrototypeGetAt { + const NAME: String = BUILTIN_STRING_MEMORY.at; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::at); +} +struct StringPrototypeCharAt; +impl Builtin for StringPrototypeCharAt { + const NAME: String = BUILTIN_STRING_MEMORY.charAt; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::char_at); +} +struct StringPrototypeCharCodeAt; +impl Builtin for StringPrototypeCharCodeAt { + const NAME: String = BUILTIN_STRING_MEMORY.charCodeAt; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::char_code_at); +} +struct StringPrototypeCodePointAt; +impl Builtin for StringPrototypeCodePointAt { + const NAME: String = BUILTIN_STRING_MEMORY.codePointAt; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::code_point_at); +} +struct StringPrototypeConcat; +impl Builtin for StringPrototypeConcat { + const NAME: String = BUILTIN_STRING_MEMORY.concat; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::concat); +} +struct StringPrototypeEndsWith; +impl Builtin for StringPrototypeEndsWith { + const NAME: String = BUILTIN_STRING_MEMORY.endsWith; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::ends_with); +} +struct StringPrototypeIncludes; +impl Builtin for StringPrototypeIncludes { + const NAME: String = BUILTIN_STRING_MEMORY.includes; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::includes); +} +struct StringPrototypeIndexOf; +impl Builtin for StringPrototypeIndexOf { + const NAME: String = BUILTIN_STRING_MEMORY.indexOf; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::index_of); +} +struct StringPrototypeIsWellFormed; +impl Builtin for StringPrototypeIsWellFormed { + const NAME: String = BUILTIN_STRING_MEMORY.isWellFormed; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::is_well_formed); +} +struct StringPrototypeGetTimezoneOffset; +impl Builtin for StringPrototypeGetTimezoneOffset { + const NAME: String = BUILTIN_STRING_MEMORY.getTimezoneOffset; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::get_timezone_offset); +} +struct StringPrototypeLastIndexOf; +impl Builtin for StringPrototypeLastIndexOf { + const NAME: String = BUILTIN_STRING_MEMORY.lastIndexOf; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::last_index_of); +} +struct StringPrototypeLocaleCompare; +impl Builtin for StringPrototypeLocaleCompare { + const NAME: String = BUILTIN_STRING_MEMORY.localeCompare; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::locale_compare); +} +struct StringPrototypeMatch; +impl Builtin for StringPrototypeMatch { + const NAME: String = BUILTIN_STRING_MEMORY.r#match; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::r#match); +} +struct StringPrototypeMatchAll; +impl Builtin for StringPrototypeMatchAll { + const NAME: String = BUILTIN_STRING_MEMORY.matchAll; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::match_all); +} +struct StringPrototypeNormalize; +impl Builtin for StringPrototypeNormalize { + const NAME: String = BUILTIN_STRING_MEMORY.normalize; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::normalize); +} +struct StringPrototypePadEnd; +impl Builtin for StringPrototypePadEnd { + const NAME: String = BUILTIN_STRING_MEMORY.padEnd; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::pad_end); +} +struct StringPrototypePadStart; +impl Builtin for StringPrototypePadStart { + const NAME: String = BUILTIN_STRING_MEMORY.padStart; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::pad_start); +} +struct StringPrototypeRepeat; +impl Builtin for StringPrototypeRepeat { + const NAME: String = BUILTIN_STRING_MEMORY.repeat; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::repeat); +} +struct StringPrototypeReplace; +impl Builtin for StringPrototypeReplace { + const NAME: String = BUILTIN_STRING_MEMORY.replace; + const LENGTH: u8 = 2; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::replace); +} +struct StringPrototypeReplaceAll; +impl Builtin for StringPrototypeReplaceAll { + const NAME: String = BUILTIN_STRING_MEMORY.replaceAll; + const LENGTH: u8 = 3; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::replace_all); +} +struct StringPrototypeSearch; +impl Builtin for StringPrototypeSearch { + const NAME: String = BUILTIN_STRING_MEMORY.search; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::search); +} +struct StringPrototypeSlice; +impl Builtin for StringPrototypeSlice { + const NAME: String = BUILTIN_STRING_MEMORY.slice; + const LENGTH: u8 = 2; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::slice); +} +struct StringPrototypeSplit; +impl Builtin for StringPrototypeSplit { + const NAME: String = BUILTIN_STRING_MEMORY.split; + const LENGTH: u8 = 2; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::split); +} +struct StringPrototypeStartsWith; +impl Builtin for StringPrototypeStartsWith { + const NAME: String = BUILTIN_STRING_MEMORY.startsWith; + const LENGTH: u8 = 1; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::starts_with); +} +struct StringPrototypeToLocaleLowerCase; +impl Builtin for StringPrototypeToLocaleLowerCase { + const NAME: String = BUILTIN_STRING_MEMORY.toLocaleLowerCase; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::to_locale_lower_case); +} +struct StringPrototypeToLocaleUpperCase; +impl Builtin for StringPrototypeToLocaleUpperCase { + const NAME: String = BUILTIN_STRING_MEMORY.toLocaleUpperCase; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::to_locale_upper_case); +} +struct StringPrototypeToLowerCase; +impl Builtin for StringPrototypeToLowerCase { + const NAME: String = BUILTIN_STRING_MEMORY.toLowerCase; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::to_lower_case); +} +struct StringPrototypeToString; +impl Builtin for StringPrototypeToString { + const NAME: String = BUILTIN_STRING_MEMORY.toString; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::to_string); +} +struct StringPrototypeToUpperCase; +impl Builtin for StringPrototypeToUpperCase { + const NAME: String = BUILTIN_STRING_MEMORY.toUpperCase; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::to_upper_case); +} +struct StringPrototypeToWellFormed; +impl Builtin for StringPrototypeToWellFormed { + const NAME: String = BUILTIN_STRING_MEMORY.toWellFormed; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::to_well_formed); +} +struct StringPrototypeTrim; +impl Builtin for StringPrototypeTrim { + const NAME: String = BUILTIN_STRING_MEMORY.trim; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::trim); +} +struct StringPrototypeTrimEnd; +impl Builtin for StringPrototypeTrimEnd { + const NAME: String = BUILTIN_STRING_MEMORY.trimEnd; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::trim_end); +} +struct StringPrototypeTrimStart; +impl Builtin for StringPrototypeTrimStart { + const NAME: String = BUILTIN_STRING_MEMORY.trimStart; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::trim_start); +} +struct StringPrototypeValueOf; +impl Builtin for StringPrototypeValueOf { + const NAME: String = BUILTIN_STRING_MEMORY.valueOf; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::value_of); +} +struct StringPrototypeIterator; +impl Builtin for StringPrototypeIterator { + const NAME: String = BUILTIN_STRING_MEMORY._Symbol_iterator_; + const LENGTH: u8 = 0; + const BEHAVIOUR: Behaviour = Behaviour::Regular(StringPrototype::iterator); +} + +impl StringPrototype { + fn at(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn char_at(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn char_code_at(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn code_point_at(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn concat(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn ends_with(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn includes(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn index_of(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn is_well_formed(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn get_timezone_offset( + _agent: &mut Agent, + _this_value: Value, + _: ArgumentsList, + ) -> JsResult { + todo!() + } + + fn last_index_of(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn locale_compare(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn r#match(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn match_all(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn normalize(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn pad_end(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn pad_start(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn repeat(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn replace(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn replace_all(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn search(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn slice(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn split(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn starts_with(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn to_locale_lower_case( + _agent: &mut Agent, + _this_value: Value, + _: ArgumentsList, + ) -> JsResult { + todo!() + } + + fn to_locale_upper_case( + _agent: &mut Agent, + _this_value: Value, + _: ArgumentsList, + ) -> JsResult { + todo!() + } + + fn to_lower_case(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn to_string(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn to_upper_case(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn to_well_formed(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn trim(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn trim_end(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn trim_start(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + fn value_of(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!(); + } + + fn iterator(_agent: &mut Agent, _this_value: Value, _: ArgumentsList) -> JsResult { + todo!() + } + + pub(crate) fn create_intrinsic(agent: &mut Agent, realm: RealmIdentifier) { + let intrinsics = agent.get_realm(realm).intrinsics(); + let this = intrinsics.string_prototype(); + let string_constructor = intrinsics.string(); + + OrdinaryObjectBuilder::new_intrinsic_object(agent, realm, this) + .with_property_capacity(36) + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_constructor_property(string_constructor) + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_builtin_function_property::() + .with_property(|builder| { + builder + .with_key(WellKnownSymbolIndexes::Iterator.into()) + .with_value_creator_readonly(|agent| { + BuiltinFunctionBuilder::new::(agent, realm) + .build() + .into_value() + }) + .with_enumerable(false) + .with_configurable(true) + .build() + }) + .build(); + } +} diff --git a/nova_vm/src/ecmascript/execution/realm/intrinsics.rs b/nova_vm/src/ecmascript/execution/realm/intrinsics.rs index eb270f944..a8a16f0af 100644 --- a/nova_vm/src/ecmascript/execution/realm/intrinsics.rs +++ b/nova_vm/src/ecmascript/execution/realm/intrinsics.rs @@ -1,6 +1,19 @@ use crate::{ ecmascript::{ - builtins::BuiltinFunction, + builtins::{ + text_processing::{ + regexp_objects::{ + regexp_constructor::RegExpConstructor, regexp_prototype::RegExpPrototype, + regexp_string_iterator_prototype::RegExpStringIteratorPrototype, + }, + string_objects::{ + string_constructor::StringConstructor, + string_iterator_objects::StringIteratorPrototype, + string_prototype::StringPrototype, + }, + }, + BuiltinFunction, + }, execution::Agent, fundamental_objects::{ boolean_objects::{ @@ -113,6 +126,12 @@ impl Intrinsics { MathObject::create_intrinsic(agent, realm); DatePrototype::create_intrinsic(agent, realm); DateConstructor::create_intrinsic(agent, realm); + StringPrototype::create_intrinsic(agent, realm); + StringConstructor::create_intrinsic(agent, realm); + StringIteratorPrototype::create_intrinsic(agent, realm); + RegExpPrototype::create_intrinsic(agent, realm); + RegExpConstructor::create_intrinsic(agent, realm); + RegExpStringIteratorPrototype::create_intrinsic(agent, realm); } pub(crate) fn get_intrinsic_default_proto( diff --git a/nova_vm/src/ecmascript/types/language/object.rs b/nova_vm/src/ecmascript/types/language/object.rs index 23c90d568..459006ba7 100644 --- a/nova_vm/src/ecmascript/types/language/object.rs +++ b/nova_vm/src/ecmascript/types/language/object.rs @@ -16,7 +16,10 @@ use super::{ }; use crate::{ ecmascript::{ - builtins::{date::Date, error::Error, ArgumentsList, Array, ArrayBuffer}, + builtins::{ + date::Date, error::Error, ArgumentsList, Array, ArrayBuffer, BuiltinFunction, + ECMAScriptFunction, + }, execution::{Agent, JsResult}, types::PropertyDescriptor, }, @@ -400,9 +403,11 @@ impl InternalMethods for Object { Object::Date(idx) => Date::from(idx).get(agent, property_key, receiver), Object::Error(idx) => Error::from(idx).get(agent, property_key, receiver), Object::BoundFunction(idx) => Function::from(idx).get(agent, property_key, receiver), - Object::BuiltinFunction(idx) => Function::from(idx).get(agent, property_key, receiver), + Object::BuiltinFunction(idx) => { + BuiltinFunction::from(idx).get(agent, property_key, receiver) + } Object::ECMAScriptFunction(idx) => { - Function::from(idx).get(agent, property_key, receiver) + ECMAScriptFunction::from(idx).get(agent, property_key, receiver) } } } 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 77547427b..47f7bf195 100644 --- a/nova_vm/src/ecmascript/types/language/object/property_key.rs +++ b/nova_vm/src/ecmascript/types/language/object/property_key.rs @@ -6,7 +6,7 @@ use crate::{ INTEGER_DISCRIMINANT, SMALL_STRING_DISCRIMINANT, STRING_DISCRIMINANT, SYMBOL_DISCRIMINANT, }, - String, Value, + String, Symbol, Value, }, }, heap::{ @@ -102,6 +102,12 @@ impl From for PropertyKey { } } +impl From for PropertyKey { + fn from(value: Symbol) -> Self { + PropertyKey::Symbol(value.0) + } +} + impl From for PropertyKey { fn from(value: String) -> Self { match value { diff --git a/nova_vm/src/ecmascript/types/language/symbol.rs b/nova_vm/src/ecmascript/types/language/symbol.rs index d8baa498b..709bdede4 100644 --- a/nova_vm/src/ecmascript/types/language/symbol.rs +++ b/nova_vm/src/ecmascript/types/language/symbol.rs @@ -21,6 +21,12 @@ impl From for Value { } } +impl From for Symbol { + fn from(value: SymbolIndex) -> Self { + Symbol(value) + } +} + impl TryFrom for Symbol { type Error = (); diff --git a/nova_vm/src/ecmascript/types/spec/reference.rs b/nova_vm/src/ecmascript/types/spec/reference.rs index a5a9a1fdf..896b1a3d8 100644 --- a/nova_vm/src/ecmascript/types/spec/reference.rs +++ b/nova_vm/src/ecmascript/types/spec/reference.rs @@ -105,7 +105,7 @@ pub(crate) fn get_value(agent: &mut Agent, reference: &Reference) -> JsResult PropertyKey::from_str(agent, atom.as_str()), - ReferencedName::Symbol(_) => todo!(), + ReferencedName::Symbol(symbol) => PropertyKey::from(*symbol), ReferencedName::PrivateName => { // b. If IsPrivateReference(V) is true, then // i. Return ? PrivateGet(baseObj, V.[[ReferencedName]]). @@ -162,12 +162,7 @@ pub(crate) fn get_value(agent: &mut Agent, reference: &Reference) -> JsResult atom, - ReferencedName::Symbol(_) => todo!(), - ReferencedName::PrivateName => { - // b. If IsPrivateReference(V) is true, then - // i. Return ? PrivateGet(baseObj, V.[[ReferencedName]]). - todo!() - } + _ => unreachable!(), }; Ok(env.get_binding_value(agent, referenced_name, reference.strict)?) } diff --git a/nova_vm/src/engine/bytecode/vm.rs b/nova_vm/src/engine/bytecode/vm.rs index 252c3008e..1c70035b0 100644 --- a/nova_vm/src/engine/bytecode/vm.rs +++ b/nova_vm/src/engine/bytecode/vm.rs @@ -229,12 +229,7 @@ impl Vm { Instruction::Typeof => { // 2. If val is a Reference Record, then let val = if let Some(reference) = vm.reference.take() { - match reference.base { - Base::Value(value) => value, - Base::Environment(_) => get_value(agent, &reference)?, - // a. If IsUnresolvableReference(val) is true, return "undefined". - Base::Unresolvable => Value::Undefined, - } + get_value(agent, &reference)? } else { vm.result.unwrap() }; @@ -337,7 +332,8 @@ impl Vm { let s = agent.heap.get(s); ReferencedName::String(Atom::from(s.as_str().to_string())) } - _ => todo!("Implement symbol and integer property keys"), + PropertyKey::Symbol(s) => ReferencedName::Symbol(s.into()), + _ => todo!("Index properties in ReferencedName"), }, strict, this_value: None, diff --git a/nova_vm/src/heap.rs b/nova_vm/src/heap.rs index eb0a6bfd5..1209eb52a 100644 --- a/nova_vm/src/heap.rs +++ b/nova_vm/src/heap.rs @@ -3,7 +3,7 @@ mod heap_bits; mod heap_constants; mod heap_gc; pub mod indexes; -mod object; +mod object_entry; mod regexp; pub(crate) use self::heap_constants::{ @@ -11,7 +11,7 @@ pub(crate) use self::heap_constants::{ IntrinsicFunctionIndexes, IntrinsicObjectIndexes, WellKnownSymbolIndexes, }; use self::indexes::{DateIndex, ErrorIndex}; -pub(crate) use self::object::{ObjectEntry, ObjectEntryPropertyDescriptor}; +pub(crate) use self::object_entry::{ObjectEntry, ObjectEntryPropertyDescriptor}; use self::{ element_array::{ ElementArray2Pow10, ElementArray2Pow12, ElementArray2Pow16, ElementArray2Pow24, @@ -21,12 +21,12 @@ use self::{ BaseIndex, BigIntIndex, BoundFunctionIndex, BuiltinFunctionIndex, ECMAScriptFunctionIndex, NumberIndex, ObjectIndex, StringIndex, }, - regexp::RegExpHeapData, }; use crate::ecmascript::{ builtins::{ date::{data::DateHeapData, Date}, error::{Error, ErrorHeapData}, + regexp::RegExpHeapData, }, types::BUILTIN_STRINGS_LIST, }; diff --git a/nova_vm/src/heap/element_array.rs b/nova_vm/src/heap/element_array.rs index 4fa359160..6cbe73f41 100644 --- a/nova_vm/src/heap/element_array.rs +++ b/nova_vm/src/heap/element_array.rs @@ -1,6 +1,6 @@ use super::{ indexes::ElementIndex, - object::{ObjectEntry, ObjectEntryPropertyDescriptor}, + object_entry::{ObjectEntry, ObjectEntryPropertyDescriptor}, }; use crate::ecmascript::types::{Function, PropertyKey, Value}; use core::panic; diff --git a/nova_vm/src/heap/heap_bits.rs b/nova_vm/src/heap/heap_bits.rs index d24f0b898..e9becd80b 100644 --- a/nova_vm/src/heap/heap_bits.rs +++ b/nova_vm/src/heap/heap_bits.rs @@ -7,13 +7,12 @@ use super::{ DateIndex, ECMAScriptFunctionIndex, ElementIndex, ErrorIndex, NumberIndex, ObjectIndex, RegExpIndex, StringIndex, SymbolIndex, }, - regexp::RegExpHeapData, ArrayHeapData, Heap, NumberHeapData, ObjectHeapData, StringHeapData, SymbolHeapData, }; use crate::ecmascript::{ builtins::{ - date::data::DateHeapData, error::ErrorHeapData, ArrayBufferHeapData, BuiltinFunction, - SealableElementsVector, + date::data::DateHeapData, error::ErrorHeapData, regexp::RegExpHeapData, + ArrayBufferHeapData, BuiltinFunction, SealableElementsVector, }, execution::{ DeclarativeEnvironment, DeclarativeEnvironmentIndex, EnvironmentIndex, FunctionEnvironment, diff --git a/nova_vm/src/heap/indexes.rs b/nova_vm/src/heap/indexes.rs index 595343728..835e31bfc 100644 --- a/nova_vm/src/heap/indexes.rs +++ b/nova_vm/src/heap/indexes.rs @@ -1,7 +1,7 @@ -use super::regexp::RegExpHeapData; use crate::ecmascript::{ builtins::{ - date::data::DateHeapData, error::ErrorHeapData, ArrayBufferHeapData, ArrayHeapData, + date::data::DateHeapData, error::ErrorHeapData, regexp::RegExpHeapData, + ArrayBufferHeapData, ArrayHeapData, }, execution::Agent, types::{ diff --git a/nova_vm/src/heap/object.rs b/nova_vm/src/heap/object.rs deleted file mode 100644 index efa2fa25d..000000000 --- a/nova_vm/src/heap/object.rs +++ /dev/null @@ -1,260 +0,0 @@ -use super::indexes::ObjectIndex; -use crate::{ - ecmascript::{ - builtins::ArgumentsList, - execution::{Agent, JsResult}, - types::{Function, Object, PropertyDescriptor, PropertyKey, Value}, - }, - heap::Heap, -}; -use std::fmt::Debug; - -#[derive(Debug)] -pub(crate) struct ObjectEntry { - pub key: PropertyKey, - pub value: ObjectEntryPropertyDescriptor, -} - -impl From for ObjectEntryPropertyDescriptor { - fn from(value: PropertyDescriptor) -> Self { - let configurable = value.configurable.unwrap_or(true); - let enumerable = value.enumerable.unwrap_or(true); - if value.get.is_some() && value.set.is_some() { - ObjectEntryPropertyDescriptor::ReadWrite { - get: value.get.unwrap(), - set: value.set.unwrap(), - enumerable, - configurable, - } - } else if value.get.is_some() { - ObjectEntryPropertyDescriptor::ReadOnly { - get: value.get.unwrap(), - enumerable, - configurable, - } - } else if value.set.is_some() { - ObjectEntryPropertyDescriptor::WriteOnly { - set: value.set.unwrap(), - enumerable, - configurable, - } - } else if value.value.is_some() { - ObjectEntryPropertyDescriptor::Data { - value: value.value.unwrap(), - writable: value.writable.unwrap_or(true), - enumerable, - configurable, - } - } else if value.writable == Some(false) { - ObjectEntryPropertyDescriptor::Blocked { - enumerable, - configurable, - } - } else { - todo!() - } - } -} - -#[derive(Debug)] -pub(crate) enum ObjectEntryPropertyDescriptor { - Data { - value: Value, - writable: bool, - enumerable: bool, - configurable: bool, - }, - Blocked { - enumerable: bool, - configurable: bool, - }, - ReadOnly { - get: Function, - enumerable: bool, - configurable: bool, - }, - WriteOnly { - set: Function, - enumerable: bool, - configurable: bool, - }, - ReadWrite { - get: Function, - set: Function, - enumerable: bool, - configurable: bool, - }, -} - -impl ObjectEntryPropertyDescriptor { - #[inline(always)] - pub const fn prototype_slot(idx: ObjectIndex) -> Self { - Self::Data { - value: Value::Object(idx), - writable: false, - enumerable: false, - configurable: false, - } - } - - #[inline(always)] - /// Read-only, unconfigurable, enumerable data descriptor - pub const fn ro(value: Value) -> Self { - Self::Data { - value, - writable: false, - enumerable: true, - configurable: false, - } - } - #[inline(always)] - /// Read-only, unconfigurable, unenumerable data descriptor - pub const fn roh(value: Value) -> Self { - Self::Data { - value, - writable: false, - enumerable: false, - configurable: false, - } - } - - #[inline(always)] - /// Read-only, configurable, enumerable data descriptor - pub const fn rox(value: Value) -> Self { - Self::Data { - value, - writable: false, - enumerable: true, - configurable: true, - } - } - #[inline(always)] - /// Read-only, configurable, unenumerable data descriptor - pub const fn roxh(value: Value) -> Self { - Self::Data { - value, - writable: false, - enumerable: false, - configurable: true, - } - } - - #[inline(always)] - /// Writable, unconfigurable, enumerable data descriptor - pub const fn rw(value: Value) -> Self { - Self::Data { - value, - writable: true, - enumerable: false, - configurable: false, - } - } - #[inline(always)] - /// Writable, unconfigurable, unenumerable data descriptor - pub const fn rwh(value: Value) -> Self { - Self::Data { - value, - writable: true, - enumerable: false, - configurable: false, - } - } - - #[inline(always)] - /// Writable, configurable, enumerable data descriptor - pub const fn rwx(value: Value) -> Self { - Self::Data { - value, - writable: true, - enumerable: false, - configurable: true, - } - } - #[inline(always)] - /// Writable, configurable, unenumerable data descriptor - pub const fn rwxh(value: Value) -> Self { - Self::Data { - value, - writable: true, - enumerable: false, - configurable: true, - } - } -} - -pub fn initialize_object_heap(_heap: &mut Heap) { - // let entries = vec![ - // ObjectEntry::new_prototype_function_entry(heap, "assign", 1, true), - // ObjectEntry::new_prototype_function_entry(heap, "create", 2, false), - // ObjectEntry::new_prototype_function_entry(heap, "defineProperties", 2, false), - // ObjectEntry::new_prototype_function_entry(heap, "defineProperty", 3, false), - // ObjectEntry::new_prototype_function_entry(heap, "entries", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "freeze", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "fromEntries", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "getOwnPropertyDescriptor", 2, false), - // ObjectEntry::new_prototype_function_entry(heap, "getOwnPropertyDescriptors", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "getOwnPropertyNames", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "getOwnPropertySymbols", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "getPrototypeOf", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "hasOwn", 2, false), - // ObjectEntry::new_prototype_function_entry(heap, "is", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "isExtensible", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "isFrozen", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "isSealed", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "keys", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "preventExtensions", 1, false), - // ObjectEntry::new_constructor_prototype_entry( - // heap, - // IntrinsicObjectIndexes::ObjectPrototype.into(), - // ), - // ObjectEntry::new_prototype_function_entry(heap, "seal", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "setPrototypeOf", 2, false), - // ObjectEntry::new_prototype_function_entry(heap, "values", 1, false), - // ]; - // heap.insert_builtin_object( - // IntrinsicObjectIndexes::ObjectConstructor, - // true, - // Some(Object::BuiltinFunction( - // IntrinsicObjectIndexes::FunctionPrototype.into(), - // )), - // entries, - // ); - // heap.builtin_functions - // [get_constructor_index(IntrinsicObjectIndexes::ObjectConstructor).into_index()] = - // Some(BuiltinFunctionHeapData { - // object_index: Some(IntrinsicObjectIndexes::ObjectConstructor.into()), - // length: 1, - // initial_name: None, - // behaviour: Behaviour::Constructor(object_constructor_binding), - // realm: RealmIdentifier::from_index(0), - // }); - // let entries = vec![ - // ObjectEntry::new( - // PropertyKey::from_str(heap, "constructor"), - // ObjectEntryPropertyDescriptor::rwx(Value::BuiltinFunction(get_constructor_index( - // IntrinsicObjectIndexes::ObjectConstructor, - // ))), - // ), - // ObjectEntry::new_prototype_function_entry(heap, "hasOwnProperty", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "isPrototypeOf", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "propertyIsEnumerable", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "toLocaleString", 0, false), - // ObjectEntry::new_prototype_function_entry(heap, "toString", 0, false), - // ObjectEntry::new_prototype_function_entry(heap, "valueOf", 0, false), - // ]; - // heap.insert_builtin_object( - // IntrinsicObjectIndexes::ObjectConstructor, - // true, - // None, - // entries, - // ); -} - -fn object_constructor_binding( - _heap: &mut Agent, - _this: Value, - _args: ArgumentsList, - _target: Option, -) -> JsResult { - Ok(Value::Object(ObjectIndex::from_index(0))) -} diff --git a/nova_vm/src/heap/object_entry.rs b/nova_vm/src/heap/object_entry.rs new file mode 100644 index 000000000..87eabd962 --- /dev/null +++ b/nova_vm/src/heap/object_entry.rs @@ -0,0 +1,78 @@ +use crate::ecmascript::types::{Function, PropertyDescriptor, PropertyKey, Value}; + +#[derive(Debug)] +pub(crate) struct ObjectEntry { + pub key: PropertyKey, + pub value: ObjectEntryPropertyDescriptor, +} + +impl From for ObjectEntryPropertyDescriptor { + fn from(value: PropertyDescriptor) -> Self { + let configurable = value.configurable.unwrap_or(true); + let enumerable = value.enumerable.unwrap_or(true); + if value.get.is_some() && value.set.is_some() { + ObjectEntryPropertyDescriptor::ReadWrite { + get: value.get.unwrap(), + set: value.set.unwrap(), + enumerable, + configurable, + } + } else if value.get.is_some() { + ObjectEntryPropertyDescriptor::ReadOnly { + get: value.get.unwrap(), + enumerable, + configurable, + } + } else if value.set.is_some() { + ObjectEntryPropertyDescriptor::WriteOnly { + set: value.set.unwrap(), + enumerable, + configurable, + } + } else if value.value.is_some() { + ObjectEntryPropertyDescriptor::Data { + value: value.value.unwrap(), + writable: value.writable.unwrap_or(true), + enumerable, + configurable, + } + } else if value.writable == Some(false) { + ObjectEntryPropertyDescriptor::Blocked { + enumerable, + configurable, + } + } else { + todo!() + } + } +} + +#[derive(Debug)] +pub(crate) enum ObjectEntryPropertyDescriptor { + Data { + value: Value, + writable: bool, + enumerable: bool, + configurable: bool, + }, + Blocked { + enumerable: bool, + configurable: bool, + }, + ReadOnly { + get: Function, + enumerable: bool, + configurable: bool, + }, + WriteOnly { + set: Function, + enumerable: bool, + configurable: bool, + }, + ReadWrite { + get: Function, + set: Function, + enumerable: bool, + configurable: bool, + }, +} diff --git a/nova_vm/src/heap/regexp.rs b/nova_vm/src/heap/regexp.rs index 7aebb96ef..8b1378917 100644 --- a/nova_vm/src/heap/regexp.rs +++ b/nova_vm/src/heap/regexp.rs @@ -1,119 +1 @@ -use super::indexes::ObjectIndex; -use crate::{ - ecmascript::{ - builtins::ArgumentsList, - execution::{Agent, JsResult}, - types::{Object, Value}, - }, - heap::Heap, -}; -#[derive(Debug, Clone, Copy)] -pub struct RegExpHeapData { - pub(super) object_index: ObjectIndex, - // pub(super) _regex: RegExp, -} - -pub fn initialize_regexp_heap(_heap: &mut Heap) { - // let species_function_name = Value::from_str(heap, "get [Symbol.species]"); - // let entries = vec![ - // ObjectEntry::new_constructor_prototype_entry( - // heap, - // IntrinsicObjectIndexes::RegExpPrototype.into(), - // ), - // ObjectEntry::new( - // PropertyKey::Symbol(WellKnownSymbolIndexes::Species.into()), - // ObjectEntryPropertyDescriptor::ReadOnly { - // get: Function::BuiltinFunction(heap.create_function( - // species_function_name, - // 0, - // false, - // )), - // enumerable: false, - // configurable: true, - // }, - // ), - // ]; - // heap.insert_builtin_object( - // IntrinsicObjectIndexes::RegExpConstructor, - // true, - // Some(Object::BuiltinFunction( - // IntrinsicObjectIndexes::FunctionPrototype.into(), - // )), - // entries, - // ); - // heap.builtin_functions - // [get_constructor_index(IntrinsicObjectIndexes::RegExpConstructor).into_index()] = - // Some(BuiltinFunctionHeapData { - // object_index: Some(IntrinsicObjectIndexes::RegExpConstructor.into()), - // length: 1, - // initial_name: None, - // behaviour: Behaviour::Constructor(constructor_binding), - // realm: RealmIdentifier::from_index(0), - // }); - // let entries = vec![ - // ObjectEntry::new( - // PropertyKey::from_str(heap, "constructor"), - // ObjectEntryPropertyDescriptor::rwx(Value::BuiltinFunction(get_constructor_index( - // IntrinsicObjectIndexes::RegExpConstructor, - // ))), - // ), - // // TODO: Write out all the getters - // ObjectEntry::new_prototype_function_entry(heap, "exec", 1, false), - // // TODO: These symbol function properties are actually rwxh, this helper generates roxh instead. - // ObjectEntry::new_prototype_symbol_function_entry( - // heap, - // "[Symbol.match]", - // WellKnownSymbolIndexes::Match.into(), - // 1, - // false, - // ), - // ObjectEntry::new_prototype_symbol_function_entry( - // heap, - // "[Symbol.matchAll]", - // WellKnownSymbolIndexes::MatchAll.into(), - // 1, - // false, - // ), - // ObjectEntry::new_prototype_symbol_function_entry( - // heap, - // "[Symbol.replace]", - // WellKnownSymbolIndexes::Replace.into(), - // 2, - // false, - // ), - // ObjectEntry::new_prototype_symbol_function_entry( - // heap, - // "[Symbol.search]", - // WellKnownSymbolIndexes::Search.into(), - // 1, - // false, - // ), - // ObjectEntry::new_prototype_symbol_function_entry( - // heap, - // "[Symbol.split]", - // WellKnownSymbolIndexes::Split.into(), - // 2, - // false, - // ), - // ObjectEntry::new_prototype_function_entry(heap, "test", 1, false), - // ObjectEntry::new_prototype_function_entry(heap, "toString", 0, false), - // ]; - // heap.insert_builtin_object( - // IntrinsicObjectIndexes::RegExpPrototype, - // true, - // Some(Object::Object( - // IntrinsicObjectIndexes::ObjectPrototype.into(), - // )), - // entries, - // ); -} - -fn constructor_binding( - _agent: &mut Agent, - _this: Value, - _args: ArgumentsList, - _target: Option, -) -> JsResult { - todo!() -}