From f4e5ebf30c4551486042364020c6aa75f6dd80e2 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Sun, 29 Sep 2024 19:58:35 +0300 Subject: [PATCH 1/7] feat(ecmascript): Builtin class constructors (start) --- nova_vm/src/ecmascript/builtins.rs | 2 + .../builtins/builtin_constructor.rs | 429 ++++++++++++++++++ .../builtins/ecmascript_function.rs | 4 +- .../function_objects/function_prototype.rs | 2 +- .../environments/function_environment.rs | 4 +- nova_vm/src/ecmascript/types/language.rs | 4 +- .../src/ecmascript/types/language/function.rs | 69 ++- .../types/language/function/data.rs | 23 +- .../src/ecmascript/types/language/object.rs | 62 ++- .../src/ecmascript/types/language/value.rs | 25 +- nova_vm/src/engine/bytecode/vm.rs | 2 +- nova_vm/src/heap.rs | 7 +- nova_vm/src/heap/heap_bits.rs | 11 +- nova_vm/src/heap/heap_gc.rs | 27 +- nova_vm/src/heap/indexes.rs | 6 +- 15 files changed, 608 insertions(+), 69 deletions(-) create mode 100644 nova_vm/src/ecmascript/builtins/builtin_constructor.rs diff --git a/nova_vm/src/ecmascript/builtins.rs b/nova_vm/src/ecmascript/builtins.rs index 75a403e46..d6dd96e38 100644 --- a/nova_vm/src/ecmascript/builtins.rs +++ b/nova_vm/src/ecmascript/builtins.rs @@ -12,6 +12,7 @@ pub(crate) mod arguments; mod array; mod array_buffer; pub mod bound_function; +mod builtin_constructor; mod builtin_function; pub(crate) mod control_abstraction_objects; pub(crate) mod data_view; @@ -49,6 +50,7 @@ pub use array::Array; pub(crate) use array::{ArrayHeapData, SealableElementsVector}; pub use array_buffer::ArrayBuffer; pub(crate) use array_buffer::ArrayBufferHeapData; +pub use builtin_constructor::BuiltinConstructorFunction; pub use builtin_function::{ create_builtin_function, ArgumentsList, Behaviour, Builtin, BuiltinFunction, BuiltinFunctionArgs, BuiltinGetter, ConstructorFn, RegularFn as JsFunction, RegularFn, diff --git a/nova_vm/src/ecmascript/builtins/builtin_constructor.rs b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs new file mode 100644 index 000000000..3045c8855 --- /dev/null +++ b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs @@ -0,0 +1,429 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use std::ops::{Index, IndexMut}; + +use crate::{ + ecmascript::{ + execution::{ + Agent, ExecutionContext, JsResult, ProtoIntrinsics, + }, + types::{ + function_create_backing_object, function_internal_define_own_property, + function_internal_delete, function_internal_get, function_internal_get_own_property, + function_internal_has_property, function_internal_own_property_keys, + function_internal_set, BuiltinConstructorHeapData, Function, + FunctionInternalProperties, InternalMethods, InternalSlots, IntoFunction, IntoObject, + IntoValue, Object, OrdinaryObject, PropertyDescriptor, PropertyKey, String, Value, + }, + }, + heap::{ + indexes::BuiltinConstructorIndex, CompactionLists, CreateHeapData, Heap, HeapMarkAndSweep, WorkQueues, + }, +}; + +use super::ArgumentsList; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct BuiltinConstructorFunction(pub(crate) BuiltinConstructorIndex); + +impl BuiltinConstructorFunction { + pub(crate) const fn _def() -> Self { + Self(BuiltinConstructorIndex::from_u32_index(0)) + } + + pub(crate) const fn get_index(self) -> usize { + self.0.into_index() + } + + pub const fn is_constructor(self) -> bool { + true + } +} + +impl From for BuiltinConstructorFunction { + fn from(value: BuiltinConstructorIndex) -> Self { + Self(value) + } +} + +impl IntoValue for BuiltinConstructorFunction { + fn into_value(self) -> Value { + self.into() + } +} + +impl IntoObject for BuiltinConstructorFunction { + fn into_object(self) -> Object { + self.into() + } +} + +impl IntoFunction for BuiltinConstructorFunction { + fn into_function(self) -> Function { + self.into() + } +} + +impl From for Value { + fn from(value: BuiltinConstructorFunction) -> Self { + Value::BuiltinConstructorFunction(value) + } +} + +impl From for Object { + fn from(value: BuiltinConstructorFunction) -> Self { + Self::BuiltinConstructorFunction(value) + } +} + +impl From for Function { + fn from(value: BuiltinConstructorFunction) -> Self { + Self::BuiltinConstructorFunction(value) + } +} + +impl Index for Agent { + type Output = BuiltinConstructorHeapData; + + fn index(&self, index: BuiltinConstructorFunction) -> &Self::Output { + &self.heap.builtin_constructors[index] + } +} + +impl IndexMut for Agent { + fn index_mut(&mut self, index: BuiltinConstructorFunction) -> &mut Self::Output { + &mut self.heap.builtin_constructors[index] + } +} + +impl Index for Vec> { + type Output = BuiltinConstructorHeapData; + + fn index(&self, index: BuiltinConstructorFunction) -> &Self::Output { + self.get(index.get_index()) + .expect("BuiltinConstructorFunction out of bounds") + .as_ref() + .expect("BuiltinConstructorFunction slot empty") + } +} + +impl IndexMut for Vec> { + fn index_mut(&mut self, index: BuiltinConstructorFunction) -> &mut Self::Output { + self.get_mut(index.get_index()) + .expect("BuiltinConstructorFunction out of bounds") + .as_mut() + .expect("BuiltinConstructorFunction slot empty") + } +} + +impl FunctionInternalProperties for BuiltinConstructorFunction { + fn get_name(self, agent: &Agent) -> String { + agent[self].initial_name.unwrap_or(String::EMPTY_STRING) + } + + fn get_length(self, agent: &Agent) -> u8 { + agent[self].length + } +} + +impl InternalSlots for BuiltinConstructorFunction { + const DEFAULT_PROTOTYPE: ProtoIntrinsics = ProtoIntrinsics::Function; + + #[inline(always)] + fn get_backing_object(self, agent: &Agent) -> Option { + agent[self].object_index + } + + fn set_backing_object(self, agent: &mut Agent, backing_object: OrdinaryObject) { + assert!(agent[self].object_index.replace(backing_object).is_none()); + } + + fn create_backing_object(self, agent: &mut Agent) -> OrdinaryObject { + function_create_backing_object(self, agent) + } +} + +impl InternalMethods for BuiltinConstructorFunction { + fn internal_get_own_property( + self, + agent: &mut Agent, + property_key: PropertyKey, + ) -> JsResult> { + function_internal_get_own_property(self, agent, property_key) + } + + fn internal_define_own_property( + self, + agent: &mut Agent, + property_key: PropertyKey, + property_descriptor: PropertyDescriptor, + ) -> JsResult { + function_internal_define_own_property(self, agent, property_key, property_descriptor) + } + + fn internal_has_property(self, agent: &mut Agent, property_key: PropertyKey) -> JsResult { + function_internal_has_property(self, agent, property_key) + } + + fn internal_get( + self, + agent: &mut Agent, + property_key: PropertyKey, + receiver: Value, + ) -> JsResult { + function_internal_get(self, agent, property_key, receiver) + } + + fn internal_set( + self, + agent: &mut Agent, + property_key: PropertyKey, + value: Value, + receiver: Value, + ) -> JsResult { + function_internal_set(self, agent, property_key, value, receiver) + } + + fn internal_delete(self, agent: &mut Agent, property_key: PropertyKey) -> JsResult { + function_internal_delete(self, agent, property_key) + } + + fn internal_own_property_keys(self, agent: &mut Agent) -> JsResult> { + function_internal_own_property_keys(self, agent) + } + + /// ### [10.3.1 \[\[Call\]\] ( thisArgument, argumentsList )](https://tc39.es/ecma262/#sec-built-in-function-objects-call-thisargument-argumentslist) + /// + /// The [[Call]] internal method of a built-in function object F takes + /// arguments thisArgument (an ECMAScript language value) and argumentsList + /// (a List of ECMAScript language values) and returns either a normal + /// completion containing an ECMAScript language value or a throw + /// completion. + fn internal_call( + self, + agent: &mut Agent, + this_argument: Value, + arguments_list: ArgumentsList, + ) -> JsResult { + // 1. Return ? BuiltinCallOrConstruct(F, thisArgument, argumentsList, undefined). + builtin_call_or_construct(agent, self, Some(this_argument), arguments_list, None) + } + + /// ### [10.3.2 \[\[Construct\]\] ( argumentsList, newTarget )](https://tc39.es/ecma262/#sec-built-in-function-objects-construct-argumentslist-newtarget) + /// + /// The [[Construct]] internal method of a built-in function object F (when + /// the method is present) takes arguments argumentsList (a List of + /// ECMAScript language values) and newTarget (a constructor) and returns + /// either a normal completion containing an Object or a throw completion. + fn internal_construct( + self, + agent: &mut Agent, + arguments_list: ArgumentsList, + new_target: Function, + ) -> JsResult { + // 1. Return ? BuiltinCallOrConstruct(F, uninitialized, argumentsList, newTarget). + builtin_call_or_construct(agent, self, None, arguments_list, Some(new_target)) + .map(|result| result.try_into().unwrap()) + } +} + +/// ### [10.3.3 BuiltinCallOrConstruct ( F, thisArgument, argumentsList, newTarget )](https://tc39.es/ecma262/#sec-builtincallorconstruct) +/// +/// The abstract operation BuiltinCallOrConstruct takes arguments F (a built-in +/// function object), thisArgument (an ECMAScript language value or +/// uninitialized), argumentsList (a List of ECMAScript language values), and +/// newTarget (a constructor or undefined) and returns either a normal +/// completion containing an ECMAScript language value or a throw completion. +pub(crate) fn builtin_call_or_construct( + agent: &mut Agent, + f: BuiltinConstructorFunction, + this_argument: Option, + arguments_list: ArgumentsList, + new_target: Option, +) -> JsResult { + // 1. Let callerContext be the running execution context. + let caller_context = agent.running_execution_context(); + // 2. If callerContext is not already suspended, suspend callerContext. + caller_context.suspend(); + // 5. Let calleeRealm be F.[[Realm]]. + let Agent { + heap: Heap { + builtin_constructors, + .. + }, + execution_context_stack, + .. + } = agent; + let heap_data = &builtin_constructors[f]; + let callee_realm = heap_data.realm; + // 3. Let calleeContext be a new execution context. + let callee_context = ExecutionContext { + // 8. Perform any necessary implementation-defined initialization of calleeContext. + ecmascript_code: None, + // 4. Set the Function of calleeContext to F. + function: Some(f.into()), + // 6. Set the Realm of calleeContext to calleeRealm. + realm: callee_realm, + // 7. Set the ScriptOrModule of calleeContext to null. + script_or_module: None, + }; + // 9. Push calleeContext onto the execution context stack; calleeContext is now the running execution context. + execution_context_stack.push(callee_context); + // 10. Let result be the Completion Record that is the result of evaluating F in a manner that conforms to + // the specification of F. If thisArgument is uninitialized, the this value is uninitialized; otherwise, + // thisArgument provides the this value. argumentsList provides the named parameters. newTarget provides the NewTarget value. + let func = heap_data.behaviour; + let result = func( + agent, + this_argument.unwrap_or(Value::Undefined), + arguments_list, + new_target.map(|target| target.into_object()), + ); + // 11. NOTE: If F is defined in this document, “the specification of F” is the behaviour specified for it via + // algorithm steps or other means. + // 12. Remove calleeContext from the execution context stack and restore callerContext as the running + // execution context. + // Note + // When calleeContext is removed from the execution context stack it must not be destroyed if it has been + // suspended and retained by an accessible Generator for later resumption. + let _callee_context = agent.execution_context_stack.pop(); + // 13. Return ? result. + result +} + +/// ### [10.3.4 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList \[ , realm \[ , prototype \[ , prefix \] \] \] )](https://tc39.es/ecma262/#sec-createbuiltinfunction) +/// +/// The abstract operation CreateBuiltinFunction takes arguments behaviour (an +/// Abstract Closure, a set of algorithm steps, or some other definition of a +/// function's behaviour provided in this specification), length (a +/// non-negative integer or +∞), name (a property key or a Private Name), and +/// additionalInternalSlotsList (a List of names of internal slots) and +/// optional arguments realm (a Realm Record), prototype (an Object or null), +/// and prefix (a String) and returns a function object. +/// additionalInternalSlotsList contains the names of additional internal slots +/// that must be defined as part of the object. This operation creates a +/// built-in function object. +// pub fn create_builtin_function( +// agent: &mut Agent, +// behaviour: Behaviour, +// args: BuiltinFunctionArgs, +// ) -> BuiltinFunction { +// // 1. If realm is not present, set realm to the current Realm Record. +// let realm = args.realm.unwrap_or(agent.current_realm_id()); + +// // 9. Set func.[[InitialName]] to null. +// // Note: SetFunctionName inlined here: We know name is a string +// let initial_name = if let Some(prefix) = args.prefix { +// // 12. Else, +// // a. Perform SetFunctionName(func, name, prefix). +// String::from_string(agent, format!("{} {}", args.name, prefix)) +// } else { +// // 11. If prefix is not present, then +// // a. Perform SetFunctionName(func, name). +// String::from_str(agent, args.name) +// }; + +// // 2. If prototype is not present, set prototype to realm.[[Intrinsics]].[[%Function.prototype%]]. + +// // 3. Let internalSlotsList be a List containing the names of all the internal slots that 10.3 +// // requires for the built-in function object that is about to be created. +// // 4. Append to internalSlotsList the elements of additionalInternalSlotsList. +// // Note: The BuiltinConstructorHeapData implements all internal slots that 10.3 requires. +// // The currently appearing spec-defined additional slots are: +// // * [[ConstructorKind]] and [[SourceText]] for class constructors. +// // * [[Promise]] and [[AlreadyResolved]] for Promise resolver functions +// // * [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], and [[RemainingElements]] for +// // Promise.all's onFulfilled function. +// // We do not yet support these, and how these end up supported is not yet fully clear. + +// // 5. Let func be a new built-in function object that, when called, performs the action +// // described by behaviour using the provided arguments as the values of the corresponding +// // parameters specified by behaviour. The new function object has internal slots whose names +// // are the elements of internalSlotsList, and an [[InitialName]] internal slot. +// let object_index = if let Some(prototype) = args.prototype { +// // If a prototype is set, then check that it is not the %Function.prototype% +// let realm_function_prototype = agent +// .get_realm(realm) +// .intrinsics() +// .get_intrinsic_default_proto(BuiltinConstructorFunction::DEFAULT_PROTOTYPE); +// if prototype == realm_function_prototype { +// // If the prototype matched the realm function prototype, then ignore it +// // as the BuiltinConstructorHeapData indirectly implies this prototype. +// None +// } else { +// // If some other prototype is defined then we need to create a backing object. +// // 6. Set func.[[Prototype]] to prototype. +// // 7. Set func.[[Extensible]] to true. +// let length_entry = ObjectEntry { +// key: PropertyKey::from(BUILTIN_STRING_MEMORY.length), +// value: ObjectEntryPropertyDescriptor::Data { +// value: args.length.into(), +// writable: false, +// enumerable: false, +// configurable: true, +// }, +// }; +// let name_entry = ObjectEntry { +// key: PropertyKey::from(BUILTIN_STRING_MEMORY.name), +// value: ObjectEntryPropertyDescriptor::Data { +// value: initial_name.into_value(), +// writable: false, +// enumerable: false, +// configurable: true, +// }, +// }; +// Some( +// agent +// .heap +// .create_object_with_prototype(prototype, &[length_entry, name_entry]), +// ) +// } +// } else { +// None +// }; + +// // 13. Return func. +// agent.heap.create(BuiltinConstructorHeapData { +// behaviour, +// initial_name: Some(initial_name), +// // 10. Perform SetFunctionLength(func, length). +// length: args.length as u8, +// // 8. Set func.[[Realm]] to realm. +// realm, +// object_index, +// compiled_initializer_bytecode: None, +// }) +// } + +impl CreateHeapData for Heap { + fn create(&mut self, data: BuiltinConstructorHeapData) -> BuiltinConstructorFunction { + self.builtin_constructors.push(Some(data)); + BuiltinConstructorIndex::last(&self.builtin_constructors).into() + } +} + +impl HeapMarkAndSweep for BuiltinConstructorFunction { + fn mark_values(&self, queues: &mut WorkQueues) { + queues.builtin_constructors.push(*self); + } + + fn sweep_values(&mut self, compactions: &CompactionLists) { + compactions.builtin_constructors.shift_index(&mut self.0); + } +} + +impl HeapMarkAndSweep for BuiltinConstructorHeapData { + fn mark_values(&self, queues: &mut WorkQueues) { + self.realm.mark_values(queues); + self.initial_name.mark_values(queues); + self.object_index.mark_values(queues); + } + + fn sweep_values(&mut self, compactions: &CompactionLists) { + self.realm.sweep_values(compactions); + self.initial_name.sweep_values(compactions); + self.object_index.sweep_values(compactions); + } +} diff --git a/nova_vm/src/ecmascript/builtins/ecmascript_function.rs b/nova_vm/src/ecmascript/builtins/ecmascript_function.rs index d2d72b621..1d666bb5d 100644 --- a/nova_vm/src/ecmascript/builtins/ecmascript_function.rs +++ b/nova_vm/src/ecmascript/builtins/ecmascript_function.rs @@ -862,7 +862,7 @@ pub(crate) fn make_constructor( // a. Set F.[[Construct]] to the definition specified in 10.3.2. } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(_) => todo!(), Function::BuiltinPromiseResolvingFunction(_) => todo!(), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -976,7 +976,7 @@ pub(crate) fn set_function_name( // 7. Return UNUSED. } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(_) => todo!(), Function::BuiltinPromiseResolvingFunction(_) => todo!(), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), 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 052434a6a..a4befcece 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 @@ -281,7 +281,7 @@ impl FunctionPrototype { Ok(Value::from_string(agent, initial_name)) } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(_) => todo!(), Function::BuiltinPromiseResolvingFunction(_) => { // Promise resolving functions have no initial name. Ok(Value::from_static_str( diff --git a/nova_vm/src/ecmascript/execution/environments/function_environment.rs b/nova_vm/src/ecmascript/execution/environments/function_environment.rs index 8ef223501..0b6668000 100644 --- a/nova_vm/src/ecmascript/execution/environments/function_environment.rs +++ b/nova_vm/src/ecmascript/execution/environments/function_environment.rs @@ -376,7 +376,7 @@ impl FunctionEnvironmentIndex { agent[func].ecmascript_function.home_object.is_some() } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(_) => todo!(), Function::BuiltinPromiseResolvingFunction(_) => unreachable!(), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -397,7 +397,7 @@ impl FunctionEnvironmentIndex { Function::BuiltinFunction(_) => unreachable!(), Function::ECMAScriptFunction(func) => agent[func].ecmascript_function.home_object, Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(_) => todo!(), Function::BuiltinPromiseResolvingFunction(_) => unreachable!(), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), diff --git a/nova_vm/src/ecmascript/types/language.rs b/nova_vm/src/ecmascript/types/language.rs index 6798784de..f521f285f 100644 --- a/nova_vm/src/ecmascript/types/language.rs +++ b/nova_vm/src/ecmascript/types/language.rs @@ -21,8 +21,8 @@ pub(crate) use function::{ function_create_backing_object, function_internal_define_own_property, function_internal_delete, function_internal_get, function_internal_get_own_property, function_internal_has_property, function_internal_own_property_keys, function_internal_set, - BoundFunctionHeapData, BuiltinFunctionHeapData, ECMAScriptFunctionHeapData, - FunctionInternalProperties, + BoundFunctionHeapData, BuiltinConstructorHeapData, BuiltinFunctionHeapData, + ECMAScriptFunctionHeapData, FunctionInternalProperties, }; pub use function::{Function, IntoFunction}; pub use global_value::Global; diff --git a/nova_vm/src/ecmascript/types/language/function.rs b/nova_vm/src/ecmascript/types/language/function.rs index 757beef83..625306fa2 100644 --- a/nova_vm/src/ecmascript/types/language/function.rs +++ b/nova_vm/src/ecmascript/types/language/function.rs @@ -17,7 +17,7 @@ use super::{ use crate::{ ecmascript::{ builtins::{ - bound_function::BoundFunction, control_abstraction_objects::promise_objects::promise_abstract_operations::promise_resolving_functions::BuiltinPromiseResolvingFunction, ArgumentsList, BuiltinFunction, ECMAScriptFunction + bound_function::BoundFunction, control_abstraction_objects::promise_objects::promise_abstract_operations::promise_resolving_functions::BuiltinPromiseResolvingFunction, ArgumentsList, BuiltinConstructorFunction, BuiltinFunction, ECMAScriptFunction }, execution::{Agent, JsResult, ProtoIntrinsics}, types::PropertyDescriptor, @@ -42,7 +42,8 @@ pub enum Function { BuiltinFunction(BuiltinFunction) = BUILTIN_FUNCTION_DISCRIMINANT, ECMAScriptFunction(ECMAScriptFunction) = ECMASCRIPT_FUNCTION_DISCRIMINANT, BuiltinGeneratorFunction = BUILTIN_GENERATOR_FUNCTION_DISCRIMINANT, - BuiltinConstructorFunction = BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, + BuiltinConstructorFunction(BuiltinConstructorFunction) = + BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, BuiltinPromiseResolvingFunction(BuiltinPromiseResolvingFunction) = BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BuiltinPromiseCollectorFunction = BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, @@ -56,7 +57,9 @@ impl std::fmt::Debug for Function { Function::BuiltinFunction(d) => write!(f, "BuiltinFunction({:?})", d), Function::ECMAScriptFunction(d) => write!(f, "ECMAScriptFunction({:?})", d), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(d) => { + write!(f, "BuiltinConstructorFunction({:?})", d) + } Function::BuiltinPromiseResolvingFunction(d) => { write!(f, "BuiltinPromiseResolvingFunction({:?})", d) } @@ -99,7 +102,9 @@ impl TryFrom for Function { Object::BuiltinFunction(d) => Ok(Function::from(d)), Object::ECMAScriptFunction(d) => Ok(Function::from(d)), Object::BuiltinGeneratorFunction => Ok(Function::BuiltinGeneratorFunction), - Object::BuiltinConstructorFunction => Ok(Function::BuiltinConstructorFunction), + Object::BuiltinConstructorFunction(data) => { + Ok(Function::BuiltinConstructorFunction(data)) + } Object::BuiltinPromiseResolvingFunction(data) => { Ok(Function::BuiltinPromiseResolvingFunction(data)) } @@ -120,7 +125,9 @@ impl TryFrom for Function { Value::BuiltinFunction(d) => Ok(Function::BuiltinFunction(d)), Value::ECMAScriptFunction(d) => Ok(Function::ECMAScriptFunction(d)), Value::BuiltinGeneratorFunction => Ok(Function::BuiltinGeneratorFunction), - Value::BuiltinConstructorFunction => Ok(Function::BuiltinConstructorFunction), + Value::BuiltinConstructorFunction(data) => { + Ok(Function::BuiltinConstructorFunction(data)) + } Value::BuiltinPromiseResolvingFunction(data) => { Ok(Function::BuiltinPromiseResolvingFunction(data)) } @@ -138,7 +145,7 @@ impl From for Object { Function::BuiltinFunction(d) => Object::from(d), Function::ECMAScriptFunction(d) => Object::from(d), Function::BuiltinGeneratorFunction => Object::BuiltinGeneratorFunction, - Function::BuiltinConstructorFunction => Object::BuiltinConstructorFunction, + Function::BuiltinConstructorFunction(data) => Object::BuiltinConstructorFunction(data), Function::BuiltinPromiseResolvingFunction(data) => { Object::BuiltinPromiseResolvingFunction(data) } @@ -155,7 +162,7 @@ impl From for Value { Function::BuiltinFunction(d) => Value::BuiltinFunction(d), Function::ECMAScriptFunction(d) => Value::ECMAScriptFunction(d), Function::BuiltinGeneratorFunction => Value::BuiltinGeneratorFunction, - Function::BuiltinConstructorFunction => Value::BuiltinConstructorFunction, + Function::BuiltinConstructorFunction(data) => Value::BuiltinConstructorFunction(data), Function::BuiltinPromiseResolvingFunction(data) => { Value::BuiltinPromiseResolvingFunction(data) } @@ -177,7 +184,7 @@ impl Function { Function::ECMAScriptFunction(f) => f.is_constructor(agent), Function::BuiltinPromiseResolvingFunction(_) => false, Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(_) => false, Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } @@ -202,7 +209,7 @@ impl InternalSlots for Function { Function::BuiltinFunction(d) => agent[d].object_index, Function::ECMAScriptFunction(d) => agent[d].object_index, Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(d) => agent[d].object_index, Function::BuiltinPromiseResolvingFunction(d) => agent[d].object_index, Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -243,7 +250,7 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_get_prototype_of(agent), Function::ECMAScriptFunction(x) => x.internal_get_prototype_of(agent), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => x.internal_get_prototype_of(agent), Function::BuiltinPromiseResolvingFunction(x) => x.internal_get_prototype_of(agent), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -260,7 +267,9 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_set_prototype_of(agent, prototype), Function::ECMAScriptFunction(x) => x.internal_set_prototype_of(agent, prototype), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => { + x.internal_set_prototype_of(agent, prototype) + } Function::BuiltinPromiseResolvingFunction(x) => { x.internal_set_prototype_of(agent, prototype) } @@ -275,7 +284,7 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_is_extensible(agent), Function::ECMAScriptFunction(x) => x.internal_is_extensible(agent), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => x.internal_is_extensible(agent), Function::BuiltinPromiseResolvingFunction(x) => x.internal_is_extensible(agent), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -288,7 +297,7 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_prevent_extensions(agent), Function::ECMAScriptFunction(x) => x.internal_prevent_extensions(agent), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => x.internal_prevent_extensions(agent), Function::BuiltinPromiseResolvingFunction(x) => x.internal_prevent_extensions(agent), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -305,7 +314,9 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_get_own_property(agent, property_key), Function::ECMAScriptFunction(x) => x.internal_get_own_property(agent, property_key), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => { + x.internal_get_own_property(agent, property_key) + } Function::BuiltinPromiseResolvingFunction(x) => { x.internal_get_own_property(agent, property_key) } @@ -331,7 +342,9 @@ impl InternalMethods for Function { x.internal_define_own_property(agent, property_key, property_descriptor) } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => { + x.internal_define_own_property(agent, property_key, property_descriptor) + } Function::BuiltinPromiseResolvingFunction(x) => { x.internal_define_own_property(agent, property_key, property_descriptor) } @@ -346,7 +359,7 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_has_property(agent, property_key), Function::ECMAScriptFunction(x) => x.internal_has_property(agent, property_key), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => x.internal_has_property(agent, property_key), Function::BuiltinPromiseResolvingFunction(x) => { x.internal_has_property(agent, property_key) } @@ -366,7 +379,9 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_get(agent, property_key, receiver), Function::ECMAScriptFunction(x) => x.internal_get(agent, property_key, receiver), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => { + x.internal_get(agent, property_key, receiver) + } Function::BuiltinPromiseResolvingFunction(x) => { x.internal_get(agent, property_key, receiver) } @@ -387,7 +402,9 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_set(agent, property_key, value, receiver), Function::ECMAScriptFunction(x) => x.internal_set(agent, property_key, value, receiver), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => { + x.internal_set(agent, property_key, value, receiver) + } Function::BuiltinPromiseResolvingFunction(x) => { x.internal_set(agent, property_key, value, receiver) } @@ -402,7 +419,7 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_delete(agent, property_key), Function::ECMAScriptFunction(x) => x.internal_delete(agent, property_key), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => x.internal_delete(agent, property_key), Function::BuiltinPromiseResolvingFunction(x) => x.internal_delete(agent, property_key), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -415,7 +432,7 @@ impl InternalMethods for Function { Function::BuiltinFunction(x) => x.internal_own_property_keys(agent), Function::ECMAScriptFunction(x) => x.internal_own_property_keys(agent), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => x.internal_own_property_keys(agent), Function::BuiltinPromiseResolvingFunction(x) => x.internal_own_property_keys(agent), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -435,7 +452,9 @@ impl InternalMethods for Function { x.internal_call(agent, this_argument, arguments_list) } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => { + x.internal_call(agent, this_argument, arguments_list) + } Function::BuiltinPromiseResolvingFunction(x) => { x.internal_call(agent, this_argument, arguments_list) } @@ -457,7 +476,9 @@ impl InternalMethods for Function { x.internal_construct(agent, arguments_list, new_target) } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => { + x.internal_construct(agent, arguments_list, new_target) + } Function::BuiltinPromiseResolvingFunction(x) => { x.internal_construct(agent, arguments_list, new_target) } @@ -474,7 +495,7 @@ impl HeapMarkAndSweep for Function { Function::BuiltinFunction(x) => x.mark_values(queues), Function::ECMAScriptFunction(x) => x.mark_values(queues), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => x.mark_values(queues), Function::BuiltinPromiseResolvingFunction(x) => x.mark_values(queues), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -487,7 +508,7 @@ impl HeapMarkAndSweep for Function { Function::BuiltinFunction(x) => x.sweep_values(compactions), Function::ECMAScriptFunction(x) => x.sweep_values(compactions), Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction => todo!(), + Function::BuiltinConstructorFunction(x) => x.sweep_values(compactions), Function::BuiltinPromiseResolvingFunction(x) => x.sweep_values(compactions), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), diff --git a/nova_vm/src/ecmascript/types/language/function/data.rs b/nova_vm/src/ecmascript/types/language/function/data.rs index e79b976bd..62d832638 100644 --- a/nova_vm/src/ecmascript/types/language/function/data.rs +++ b/nova_vm/src/ecmascript/types/language/function/data.rs @@ -6,7 +6,7 @@ use std::ptr::NonNull; use crate::{ ecmascript::{ - builtins::{Behaviour, ECMAScriptFunctionObjectHeapData}, + builtins::{Behaviour, ConstructorFn, ECMAScriptFunctionObjectHeapData}, execution::RealmIdentifier, types::{OrdinaryObject, String, Value}, }, @@ -52,6 +52,27 @@ pub struct BuiltinFunctionHeapData { pub(crate) behaviour: Behaviour, } +#[derive(Debug, Clone)] +pub struct BuiltinConstructorHeapData { + pub(crate) object_index: Option, + pub(crate) length: u8, + /// #### \[\[Realm]] + /// A Realm Record that represents the realm in which the function was + /// created. + pub(crate) realm: RealmIdentifier, + /// #### \[\[InitialName]] + /// A String that is the initial name of the function. It is used by + /// 20.2.3.5 (`Function.prototype.toString()`). + pub(crate) initial_name: Option, + pub(crate) behaviour: ConstructorFn, + /// Stores the compiled bytecode of class field initializers. + pub(crate) compiled_initializer_bytecode: Option>, +} + +// SAFETY: We promise not to ever mutate the Executable, especially not from +// foreign threads. +unsafe impl Send for BuiltinConstructorHeapData {} + #[derive(Debug)] pub struct ECMAScriptFunctionHeapData { pub(crate) object_index: Option, diff --git a/nova_vm/src/ecmascript/types/language/object.rs b/nova_vm/src/ecmascript/types/language/object.rs index f06fe3fd0..7a16d2d8b 100644 --- a/nova_vm/src/ecmascript/types/language/object.rs +++ b/nova_vm/src/ecmascript/types/language/object.rs @@ -63,7 +63,8 @@ use crate::{ weak_map::WeakMap, weak_ref::WeakRef, weak_set::WeakSet, - ArgumentsList, Array, ArrayBuffer, BuiltinFunction, ECMAScriptFunction, + ArgumentsList, Array, ArrayBuffer, BuiltinConstructorFunction, BuiltinFunction, + ECMAScriptFunction, }, execution::{Agent, JsResult}, types::PropertyDescriptor, @@ -92,7 +93,8 @@ pub enum Object { BuiltinFunction(BuiltinFunction) = BUILTIN_FUNCTION_DISCRIMINANT, ECMAScriptFunction(ECMAScriptFunction) = ECMASCRIPT_FUNCTION_DISCRIMINANT, BuiltinGeneratorFunction = BUILTIN_GENERATOR_FUNCTION_DISCRIMINANT, - BuiltinConstructorFunction = BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, + BuiltinConstructorFunction(BuiltinConstructorFunction) = + BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT, BuiltinPromiseResolvingFunction(BuiltinPromiseResolvingFunction) = BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BuiltinPromiseCollectorFunction = BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT, @@ -147,7 +149,7 @@ impl IntoValue for Object { Object::BuiltinFunction(data) => Value::BuiltinFunction(data), Object::ECMAScriptFunction(data) => Value::ECMAScriptFunction(data), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => Value::BuiltinConstructorFunction(data), Object::BuiltinPromiseResolvingFunction(data) => { Value::BuiltinPromiseResolvingFunction(data) } @@ -323,7 +325,7 @@ impl From for Value { Object::BuiltinFunction(data) => Value::BuiltinFunction(data), Object::ECMAScriptFunction(data) => Value::ECMAScriptFunction(data), Object::BuiltinGeneratorFunction => Value::BuiltinGeneratorFunction, - Object::BuiltinConstructorFunction => Value::BuiltinConstructorFunction, + Object::BuiltinConstructorFunction(data) => Value::BuiltinConstructorFunction(data), Object::BuiltinPromiseResolvingFunction(data) => { Value::BuiltinPromiseResolvingFunction(data) } @@ -393,7 +395,7 @@ impl TryFrom for Object { Value::BuiltinFunction(x) => Ok(Object::from(x)), Value::ECMAScriptFunction(x) => Ok(Object::from(x)), Value::BuiltinGeneratorFunction => Ok(Object::BuiltinGeneratorFunction), - Value::BuiltinConstructorFunction => Ok(Object::BuiltinConstructorFunction), + Value::BuiltinConstructorFunction(data) => Ok(Object::BuiltinConstructorFunction(data)), Value::BuiltinPromiseResolvingFunction(data) => { Ok(Object::BuiltinPromiseResolvingFunction(data)) } @@ -456,7 +458,7 @@ impl Hash for Object { Object::BuiltinFunction(data) => data.get_index().hash(state), Object::ECMAScriptFunction(data) => data.get_index().hash(state), Object::BuiltinGeneratorFunction => {} - Object::BuiltinConstructorFunction => {} + Object::BuiltinConstructorFunction(data) => data.get_index().hash(state), Object::BuiltinPromiseResolvingFunction(data) => data.get_index().hash(state), Object::BuiltinPromiseCollectorFunction => {} Object::BuiltinProxyRevokerFunction => {} @@ -525,7 +527,7 @@ impl InternalSlots for Object { Object::BuiltinFunction(data) => data.internal_extensible(agent), Object::ECMAScriptFunction(data) => data.internal_extensible(agent), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => data.internal_extensible(agent), Object::BuiltinPromiseResolvingFunction(data) => data.internal_extensible(agent), Object::BuiltinPromiseCollectorFunction => todo!(), Object::BuiltinProxyRevokerFunction => todo!(), @@ -582,7 +584,7 @@ impl InternalSlots for Object { Object::BuiltinFunction(idx) => idx.internal_set_extensible(agent, value), Object::ECMAScriptFunction(idx) => idx.internal_set_extensible(agent, value), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(idx) => idx.internal_set_extensible(agent, value), Object::BuiltinPromiseResolvingFunction(data) => { data.internal_set_extensible(agent, value) } @@ -657,7 +659,7 @@ impl InternalSlots for Object { Object::BuiltinFunction(data) => data.internal_prototype(agent), Object::ECMAScriptFunction(data) => data.internal_prototype(agent), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => data.internal_prototype(agent), Object::BuiltinPromiseResolvingFunction(data) => data.internal_prototype(agent), Object::BuiltinPromiseCollectorFunction => todo!(), Object::BuiltinProxyRevokerFunction => todo!(), @@ -714,7 +716,9 @@ impl InternalSlots for Object { Object::BuiltinFunction(data) => data.internal_set_prototype(agent, prototype), Object::ECMAScriptFunction(data) => data.internal_set_prototype(agent, prototype), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => { + data.internal_set_prototype(agent, prototype) + } Object::BuiltinPromiseResolvingFunction(data) => { data.internal_set_prototype(agent, prototype) } @@ -791,7 +795,7 @@ impl InternalMethods for Object { Object::BuiltinFunction(data) => data.internal_get_prototype_of(agent), Object::ECMAScriptFunction(data) => data.internal_get_prototype_of(agent), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => data.internal_get_prototype_of(agent), Object::BuiltinPromiseResolvingFunction(data) => data.internal_get_prototype_of(agent), Object::BuiltinPromiseCollectorFunction => todo!(), Object::BuiltinProxyRevokerFunction => todo!(), @@ -866,7 +870,9 @@ impl InternalMethods for Object { Object::BuiltinFunction(data) => data.internal_set_prototype_of(agent, prototype), Object::ECMAScriptFunction(data) => data.internal_set_prototype_of(agent, prototype), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => { + data.internal_set_prototype_of(agent, prototype) + } Object::BuiltinPromiseResolvingFunction(data) => { data.internal_set_prototype_of(agent, prototype) } @@ -941,7 +947,7 @@ impl InternalMethods for Object { Object::BuiltinFunction(data) => data.internal_is_extensible(agent), Object::ECMAScriptFunction(data) => data.internal_is_extensible(agent), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => data.internal_is_extensible(agent), Object::BuiltinPromiseResolvingFunction(data) => data.internal_is_extensible(agent), Object::BuiltinPromiseCollectorFunction => todo!(), Object::BuiltinProxyRevokerFunction => todo!(), @@ -1006,7 +1012,7 @@ impl InternalMethods for Object { Object::BuiltinFunction(data) => data.internal_prevent_extensions(agent), Object::ECMAScriptFunction(data) => data.internal_prevent_extensions(agent), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => data.internal_prevent_extensions(agent), Object::BuiltinPromiseResolvingFunction(data) => { data.internal_prevent_extensions(agent) } @@ -1085,7 +1091,9 @@ impl InternalMethods for Object { Object::BuiltinFunction(data) => data.internal_get_own_property(agent, property_key), Object::ECMAScriptFunction(data) => data.internal_get_own_property(agent, property_key), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => { + data.internal_get_own_property(agent, property_key) + } Object::BuiltinPromiseResolvingFunction(data) => { data.internal_get_own_property(agent, property_key) } @@ -1183,7 +1191,9 @@ impl InternalMethods for Object { data.internal_define_own_property(agent, property_key, property_descriptor) } Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => { + data.internal_define_own_property(agent, property_key, property_descriptor) + } Object::BuiltinPromiseResolvingFunction(data) => { data.internal_define_own_property(agent, property_key, property_descriptor) } @@ -1297,7 +1307,9 @@ impl InternalMethods for Object { Object::BuiltinFunction(data) => data.internal_has_property(agent, property_key), Object::ECMAScriptFunction(data) => data.internal_has_property(agent, property_key), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => { + data.internal_has_property(agent, property_key) + } Object::BuiltinPromiseResolvingFunction(data) => { data.internal_has_property(agent, property_key) } @@ -1377,7 +1389,9 @@ impl InternalMethods for Object { Object::BuiltinFunction(data) => data.internal_get(agent, property_key, receiver), Object::ECMAScriptFunction(data) => data.internal_get(agent, property_key, receiver), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => { + data.internal_get(agent, property_key, receiver) + } Object::BuiltinPromiseResolvingFunction(data) => { data.internal_get(agent, property_key, receiver) } @@ -1462,7 +1476,9 @@ impl InternalMethods for Object { data.internal_set(agent, property_key, value, receiver) } Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => { + data.internal_set(agent, property_key, value, receiver) + } Object::BuiltinPromiseResolvingFunction(data) => { data.internal_set(agent, property_key, value, receiver) } @@ -1546,7 +1562,7 @@ impl InternalMethods for Object { Object::BuiltinFunction(data) => data.internal_delete(agent, property_key), Object::ECMAScriptFunction(data) => data.internal_delete(agent, property_key), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => data.internal_delete(agent, property_key), Object::BuiltinPromiseResolvingFunction(data) => { data.internal_delete(agent, property_key) } @@ -1621,7 +1637,7 @@ impl InternalMethods for Object { Object::BuiltinFunction(data) => data.internal_own_property_keys(agent), Object::ECMAScriptFunction(data) => data.internal_own_property_keys(agent), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => data.internal_own_property_keys(agent), Object::BuiltinPromiseResolvingFunction(data) => data.internal_own_property_keys(agent), Object::BuiltinPromiseCollectorFunction => todo!(), Object::BuiltinProxyRevokerFunction => todo!(), @@ -1733,7 +1749,7 @@ impl HeapMarkAndSweep for Object { Object::BuiltinFunction(data) => data.mark_values(queues), Object::ECMAScriptFunction(data) => data.mark_values(queues), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => data.mark_values(queues), Object::BuiltinPromiseResolvingFunction(data) => data.mark_values(queues), Object::BuiltinPromiseCollectorFunction => todo!(), Object::BuiltinProxyRevokerFunction => todo!(), @@ -1780,7 +1796,7 @@ impl HeapMarkAndSweep for Object { Object::BuiltinFunction(data) => data.sweep_values(compactions), Object::ECMAScriptFunction(data) => data.sweep_values(compactions), Object::BuiltinGeneratorFunction => todo!(), - Object::BuiltinConstructorFunction => todo!(), + Object::BuiltinConstructorFunction(data) => data.sweep_values(compactions), Object::BuiltinPromiseResolvingFunction(data) => data.sweep_values(compactions), Object::BuiltinPromiseCollectorFunction => todo!(), Object::BuiltinProxyRevokerFunction => todo!(), diff --git a/nova_vm/src/ecmascript/types/language/value.rs b/nova_vm/src/ecmascript/types/language/value.rs index fa2fff012..856b9c63e 100644 --- a/nova_vm/src/ecmascript/types/language/value.rs +++ b/nova_vm/src/ecmascript/types/language/value.rs @@ -41,7 +41,7 @@ use crate::{ weak_map::WeakMap, weak_ref::WeakRef, weak_set::WeakSet, - Array, ArrayBuffer, BuiltinFunction, ECMAScriptFunction, + Array, ArrayBuffer, BuiltinConstructorFunction, BuiltinFunction, ECMAScriptFunction, }, execution::{Agent, JsResult}, types::BUILTIN_STRING_MEMORY, @@ -120,7 +120,9 @@ pub enum Value { // TODO: Figure out if all the special function types are wanted or if we'd // prefer to just keep them as internal variants of the three above ones. BuiltinGeneratorFunction, - BuiltinConstructorFunction, + /// Default class constructor created in step 14 of + /// [ClassDefinitionEvaluation](https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation). + BuiltinConstructorFunction(BuiltinConstructorFunction), BuiltinPromiseResolvingFunction(BuiltinPromiseResolvingFunction), BuiltinPromiseCollectorFunction, BuiltinProxyRevokerFunction, @@ -235,8 +237,9 @@ pub(crate) const REGEXP_DISCRIMINANT: u8 = value_discriminant(Value::RegExp(RegE pub(crate) const BUILTIN_GENERATOR_FUNCTION_DISCRIMINANT: u8 = value_discriminant(Value::BuiltinGeneratorFunction); -pub(crate) const BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT: u8 = - value_discriminant(Value::BuiltinConstructorFunction); +pub(crate) const BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT: u8 = value_discriminant( + Value::BuiltinConstructorFunction(BuiltinConstructorFunction::_def()), +); pub(crate) const BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT: u8 = value_discriminant( Value::BuiltinPromiseResolvingFunction(BuiltinPromiseResolvingFunction::_def()), ); @@ -543,7 +546,10 @@ impl Value { data.get_index().hash(hasher); } Value::BuiltinGeneratorFunction => todo!(), - Value::BuiltinConstructorFunction => todo!(), + Value::BuiltinConstructorFunction(data) => { + discriminant.hash(hasher); + data.get_index().hash(hasher); + } Value::BuiltinPromiseResolvingFunction(data) => { discriminant.hash(hasher); data.get_index().hash(hasher); @@ -742,7 +748,10 @@ impl Value { data.get_index().hash(hasher); } Value::BuiltinGeneratorFunction => todo!(), - Value::BuiltinConstructorFunction => todo!(), + Value::BuiltinConstructorFunction(data) => { + discriminant.hash(hasher); + data.get_index().hash(hasher); + } Value::BuiltinPromiseResolvingFunction(data) => { discriminant.hash(hasher); data.get_index().hash(hasher); @@ -1029,7 +1038,7 @@ impl HeapMarkAndSweep for Value { Value::Float32Array(data) => data.mark_values(queues), Value::Float64Array(data) => data.mark_values(queues), Value::BuiltinGeneratorFunction => todo!(), - Value::BuiltinConstructorFunction => todo!(), + Value::BuiltinConstructorFunction(data) => data.mark_values(queues), Value::BuiltinPromiseResolvingFunction(data) => data.mark_values(queues), Value::BuiltinPromiseCollectorFunction => todo!(), Value::BuiltinProxyRevokerFunction => todo!(), @@ -1093,7 +1102,7 @@ impl HeapMarkAndSweep for Value { Value::Float32Array(data) => data.sweep_values(compactions), Value::Float64Array(data) => data.sweep_values(compactions), Value::BuiltinGeneratorFunction => todo!(), - Value::BuiltinConstructorFunction => todo!(), + Value::BuiltinConstructorFunction(data) => data.sweep_values(compactions), Value::BuiltinPromiseResolvingFunction(data) => data.sweep_values(compactions), Value::BuiltinPromiseCollectorFunction => todo!(), Value::BuiltinProxyRevokerFunction => todo!(), diff --git a/nova_vm/src/engine/bytecode/vm.rs b/nova_vm/src/engine/bytecode/vm.rs index d6c32533b..f6dd69b9e 100644 --- a/nova_vm/src/engine/bytecode/vm.rs +++ b/nova_vm/src/engine/bytecode/vm.rs @@ -2074,7 +2074,7 @@ fn typeof_operator(_: &mut Agent, val: Value) -> String { // 13. If val has a [[Call]] internal slot, return "function". Value::BoundFunction(_) | Value::BuiltinFunction(_) | Value::ECMAScriptFunction(_) | Value::BuiltinGeneratorFunction | - Value::BuiltinConstructorFunction | + Value::BuiltinConstructorFunction(_) | Value::BuiltinPromiseResolvingFunction(_) | Value::BuiltinPromiseCollectorFunction | Value::BuiltinProxyRevokerFunction => BUILTIN_STRING_MEMORY.function, diff --git a/nova_vm/src/heap.rs b/nova_vm/src/heap.rs index 7e5f01a1c..8ea620107 100644 --- a/nova_vm/src/heap.rs +++ b/nova_vm/src/heap.rs @@ -63,7 +63,10 @@ use crate::ecmascript::{ weak_set::data::WeakSetHeapData, }, scripts_and_modules::source_code::SourceCodeHeapData, - types::{bigint::HeapBigInt, HeapNumber, HeapString, OrdinaryObject, BUILTIN_STRINGS_LIST}, + types::{ + bigint::HeapBigInt, BuiltinConstructorHeapData, HeapNumber, HeapString, OrdinaryObject, + BUILTIN_STRINGS_LIST, + }, }; use crate::ecmascript::{ builtins::{ArrayBufferHeapData, ArrayHeapData}, @@ -87,6 +90,7 @@ pub struct Heap { pub(crate) await_reactions: Vec>, pub bigints: Vec>, pub bound_functions: Vec>, + pub builtin_constructors: Vec>, pub builtin_functions: Vec>, pub data_views: Vec>, pub dates: Vec>, @@ -167,6 +171,7 @@ impl Heap { await_reactions: Vec::with_capacity(1024), bigints: Vec::with_capacity(1024), bound_functions: Vec::with_capacity(256), + builtin_constructors: Vec::with_capacity(256), builtin_functions: Vec::with_capacity(1024), data_views: Vec::with_capacity(0), dates: Vec::with_capacity(1024), diff --git a/nova_vm/src/heap/heap_bits.rs b/nova_vm/src/heap/heap_bits.rs index 7b3972ae5..aebfb668f 100644 --- a/nova_vm/src/heap/heap_bits.rs +++ b/nova_vm/src/heap/heap_bits.rs @@ -40,7 +40,7 @@ use crate::ecmascript::{ weak_map::WeakMap, weak_ref::WeakRef, weak_set::WeakSet, - Array, ArrayBuffer, BuiltinFunction, ECMAScriptFunction, + Array, ArrayBuffer, BuiltinConstructorFunction, BuiltinFunction, ECMAScriptFunction, }, execution::{ DeclarativeEnvironmentIndex, EnvironmentIndex, FunctionEnvironmentIndex, @@ -61,6 +61,7 @@ pub struct HeapBits { pub await_reactions: Box<[bool]>, pub bigints: Box<[bool]>, pub bound_functions: Box<[bool]>, + pub builtin_constructors: Box<[bool]>, pub builtin_functions: Box<[bool]>, pub data_views: Box<[bool]>, pub dates: Box<[bool]>, @@ -114,6 +115,7 @@ pub(crate) struct WorkQueues { pub await_reactions: Vec, pub bigints: Vec, pub bound_functions: Vec, + pub builtin_constructors: Vec, pub builtin_functions: Vec, pub data_views: Vec, pub dates: Vec, @@ -167,6 +169,7 @@ impl HeapBits { let await_reactions = vec![false; heap.await_reactions.len()]; let bigints = vec![false; heap.bigints.len()]; let bound_functions = vec![false; heap.bound_functions.len()]; + 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()]; let dates = vec![false; heap.dates.len()]; @@ -217,6 +220,7 @@ impl HeapBits { await_reactions: await_reactions.into_boxed_slice(), bigints: bigints.into_boxed_slice(), bound_functions: bound_functions.into_boxed_slice(), + builtin_constructors: builtin_constructors.into_boxed_slice(), builtin_functions: builtin_functions.into_boxed_slice(), data_views: data_views.into_boxed_slice(), dates: dates.into_boxed_slice(), @@ -273,6 +277,7 @@ impl WorkQueues { await_reactions: Vec::with_capacity(heap.await_reactions.len() / 4), bigints: Vec::with_capacity(heap.bigints.len() / 4), bound_functions: Vec::with_capacity(heap.bound_functions.len() / 4), + 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), dates: Vec::with_capacity(heap.dates.len() / 4), @@ -352,6 +357,7 @@ impl WorkQueues { await_reactions, bigints, bound_functions, + builtin_constructors, builtin_functions, data_views, dates, @@ -402,6 +408,7 @@ impl WorkQueues { && await_reactions.is_empty() && bigints.is_empty() && bound_functions.is_empty() + && builtin_constructors.is_empty() && builtin_functions.is_empty() && data_views.is_empty() && dates.is_empty() @@ -593,6 +600,7 @@ pub(crate) struct CompactionLists { pub await_reactions: CompactionList, pub bigints: CompactionList, pub bound_functions: CompactionList, + pub builtin_constructors: CompactionList, pub builtin_functions: CompactionList, pub data_views: CompactionList, pub dates: CompactionList, @@ -673,6 +681,7 @@ impl CompactionLists { await_reactions: CompactionList::from_mark_bits(&bits.await_reactions), bigints: CompactionList::from_mark_bits(&bits.bigints), bound_functions: CompactionList::from_mark_bits(&bits.bound_functions), + builtin_constructors: CompactionList::from_mark_bits(&bits.builtin_constructors), builtin_functions: CompactionList::from_mark_bits(&bits.builtin_functions), ecmascript_functions: CompactionList::from_mark_bits(&bits.ecmascript_functions), embedder_objects: CompactionList::from_mark_bits(&bits.embedder_objects), diff --git a/nova_vm/src/heap/heap_gc.rs b/nova_vm/src/heap/heap_gc.rs index 8731af6e3..bf43e555d 100644 --- a/nova_vm/src/heap/heap_gc.rs +++ b/nova_vm/src/heap/heap_gc.rs @@ -47,7 +47,7 @@ use crate::ecmascript::{ weak_map::WeakMap, weak_ref::WeakRef, weak_set::WeakSet, - Array, ArrayBuffer, BuiltinFunction, ECMAScriptFunction, + Array, ArrayBuffer, BuiltinConstructorFunction, BuiltinFunction, ECMAScriptFunction, }, execution::{ DeclarativeEnvironmentIndex, Environments, FunctionEnvironmentIndex, @@ -108,6 +108,7 @@ pub fn heap_gc(heap: &mut Heap, root_realms: &mut [Option]) { await_reactions, bigints, bound_functions, + builtin_constructors, builtin_functions, data_views, dates, @@ -378,6 +379,20 @@ pub fn heap_gc(heap: &mut Heap, root_realms: &mut [Option]) { source_codes.get(index).mark_values(&mut queues); } }); + let mut builtin_constructors_marks: Box<[BuiltinConstructorFunction]> = + queues.builtin_constructors.drain(..).collect(); + builtin_constructors_marks.sort(); + builtin_constructors_marks.iter().for_each(|&idx| { + let index = idx.get_index(); + if let Some(marked) = bits.builtin_constructors.get_mut(index) { + if *marked { + // Already marked, ignore + return; + } + *marked = true; + builtin_constructors.get(index).mark_values(&mut queues); + } + }); let mut builtin_functions_marks: Box<[BuiltinFunction]> = queues.builtin_functions.drain(..).collect(); builtin_functions_marks.sort(); @@ -901,6 +916,7 @@ fn sweep(heap: &mut Heap, bits: &HeapBits, root_realms: &mut [Option; pub type BigIntIndex = BaseIndex; pub type BoundFunctionIndex = BaseIndex; pub type BuiltinFunctionIndex = BaseIndex; +pub type BuiltinConstructorIndex = BaseIndex; pub type DataViewIndex = BaseIndex; pub type DateIndex = BaseIndex; pub type ECMAScriptFunctionIndex = BaseIndex; From 1b25c06fdf7a6df162db0eedcabb84954a10835b Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Mon, 30 Sep 2024 00:03:38 +0300 Subject: [PATCH 2/7] feat(ecmascript): Implement builtin class constructor building and super class constructing --- nova_vm/src/ecmascript/builtins.rs | 1 + .../builtins/builtin_constructor.rs | 239 +++++++++--------- .../builtins/ecmascript_function.rs | 63 +++-- .../function_objects/function_prototype.rs | 4 +- .../object_objects/object_constructor.rs | 1 + .../src/ecmascript/execution/environments.rs | 6 +- .../environments/function_environment.rs | 4 +- .../class_definitions.rs | 32 +-- .../src/ecmascript/types/language/function.rs | 2 +- .../types/language/function/data.rs | 25 +- nova_vm/src/engine/bytecode/executable.rs | 42 +-- nova_vm/src/engine/bytecode/instructions.rs | 6 + nova_vm/src/engine/bytecode/vm.rs | 98 ++++--- 13 files changed, 294 insertions(+), 229 deletions(-) diff --git a/nova_vm/src/ecmascript/builtins.rs b/nova_vm/src/ecmascript/builtins.rs index d6dd96e38..a05759160 100644 --- a/nova_vm/src/ecmascript/builtins.rs +++ b/nova_vm/src/ecmascript/builtins.rs @@ -51,6 +51,7 @@ pub(crate) use array::{ArrayHeapData, SealableElementsVector}; pub use array_buffer::ArrayBuffer; pub(crate) use array_buffer::ArrayBufferHeapData; pub use builtin_constructor::BuiltinConstructorFunction; +pub(crate) use builtin_constructor::{create_builtin_constructor, BuiltinConstructorArgs}; pub use builtin_function::{ create_builtin_function, ArgumentsList, Behaviour, Builtin, BuiltinFunction, BuiltinFunctionArgs, BuiltinGetter, ConstructorFn, RegularFn as JsFunction, RegularFn, diff --git a/nova_vm/src/ecmascript/builtins/builtin_constructor.rs b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs index 3045c8855..5c720daca 100644 --- a/nova_vm/src/ecmascript/builtins/builtin_constructor.rs +++ b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs @@ -6,8 +6,9 @@ use std::ops::{Index, IndexMut}; use crate::{ ecmascript::{ - execution::{ - Agent, ExecutionContext, JsResult, ProtoIntrinsics, + execution::{agent::ExceptionType, Agent, ExecutionContext, JsResult, ProtoIntrinsics}, + syntax_directed_operations::class_definitions::{ + base_class_default_constructor, derived_class_default_constructor, }, types::{ function_create_backing_object, function_internal_define_own_property, @@ -16,10 +17,12 @@ use crate::{ function_internal_set, BuiltinConstructorHeapData, Function, FunctionInternalProperties, InternalMethods, InternalSlots, IntoFunction, IntoObject, IntoValue, Object, OrdinaryObject, PropertyDescriptor, PropertyKey, String, Value, + BUILTIN_STRING_MEMORY, }, }, heap::{ - indexes::BuiltinConstructorIndex, CompactionLists, CreateHeapData, Heap, HeapMarkAndSweep, WorkQueues, + indexes::BuiltinConstructorIndex, CompactionLists, CreateHeapData, Heap, HeapMarkAndSweep, + ObjectEntry, ObjectEntryPropertyDescriptor, WorkQueues, }, }; @@ -119,12 +122,12 @@ impl IndexMut for Vec String { - agent[self].initial_name.unwrap_or(String::EMPTY_STRING) + fn get_name(self, _: &Agent) -> String { + unreachable!(); } - fn get_length(self, agent: &Agent) -> u8 { - agent[self].length + fn get_length(self, _: &Agent) -> u8 { + unreachable!(); } } @@ -201,14 +204,13 @@ impl InternalMethods for BuiltinConstructorFunction { /// (a List of ECMAScript language values) and returns either a normal /// completion containing an ECMAScript language value or a throw /// completion. - fn internal_call( - self, - agent: &mut Agent, - this_argument: Value, - arguments_list: ArgumentsList, - ) -> JsResult { + fn internal_call(self, agent: &mut Agent, _: Value, _: ArgumentsList) -> JsResult { // 1. Return ? BuiltinCallOrConstruct(F, thisArgument, argumentsList, undefined). - builtin_call_or_construct(agent, self, Some(this_argument), arguments_list, None) + // ii. If NewTarget is undefined, throw a TypeError exception. + Err(agent.throw_exception_with_static_message( + ExceptionType::TypeError, + "class constructors must be invoked with 'new'", + )) } /// ### [10.3.2 \[\[Construct\]\] ( argumentsList, newTarget )](https://tc39.es/ecma262/#sec-built-in-function-objects-construct-argumentslist-newtarget) @@ -224,8 +226,7 @@ impl InternalMethods for BuiltinConstructorFunction { new_target: Function, ) -> JsResult { // 1. Return ? BuiltinCallOrConstruct(F, uninitialized, argumentsList, newTarget). - builtin_call_or_construct(agent, self, None, arguments_list, Some(new_target)) - .map(|result| result.try_into().unwrap()) + builtin_call_or_construct(agent, self, arguments_list, new_target) } } @@ -236,13 +237,12 @@ impl InternalMethods for BuiltinConstructorFunction { /// uninitialized), argumentsList (a List of ECMAScript language values), and /// newTarget (a constructor or undefined) and returns either a normal /// completion containing an ECMAScript language value or a throw completion. -pub(crate) fn builtin_call_or_construct( +fn builtin_call_or_construct( agent: &mut Agent, f: BuiltinConstructorFunction, - this_argument: Option, arguments_list: ArgumentsList, - new_target: Option, -) -> JsResult { + new_target: Function, +) -> JsResult { // 1. Let callerContext be the running execution context. let caller_context = agent.running_execution_context(); // 2. If callerContext is not already suspended, suspend callerContext. @@ -263,7 +263,7 @@ pub(crate) fn builtin_call_or_construct( // 8. Perform any necessary implementation-defined initialization of calleeContext. ecmascript_code: None, // 4. Set the Function of calleeContext to F. - function: Some(f.into()), + function: Some(f.into_function()), // 6. Set the Realm of calleeContext to calleeRealm. realm: callee_realm, // 7. Set the ScriptOrModule of calleeContext to null. @@ -274,13 +274,11 @@ pub(crate) fn builtin_call_or_construct( // 10. Let result be the Completion Record that is the result of evaluating F in a manner that conforms to // the specification of F. If thisArgument is uninitialized, the this value is uninitialized; otherwise, // thisArgument provides the this value. argumentsList provides the named parameters. newTarget provides the NewTarget value. - let func = heap_data.behaviour; - let result = func( - agent, - this_argument.unwrap_or(Value::Undefined), - arguments_list, - new_target.map(|target| target.into_object()), - ); + let result = if heap_data.is_derived { + derived_class_default_constructor(agent, arguments_list, new_target.into_object()) + } else { + base_class_default_constructor(agent, new_target.into_object()) + }; // 11. NOTE: If F is defined in this document, “the specification of F” is the behaviour specified for it via // algorithm steps or other means. // 12. Remove calleeContext from the execution context stack and restore callerContext as the running @@ -293,6 +291,14 @@ pub(crate) fn builtin_call_or_construct( result } +pub(crate) struct BuiltinConstructorArgs { + pub(crate) is_derived: bool, + pub(crate) length: u8, + pub(crate) initial_name: String, + pub(crate) prototype: Option, + pub(crate) prototype_property: Object, +} + /// ### [10.3.4 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList \[ , realm \[ , prototype \[ , prefix \] \] \] )](https://tc39.es/ecma262/#sec-createbuiltinfunction) /// /// The abstract operation CreateBuiltinFunction takes arguments behaviour (an @@ -305,97 +311,74 @@ pub(crate) fn builtin_call_or_construct( /// additionalInternalSlotsList contains the names of additional internal slots /// that must be defined as part of the object. This operation creates a /// built-in function object. -// pub fn create_builtin_function( -// agent: &mut Agent, -// behaviour: Behaviour, -// args: BuiltinFunctionArgs, -// ) -> BuiltinFunction { -// // 1. If realm is not present, set realm to the current Realm Record. -// let realm = args.realm.unwrap_or(agent.current_realm_id()); - -// // 9. Set func.[[InitialName]] to null. -// // Note: SetFunctionName inlined here: We know name is a string -// let initial_name = if let Some(prefix) = args.prefix { -// // 12. Else, -// // a. Perform SetFunctionName(func, name, prefix). -// String::from_string(agent, format!("{} {}", args.name, prefix)) -// } else { -// // 11. If prefix is not present, then -// // a. Perform SetFunctionName(func, name). -// String::from_str(agent, args.name) -// }; - -// // 2. If prototype is not present, set prototype to realm.[[Intrinsics]].[[%Function.prototype%]]. - -// // 3. Let internalSlotsList be a List containing the names of all the internal slots that 10.3 -// // requires for the built-in function object that is about to be created. -// // 4. Append to internalSlotsList the elements of additionalInternalSlotsList. -// // Note: The BuiltinConstructorHeapData implements all internal slots that 10.3 requires. -// // The currently appearing spec-defined additional slots are: -// // * [[ConstructorKind]] and [[SourceText]] for class constructors. -// // * [[Promise]] and [[AlreadyResolved]] for Promise resolver functions -// // * [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], and [[RemainingElements]] for -// // Promise.all's onFulfilled function. -// // We do not yet support these, and how these end up supported is not yet fully clear. - -// // 5. Let func be a new built-in function object that, when called, performs the action -// // described by behaviour using the provided arguments as the values of the corresponding -// // parameters specified by behaviour. The new function object has internal slots whose names -// // are the elements of internalSlotsList, and an [[InitialName]] internal slot. -// let object_index = if let Some(prototype) = args.prototype { -// // If a prototype is set, then check that it is not the %Function.prototype% -// let realm_function_prototype = agent -// .get_realm(realm) -// .intrinsics() -// .get_intrinsic_default_proto(BuiltinConstructorFunction::DEFAULT_PROTOTYPE); -// if prototype == realm_function_prototype { -// // If the prototype matched the realm function prototype, then ignore it -// // as the BuiltinConstructorHeapData indirectly implies this prototype. -// None -// } else { -// // If some other prototype is defined then we need to create a backing object. -// // 6. Set func.[[Prototype]] to prototype. -// // 7. Set func.[[Extensible]] to true. -// let length_entry = ObjectEntry { -// key: PropertyKey::from(BUILTIN_STRING_MEMORY.length), -// value: ObjectEntryPropertyDescriptor::Data { -// value: args.length.into(), -// writable: false, -// enumerable: false, -// configurable: true, -// }, -// }; -// let name_entry = ObjectEntry { -// key: PropertyKey::from(BUILTIN_STRING_MEMORY.name), -// value: ObjectEntryPropertyDescriptor::Data { -// value: initial_name.into_value(), -// writable: false, -// enumerable: false, -// configurable: true, -// }, -// }; -// Some( -// agent -// .heap -// .create_object_with_prototype(prototype, &[length_entry, name_entry]), -// ) -// } -// } else { -// None -// }; - -// // 13. Return func. -// agent.heap.create(BuiltinConstructorHeapData { -// behaviour, -// initial_name: Some(initial_name), -// // 10. Perform SetFunctionLength(func, length). -// length: args.length as u8, -// // 8. Set func.[[Realm]] to realm. -// realm, -// object_index, -// compiled_initializer_bytecode: None, -// }) -// } +pub(crate) fn create_builtin_constructor( + agent: &mut Agent, + args: BuiltinConstructorArgs, +) -> BuiltinConstructorFunction { + // 1. If realm is not present, set realm to the current Realm Record. + let realm = agent.current_realm_id(); + + // 9. Set func.[[InitialName]] to null. + + // 2. If prototype is not present, set prototype to realm.[[Intrinsics]].[[%Function.prototype%]]. + + // 3. Let internalSlotsList be a List containing the names of all the internal slots that 10.3 + // requires for the built-in function object that is about to be created. + // 4. Append to internalSlotsList the elements of additionalInternalSlotsList. + // * [[ConstructorKind]] and [[SourceText]] for class constructors. + + // 5. Let func be a new built-in function object that, when called, performs the action + // described by behaviour using the provided arguments as the values of the corresponding + // parameters specified by behaviour. The new function object has internal slots whose names + // are the elements of internalSlotsList, and an [[InitialName]] internal slot. + + // 7. Set func.[[Extensible]] to true. + let length_entry = ObjectEntry { + key: PropertyKey::from(BUILTIN_STRING_MEMORY.length), + value: ObjectEntryPropertyDescriptor::Data { + value: args.length.into(), + writable: false, + enumerable: false, + configurable: true, + }, + }; + let name_entry = ObjectEntry { + key: PropertyKey::from(BUILTIN_STRING_MEMORY.name), + value: ObjectEntryPropertyDescriptor::Data { + value: args.initial_name.into_value(), + writable: false, + enumerable: false, + configurable: true, + }, + }; + let prototype_entry = ObjectEntry { + key: PropertyKey::from(BUILTIN_STRING_MEMORY.prototype), + value: ObjectEntryPropertyDescriptor::Data { + value: args.prototype_property.into_value(), + writable: false, + enumerable: false, + configurable: false, + }, + }; + let entries = [length_entry, name_entry, prototype_entry]; + let backing_object = if let Some(prototype) = args.prototype { + agent.heap.create_object_with_prototype(prototype, &entries) + } else { + agent.heap.create_null_object(&entries) + }; + + // 13. Return func. + agent.heap.create(BuiltinConstructorHeapData { + // 10. Perform SetFunctionLength(func, length). + length: args.length, + // 8. Set func.[[Realm]] to realm. + realm, + compiled_initializer_bytecode: None, + is_derived: args.is_derived, + object_index: Some(backing_object), + class_span: (), + }) +} impl CreateHeapData for Heap { fn create(&mut self, data: BuiltinConstructorHeapData) -> BuiltinConstructorFunction { @@ -417,13 +400,27 @@ impl HeapMarkAndSweep for BuiltinConstructorFunction { impl HeapMarkAndSweep for BuiltinConstructorHeapData { fn mark_values(&self, queues: &mut WorkQueues) { self.realm.mark_values(queues); - self.initial_name.mark_values(queues); self.object_index.mark_values(queues); + if let Some(exe) = &self.compiled_initializer_bytecode { + // SAFETY: This is a valid, non-null pointer to an owned Executable + // that cannot have any live mutable references to it. + unsafe { exe.as_ref() }.mark_values(queues); + } } fn sweep_values(&mut self, compactions: &CompactionLists) { self.realm.sweep_values(compactions); - self.initial_name.sweep_values(compactions); self.object_index.sweep_values(compactions); + if let Some(exe) = &mut self.compiled_initializer_bytecode { + // SAFETY: This is a valid, non-null pointer to an owned Executable + // that cannot have any live references to it. + // References to this Executable are only created above for marking + // and in function_definition for running the function. Both of the + // references only live for the duration of a synchronous call and + // no longer. Sweeping cannot run concurrently with marking or with + // ECMAScript code execution. Hence we can be sure that this is not + // an aliasing violation. + unsafe { exe.as_mut() }.sweep_values(compactions); + } } } diff --git a/nova_vm/src/ecmascript/builtins/ecmascript_function.rs b/nova_vm/src/ecmascript/builtins/ecmascript_function.rs index 1d666bb5d..26bb4e4b2 100644 --- a/nova_vm/src/ecmascript/builtins/ecmascript_function.rs +++ b/nova_vm/src/ecmascript/builtins/ecmascript_function.rs @@ -24,8 +24,8 @@ use crate::{ ExceptionType::{self, SyntaxError}, }, new_function_environment, Agent, ECMAScriptCodeEvaluationState, EnvironmentIndex, - ExecutionContext, JsResult, PrivateEnvironmentIndex, ProtoIntrinsics, RealmIdentifier, - ThisBindingStatus, + ExecutionContext, FunctionEnvironmentIndex, JsResult, PrivateEnvironmentIndex, + ProtoIntrinsics, RealmIdentifier, ThisBindingStatus, }, scripts_and_modules::{source_code::SourceCode, ScriptOrModule}, syntax_directed_operations::function_definitions::{ @@ -436,7 +436,9 @@ impl InternalMethods for ECMAScriptFunction { return Err(error); } // 5. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument). - // Note: We pass in the localEnv directly to avoid borrow issues. + let EnvironmentIndex::Function(local_env) = local_env else { + panic!("localEnv is not a Function Environment Record"); + }; ordinary_call_bind_this(agent, self, local_env, this_argument); // 6. Let result be Completion(OrdinaryCallEvaluateBody(F, argumentsList)). let result = ordinary_call_evaluate_body(agent, self, arguments_list); @@ -480,6 +482,9 @@ impl InternalMethods for ECMAScriptFunction { .as_ref() .unwrap() .lexical_environment; + let EnvironmentIndex::Function(constructor_env) = constructor_env else { + panic!("constructorEnv is not a Function Environment Record"); + }; // 5. Assert: calleeContext is now the running execution context. // assert!(std::ptr::eq(agent.running_execution_context(), callee_context)); @@ -494,14 +499,16 @@ impl InternalMethods for ECMAScriptFunction { ); // b. Let initializeResult be Completion(InitializeInstanceElements(thisArgument, F)). // c. If initializeResult is an abrupt completion, then - // i. Remove calleeContext from the execution context stack and restore callerContext as the running execution context. + // i. Remove calleeContext from the execution context stack and + // restore callerContext as the running execution context. // ii. Return ? initializeResult. // TODO: Classes. } // 8. Let result be Completion(OrdinaryCallEvaluateBody(F, argumentsList)). let result = ordinary_call_evaluate_body(agent, self, arguments_list); - // 9. Remove calleeContext from the execution context stack and restore callerContext as the running execution context. + // 9. Remove calleeContext from the execution context stack and restore + // callerContext as the running execution context. agent.execution_context_stack.pop(); // 10. If result is a return completion, then // 11. Else, @@ -510,17 +517,31 @@ impl InternalMethods for ECMAScriptFunction { // 10. If result is a return completion, then // a. If result.[[Value]] is an Object, return result.[[Value]]. if let Ok(value) = Object::try_from(value) { - return Ok(value); - } + Ok(value) + } else // b. If kind is base, return thisArgument. if is_base { - return Ok(this_argument.unwrap()); - } - todo!("Derived classes"); + Ok(this_argument.unwrap()) + } else // c. If result.[[Value]] is not undefined, throw a TypeError exception. - // 12. Let thisBinding be ? constructorEnv.GetThisBinding(). - // 13. Assert: thisBinding is an Object. - // 14. Return thisBinding. + if !value.is_undefined() { + let message = format!( + "derived class constructor returned invalid value {}", + value.string_repr(agent).as_str(agent) + ); + let message = String::from_string(agent, message); + Err(agent.throw_exception_with_message(ExceptionType::TypeError, message)) + } else { + // 12. Let thisBinding be ? constructorEnv.GetThisBinding(). + // 13. Assert: thisBinding is an Object. + let Ok(this_binding) = Object::try_from(constructor_env.get_this_binding(agent)?) + else { + unreachable!(); + }; + + // 14. Return thisBinding. + Ok(this_binding) + } } } @@ -583,7 +604,7 @@ pub(crate) fn prepare_for_ordinary_call( pub(crate) fn ordinary_call_bind_this( agent: &mut Agent, f: ECMAScriptFunction, - local_env: EnvironmentIndex, + local_env: FunctionEnvironmentIndex, this_argument: Value, ) { let function_heap_data = &agent[f].ecmascript_function; @@ -618,9 +639,6 @@ pub(crate) fn ordinary_call_bind_this( } }; // 7. Assert: localEnv is a Function Environment Record. - let EnvironmentIndex::Function(local_env) = local_env else { - panic!("localEnv is not a Function Environment Record"); - }; // 8. Assert: The next step never returns an abrupt completion because localEnv.[[ThisBindingStatus]] is not INITIALIZED. assert_ne!( local_env.get_this_binding_status(agent), @@ -851,8 +869,6 @@ pub(crate) fn make_constructor( // a. Assert: IsConstructor(F) is false. debug_assert!(!data.ecmascript_function.constructor_status.is_constructor()); // b. Assert: F is an extensible object that does not have a "prototype" own property. - // TODO: Handle Some() object indexes? - assert!(data.object_index.is_none()); // c. Set F.[[Construct]] to the definition specified in 10.2.2. // 3. Set F.[[ConstructorKind]] to BASE. data.ecmascript_function.constructor_status = ConstructorStatus::ConstructorFunction; @@ -862,7 +878,7 @@ pub(crate) fn make_constructor( // a. Set F.[[Construct]] to the definition specified in 10.3.2. } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction(_) => todo!(), + Function::BuiltinConstructorFunction(_) => unreachable!(), Function::BuiltinPromiseResolvingFunction(_) => todo!(), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -965,18 +981,17 @@ pub(crate) fn set_function_name( assert!(function.name.is_none()); function.name = Some(name); } - Function::BuiltinFunction(_idx) => todo!(), + Function::BuiltinFunction(_idx) => unreachable!(), Function::ECMAScriptFunction(idx) => { let function = &mut agent[idx]; // 1. Assert: F is an extensible object that does not have a "name" own property. - // TODO: Also potentially allow running this function with Some() object index if needed. - assert!(function.object_index.is_none() && function.name.is_none()); + assert!(function.name.is_none()); // 6. Perform ! DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }). function.name = Some(name); // 7. Return UNUSED. } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction(_) => todo!(), + Function::BuiltinConstructorFunction(_) => unreachable!(), Function::BuiltinPromiseResolvingFunction(_) => todo!(), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), 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 a4befcece..91c1c3aa6 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 @@ -281,7 +281,9 @@ impl FunctionPrototype { Ok(Value::from_string(agent, initial_name)) } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction(_) => todo!(), + Function::BuiltinConstructorFunction(_) => { + Ok(Value::from_static_str(agent, "class { [ native code ] }")) + } Function::BuiltinPromiseResolvingFunction(_) => { // Promise resolving functions have no initial name. Ok(Value::from_static_str( diff --git a/nova_vm/src/ecmascript/builtins/fundamental_objects/object_objects/object_constructor.rs b/nova_vm/src/ecmascript/builtins/fundamental_objects/object_objects/object_constructor.rs index 9bbfe0503..cf76746e8 100644 --- a/nova_vm/src/ecmascript/builtins/fundamental_objects/object_objects/object_constructor.rs +++ b/nova_vm/src/ecmascript/builtins/fundamental_objects/object_objects/object_constructor.rs @@ -706,6 +706,7 @@ impl ObjectConstructor { /// ### [20.1.2.19 Object.keys ( O )](https://tc39.es/ecma262/#sec-object.keys) fn keys(agent: &mut Agent, _: Value, arguments: ArgumentsList) -> JsResult { let o = arguments.get(0); + println!("key target: {:?}", o); // 1. Let obj be ? ToObject(O). let obj = to_object(agent, o)?; // 2. Let keyList be ? EnumerableOwnProperties(obj, KEY). diff --git a/nova_vm/src/ecmascript/execution/environments.rs b/nova_vm/src/ecmascript/execution/environments.rs index 97088154a..317cff367 100644 --- a/nova_vm/src/ecmascript/execution/environments.rs +++ b/nova_vm/src/ecmascript/execution/environments.rs @@ -377,10 +377,10 @@ impl EnvironmentIndex { /// true if it does and false if it does not. pub(crate) fn has_this_binding(self, agent: &mut Agent) -> bool { match self { - EnvironmentIndex::Declarative(idx) => idx.has_this_binding(), + EnvironmentIndex::Declarative(_) => false, EnvironmentIndex::Function(idx) => idx.has_this_binding(agent), - EnvironmentIndex::Global(idx) => idx.has_this_binding(), - EnvironmentIndex::Object(idx) => idx.has_this_binding(), + EnvironmentIndex::Global(_) => true, + EnvironmentIndex::Object(_) => false, } } diff --git a/nova_vm/src/ecmascript/execution/environments/function_environment.rs b/nova_vm/src/ecmascript/execution/environments/function_environment.rs index 0b6668000..38f348c1d 100644 --- a/nova_vm/src/ecmascript/execution/environments/function_environment.rs +++ b/nova_vm/src/ecmascript/execution/environments/function_environment.rs @@ -376,7 +376,7 @@ impl FunctionEnvironmentIndex { agent[func].ecmascript_function.home_object.is_some() } Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction(_) => todo!(), + Function::BuiltinConstructorFunction(_) => unreachable!(), Function::BuiltinPromiseResolvingFunction(_) => unreachable!(), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), @@ -397,7 +397,7 @@ impl FunctionEnvironmentIndex { Function::BuiltinFunction(_) => unreachable!(), Function::ECMAScriptFunction(func) => agent[func].ecmascript_function.home_object, Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction(_) => todo!(), + Function::BuiltinConstructorFunction(_) => unreachable!(), Function::BuiltinPromiseResolvingFunction(_) => unreachable!(), Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), diff --git a/nova_vm/src/ecmascript/syntax_directed_operations/class_definitions.rs b/nova_vm/src/ecmascript/syntax_directed_operations/class_definitions.rs index 004d88f06..311e12398 100644 --- a/nova_vm/src/ecmascript/syntax_directed_operations/class_definitions.rs +++ b/nova_vm/src/ecmascript/syntax_directed_operations/class_definitions.rs @@ -8,22 +8,15 @@ use crate::ecmascript::{ }, builtins::{ordinary::ordinary_create_from_constructor, ArgumentsList}, execution::{agent::ExceptionType, Agent, JsResult, ProtoIntrinsics}, - types::{Function, InternalMethods, Object, Value}, + types::{Function, InternalMethods, Object}, }; pub(crate) fn base_class_default_constructor( agent: &mut Agent, - _this_value: Value, - _: ArgumentsList, - new_target: Option, -) -> JsResult { + new_target: Object, +) -> JsResult { // ii. If NewTarget is undefined, throw a TypeError exception. - let Some(new_target) = new_target else { - return Err(agent.throw_exception_with_static_message( - ExceptionType::TypeError, - "class constructors must be invoked with 'new'", - )); - }; + // Note: We've already checked this at an earlier level. // iii. Let F be the active function object. // let f = agent.running_execution_context().function.unwrap(); @@ -41,23 +34,18 @@ pub(crate) fn base_class_default_constructor( // TODO: Handle InitializeInstanceElements somehow. // vii. Return result. - Ok(result.into_value()) + Ok(result) } pub(crate) fn derived_class_default_constructor( agent: &mut Agent, - _this_value: Value, args: ArgumentsList, - new_target: Option, -) -> JsResult { + new_target: Object, +) -> JsResult { // i. Let args be the List of arguments that was passed to this function by [[Call]] or [[Construct]]. // ii. If NewTarget is undefined, throw a TypeError exception. - let Some(new_target) = new_target else { - return Err(agent.throw_exception_with_static_message( - ExceptionType::TypeError, - "class constructors must be invoked with 'new'", - )); - }; + // Note: We've already checked this at an earlier level. + // iii. Let F be the active function object. let f = agent.running_execution_context().function.unwrap(); @@ -87,5 +75,5 @@ pub(crate) fn derived_class_default_constructor( // TODO: Handle InitializeInstanceElements somehow. // vii. Return result. - Ok(result.into_value()) + Ok(result) } diff --git a/nova_vm/src/ecmascript/types/language/function.rs b/nova_vm/src/ecmascript/types/language/function.rs index 625306fa2..7d4d3f813 100644 --- a/nova_vm/src/ecmascript/types/language/function.rs +++ b/nova_vm/src/ecmascript/types/language/function.rs @@ -184,7 +184,7 @@ impl Function { Function::ECMAScriptFunction(f) => f.is_constructor(agent), Function::BuiltinPromiseResolvingFunction(_) => false, Function::BuiltinGeneratorFunction => todo!(), - Function::BuiltinConstructorFunction(_) => false, + Function::BuiltinConstructorFunction(_) => true, Function::BuiltinPromiseCollectorFunction => todo!(), Function::BuiltinProxyRevokerFunction => todo!(), } diff --git a/nova_vm/src/ecmascript/types/language/function/data.rs b/nova_vm/src/ecmascript/types/language/function/data.rs index 62d832638..71bafbb19 100644 --- a/nova_vm/src/ecmascript/types/language/function/data.rs +++ b/nova_vm/src/ecmascript/types/language/function/data.rs @@ -6,7 +6,7 @@ use std::ptr::NonNull; use crate::{ ecmascript::{ - builtins::{Behaviour, ConstructorFn, ECMAScriptFunctionObjectHeapData}, + builtins::{Behaviour, ECMAScriptFunctionObjectHeapData}, execution::RealmIdentifier, types::{OrdinaryObject, String, Value}, }, @@ -55,16 +55,19 @@ pub struct BuiltinFunctionHeapData { #[derive(Debug, Clone)] pub struct BuiltinConstructorHeapData { pub(crate) object_index: Option, + /// Note: If we decide to always create a backing object for builtin + /// constructors, then we can maybe drop this. pub(crate) length: u8, /// #### \[\[Realm]] /// A Realm Record that represents the realm in which the function was /// created. pub(crate) realm: RealmIdentifier, - /// #### \[\[InitialName]] - /// A String that is the initial name of the function. It is used by - /// 20.2.3.5 (`Function.prototype.toString()`). - pub(crate) initial_name: Option, - pub(crate) behaviour: ConstructorFn, + pub(crate) class_span: (), + /// ### \[\[ConstructorKind]] + /// + /// If the boolean is `true` then ConstructorKind is Derived, else it is + /// Base. + pub(crate) is_derived: bool, /// Stores the compiled bytecode of class field initializers. pub(crate) compiled_initializer_bytecode: Option>, } @@ -73,6 +76,16 @@ pub struct BuiltinConstructorHeapData { // foreign threads. unsafe impl Send for BuiltinConstructorHeapData {} +impl Drop for BuiltinConstructorHeapData { + fn drop(&mut self) { + if let Some(exe) = self.compiled_initializer_bytecode.take() { + // SAFETY: No references to this compiled bytecode should exist as + // otherwise we should not have been garbage collected. + drop(unsafe { Box::from_raw(exe.as_ptr()) }); + } + } +} + #[derive(Debug)] pub struct ECMAScriptFunctionHeapData { pub(crate) object_index: Option, diff --git a/nova_vm/src/engine/bytecode/executable.rs b/nova_vm/src/engine/bytecode/executable.rs index ed80b9484..6c789a1e9 100644 --- a/nova_vm/src/engine/bytecode/executable.rs +++ b/nova_vm/src/engine/bytecode/executable.rs @@ -1381,21 +1381,27 @@ impl CompileEvaluation for CallExpression<'_> { // 1. Let ref be ? Evaluation of CallExpression. ctx.is_call_optional_chain_this = is_chain_expression(&self.callee); - self.callee.compile(ctx); - // 2. Let func be ? GetValue(ref). - let need_pop_reference = if is_reference(&self.callee) { - ctx.add_instruction(Instruction::GetValueKeepReference); - // Optimization: If we know arguments is empty, we don't need to - // worry about arguments evaluation clobbering our function's this - // reference. - if !self.arguments.is_empty() { - ctx.add_instruction(Instruction::PushReference); - true + let is_super_call = matches!(self.callee, ast::Expression::Super(_)); + let need_pop_reference = if is_super_call { + // Note: There is nothing to do with super calls here. + false + } else { + self.callee.compile(ctx); + if is_reference(&self.callee) { + // 2. Let func be ? GetValue(ref). + ctx.add_instruction(Instruction::GetValueKeepReference); + // Optimization: If we know arguments is empty, we don't need to + // worry about arguments evaluation clobbering our function's this + // reference. + if !self.arguments.is_empty() { + ctx.add_instruction(Instruction::PushReference); + true + } else { + false + } } else { false } - } else { - false }; if self.optional { @@ -1426,7 +1432,7 @@ impl CompileEvaluation for CallExpression<'_> { }; // Register our jump slot to the chain nullish case handling. ctx.optional_chains.as_mut().unwrap().push(jump_over_call); - } else { + } else if !is_super_call { ctx.add_instruction(Instruction::Load); } // If we're in an optional chain, we need to pluck it out while we're @@ -1438,10 +1444,14 @@ impl CompileEvaluation for CallExpression<'_> { ctx.optional_chains.replace(optional_chain); } - if need_pop_reference { - ctx.add_instruction(Instruction::PopReference); + if is_super_call { + ctx.add_instruction_with_immediate(Instruction::EvaluateSuper, num_arguments); + } else { + if need_pop_reference { + ctx.add_instruction(Instruction::PopReference); + } + ctx.add_instruction_with_immediate(Instruction::EvaluateCall, num_arguments); } - ctx.add_instruction_with_immediate(Instruction::EvaluateCall, num_arguments); } } diff --git a/nova_vm/src/engine/bytecode/instructions.rs b/nova_vm/src/engine/bytecode/instructions.rs index e7b5dcb36..8af45c53c 100644 --- a/nova_vm/src/engine/bytecode/instructions.rs +++ b/nova_vm/src/engine/bytecode/instructions.rs @@ -72,6 +72,11 @@ pub enum Instruction { /// stack afterwards is the constructor to /// call. EvaluateNew, + /// Store SuperCall() as the result value. + /// + /// This instruction has the number of argumnet values that need to be + /// popped from the stack (last to first) as an argument. + EvaluateSuper, /// Store EvaluatePropertyAccessWithExpressionKey() as the result value. EvaluatePropertyAccessWithExpressionKey, /// Store EvaluatePropertyAccessWithIdentifierKey() as the result value. @@ -377,6 +382,7 @@ impl Instruction { | Self::DirectEvalCall | Self::EvaluateCall | Self::EvaluateNew + | Self::EvaluateSuper | Self::EvaluatePropertyAccessWithIdentifierKey | Self::InstantiateArrowFunctionExpression | Self::InstantiateOrdinaryFunctionExpression diff --git a/nova_vm/src/engine/bytecode/vm.rs b/nova_vm/src/engine/bytecode/vm.rs index f6dd69b9e..97c49013b 100644 --- a/nova_vm/src/engine/bytecode/vm.rs +++ b/nova_vm/src/engine/bytecode/vm.rs @@ -27,11 +27,11 @@ use crate::{ }, }, builtins::{ - array_create, create_builtin_function, create_unmapped_arguments_object, + array_create, create_builtin_constructor, create_unmapped_arguments_object, global_object::perform_eval, make_constructor, make_method, ordinary::ordinary_object_create_with_intrinsics, ordinary_function_create, - set_function_name, ArgumentsList, Array, Behaviour, BuiltinFunctionArgs, - ConstructorStatus, OrdinaryFunctionCreateParams, + set_function_name, ArgumentsList, Array, BuiltinConstructorArgs, ConstructorStatus, + OrdinaryFunctionCreateParams, }, execution::{ agent::{resolve_binding, ExceptionType, JsError}, @@ -39,9 +39,6 @@ use crate::{ new_declarative_environment, Agent, ECMAScriptCodeEvaluationState, EnvironmentIndex, JsResult, ProtoIntrinsics, }, - syntax_directed_operations::class_definitions::{ - base_class_default_constructor, derived_class_default_constructor, - }, types::{ get_this_value, get_value, initialize_referenced_binding, is_private_reference, is_super_reference, put_value, Base, BigInt, Function, InternalMethods, IntoFunction, @@ -982,27 +979,26 @@ impl Vm { let function_prototype = if has_constructor_parent { Some(Object::try_from(vm.stack.pop().unwrap()).unwrap()) } else { - None + Some( + agent + .current_realm() + .intrinsics() + .function_prototype() + .into_object(), + ) }; let proto = Object::try_from(*vm.stack.last().unwrap()).unwrap(); - let behaviour = if has_constructor_parent { - Behaviour::Constructor(derived_class_default_constructor) - } else { - Behaviour::Constructor(base_class_default_constructor) - }; - let function = create_builtin_function( + let function = create_builtin_constructor( agent, - behaviour, - BuiltinFunctionArgs { + BuiltinConstructorArgs { + initial_name: class_name, + is_derived: has_constructor_parent, length: 0, - name: "", - realm: None, prototype: function_prototype, - prefix: None, + prototype_property: proto, }, ); - agent[function].initial_name = Some(class_name); proto .internal_define_own_property( @@ -1018,20 +1014,6 @@ impl Vm { ) .unwrap(); - function - .internal_define_own_property( - agent, - BUILTIN_STRING_MEMORY.prototype.into(), - PropertyDescriptor { - value: Some(proto.into_value()), - writable: Some(false), - enumerable: Some(false), - configurable: Some(false), - ..Default::default() - }, - ) - .unwrap(); - vm.result = Some(function.into_value()); } Instruction::Swap => { @@ -1118,6 +1100,56 @@ impl Vm { .map(|result| result.into_value())?, ); } + Instruction::EvaluateSuper => { + let EnvironmentIndex::Function(this_env) = get_this_environment(agent) else { + unreachable!(); + }; + // 1. Let newTarget be GetNewTarget(). + // 2. Assert: newTarget is an Object. + // 3. Let func be GetSuperConstructor(). + let (new_target, func) = { + let data = &agent[this_env]; + ( + Function::try_from(data.new_target.unwrap()).unwrap(), + data.function_object + .internal_get_prototype_of(agent) + .unwrap(), + ) + }; + // 4. Let argList be ? ArgumentListEvaluation of Arguments. + let arg_list = vm.get_call_args(instr); + // 5. If IsConstructor(func) is false, throw a TypeError exception. + let Some(func) = func.and_then(|func| is_constructor(agent, func)) else { + let error_message = format!( + "'{}' is not a constructor.", + func.map_or(Value::Null, |func| func.into_value()) + .string_repr(agent) + .as_str(agent) + ); + return Err(agent.throw_exception(ExceptionType::TypeError, error_message)); + }; + // 6. Let result be ? Construct(func, argList, newTarget). + let result = construct( + agent, + func, + Some(ArgumentsList(&arg_list)), + Some(new_target), + )?; + // 7. Let thisER be GetThisEnvironment(). + let EnvironmentIndex::Function(this_er) = get_this_environment(agent) else { + unreachable!(); + }; + // 8. Perform ? thisER.BindThisValue(result). + this_er.bind_this_value(agent, result.into_value())?; + // 9. Let F be thisER.[[FunctionObject]]. + // 10. Assert: F is an ECMAScript function object. + let Function::ECMAScriptFunction(_f) = agent[this_er].function_object else { + unreachable!(); + }; + // 11. Perform ? InitializeInstanceElements(result, F). + // 12. Return result. + vm.result = Some(result.into_value()); + } Instruction::EvaluatePropertyAccessWithExpressionKey => { let property_name_value = vm.result.take().unwrap(); let base_value = vm.stack.pop().unwrap(); From 12f4da2dd6862fab6bb70eb62665bc8562679e33 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Thu, 3 Oct 2024 23:08:14 +0300 Subject: [PATCH 3/7] Implement class field initializers --- .../operations_on_objects.rs | 71 ++++++++++++++++-- .../builtins/builtin_constructor.rs | 72 ++++++++++++++++--- nova_vm/src/ecmascript/execution.rs | 9 +-- nova_vm/src/ecmascript/execution/agent.rs | 9 +++ .../src/ecmascript/execution/environments.rs | 4 +- .../environments/function_environment.rs | 29 +++++++- .../class_definitions.rs | 15 ++-- .../types/language/function/data.rs | 25 +++++-- nova_vm/src/engine/bytecode/executable.rs | 4 ++ .../executable/class_definition_evaluation.rs | 72 ++++++++++--------- nova_vm/src/engine/bytecode/vm.rs | 32 +++++++-- 11 files changed, 271 insertions(+), 71 deletions(-) diff --git a/nova_vm/src/ecmascript/abstract_operations/operations_on_objects.rs b/nova_vm/src/ecmascript/abstract_operations/operations_on_objects.rs index 482b68e59..bedb6a7d7 100644 --- a/nova_vm/src/ecmascript/abstract_operations/operations_on_objects.rs +++ b/nova_vm/src/ecmascript/abstract_operations/operations_on_objects.rs @@ -17,15 +17,19 @@ use crate::{ builtins::{ array_create, keyed_collections::map_objects::map_prototype::canonicalize_keyed_collection_key, - ArgumentsList, Array, + ArgumentsList, Array, BuiltinConstructorFunction, + }, + execution::{ + agent::ExceptionType, new_class_field_initializer_environment, Agent, + ECMAScriptCodeEvaluationState, EnvironmentIndex, ExecutionContext, JsResult, + RealmIdentifier, }, - execution::{agent::ExceptionType, Agent, JsResult, RealmIdentifier}, types::{ - Function, InternalMethods, IntoObject, IntoValue, Number, Object, OrdinaryObject, - PropertyDescriptor, PropertyKey, String, Value, BUILTIN_STRING_MEMORY, + Function, InternalMethods, IntoFunction, IntoObject, IntoValue, Number, Object, + OrdinaryObject, PropertyDescriptor, PropertyKey, String, Value, BUILTIN_STRING_MEMORY, }, }, - engine::instanceof_operator, + engine::{instanceof_operator, Vm}, heap::{Heap, ObjectEntry}, SmallInteger, }; @@ -870,6 +874,63 @@ pub(crate) fn copy_data_properties_into_object( )) } +/// [7.3.33 InitializeInstanceElements ( O, constructor )](https://tc39.es/ecma262/#sec-initializeinstanceelements) +/// +/// The abstract operation InitializeInstanceElements takes arguments O (an +/// Object) and constructor (an ECMAScript function object) and returns either +/// a normal completion containing unused or a throw completion. +pub(crate) fn initialize_instance_elements( + agent: &mut Agent, + o: Object, + constructor: BuiltinConstructorFunction, +) -> JsResult<()> { + // 1. Let methods be the value of constructor.[[PrivateMethods]]. + // 2. For each PrivateElement method of methods, do + // a. Perform ? PrivateMethodOrAccessorAdd(O, method). + // TODO: Private properties and methods. + // 3. Let fields be the value of constructor.[[Fields]]. + // 4. For each element fieldRecord of fields, do + // a. Perform ? DefineField(O, fieldRecord). + // 5. Return unused. + let constructor_data = &agent[constructor]; + if let Some(bytecode) = constructor_data.compiled_initializer_bytecode { + // Note: The code here looks quite a bit different from what the spec + // says. For one, the spec is bugged and doesn't consider default + // constructors at all. Second, we compile field initializers into + // the ECMAScript class constructors directly, so our code only needs + // to work for builtin constructors. + // Third, the spec defines the initializers as individual functions + // run one after the other. Instea we compile all of the initializers + // into a single bytecode executable associated with the constructor. + // The problem then becomes how to run this executable as an ECMAScript + // function. + // To do this, we need a new execution context that points to a new + // Function environment. The function environment should be lexically a + // child of the class constructor's creating environment. + let bytecode = unsafe { bytecode.as_ref() }; + let f = constructor.into_function(); + let outer_env = constructor_data.environment; + let outer_priv_env = constructor_data.private_environment; + let source_code = constructor_data.source_code; + let decl_env = new_class_field_initializer_environment(agent, f, o, outer_env); + agent.execution_context_stack.push(ExecutionContext { + ecmascript_code: Some(ECMAScriptCodeEvaluationState { + lexical_environment: EnvironmentIndex::Function(decl_env), + variable_environment: EnvironmentIndex::Function(decl_env), + private_environment: outer_priv_env, + is_strict_mode: true, + source_code, + }), + function: Some(f), + realm: agent[constructor].realm, + script_or_module: None, + }); + let _ = Vm::execute(agent, bytecode, None).into_js_result()?; + agent.execution_context_stack.pop(); + } + Ok(()) +} + /// ### [7.3.34 AddValueToKeyedGroup ( groups, key, value )](https://tc39.es/ecma262/#sec-add-value-to-keyed-group) /// The abstract operation AddValueToKeyedGroup takes arguments groups (a List of Records with fields /// [[Key]] (an ECMAScript language value) and [[Elements]] (a List of ECMAScript language values)), diff --git a/nova_vm/src/ecmascript/builtins/builtin_constructor.rs b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs index 5c720daca..83e40bf0f 100644 --- a/nova_vm/src/ecmascript/builtins/builtin_constructor.rs +++ b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs @@ -2,11 +2,20 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use std::ops::{Index, IndexMut}; +use std::{ + ops::{Index, IndexMut}, + ptr::NonNull, +}; + +use oxc_span::Span; use crate::{ ecmascript::{ - execution::{agent::ExceptionType, Agent, ExecutionContext, JsResult, ProtoIntrinsics}, + execution::{ + agent::ExceptionType, Agent, EnvironmentIndex, ExecutionContext, JsResult, + PrivateEnvironmentIndex, ProtoIntrinsics, + }, + scripts_and_modules::source_code::SourceCode, syntax_directed_operations::class_definitions::{ base_class_default_constructor, derived_class_default_constructor, }, @@ -20,6 +29,7 @@ use crate::{ BUILTIN_STRING_MEMORY, }, }, + engine::Executable, heap::{ indexes::BuiltinConstructorIndex, CompactionLists, CreateHeapData, Heap, HeapMarkAndSweep, ObjectEntry, ObjectEntryPropertyDescriptor, WorkQueues, @@ -87,6 +97,39 @@ impl From for Function { } } +impl TryFrom for BuiltinConstructorFunction { + type Error = (); + + fn try_from(value: Value) -> Result { + match value { + Value::BuiltinConstructorFunction(data) => Ok(data), + _ => Err(()), + } + } +} + +impl TryFrom for BuiltinConstructorFunction { + type Error = (); + + fn try_from(value: Object) -> Result { + match value { + Object::BuiltinConstructorFunction(data) => Ok(data), + _ => Err(()), + } + } +} + +impl TryFrom for BuiltinConstructorFunction { + type Error = (); + + fn try_from(value: Function) -> Result { + match value { + Function::BuiltinConstructorFunction(data) => Ok(data), + _ => Err(()), + } + } +} + impl Index for Agent { type Output = BuiltinConstructorHeapData; @@ -293,10 +336,14 @@ fn builtin_call_or_construct( pub(crate) struct BuiltinConstructorArgs { pub(crate) is_derived: bool, - pub(crate) length: u8, - pub(crate) initial_name: String, + pub(crate) class_name: String, pub(crate) prototype: Option, pub(crate) prototype_property: Object, + pub(crate) compiled_initializer_bytecode: Option>, + pub(crate) env: EnvironmentIndex, + pub(crate) private_env: Option, + pub(crate) source_code: SourceCode, + pub(crate) source_text: Span, } /// ### [10.3.4 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList \[ , realm \[ , prototype \[ , prefix \] \] \] )](https://tc39.es/ecma262/#sec-createbuiltinfunction) @@ -336,7 +383,7 @@ pub(crate) fn create_builtin_constructor( let length_entry = ObjectEntry { key: PropertyKey::from(BUILTIN_STRING_MEMORY.length), value: ObjectEntryPropertyDescriptor::Data { - value: args.length.into(), + value: 0.into(), writable: false, enumerable: false, configurable: true, @@ -345,7 +392,7 @@ pub(crate) fn create_builtin_constructor( let name_entry = ObjectEntry { key: PropertyKey::from(BUILTIN_STRING_MEMORY.name), value: ObjectEntryPropertyDescriptor::Data { - value: args.initial_name.into_value(), + value: args.class_name.into_value(), writable: false, enumerable: false, configurable: true, @@ -367,16 +414,23 @@ pub(crate) fn create_builtin_constructor( agent.heap.create_null_object(&entries) }; + let compiled_initializer_bytecode = args + .compiled_initializer_bytecode + .map(|bytecode| NonNull::from(Box::leak(bytecode))); + // 13. Return func. agent.heap.create(BuiltinConstructorHeapData { // 10. Perform SetFunctionLength(func, length). - length: args.length, + // Skipped as length of builtin constructors is always 0. // 8. Set func.[[Realm]] to realm. realm, - compiled_initializer_bytecode: None, + compiled_initializer_bytecode, is_derived: args.is_derived, object_index: Some(backing_object), - class_span: (), + environment: args.env, + private_environment: args.private_env, + source_text: args.source_text, + source_code: args.source_code, }) } diff --git a/nova_vm/src/ecmascript/execution.rs b/nova_vm/src/ecmascript/execution.rs index c8370ca02..f39417575 100644 --- a/nova_vm/src/ecmascript/execution.rs +++ b/nova_vm/src/ecmascript/execution.rs @@ -11,10 +11,11 @@ mod realm; pub use agent::{Agent, JsResult}; pub use default_host_hooks::DefaultHostHooks; pub(crate) use environments::{ - get_this_environment, new_class_static_element_environment, new_declarative_environment, - new_function_environment, DeclarativeEnvironmentIndex, EnvironmentIndex, Environments, - FunctionEnvironmentIndex, GlobalEnvironment, GlobalEnvironmentIndex, ModuleEnvironmentIndex, - ObjectEnvironmentIndex, PrivateEnvironmentIndex, ThisBindingStatus, + get_this_environment, new_class_field_initializer_environment, + new_class_static_element_environment, new_declarative_environment, new_function_environment, + DeclarativeEnvironmentIndex, EnvironmentIndex, Environments, FunctionEnvironmentIndex, + GlobalEnvironment, GlobalEnvironmentIndex, ModuleEnvironmentIndex, ObjectEnvironmentIndex, + PrivateEnvironmentIndex, ThisBindingStatus, }; pub(crate) use execution_context::*; #[cfg(test)] diff --git a/nova_vm/src/ecmascript/execution/agent.rs b/nova_vm/src/ecmascript/execution/agent.rs index 233db199b..046442d1c 100644 --- a/nova_vm/src/ecmascript/execution/agent.rs +++ b/nova_vm/src/ecmascript/execution/agent.rs @@ -400,6 +400,15 @@ impl Agent { self.execution_context_stack.last_mut().unwrap() } + /// Panics if no active function object exists. + pub(crate) fn active_function_object(&self) -> Function { + self.execution_context_stack + .last() + .unwrap() + .function + .unwrap() + } + /// Get access to the Host data, useful to share state between calls of built-in functions. /// /// Note: This will panic if not implemented manually. diff --git a/nova_vm/src/ecmascript/execution/environments.rs b/nova_vm/src/ecmascript/execution/environments.rs index 317cff367..63054fa77 100644 --- a/nova_vm/src/ecmascript/execution/environments.rs +++ b/nova_vm/src/ecmascript/execution/environments.rs @@ -35,8 +35,8 @@ mod private_environment; pub(crate) use declarative_environment::{new_declarative_environment, DeclarativeEnvironment}; pub(crate) use function_environment::{ - new_class_static_element_environment, new_function_environment, FunctionEnvironment, - ThisBindingStatus, + new_class_field_initializer_environment, new_class_static_element_environment, + new_function_environment, FunctionEnvironment, ThisBindingStatus, }; pub(crate) use global_environment::GlobalEnvironment; pub(crate) use object_environment::ObjectEnvironment; diff --git a/nova_vm/src/ecmascript/execution/environments/function_environment.rs b/nova_vm/src/ecmascript/execution/environments/function_environment.rs index 38f348c1d..47b426805 100644 --- a/nova_vm/src/ecmascript/execution/environments/function_environment.rs +++ b/nova_vm/src/ecmascript/execution/environments/function_environment.rs @@ -2,7 +2,9 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use super::{DeclarativeEnvironment, DeclarativeEnvironmentIndex, FunctionEnvironmentIndex}; +use super::{ + DeclarativeEnvironment, DeclarativeEnvironmentIndex, EnvironmentIndex, FunctionEnvironmentIndex, +}; use crate::{ ecmascript::{ builtins::{ECMAScriptFunction, ThisMode}, @@ -167,6 +169,31 @@ pub(crate) fn new_class_static_element_environment( agent.heap.environments.push_function_environment(env) } +pub(crate) fn new_class_field_initializer_environment( + agent: &mut Agent, + class_constructor: Function, + class_instance: Object, + outer_env: EnvironmentIndex, +) -> FunctionEnvironmentIndex { + agent + .heap + .environments + .declarative + .push(Some(DeclarativeEnvironment::new(Some(outer_env)))); + let declarative_environment = + DeclarativeEnvironmentIndex::last(&agent.heap.environments.declarative); + agent + .heap + .environments + .push_function_environment(FunctionEnvironment { + this_value: Some(class_instance.into_value()), + this_binding_status: ThisBindingStatus::Initialized, + function_object: class_constructor, + new_target: None, + declarative_environment, + }) +} + impl FunctionEnvironmentIndex { pub(crate) fn get_this_binding_status(self, agent: &Agent) -> ThisBindingStatus { agent[self].this_binding_status diff --git a/nova_vm/src/ecmascript/syntax_directed_operations/class_definitions.rs b/nova_vm/src/ecmascript/syntax_directed_operations/class_definitions.rs index 311e12398..0d143b07e 100644 --- a/nova_vm/src/ecmascript/syntax_directed_operations/class_definitions.rs +++ b/nova_vm/src/ecmascript/syntax_directed_operations/class_definitions.rs @@ -4,9 +4,12 @@ use crate::ecmascript::{ abstract_operations::{ - operations_on_objects::construct, testing_and_comparison::is_constructor, + operations_on_objects::{construct, initialize_instance_elements}, + testing_and_comparison::is_constructor, + }, + builtins::{ + ordinary::ordinary_create_from_constructor, ArgumentsList, BuiltinConstructorFunction, }, - builtins::{ordinary::ordinary_create_from_constructor, ArgumentsList}, execution::{agent::ExceptionType, Agent, JsResult, ProtoIntrinsics}, types::{Function, InternalMethods, Object}, }; @@ -19,7 +22,7 @@ pub(crate) fn base_class_default_constructor( // Note: We've already checked this at an earlier level. // iii. Let F be the active function object. - // let f = agent.running_execution_context().function.unwrap(); + let f = BuiltinConstructorFunction::try_from(agent.active_function_object()).unwrap(); // iv. If F.[[ConstructorKind]] is derived, then // v. Else, @@ -31,7 +34,7 @@ pub(crate) fn base_class_default_constructor( ProtoIntrinsics::Object, )?; // vi. Perform ? InitializeInstanceElements(result, F). - // TODO: Handle InitializeInstanceElements somehow. + initialize_instance_elements(agent, result, f)?; // vii. Return result. Ok(result) @@ -47,7 +50,7 @@ pub(crate) fn derived_class_default_constructor( // Note: We've already checked this at an earlier level. // iii. Let F be the active function object. - let f = agent.running_execution_context().function.unwrap(); + let f = BuiltinConstructorFunction::try_from(agent.active_function_object()).unwrap(); // iv. If F.[[ConstructorKind]] is derived, then // 1. NOTE: This branch behaves similarly to constructor(...args) { super(...args); }. @@ -72,7 +75,7 @@ pub(crate) fn derived_class_default_constructor( Some(Function::try_from(new_target).unwrap()), )?; // vi. Perform ? InitializeInstanceElements(result, F). - // TODO: Handle InitializeInstanceElements somehow. + initialize_instance_elements(agent, result, f)?; // vii. Return result. Ok(result) diff --git a/nova_vm/src/ecmascript/types/language/function/data.rs b/nova_vm/src/ecmascript/types/language/function/data.rs index 71bafbb19..2cf8af264 100644 --- a/nova_vm/src/ecmascript/types/language/function/data.rs +++ b/nova_vm/src/ecmascript/types/language/function/data.rs @@ -4,10 +4,13 @@ use std::ptr::NonNull; +use oxc_span::Span; + use crate::{ ecmascript::{ builtins::{Behaviour, ECMAScriptFunctionObjectHeapData}, - execution::RealmIdentifier, + execution::{EnvironmentIndex, PrivateEnvironmentIndex, RealmIdentifier}, + scripts_and_modules::source_code::SourceCode, types::{OrdinaryObject, String, Value}, }, engine::Executable, @@ -55,14 +58,10 @@ pub struct BuiltinFunctionHeapData { #[derive(Debug, Clone)] pub struct BuiltinConstructorHeapData { pub(crate) object_index: Option, - /// Note: If we decide to always create a backing object for builtin - /// constructors, then we can maybe drop this. - pub(crate) length: u8, /// #### \[\[Realm]] /// A Realm Record that represents the realm in which the function was /// created. pub(crate) realm: RealmIdentifier, - pub(crate) class_span: (), /// ### \[\[ConstructorKind]] /// /// If the boolean is `true` then ConstructorKind is Derived, else it is @@ -70,6 +69,22 @@ pub struct BuiltinConstructorHeapData { pub(crate) is_derived: bool, /// Stores the compiled bytecode of class field initializers. pub(crate) compiled_initializer_bytecode: Option>, + /// ### \[\[Environment]] + /// + /// This is required for class field initializers. + pub(crate) environment: EnvironmentIndex, + /// ### \[\[PrivateEnvironment]] + /// + /// This is required for class field initializers. + pub(crate) private_environment: Option, + /// \[\[SourceText]] + pub(crate) source_text: Span, + + /// \[\[SourceCode]] + /// + /// Nova specific addition: This SourceCode is where \[\[SourceText]] + /// refers to. + pub(crate) source_code: SourceCode, } // SAFETY: We promise not to ever mutate the Executable, especially not from diff --git a/nova_vm/src/engine/bytecode/executable.rs b/nova_vm/src/engine/bytecode/executable.rs index 6c789a1e9..de5acd35e 100644 --- a/nova_vm/src/engine/bytecode/executable.rs +++ b/nova_vm/src/engine/bytecode/executable.rs @@ -52,6 +52,7 @@ pub(crate) struct CompileContext<'agent> { function_expressions: Vec, /// Arrow function expressions being built arrow_function_expressions: Vec, + class_initializer_bytecodes: Vec<(Option, bool)>, /// NamedEvaluation name parameter name_identifier: Option, /// If true, indicates that all bindings being created are lexical. @@ -77,6 +78,7 @@ impl CompileContext<'_> { constants: Vec::new(), function_expressions: Vec::new(), arrow_function_expressions: Vec::new(), + class_initializer_bytecodes: Vec::new(), name_identifier: None, lexical_binding_state: false, current_continue: None, @@ -219,6 +221,7 @@ impl CompileContext<'_> { constants: self.constants.into_boxed_slice(), function_expressions: self.function_expressions.into_boxed_slice(), arrow_function_expressions: self.arrow_function_expressions.into_boxed_slice(), + class_initializer_bytecodes: self.class_initializer_bytecodes.into_boxed_slice(), } } @@ -521,6 +524,7 @@ pub(crate) struct Executable { pub(crate) constants: Box<[Value]>, pub(crate) function_expressions: Box<[FunctionExpression]>, pub(crate) arrow_function_expressions: Box<[ArrowFunctionExpression]>, + pub(crate) class_initializer_bytecodes: Box<[(Option, bool)]>, } impl Executable { diff --git a/nova_vm/src/engine/bytecode/executable/class_definition_evaluation.rs b/nova_vm/src/engine/bytecode/executable/class_definition_evaluation.rs index 2dc8d4ff2..e8e825128 100644 --- a/nova_vm/src/engine/bytecode/executable/class_definition_evaluation.rs +++ b/nova_vm/src/engine/bytecode/executable/class_definition_evaluation.rs @@ -271,13 +271,9 @@ impl CompileEvaluation for ast::Class<'_> { } // 14. If constructor is not empty, then - let constructor_expression_index = if let Some(constructor) = constructor { + let constructor_index = if let Some(constructor) = constructor { // a. Let constructorInfo be ! DefineMethod of constructor with arguments proto and constructorParent. - Some(define_constructor_method( - ctx, - constructor, - has_constructor_parent, - )) + define_constructor_method(ctx, constructor, has_constructor_parent) // b. Let F be constructorInfo.[[Closure]]. // c. Perform MakeClassConstructor(F). // d. Perform SetFunctionName(F, className). @@ -287,11 +283,12 @@ impl CompileEvaluation for ast::Class<'_> { // ... // b. Let F be CreateBuiltinFunction(defaultConstructor, 0, className, « [[ConstructorKind]], [[SourceText]] », the current Realm Record, constructorParent). + let index = IndexType::try_from(ctx.class_initializer_bytecodes.len()).unwrap(); ctx.add_instruction_with_immediate( Instruction::ClassDefineDefaultConstructor, - has_constructor_parent.into(), + index.into(), ); - None + index }; // result: F @@ -441,32 +438,39 @@ impl CompileEvaluation for ast::Class<'_> { } } } - let constructor = - constructor.expect("Class fields with default constructor not supported yet"); - let constructor_expression_index = constructor_expression_index.unwrap(); - let constructor_data = CompileFunctionBodyData { - // SAFETY: The SourceCode that contains this code cannot be garbage collected - // as long as the constructor function we produce here lives. - body: unsafe { - std::mem::transmute::<&ast::FunctionBody<'_>, &ast::FunctionBody<'static>>( - constructor.value.body.as_ref().unwrap(), - ) - }, - // SAFETY: The SourceCode that contains this code cannot be garbage collected - // as long as the constructor function we produce here lives. - params: unsafe { - std::mem::transmute::<&ast::FormalParameters<'_>, &ast::FormalParameters<'static>>( - &constructor.value.params, - ) - }, - is_concise_body: false, - is_lexical: false, - is_strict: false, - }; - constructor_ctx.compile_function_body(constructor_data); - let executable = constructor_ctx.finish(); - ctx.function_expressions[constructor_expression_index as usize].compiled_bytecode = - Some(executable); + if let Some(constructor) = constructor { + let constructor_data = CompileFunctionBodyData { + // SAFETY: The SourceCode that contains this code cannot be garbage collected + // as long as the constructor function we produce here lives. + body: unsafe { + std::mem::transmute::<&ast::FunctionBody<'_>, &ast::FunctionBody<'static>>( + constructor.value.body.as_ref().unwrap(), + ) + }, + // SAFETY: The SourceCode that contains this code cannot be garbage collected + // as long as the constructor function we produce here lives. + params: unsafe { + std::mem::transmute::< + &ast::FormalParameters<'_>, + &ast::FormalParameters<'static>, + >(&constructor.value.params) + }, + is_concise_body: false, + is_lexical: false, + // Class code is always strict. + is_strict: true, + }; + constructor_ctx.compile_function_body(constructor_data); + let executable = constructor_ctx.finish(); + ctx.function_expressions[constructor_index as usize].compiled_bytecode = + Some(executable); + } else { + ctx.class_initializer_bytecodes + .push((Some(constructor_ctx.finish()), has_constructor_parent)); + } + } else if constructor.is_none() { + ctx.class_initializer_bytecodes + .push((None, has_constructor_parent)); } // 30. For each PrivateElement method of staticPrivateMethods, do // a. Perform ! PrivateMethodOrAccessorAdd(F, method). diff --git a/nova_vm/src/engine/bytecode/vm.rs b/nova_vm/src/engine/bytecode/vm.rs index 97c49013b..c3d0309a1 100644 --- a/nova_vm/src/engine/bytecode/vm.rs +++ b/nova_vm/src/engine/bytecode/vm.rs @@ -6,6 +6,7 @@ use std::{ptr::NonNull, sync::OnceLock}; use ahash::AHashSet; use oxc_ast::ast; +use oxc_span::Span; use oxc_syntax::operator::BinaryOperator; use crate::{ @@ -971,9 +972,15 @@ impl Vm { vm.result = Some(function.into_value()); } Instruction::ClassDefineDefaultConstructor => { - let has_constructor_parent = instr.args[0].unwrap(); - assert!(has_constructor_parent <= 1); - let has_constructor_parent = has_constructor_parent == 1; + let class_initializer_bytecode_index = instr.args[0].unwrap(); + let (compiled_initializer_bytecode, has_constructor_parent) = executable + .class_initializer_bytecodes + .get(class_initializer_bytecode_index as usize) + .unwrap(); + let has_constructor_parent = *has_constructor_parent; + let compiled_initializer_bytecode = compiled_initializer_bytecode + .as_ref() + .map(|bytecode| Box::new(bytecode.clone())); let class_name = String::try_from(vm.stack.pop().unwrap()).unwrap(); let function_prototype = if has_constructor_parent { @@ -989,14 +996,29 @@ impl Vm { }; let proto = Object::try_from(*vm.stack.last().unwrap()).unwrap(); + let ECMAScriptCodeEvaluationState { + lexical_environment, + private_environment, + source_code, + .. + } = *agent + .running_execution_context() + .ecmascript_code + .as_ref() + .unwrap(); + let function = create_builtin_constructor( agent, BuiltinConstructorArgs { - initial_name: class_name, + class_name, is_derived: has_constructor_parent, - length: 0, prototype: function_prototype, prototype_property: proto, + compiled_initializer_bytecode, + env: lexical_environment, + private_env: private_environment, + source_code, + source_text: Span::new(0, 0), }, ); From 0fbe3565b68828ef1ff4968e60d79831ad0b3624 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Thu, 3 Oct 2024 23:20:12 +0300 Subject: [PATCH 4/7] chore(test262): Update expectations --- tests/expectations.json | 317 ---------------------------------------- tests/metrics.json | 8 +- 2 files changed, 4 insertions(+), 321 deletions(-) diff --git a/tests/expectations.json b/tests/expectations.json index 9e9d1f568..3bd8d6c97 100644 --- a/tests/expectations.json +++ b/tests/expectations.json @@ -2116,9 +2116,7 @@ "built-ins/Function/internals/Construct/base-ctor-revoked-proxy-realm.js": "FAIL", "built-ins/Function/internals/Construct/base-ctor-revoked-proxy.js": "CRASH", "built-ins/Function/internals/Construct/derived-return-val-realm.js": "FAIL", - "built-ins/Function/internals/Construct/derived-return-val.js": "CRASH", "built-ins/Function/internals/Construct/derived-this-uninitialized-realm.js": "FAIL", - "built-ins/Function/internals/Construct/derived-this-uninitialized.js": "CRASH", "built-ins/Function/proto-from-ctor-realm-prototype.js": "FAIL", "built-ins/Function/proto-from-ctor-realm.js": "FAIL", "built-ins/Function/prototype/Symbol.hasInstance/length.js": "FAIL", @@ -13065,10 +13063,8 @@ "language/expressions/arrow-function/length-dflt.js": "FAIL", "language/expressions/arrow-function/lexical-new.target-closure-returned.js": "CRASH", "language/expressions/arrow-function/lexical-new.target.js": "CRASH", - "language/expressions/arrow-function/lexical-super-call-from-within-constructor.js": "CRASH", "language/expressions/arrow-function/lexical-super-property-from-within-constructor.js": "CRASH", "language/expressions/arrow-function/lexical-super-property.js": "CRASH", - "language/expressions/arrow-function/lexical-supercall-from-immediately-invoked-arrow.js": "CRASH", "language/expressions/arrow-function/scope-param-rest-elem-var-close.js": "CRASH", "language/expressions/arrow-function/scope-param-rest-elem-var-open.js": "CRASH", "language/expressions/arrow-function/syntax/arrowparameters-cover-initialize-2.js": "CRASH", @@ -15728,17 +15724,11 @@ "language/expressions/class/dstr/private-meth-static-obj-ptrn-rest-getter.js": "CRASH", "language/expressions/class/dstr/private-meth-static-obj-ptrn-rest-skip-non-enumerable.js": "CRASH", "language/expressions/class/dstr/private-meth-static-obj-ptrn-rest-val-obj.js": "CRASH", - "language/expressions/class/elements/after-same-line-gen-computed-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-gen-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/after-same-line-gen-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/after-same-line-gen-literal-names.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-private-field-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-private-method-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-private-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-gen-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/after-same-line-gen-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-rs-private-getter.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-rs-private-method-alt.js": "CRASH", @@ -15768,17 +15758,11 @@ "language/expressions/class/elements/after-same-line-gen-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-static-private-methods.js": "CRASH", "language/expressions/class/elements/after-same-line-gen-string-literal-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-method-computed-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-method-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/after-same-line-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/after-same-line-method-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/after-same-line-method-literal-names.js": "CRASH", "language/expressions/class/elements/after-same-line-method-private-field-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-method-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-method-private-method-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-method-private-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-method-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/after-same-line-method-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/after-same-line-method-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/after-same-line-method-rs-private-getter.js": "CRASH", "language/expressions/class/elements/after-same-line-method-rs-private-method-alt.js": "CRASH", @@ -15848,17 +15832,11 @@ "language/expressions/class/elements/after-same-line-static-async-gen-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-gen-static-private-methods.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-gen-string-literal-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-async-method-computed-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-async-method-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-async-method-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-async-method-literal-names.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-private-field-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-private-method-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-private-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-async-method-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-async-method-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-rs-private-getter.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-rs-private-method-alt.js": "CRASH", @@ -15888,17 +15866,11 @@ "language/expressions/class/elements/after-same-line-static-async-method-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-static-private-methods.js": "CRASH", "language/expressions/class/elements/after-same-line-static-async-method-string-literal-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-gen-computed-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-gen-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-gen-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-gen-literal-names.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-private-field-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-private-method-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-private-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-gen-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-gen-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-rs-private-getter.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-rs-private-method-alt.js": "CRASH", @@ -15928,17 +15900,11 @@ "language/expressions/class/elements/after-same-line-static-gen-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-static-private-methods.js": "CRASH", "language/expressions/class/elements/after-same-line-static-gen-string-literal-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-method-computed-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-method-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/after-same-line-static-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-method-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-method-literal-names.js": "CRASH", "language/expressions/class/elements/after-same-line-static-method-private-field-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-static-method-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-static-method-private-method-usage.js": "CRASH", "language/expressions/class/elements/after-same-line-static-method-private-names.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-method-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/after-same-line-static-method-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/after-same-line-static-method-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/after-same-line-static-method-rs-private-getter.js": "CRASH", "language/expressions/class/elements/after-same-line-static-method-rs-private-method-alt.js": "CRASH", @@ -16139,8 +16105,6 @@ "language/expressions/class/elements/class-name-static-initializer-anonymous.js": "CRASH", "language/expressions/class/elements/class-name-static-initializer-decl.js": "CRASH", "language/expressions/class/elements/class-name-static-initializer-expr.js": "CRASH", - "language/expressions/class/elements/computed-name-toprimitive-symbol.js": "CRASH", - "language/expressions/class/elements/computed-name-toprimitive.js": "CRASH", "language/expressions/class/elements/derived-cls-direct-eval-contains-superproperty-1.js": "CRASH", "language/expressions/class/elements/derived-cls-direct-eval-contains-superproperty-2.js": "CRASH", "language/expressions/class/elements/derived-cls-direct-eval-err-contains-supercall-1.js": "CRASH", @@ -16153,7 +16117,6 @@ "language/expressions/class/elements/derived-cls-indirect-eval-err-contains-supercall.js": "CRASH", "language/expressions/class/elements/direct-eval-err-contains-arguments.js": "CRASH", "language/expressions/class/elements/direct-eval-err-contains-newtarget.js": "CRASH", - "language/expressions/class/elements/evaluation-error/computed-name-referenceerror.js": "CRASH", "language/expressions/class/elements/evaluation-error/computed-name-toprimitive-err.js": "CRASH", "language/expressions/class/elements/evaluation-error/computed-name-toprimitive-returns-noncallable.js": "CRASH", "language/expressions/class/elements/evaluation-error/computed-name-toprimitive-returns-nonobject.js": "CRASH", @@ -16162,9 +16125,6 @@ "language/expressions/class/elements/field-declaration.js": "CRASH", "language/expressions/class/elements/field-definition-accessor-no-line-terminator.js": "CRASH", "language/expressions/class/elements/fields-anonymous-function-length.js": "CRASH", - "language/expressions/class/elements/fields-asi-1.js": "CRASH", - "language/expressions/class/elements/fields-asi-2.js": "CRASH", - "language/expressions/class/elements/fields-asi-5.js": "CRASH", "language/expressions/class/elements/fields-computed-name-static-propname-prototype.js": "CRASH", "language/expressions/class/elements/fields-multiple-definitions-static-private-methods-proxy.js": "CRASH", "language/expressions/class/elements/fields-run-once-on-double-super.js": "CRASH", @@ -16178,20 +16138,12 @@ "language/expressions/class/elements/indirect-eval-contains-arguments.js": "CRASH", "language/expressions/class/elements/indirect-eval-err-contains-newtarget.js": "CRASH", "language/expressions/class/elements/init-err-evaluation.js": "CRASH", - "language/expressions/class/elements/init-value-defined-after-class.js": "CRASH", - "language/expressions/class/elements/init-value-incremental.js": "CRASH", "language/expressions/class/elements/intercalated-static-non-static-computed-fields.js": "CRASH", - "language/expressions/class/elements/multiple-definitions-computed-names.js": "CRASH", - "language/expressions/class/elements/multiple-definitions-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/multiple-definitions-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/multiple-definitions-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/multiple-definitions-literal-names.js": "CRASH", "language/expressions/class/elements/multiple-definitions-private-field-usage.js": "CRASH", "language/expressions/class/elements/multiple-definitions-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/multiple-definitions-private-method-usage.js": "CRASH", "language/expressions/class/elements/multiple-definitions-private-names.js": "CRASH", - "language/expressions/class/elements/multiple-definitions-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/multiple-definitions-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/multiple-definitions-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/multiple-definitions-rs-private-getter.js": "CRASH", "language/expressions/class/elements/multiple-definitions-rs-private-method-alt.js": "CRASH", @@ -16221,17 +16173,11 @@ "language/expressions/class/elements/multiple-definitions-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/multiple-definitions-static-private-methods.js": "CRASH", "language/expressions/class/elements/multiple-definitions-string-literal-names.js": "CRASH", - "language/expressions/class/elements/multiple-stacked-definitions-computed-names.js": "CRASH", - "language/expressions/class/elements/multiple-stacked-definitions-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/multiple-stacked-definitions-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/multiple-stacked-definitions-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/multiple-stacked-definitions-literal-names.js": "CRASH", "language/expressions/class/elements/multiple-stacked-definitions-private-field-usage.js": "CRASH", "language/expressions/class/elements/multiple-stacked-definitions-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/multiple-stacked-definitions-private-method-usage.js": "CRASH", "language/expressions/class/elements/multiple-stacked-definitions-private-names.js": "CRASH", - "language/expressions/class/elements/multiple-stacked-definitions-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/multiple-stacked-definitions-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/multiple-stacked-definitions-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/multiple-stacked-definitions-rs-private-getter.js": "CRASH", "language/expressions/class/elements/multiple-stacked-definitions-rs-private-method-alt.js": "CRASH", @@ -16289,17 +16235,11 @@ "language/expressions/class/elements/nested-private-direct-eval-err-contains-newtarget.js": "CRASH", "language/expressions/class/elements/nested-private-indirect-eval-contains-arguments.js": "CRASH", "language/expressions/class/elements/nested-private-indirect-eval-err-contains-newtarget.js": "CRASH", - "language/expressions/class/elements/new-no-sc-line-method-computed-names.js": "CRASH", - "language/expressions/class/elements/new-no-sc-line-method-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/new-no-sc-line-method-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/new-no-sc-line-method-literal-names.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-private-field-usage.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-private-method-usage.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-private-names.js": "CRASH", - "language/expressions/class/elements/new-no-sc-line-method-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/new-no-sc-line-method-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-rs-private-getter.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-rs-private-method-alt.js": "CRASH", @@ -16329,17 +16269,11 @@ "language/expressions/class/elements/new-no-sc-line-method-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-static-private-methods.js": "CRASH", "language/expressions/class/elements/new-no-sc-line-method-string-literal-names.js": "CRASH", - "language/expressions/class/elements/new-sc-line-gen-computed-names.js": "CRASH", - "language/expressions/class/elements/new-sc-line-gen-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/new-sc-line-gen-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/new-sc-line-gen-literal-names.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-private-field-usage.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-private-method-usage.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-private-names.js": "CRASH", - "language/expressions/class/elements/new-sc-line-gen-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/new-sc-line-gen-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-rs-private-getter.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-rs-private-method-alt.js": "CRASH", @@ -16369,17 +16303,11 @@ "language/expressions/class/elements/new-sc-line-gen-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-static-private-methods.js": "CRASH", "language/expressions/class/elements/new-sc-line-gen-string-literal-names.js": "CRASH", - "language/expressions/class/elements/new-sc-line-method-computed-names.js": "CRASH", - "language/expressions/class/elements/new-sc-line-method-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/new-sc-line-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/new-sc-line-method-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/new-sc-line-method-literal-names.js": "CRASH", "language/expressions/class/elements/new-sc-line-method-private-field-usage.js": "CRASH", "language/expressions/class/elements/new-sc-line-method-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/new-sc-line-method-private-method-usage.js": "CRASH", "language/expressions/class/elements/new-sc-line-method-private-names.js": "CRASH", - "language/expressions/class/elements/new-sc-line-method-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/new-sc-line-method-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/new-sc-line-method-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/new-sc-line-method-rs-private-getter.js": "CRASH", "language/expressions/class/elements/new-sc-line-method-rs-private-method-alt.js": "CRASH", @@ -16509,19 +16437,12 @@ "language/expressions/class/elements/prod-private-method-before-super-return-in-field-initializer.js": "CRASH", "language/expressions/class/elements/prod-private-setter-before-super-return-in-constructor.js": "CRASH", "language/expressions/class/elements/prod-private-setter-before-super-return-in-field-initializer.js": "CRASH", - "language/expressions/class/elements/redeclaration-symbol.js": "CRASH", "language/expressions/class/elements/redeclaration.js": "CRASH", - "language/expressions/class/elements/regular-definitions-computed-names.js": "CRASH", - "language/expressions/class/elements/regular-definitions-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/regular-definitions-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/regular-definitions-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/regular-definitions-literal-names.js": "CRASH", "language/expressions/class/elements/regular-definitions-private-field-usage.js": "CRASH", "language/expressions/class/elements/regular-definitions-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/regular-definitions-private-method-usage.js": "CRASH", "language/expressions/class/elements/regular-definitions-private-names.js": "CRASH", - "language/expressions/class/elements/regular-definitions-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/regular-definitions-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/regular-definitions-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/regular-definitions-rs-private-getter.js": "CRASH", "language/expressions/class/elements/regular-definitions-rs-private-method-alt.js": "CRASH", @@ -16591,17 +16512,11 @@ "language/expressions/class/elements/same-line-async-gen-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/same-line-async-gen-static-private-methods.js": "CRASH", "language/expressions/class/elements/same-line-async-gen-string-literal-names.js": "CRASH", - "language/expressions/class/elements/same-line-async-method-computed-names.js": "CRASH", - "language/expressions/class/elements/same-line-async-method-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/same-line-async-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/same-line-async-method-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/same-line-async-method-literal-names.js": "CRASH", "language/expressions/class/elements/same-line-async-method-private-field-usage.js": "CRASH", "language/expressions/class/elements/same-line-async-method-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/same-line-async-method-private-method-usage.js": "CRASH", "language/expressions/class/elements/same-line-async-method-private-names.js": "CRASH", - "language/expressions/class/elements/same-line-async-method-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/same-line-async-method-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/same-line-async-method-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/same-line-async-method-rs-private-getter.js": "CRASH", "language/expressions/class/elements/same-line-async-method-rs-private-method-alt.js": "CRASH", @@ -16631,17 +16546,11 @@ "language/expressions/class/elements/same-line-async-method-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/same-line-async-method-static-private-methods.js": "CRASH", "language/expressions/class/elements/same-line-async-method-string-literal-names.js": "CRASH", - "language/expressions/class/elements/same-line-gen-computed-names.js": "CRASH", - "language/expressions/class/elements/same-line-gen-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/same-line-gen-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/same-line-gen-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/same-line-gen-literal-names.js": "CRASH", "language/expressions/class/elements/same-line-gen-private-field-usage.js": "CRASH", "language/expressions/class/elements/same-line-gen-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/same-line-gen-private-method-usage.js": "CRASH", "language/expressions/class/elements/same-line-gen-private-names.js": "CRASH", - "language/expressions/class/elements/same-line-gen-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/same-line-gen-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/same-line-gen-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/same-line-gen-rs-private-getter.js": "CRASH", "language/expressions/class/elements/same-line-gen-rs-private-method-alt.js": "CRASH", @@ -16671,17 +16580,11 @@ "language/expressions/class/elements/same-line-gen-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/same-line-gen-static-private-methods.js": "CRASH", "language/expressions/class/elements/same-line-gen-string-literal-names.js": "CRASH", - "language/expressions/class/elements/same-line-method-computed-names.js": "CRASH", - "language/expressions/class/elements/same-line-method-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/same-line-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/same-line-method-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/same-line-method-literal-names.js": "CRASH", "language/expressions/class/elements/same-line-method-private-field-usage.js": "CRASH", "language/expressions/class/elements/same-line-method-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/same-line-method-private-method-usage.js": "CRASH", "language/expressions/class/elements/same-line-method-private-names.js": "CRASH", - "language/expressions/class/elements/same-line-method-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/same-line-method-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/same-line-method-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/same-line-method-rs-private-getter.js": "CRASH", "language/expressions/class/elements/same-line-method-rs-private-method-alt.js": "CRASH", @@ -16711,8 +16614,6 @@ "language/expressions/class/elements/same-line-method-static-private-methods-with-fields.js": "CRASH", "language/expressions/class/elements/same-line-method-static-private-methods.js": "CRASH", "language/expressions/class/elements/same-line-method-string-literal-names.js": "CRASH", - "language/expressions/class/elements/static-as-valid-instance-field-assigned.js": "CRASH", - "language/expressions/class/elements/static-as-valid-instance-field.js": "CRASH", "language/expressions/class/elements/static-as-valid-static-field-assigned.js": "CRASH", "language/expressions/class/elements/static-as-valid-static-field.js": "CRASH", "language/expressions/class/elements/static-field-anonymous-function-length.js": "CRASH", @@ -16738,11 +16639,6 @@ "language/expressions/class/elements/static-private-setter.js": "CRASH", "language/expressions/class/elements/super-access-from-arrow-func-on-field.js": "CRASH", "language/expressions/class/elements/syntax/valid/grammar-field-accessor.js": "CRASH", - "language/expressions/class/elements/syntax/valid/grammar-field-classelementname-initializer-alt.js": "CRASH", - "language/expressions/class/elements/syntax/valid/grammar-field-classelementname-initializer.js": "CRASH", - "language/expressions/class/elements/syntax/valid/grammar-field-identifier-alt.js": "CRASH", - "language/expressions/class/elements/syntax/valid/grammar-field-identifier.js": "CRASH", - "language/expressions/class/elements/syntax/valid/grammar-fields-multi-line.js": "CRASH", "language/expressions/class/elements/syntax/valid/grammar-privatemeth-duplicate-get-set.js": "CRASH", "language/expressions/class/elements/syntax/valid/grammar-privatemeth-duplicate-meth-nestedclassmeth.js": "CRASH", "language/expressions/class/elements/syntax/valid/grammar-privatename-classelementname-initializer-alt.js": "CRASH", @@ -16754,17 +16650,11 @@ "language/expressions/class/elements/syntax/valid/grammar-static-private-async-meth-prototype.js": "CRASH", "language/expressions/class/elements/syntax/valid/grammar-static-private-gen-meth-prototype.js": "CRASH", "language/expressions/class/elements/syntax/valid/grammar-static-private-meth-prototype.js": "CRASH", - "language/expressions/class/elements/wrapped-in-sc-computed-names.js": "CRASH", - "language/expressions/class/elements/wrapped-in-sc-computed-symbol-names.js": "CRASH", "language/expressions/class/elements/wrapped-in-sc-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/expressions/class/elements/wrapped-in-sc-literal-names-asi.js": "CRASH", - "language/expressions/class/elements/wrapped-in-sc-literal-names.js": "CRASH", "language/expressions/class/elements/wrapped-in-sc-private-field-usage.js": "CRASH", "language/expressions/class/elements/wrapped-in-sc-private-method-getter-usage.js": "CRASH", "language/expressions/class/elements/wrapped-in-sc-private-method-usage.js": "CRASH", "language/expressions/class/elements/wrapped-in-sc-private-names.js": "CRASH", - "language/expressions/class/elements/wrapped-in-sc-rs-field-identifier-initializer.js": "CRASH", - "language/expressions/class/elements/wrapped-in-sc-rs-field-identifier.js": "CRASH", "language/expressions/class/elements/wrapped-in-sc-rs-private-getter-alt.js": "CRASH", "language/expressions/class/elements/wrapped-in-sc-rs-private-getter.js": "CRASH", "language/expressions/class/elements/wrapped-in-sc-rs-private-method-alt.js": "CRASH", @@ -16850,7 +16740,6 @@ "language/expressions/class/subclass-builtins/subclass-Date.js": "CRASH", "language/expressions/class/subclass-builtins/subclass-Float32Array.js": "CRASH", "language/expressions/class/subclass-builtins/subclass-Float64Array.js": "CRASH", - "language/expressions/class/subclass-builtins/subclass-Function.js": "CRASH", "language/expressions/class/subclass-builtins/subclass-Int16Array.js": "CRASH", "language/expressions/class/subclass-builtins/subclass-Int32Array.js": "CRASH", "language/expressions/class/subclass-builtins/subclass-Int8Array.js": "CRASH", @@ -18465,54 +18354,7 @@ "language/expressions/right-shift/bigint.js": "CRASH", "language/expressions/right-shift/order-of-evaluation.js": "FAIL", "language/expressions/subtraction/order-of-evaluation.js": "FAIL", - "language/expressions/super/call-arg-evaluation-err.js": "CRASH", - "language/expressions/super/call-bind-this-value-twice.js": "CRASH", - "language/expressions/super/call-bind-this-value.js": "CRASH", - "language/expressions/super/call-construct-error.js": "CRASH", "language/expressions/super/call-construct-invocation.js": "CRASH", - "language/expressions/super/call-expr-value.js": "CRASH", - "language/expressions/super/call-proto-not-ctor.js": "CRASH", - "language/expressions/super/call-spread-err-mult-err-expr-throws.js": "CRASH", - "language/expressions/super/call-spread-err-mult-err-iter-get-value.js": "CRASH", - "language/expressions/super/call-spread-err-mult-err-itr-get-call.js": "CRASH", - "language/expressions/super/call-spread-err-mult-err-itr-get-get.js": "CRASH", - "language/expressions/super/call-spread-err-mult-err-itr-step.js": "CRASH", - "language/expressions/super/call-spread-err-mult-err-itr-value.js": "CRASH", - "language/expressions/super/call-spread-err-mult-err-obj-unresolvable.js": "CRASH", - "language/expressions/super/call-spread-err-mult-err-unresolvable.js": "CRASH", - "language/expressions/super/call-spread-err-sngl-err-expr-throws.js": "CRASH", - "language/expressions/super/call-spread-err-sngl-err-itr-get-call.js": "CRASH", - "language/expressions/super/call-spread-err-sngl-err-itr-get-get.js": "CRASH", - "language/expressions/super/call-spread-err-sngl-err-itr-get-value.js": "CRASH", - "language/expressions/super/call-spread-err-sngl-err-itr-step.js": "CRASH", - "language/expressions/super/call-spread-err-sngl-err-itr-value.js": "CRASH", - "language/expressions/super/call-spread-err-sngl-err-obj-unresolvable.js": "CRASH", - "language/expressions/super/call-spread-err-sngl-err-unresolvable.js": "CRASH", - "language/expressions/super/call-spread-mult-empty.js": "CRASH", - "language/expressions/super/call-spread-mult-expr.js": "CRASH", - "language/expressions/super/call-spread-mult-iter.js": "CRASH", - "language/expressions/super/call-spread-mult-literal.js": "CRASH", - "language/expressions/super/call-spread-mult-obj-ident.js": "CRASH", - "language/expressions/super/call-spread-mult-obj-null.js": "CRASH", - "language/expressions/super/call-spread-mult-obj-undefined.js": "CRASH", - "language/expressions/super/call-spread-obj-getter-descriptor.js": "CRASH", - "language/expressions/super/call-spread-obj-getter-init.js": "CRASH", - "language/expressions/super/call-spread-obj-manipulate-outter-obj-in-getter.js": "CRASH", - "language/expressions/super/call-spread-obj-mult-spread-getter.js": "CRASH", - "language/expressions/super/call-spread-obj-mult-spread.js": "CRASH", - "language/expressions/super/call-spread-obj-null.js": "CRASH", - "language/expressions/super/call-spread-obj-override-immutable.js": "CRASH", - "language/expressions/super/call-spread-obj-overrides-prev-properties.js": "CRASH", - "language/expressions/super/call-spread-obj-skip-non-enumerable.js": "CRASH", - "language/expressions/super/call-spread-obj-spread-order.js": "CRASH", - "language/expressions/super/call-spread-obj-symbol-property.js": "CRASH", - "language/expressions/super/call-spread-obj-undefined.js": "CRASH", - "language/expressions/super/call-spread-obj-with-overrides.js": "CRASH", - "language/expressions/super/call-spread-sngl-empty.js": "CRASH", - "language/expressions/super/call-spread-sngl-expr.js": "CRASH", - "language/expressions/super/call-spread-sngl-iter.js": "CRASH", - "language/expressions/super/call-spread-sngl-literal.js": "CRASH", - "language/expressions/super/call-spread-sngl-obj-ident.js": "CRASH", "language/expressions/super/prop-dot-cls-null-proto.js": "CRASH", "language/expressions/super/prop-dot-cls-ref-strict.js": "CRASH", "language/expressions/super/prop-dot-cls-ref-this.js": "CRASH", @@ -18944,7 +18786,6 @@ "language/literals/string/paragraph-separator-eval.js": "FAIL", "language/module-code/top-level-await/new-await-script-code.js": "FAIL", "language/reserved-words/await-script.js": "FAIL", - "language/rest-parameters/with-new-target.js": "CRASH", "language/source-text/6.1.js": "CRASH", "language/statementList/block-block-with-labels.js": "CRASH", "language/statementList/block-let-declaration.js": "FAIL", @@ -19451,7 +19292,6 @@ "language/statements/class/class-name-ident-static.js": "CRASH", "language/statements/class/class-name-ident-yield-escaped.js": "CRASH", "language/statements/class/class-name-ident-yield.js": "CRASH", - "language/statements/class/classelementname-abrupt-completion.js": "CRASH", "language/statements/class/cpn-class-decl-fields-computed-property-name-from-additive-expression-add.js": "CRASH", "language/statements/class/cpn-class-decl-fields-computed-property-name-from-additive-expression-subtract.js": "CRASH", "language/statements/class/cpn-class-decl-fields-computed-property-name-from-arrow-function-expression.js": "CRASH", @@ -19515,7 +19355,6 @@ "language/statements/class/cptn-decl.js": "CRASH", "language/statements/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier.js": "CRASH", "language/statements/class/decorator/syntax/valid/class-element-decorator-call-expr-identifier-reference.js": "CRASH", - "language/statements/class/decorator/syntax/valid/class-element-decorator-member-expr-decorator-member-expr.js": "CRASH", "language/statements/class/decorator/syntax/valid/class-element-decorator-member-expr-identifier-reference.js": "CRASH", "language/statements/class/decorator/syntax/valid/class-element-decorator-parenthesized-expr-identifier-reference.js": "CRASH", "language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference.js": "FAIL", @@ -19529,11 +19368,8 @@ "language/statements/class/definition/methods-async-super-call-param.js": "CRASH", "language/statements/class/definition/methods-gen-yield-star-before-newline.js": "CRASH", "language/statements/class/definition/numeric-property-names.js": "CRASH", - "language/statements/class/definition/prototype-wiring.js": "CRASH", "language/statements/class/definition/side-effects-in-extends.js": "CRASH", - "language/statements/class/definition/this-access-restriction-2.js": "CRASH", "language/statements/class/definition/this-access-restriction.js": "CRASH", - "language/statements/class/definition/this-check-ordering.js": "CRASH", "language/statements/class/dstr/async-gen-meth-ary-init-iter-close.js": "CRASH", "language/statements/class/dstr/async-gen-meth-ary-init-iter-get-err-array-prototype.js": "CRASH", "language/statements/class/dstr/async-gen-meth-ary-init-iter-get-err.js": "CRASH", @@ -21043,17 +20879,11 @@ "language/statements/class/dstr/private-meth-static-obj-ptrn-rest-skip-non-enumerable.js": "CRASH", "language/statements/class/dstr/private-meth-static-obj-ptrn-rest-val-obj.js": "CRASH", "language/statements/class/elements/abrupt-completition-on-field-initializer.js": "CRASH", - "language/statements/class/elements/after-same-line-gen-computed-names.js": "CRASH", - "language/statements/class/elements/after-same-line-gen-computed-symbol-names.js": "CRASH", "language/statements/class/elements/after-same-line-gen-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/after-same-line-gen-literal-names-asi.js": "CRASH", - "language/statements/class/elements/after-same-line-gen-literal-names.js": "CRASH", "language/statements/class/elements/after-same-line-gen-private-field-usage.js": "CRASH", "language/statements/class/elements/after-same-line-gen-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/after-same-line-gen-private-method-usage.js": "CRASH", "language/statements/class/elements/after-same-line-gen-private-names.js": "CRASH", - "language/statements/class/elements/after-same-line-gen-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/after-same-line-gen-rs-field-identifier.js": "CRASH", "language/statements/class/elements/after-same-line-gen-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/after-same-line-gen-rs-private-getter.js": "CRASH", "language/statements/class/elements/after-same-line-gen-rs-private-method-alt.js": "CRASH", @@ -21083,17 +20913,11 @@ "language/statements/class/elements/after-same-line-gen-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/after-same-line-gen-static-private-methods.js": "CRASH", "language/statements/class/elements/after-same-line-gen-string-literal-names.js": "CRASH", - "language/statements/class/elements/after-same-line-method-computed-names.js": "CRASH", - "language/statements/class/elements/after-same-line-method-computed-symbol-names.js": "CRASH", "language/statements/class/elements/after-same-line-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/after-same-line-method-literal-names-asi.js": "CRASH", - "language/statements/class/elements/after-same-line-method-literal-names.js": "CRASH", "language/statements/class/elements/after-same-line-method-private-field-usage.js": "CRASH", "language/statements/class/elements/after-same-line-method-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/after-same-line-method-private-method-usage.js": "CRASH", "language/statements/class/elements/after-same-line-method-private-names.js": "CRASH", - "language/statements/class/elements/after-same-line-method-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/after-same-line-method-rs-field-identifier.js": "CRASH", "language/statements/class/elements/after-same-line-method-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/after-same-line-method-rs-private-getter.js": "CRASH", "language/statements/class/elements/after-same-line-method-rs-private-method-alt.js": "CRASH", @@ -21163,17 +20987,11 @@ "language/statements/class/elements/after-same-line-static-async-gen-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-gen-static-private-methods.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-gen-string-literal-names.js": "CRASH", - "language/statements/class/elements/after-same-line-static-async-method-computed-names.js": "CRASH", - "language/statements/class/elements/after-same-line-static-async-method-computed-symbol-names.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/after-same-line-static-async-method-literal-names-asi.js": "CRASH", - "language/statements/class/elements/after-same-line-static-async-method-literal-names.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-private-field-usage.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-private-method-usage.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-private-names.js": "CRASH", - "language/statements/class/elements/after-same-line-static-async-method-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/after-same-line-static-async-method-rs-field-identifier.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-rs-private-getter.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-rs-private-method-alt.js": "CRASH", @@ -21203,17 +21021,11 @@ "language/statements/class/elements/after-same-line-static-async-method-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-static-private-methods.js": "CRASH", "language/statements/class/elements/after-same-line-static-async-method-string-literal-names.js": "CRASH", - "language/statements/class/elements/after-same-line-static-gen-computed-names.js": "CRASH", - "language/statements/class/elements/after-same-line-static-gen-computed-symbol-names.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/after-same-line-static-gen-literal-names-asi.js": "CRASH", - "language/statements/class/elements/after-same-line-static-gen-literal-names.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-private-field-usage.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-private-method-usage.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-private-names.js": "CRASH", - "language/statements/class/elements/after-same-line-static-gen-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/after-same-line-static-gen-rs-field-identifier.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-rs-private-getter.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-rs-private-method-alt.js": "CRASH", @@ -21243,17 +21055,11 @@ "language/statements/class/elements/after-same-line-static-gen-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-static-private-methods.js": "CRASH", "language/statements/class/elements/after-same-line-static-gen-string-literal-names.js": "CRASH", - "language/statements/class/elements/after-same-line-static-method-computed-names.js": "CRASH", - "language/statements/class/elements/after-same-line-static-method-computed-symbol-names.js": "CRASH", "language/statements/class/elements/after-same-line-static-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/after-same-line-static-method-literal-names-asi.js": "CRASH", - "language/statements/class/elements/after-same-line-static-method-literal-names.js": "CRASH", "language/statements/class/elements/after-same-line-static-method-private-field-usage.js": "CRASH", "language/statements/class/elements/after-same-line-static-method-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/after-same-line-static-method-private-method-usage.js": "CRASH", "language/statements/class/elements/after-same-line-static-method-private-names.js": "CRASH", - "language/statements/class/elements/after-same-line-static-method-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/after-same-line-static-method-rs-field-identifier.js": "CRASH", "language/statements/class/elements/after-same-line-static-method-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/after-same-line-static-method-rs-private-getter.js": "CRASH", "language/statements/class/elements/after-same-line-static-method-rs-private-method-alt.js": "CRASH", @@ -21453,9 +21259,6 @@ "language/statements/class/elements/async-private-method/returns-async-function.js": "CRASH", "language/statements/class/elements/class-field-is-observable-by-proxy.js": "CRASH", "language/statements/class/elements/class-field-on-frozen-objects.js": "CRASH", - "language/statements/class/elements/computed-name-toprimitive-symbol.js": "CRASH", - "language/statements/class/elements/computed-name-toprimitive.js": "CRASH", - "language/statements/class/elements/computed-property-abrupt-completition.js": "CRASH", "language/statements/class/elements/derived-cls-direct-eval-contains-superproperty-1.js": "CRASH", "language/statements/class/elements/derived-cls-direct-eval-contains-superproperty-2.js": "CRASH", "language/statements/class/elements/derived-cls-direct-eval-err-contains-supercall-1.js": "CRASH", @@ -21468,7 +21271,6 @@ "language/statements/class/elements/derived-cls-indirect-eval-err-contains-supercall.js": "CRASH", "language/statements/class/elements/direct-eval-err-contains-arguments.js": "CRASH", "language/statements/class/elements/direct-eval-err-contains-newtarget.js": "CRASH", - "language/statements/class/elements/evaluation-error/computed-name-referenceerror.js": "CRASH", "language/statements/class/elements/evaluation-error/computed-name-toprimitive-err.js": "CRASH", "language/statements/class/elements/evaluation-error/computed-name-toprimitive-returns-noncallable.js": "CRASH", "language/statements/class/elements/evaluation-error/computed-name-toprimitive-returns-nonobject.js": "CRASH", @@ -21478,15 +21280,10 @@ "language/statements/class/elements/field-definition-accessor-no-line-terminator.js": "CRASH", "language/statements/class/elements/fielddefinition-initializer-abrupt-completion.js": "CRASH", "language/statements/class/elements/fields-anonymous-function-length.js": "CRASH", - "language/statements/class/elements/fields-asi-1.js": "CRASH", - "language/statements/class/elements/fields-asi-2.js": "CRASH", - "language/statements/class/elements/fields-asi-5.js": "CRASH", - "language/statements/class/elements/fields-computed-name-propname-constructor.js": "CRASH", "language/statements/class/elements/fields-computed-name-static-computed-var-propname-constructor.js": "CRASH", "language/statements/class/elements/fields-computed-name-static-computed-var-propname-prototype.js": "CRASH", "language/statements/class/elements/fields-computed-name-static-propname-constructor.js": "CRASH", "language/statements/class/elements/fields-computed-name-static-propname-prototype.js": "CRASH", - "language/statements/class/elements/fields-hash-constructor-is-a-valid-name.js": "CRASH", "language/statements/class/elements/gen-private-method-static/yield-spread-arr-multiple.js": "CRASH", "language/statements/class/elements/gen-private-method-static/yield-spread-arr-single.js": "CRASH", "language/statements/class/elements/gen-private-method-static/yield-spread-obj.js": "CRASH", @@ -21500,20 +21297,12 @@ "language/statements/class/elements/indirect-eval-contains-arguments.js": "CRASH", "language/statements/class/elements/indirect-eval-err-contains-newtarget.js": "CRASH", "language/statements/class/elements/init-err-evaluation.js": "CRASH", - "language/statements/class/elements/init-value-defined-after-class.js": "CRASH", - "language/statements/class/elements/init-value-incremental.js": "CRASH", "language/statements/class/elements/intercalated-static-non-static-computed-fields.js": "CRASH", - "language/statements/class/elements/multiple-definitions-computed-names.js": "CRASH", - "language/statements/class/elements/multiple-definitions-computed-symbol-names.js": "CRASH", "language/statements/class/elements/multiple-definitions-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/multiple-definitions-literal-names-asi.js": "CRASH", - "language/statements/class/elements/multiple-definitions-literal-names.js": "CRASH", "language/statements/class/elements/multiple-definitions-private-field-usage.js": "CRASH", "language/statements/class/elements/multiple-definitions-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/multiple-definitions-private-method-usage.js": "CRASH", "language/statements/class/elements/multiple-definitions-private-names.js": "CRASH", - "language/statements/class/elements/multiple-definitions-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/multiple-definitions-rs-field-identifier.js": "CRASH", "language/statements/class/elements/multiple-definitions-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/multiple-definitions-rs-private-getter.js": "CRASH", "language/statements/class/elements/multiple-definitions-rs-private-method-alt.js": "CRASH", @@ -21543,17 +21332,11 @@ "language/statements/class/elements/multiple-definitions-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/multiple-definitions-static-private-methods.js": "CRASH", "language/statements/class/elements/multiple-definitions-string-literal-names.js": "CRASH", - "language/statements/class/elements/multiple-stacked-definitions-computed-names.js": "CRASH", - "language/statements/class/elements/multiple-stacked-definitions-computed-symbol-names.js": "CRASH", "language/statements/class/elements/multiple-stacked-definitions-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/multiple-stacked-definitions-literal-names-asi.js": "CRASH", - "language/statements/class/elements/multiple-stacked-definitions-literal-names.js": "CRASH", "language/statements/class/elements/multiple-stacked-definitions-private-field-usage.js": "CRASH", "language/statements/class/elements/multiple-stacked-definitions-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/multiple-stacked-definitions-private-method-usage.js": "CRASH", "language/statements/class/elements/multiple-stacked-definitions-private-names.js": "CRASH", - "language/statements/class/elements/multiple-stacked-definitions-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/multiple-stacked-definitions-rs-field-identifier.js": "CRASH", "language/statements/class/elements/multiple-stacked-definitions-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/multiple-stacked-definitions-rs-private-getter.js": "CRASH", "language/statements/class/elements/multiple-stacked-definitions-rs-private-method-alt.js": "CRASH", @@ -21611,17 +21394,11 @@ "language/statements/class/elements/nested-private-direct-eval-err-contains-newtarget.js": "CRASH", "language/statements/class/elements/nested-private-indirect-eval-contains-arguments.js": "CRASH", "language/statements/class/elements/nested-private-indirect-eval-err-contains-newtarget.js": "CRASH", - "language/statements/class/elements/new-no-sc-line-method-computed-names.js": "CRASH", - "language/statements/class/elements/new-no-sc-line-method-computed-symbol-names.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/new-no-sc-line-method-literal-names-asi.js": "CRASH", - "language/statements/class/elements/new-no-sc-line-method-literal-names.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-private-field-usage.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-private-method-usage.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-private-names.js": "CRASH", - "language/statements/class/elements/new-no-sc-line-method-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/new-no-sc-line-method-rs-field-identifier.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-rs-private-getter.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-rs-private-method-alt.js": "CRASH", @@ -21651,17 +21428,11 @@ "language/statements/class/elements/new-no-sc-line-method-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-static-private-methods.js": "CRASH", "language/statements/class/elements/new-no-sc-line-method-string-literal-names.js": "CRASH", - "language/statements/class/elements/new-sc-line-gen-computed-names.js": "CRASH", - "language/statements/class/elements/new-sc-line-gen-computed-symbol-names.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/new-sc-line-gen-literal-names-asi.js": "CRASH", - "language/statements/class/elements/new-sc-line-gen-literal-names.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-private-field-usage.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-private-method-usage.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-private-names.js": "CRASH", - "language/statements/class/elements/new-sc-line-gen-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/new-sc-line-gen-rs-field-identifier.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-rs-private-getter.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-rs-private-method-alt.js": "CRASH", @@ -21691,17 +21462,11 @@ "language/statements/class/elements/new-sc-line-gen-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-static-private-methods.js": "CRASH", "language/statements/class/elements/new-sc-line-gen-string-literal-names.js": "CRASH", - "language/statements/class/elements/new-sc-line-method-computed-names.js": "CRASH", - "language/statements/class/elements/new-sc-line-method-computed-symbol-names.js": "CRASH", "language/statements/class/elements/new-sc-line-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/new-sc-line-method-literal-names-asi.js": "CRASH", - "language/statements/class/elements/new-sc-line-method-literal-names.js": "CRASH", "language/statements/class/elements/new-sc-line-method-private-field-usage.js": "CRASH", "language/statements/class/elements/new-sc-line-method-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/new-sc-line-method-private-method-usage.js": "CRASH", "language/statements/class/elements/new-sc-line-method-private-names.js": "CRASH", - "language/statements/class/elements/new-sc-line-method-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/new-sc-line-method-rs-field-identifier.js": "CRASH", "language/statements/class/elements/new-sc-line-method-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/new-sc-line-method-rs-private-getter.js": "CRASH", "language/statements/class/elements/new-sc-line-method-rs-private-method-alt.js": "CRASH", @@ -21905,19 +21670,12 @@ "language/statements/class/elements/prod-private-setter-before-super-return-in-field-initializer.js": "CRASH", "language/statements/class/elements/public-class-field-initialization-is-visible-to-proxy.js": "CRASH", "language/statements/class/elements/public-class-field-initialization-on-super-class-with-setter.js": "CRASH", - "language/statements/class/elements/redeclaration-symbol.js": "CRASH", "language/statements/class/elements/redeclaration.js": "CRASH", - "language/statements/class/elements/regular-definitions-computed-names.js": "CRASH", - "language/statements/class/elements/regular-definitions-computed-symbol-names.js": "CRASH", "language/statements/class/elements/regular-definitions-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/regular-definitions-literal-names-asi.js": "CRASH", - "language/statements/class/elements/regular-definitions-literal-names.js": "CRASH", "language/statements/class/elements/regular-definitions-private-field-usage.js": "CRASH", "language/statements/class/elements/regular-definitions-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/regular-definitions-private-method-usage.js": "CRASH", "language/statements/class/elements/regular-definitions-private-names.js": "CRASH", - "language/statements/class/elements/regular-definitions-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/regular-definitions-rs-field-identifier.js": "CRASH", "language/statements/class/elements/regular-definitions-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/regular-definitions-rs-private-getter.js": "CRASH", "language/statements/class/elements/regular-definitions-rs-private-method-alt.js": "CRASH", @@ -21987,17 +21745,11 @@ "language/statements/class/elements/same-line-async-gen-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/same-line-async-gen-static-private-methods.js": "CRASH", "language/statements/class/elements/same-line-async-gen-string-literal-names.js": "CRASH", - "language/statements/class/elements/same-line-async-method-computed-names.js": "CRASH", - "language/statements/class/elements/same-line-async-method-computed-symbol-names.js": "CRASH", "language/statements/class/elements/same-line-async-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/same-line-async-method-literal-names-asi.js": "CRASH", - "language/statements/class/elements/same-line-async-method-literal-names.js": "CRASH", "language/statements/class/elements/same-line-async-method-private-field-usage.js": "CRASH", "language/statements/class/elements/same-line-async-method-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/same-line-async-method-private-method-usage.js": "CRASH", "language/statements/class/elements/same-line-async-method-private-names.js": "CRASH", - "language/statements/class/elements/same-line-async-method-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/same-line-async-method-rs-field-identifier.js": "CRASH", "language/statements/class/elements/same-line-async-method-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/same-line-async-method-rs-private-getter.js": "CRASH", "language/statements/class/elements/same-line-async-method-rs-private-method-alt.js": "CRASH", @@ -22027,17 +21779,11 @@ "language/statements/class/elements/same-line-async-method-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/same-line-async-method-static-private-methods.js": "CRASH", "language/statements/class/elements/same-line-async-method-string-literal-names.js": "CRASH", - "language/statements/class/elements/same-line-gen-computed-names.js": "CRASH", - "language/statements/class/elements/same-line-gen-computed-symbol-names.js": "CRASH", "language/statements/class/elements/same-line-gen-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/same-line-gen-literal-names-asi.js": "CRASH", - "language/statements/class/elements/same-line-gen-literal-names.js": "CRASH", "language/statements/class/elements/same-line-gen-private-field-usage.js": "CRASH", "language/statements/class/elements/same-line-gen-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/same-line-gen-private-method-usage.js": "CRASH", "language/statements/class/elements/same-line-gen-private-names.js": "CRASH", - "language/statements/class/elements/same-line-gen-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/same-line-gen-rs-field-identifier.js": "CRASH", "language/statements/class/elements/same-line-gen-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/same-line-gen-rs-private-getter.js": "CRASH", "language/statements/class/elements/same-line-gen-rs-private-method-alt.js": "CRASH", @@ -22067,17 +21813,11 @@ "language/statements/class/elements/same-line-gen-static-private-methods-with-fields.js": "CRASH", "language/statements/class/elements/same-line-gen-static-private-methods.js": "CRASH", "language/statements/class/elements/same-line-gen-string-literal-names.js": "CRASH", - "language/statements/class/elements/same-line-method-computed-names.js": "CRASH", - "language/statements/class/elements/same-line-method-computed-symbol-names.js": "CRASH", "language/statements/class/elements/same-line-method-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/same-line-method-literal-names-asi.js": "CRASH", - "language/statements/class/elements/same-line-method-literal-names.js": "CRASH", "language/statements/class/elements/same-line-method-private-field-usage.js": "CRASH", "language/statements/class/elements/same-line-method-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/same-line-method-private-method-usage.js": "CRASH", "language/statements/class/elements/same-line-method-private-names.js": "CRASH", - "language/statements/class/elements/same-line-method-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/same-line-method-rs-field-identifier.js": "CRASH", "language/statements/class/elements/same-line-method-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/same-line-method-rs-private-getter.js": "CRASH", "language/statements/class/elements/same-line-method-rs-private-method-alt.js": "CRASH", @@ -22112,8 +21852,6 @@ "language/statements/class/elements/set-access-of-missing-shadowed-private-setter.js": "CRASH", "language/statements/class/elements/set-access-of-private-method.js": "CRASH", "language/statements/class/elements/set-access-of-shadowed-private-method.js": "CRASH", - "language/statements/class/elements/static-as-valid-instance-field-assigned.js": "CRASH", - "language/statements/class/elements/static-as-valid-instance-field.js": "CRASH", "language/statements/class/elements/static-as-valid-static-field-assigned.js": "CRASH", "language/statements/class/elements/static-as-valid-static-field.js": "CRASH", "language/statements/class/elements/static-field-anonymous-function-length.js": "CRASH", @@ -22121,7 +21859,6 @@ "language/statements/class/elements/static-field-declaration.js": "CRASH", "language/statements/class/elements/static-field-init-this-inside-arrow-function.js": "CRASH", "language/statements/class/elements/static-field-init-with-this.js": "CRASH", - "language/statements/class/elements/static-field-initializer-error.js": "CRASH", "language/statements/class/elements/static-field-redeclaration.js": "CRASH", "language/statements/class/elements/static-fielddefinition-initializer-abrupt-completion.js": "CRASH", "language/statements/class/elements/static-private-fields-proxy-default-handler-throws.js": "CRASH", @@ -22144,13 +21881,8 @@ "language/statements/class/elements/super-access-inside-a-private-setter.js": "CRASH", "language/statements/class/elements/super-fielddefinition-initializer-abrupt-completion.js": "CRASH", "language/statements/class/elements/syntax/valid/grammar-field-accessor.js": "CRASH", - "language/statements/class/elements/syntax/valid/grammar-field-classelementname-initializer-alt.js": "CRASH", - "language/statements/class/elements/syntax/valid/grammar-field-classelementname-initializer.js": "CRASH", - "language/statements/class/elements/syntax/valid/grammar-field-identifier-alt.js": "CRASH", - "language/statements/class/elements/syntax/valid/grammar-field-identifier.js": "CRASH", "language/statements/class/elements/syntax/valid/grammar-field-named-get-followed-by-generator-asi.js": "CRASH", "language/statements/class/elements/syntax/valid/grammar-field-named-set-followed-by-generator-asi.js": "CRASH", - "language/statements/class/elements/syntax/valid/grammar-fields-multi-line.js": "CRASH", "language/statements/class/elements/syntax/valid/grammar-privatemeth-duplicate-get-set.js": "CRASH", "language/statements/class/elements/syntax/valid/grammar-privatemeth-duplicate-meth-nestedclassmeth.js": "CRASH", "language/statements/class/elements/syntax/valid/grammar-privatename-classelementname-initializer-alt.js": "CRASH", @@ -22162,17 +21894,11 @@ "language/statements/class/elements/syntax/valid/grammar-static-private-async-meth-prototype.js": "CRASH", "language/statements/class/elements/syntax/valid/grammar-static-private-gen-meth-prototype.js": "CRASH", "language/statements/class/elements/syntax/valid/grammar-static-private-meth-prototype.js": "CRASH", - "language/statements/class/elements/wrapped-in-sc-computed-names.js": "CRASH", - "language/statements/class/elements/wrapped-in-sc-computed-symbol-names.js": "CRASH", "language/statements/class/elements/wrapped-in-sc-grammar-privatename-identifier-semantics-stringvalue.js": "CRASH", - "language/statements/class/elements/wrapped-in-sc-literal-names-asi.js": "CRASH", - "language/statements/class/elements/wrapped-in-sc-literal-names.js": "CRASH", "language/statements/class/elements/wrapped-in-sc-private-field-usage.js": "CRASH", "language/statements/class/elements/wrapped-in-sc-private-method-getter-usage.js": "CRASH", "language/statements/class/elements/wrapped-in-sc-private-method-usage.js": "CRASH", "language/statements/class/elements/wrapped-in-sc-private-names.js": "CRASH", - "language/statements/class/elements/wrapped-in-sc-rs-field-identifier-initializer.js": "CRASH", - "language/statements/class/elements/wrapped-in-sc-rs-field-identifier.js": "CRASH", "language/statements/class/elements/wrapped-in-sc-rs-private-getter-alt.js": "CRASH", "language/statements/class/elements/wrapped-in-sc-rs-private-getter.js": "CRASH", "language/statements/class/elements/wrapped-in-sc-rs-private-method-alt.js": "CRASH", @@ -22210,8 +21936,6 @@ "language/statements/class/gen-method/dflt-params-ref-later.js": "CRASH", "language/statements/class/gen-method/dflt-params-ref-self.js": "CRASH", "language/statements/class/method-length-dflt.js": "CRASH", - "language/statements/class/static-classelementname-abrupt-completion.js": "CRASH", - "language/statements/class/static-init-abrupt.js": "CRASH", "language/statements/class/static-init-arguments-functions.js": "CRASH", "language/statements/class/static-init-arguments-methods.js": "CRASH", "language/statements/class/static-init-await-binding-valid.js": "FAIL", @@ -22229,7 +21953,6 @@ "language/statements/class/subclass-builtins/subclass-Date.js": "CRASH", "language/statements/class/subclass-builtins/subclass-Float32Array.js": "CRASH", "language/statements/class/subclass-builtins/subclass-Float64Array.js": "CRASH", - "language/statements/class/subclass-builtins/subclass-Function.js": "CRASH", "language/statements/class/subclass-builtins/subclass-Int16Array.js": "CRASH", "language/statements/class/subclass-builtins/subclass-Int32Array.js": "CRASH", "language/statements/class/subclass-builtins/subclass-Int8Array.js": "CRASH", @@ -22243,54 +21966,29 @@ "language/statements/class/subclass-builtins/subclass-WeakMap.js": "CRASH", "language/statements/class/subclass-builtins/subclass-WeakRef.js": "CRASH", "language/statements/class/subclass-builtins/subclass-WeakSet.js": "CRASH", - "language/statements/class/subclass/binding.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Array/contructor-calls-super-multiple-arguments.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Array/contructor-calls-super-single-argument.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Array/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/ArrayBuffer/regular-subclassing.js": "CRASH", - "language/statements/class/subclass/builtin-objects/ArrayBuffer/super-must-be-called.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Boolean/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/DataView/regular-subclassing.js": "CRASH", "language/statements/class/subclass/builtin-objects/DataView/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/Date/regular-subclassing.js": "CRASH", "language/statements/class/subclass/builtin-objects/Date/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/Error/message-property-assignment.js": "CRASH", "language/statements/class/subclass/builtin-objects/Error/regular-subclassing.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Error/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/Function/instance-length.js": "CRASH", "language/statements/class/subclass/builtin-objects/Function/instance-name.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Function/regular-subclassing.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Function/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/GeneratorFunction/instance-length.js": "CRASH", "language/statements/class/subclass/builtin-objects/GeneratorFunction/instance-name.js": "CRASH", - "language/statements/class/subclass/builtin-objects/GeneratorFunction/instance-prototype.js": "CRASH", - "language/statements/class/subclass/builtin-objects/GeneratorFunction/regular-subclassing.js": "CRASH", - "language/statements/class/subclass/builtin-objects/GeneratorFunction/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/Map/regular-subclassing.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Map/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/NativeError/EvalError-message.js": "CRASH", - "language/statements/class/subclass/builtin-objects/NativeError/EvalError-super.js": "CRASH", "language/statements/class/subclass/builtin-objects/NativeError/RangeError-message.js": "CRASH", - "language/statements/class/subclass/builtin-objects/NativeError/RangeError-super.js": "CRASH", "language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-message.js": "CRASH", - "language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-super.js": "CRASH", "language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-message.js": "CRASH", - "language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-super.js": "CRASH", "language/statements/class/subclass/builtin-objects/NativeError/TypeError-message.js": "CRASH", - "language/statements/class/subclass/builtin-objects/NativeError/TypeError-super.js": "CRASH", "language/statements/class/subclass/builtin-objects/NativeError/URIError-message.js": "CRASH", - "language/statements/class/subclass/builtin-objects/NativeError/URIError-super.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Number/super-must-be-called.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Object/constructor-return-undefined-throws.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Object/constructor-returns-non-object.js": "CRASH", "language/statements/class/subclass/builtin-objects/Promise/regular-subclassing.js": "CRASH", "language/statements/class/subclass/builtin-objects/Promise/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/RegExp/lastIndex.js": "CRASH", "language/statements/class/subclass/builtin-objects/RegExp/regular-subclassing.js": "CRASH", "language/statements/class/subclass/builtin-objects/RegExp/super-must-be-called.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Set/super-must-be-called.js": "CRASH", - "language/statements/class/subclass/builtin-objects/String/super-must-be-called.js": "CRASH", - "language/statements/class/subclass/builtin-objects/Symbol/new-symbol-with-super-throws.js": "CRASH", "language/statements/class/subclass/builtin-objects/TypedArray/regular-subclassing.js": "CRASH", "language/statements/class/subclass/builtin-objects/TypedArray/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtin-objects/WeakMap/regular-subclassing.js": "CRASH", @@ -22298,26 +21996,12 @@ "language/statements/class/subclass/builtin-objects/WeakSet/regular-subclassing.js": "CRASH", "language/statements/class/subclass/builtin-objects/WeakSet/super-must-be-called.js": "CRASH", "language/statements/class/subclass/builtins.js": "CRASH", - "language/statements/class/subclass/class-definition-null-proto-super.js": "CRASH", - "language/statements/class/subclass/class-definition-null-proto-this.js": "CRASH", "language/statements/class/subclass/derived-class-return-override-catch-finally-arrow.js": "CRASH", "language/statements/class/subclass/derived-class-return-override-catch-finally.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-catch-super-arrow.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-catch-super.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-catch.js": "CRASH", "language/statements/class/subclass/derived-class-return-override-finally-super-arrow.js": "CRASH", "language/statements/class/subclass/derived-class-return-override-finally-super.js": "CRASH", "language/statements/class/subclass/derived-class-return-override-for-of-arrow.js": "CRASH", "language/statements/class/subclass/derived-class-return-override-for-of.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-with-boolean.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-with-empty.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-with-null.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-with-number.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-with-object.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-with-string.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-with-symbol.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-with-this.js": "CRASH", - "language/statements/class/subclass/derived-class-return-override-with-undefined.js": "CRASH", "language/statements/class/subclass/superclass-arrow-function.js": "CRASH", "language/statements/class/subclass/superclass-async-function.js": "CRASH", "language/statements/class/subclass/superclass-async-generator-function.js": "CRASH", @@ -22330,7 +22014,6 @@ "language/statements/class/super/in-static-getter.js": "CRASH", "language/statements/class/super/in-static-methods.js": "CRASH", "language/statements/class/super/in-static-setter.js": "CRASH", - "language/statements/class/syntax/class-body-has-direct-super-class-heritage.js": "CRASH", "language/statements/class/syntax/class-body-method-definition-super-property.js": "CRASH", "language/statements/const/cptn-value.js": "FAIL", "language/statements/const/dstr/ary-ptrn-elem-id-init-fn-name-class.js": "CRASH", diff --git a/tests/metrics.json b/tests/metrics.json index 4d199b9db..edaedd665 100644 --- a/tests/metrics.json +++ b/tests/metrics.json @@ -1,11 +1,11 @@ { "results": { - "crash": 16842, - "fail": 7996, - "pass": 20331, + "crash": 16334, + "fail": 8198, + "pass": 20637, "skip": 40, "timeout": 3, "unresolved": 0 }, "total": 45172 -} \ No newline at end of file +} From f1bd9c1afca0258dfea7a299cb14cfb277c9e6e1 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Fri, 4 Oct 2024 03:35:43 +0300 Subject: [PATCH 5/7] Fix mark&sweep of BuiltinConstructorHeapData --- nova_vm/src/ecmascript/builtins/builtin_constructor.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nova_vm/src/ecmascript/builtins/builtin_constructor.rs b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs index 83e40bf0f..4a68baaed 100644 --- a/nova_vm/src/ecmascript/builtins/builtin_constructor.rs +++ b/nova_vm/src/ecmascript/builtins/builtin_constructor.rs @@ -455,6 +455,9 @@ impl HeapMarkAndSweep for BuiltinConstructorHeapData { fn mark_values(&self, queues: &mut WorkQueues) { self.realm.mark_values(queues); self.object_index.mark_values(queues); + self.environment.mark_values(queues); + self.private_environment.mark_values(queues); + self.source_code.mark_values(queues); if let Some(exe) = &self.compiled_initializer_bytecode { // SAFETY: This is a valid, non-null pointer to an owned Executable // that cannot have any live mutable references to it. @@ -465,6 +468,9 @@ impl HeapMarkAndSweep for BuiltinConstructorHeapData { fn sweep_values(&mut self, compactions: &CompactionLists) { self.realm.sweep_values(compactions); self.object_index.sweep_values(compactions); + self.environment.sweep_values(compactions); + self.private_environment.sweep_values(compactions); + self.source_code.sweep_values(compactions); if let Some(exe) = &mut self.compiled_initializer_bytecode { // SAFETY: This is a valid, non-null pointer to an owned Executable // that cannot have any live references to it. From 3d658854b488d6d38236e44a86b88e167fa2607a Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Sat, 5 Oct 2024 16:20:32 +0300 Subject: [PATCH 6/7] typo --- nova_vm/src/engine/bytecode/instructions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova_vm/src/engine/bytecode/instructions.rs b/nova_vm/src/engine/bytecode/instructions.rs index 8af45c53c..647b968c7 100644 --- a/nova_vm/src/engine/bytecode/instructions.rs +++ b/nova_vm/src/engine/bytecode/instructions.rs @@ -74,7 +74,7 @@ pub enum Instruction { EvaluateNew, /// Store SuperCall() as the result value. /// - /// This instruction has the number of argumnet values that need to be + /// This instruction has the number of argument values that need to be /// popped from the stack (last to first) as an argument. EvaluateSuper, /// Store EvaluatePropertyAccessWithExpressionKey() as the result value. From 457e8b3f84f205a3afdfb1a134bc45a44189c7ab Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Sat, 5 Oct 2024 17:21:50 +0300 Subject: [PATCH 7/7] chore(test262): Update expectations --- tests/metrics.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/metrics.json b/tests/metrics.json index edaedd665..b3c225315 100644 --- a/tests/metrics.json +++ b/tests/metrics.json @@ -1,11 +1,11 @@ { "results": { - "crash": 16334, - "fail": 8198, - "pass": 20637, + "crash": 16310, + "fail": 8211, + "pass": 20648, "skip": 40, "timeout": 3, "unresolved": 0 }, - "total": 45172 -} + "total": 45212 +} \ No newline at end of file