diff --git a/nova_cli/src/main.rs b/nova_cli/src/main.rs index 718fd5248..7958656c9 100644 --- a/nova_cli/src/main.rs +++ b/nova_cli/src/main.rs @@ -282,7 +282,11 @@ impl HostHooks for CliHostHooks { m.into() }) .map_err(|err| { - agent.throw_exception(ExceptionType::Error, err.first().unwrap().to_string(), gc) + agent.throw_exception( + ExceptionType::SyntaxError, + err.first().unwrap().to_string(), + gc, + ) }); finish_loading_imported_module(agent, referrer, module_request, payload, result, gc); } diff --git a/nova_vm/src/ecmascript/execution/agent.rs b/nova_vm/src/ecmascript/execution/agent.rs index 3567384af..64b9bd099 100644 --- a/nova_vm/src/ecmascript/execution/agent.rs +++ b/nova_vm/src/ecmascript/execution/agent.rs @@ -506,6 +506,33 @@ pub trait HostHooks: core::fmt::Debug { unimplemented!(); } + /// ### [16.2.1.12.1 HostGetSupportedImportAttributes ( )](https://tc39.es/ecma262/#sec-hostgetsupportedimportattributes) + /// + /// The host-defined abstract operation HostGetSupportedImportAttributes + /// takes no arguments and returns a List of Strings. It allows host + /// environments to specify which import attributes they support. Only + /// attributes with supported keys will be provided to the host. + /// + /// An implementation of HostGetSupportedImportAttributes must conform to + /// the following requirements: + /// + /// * It must return a List of Strings, each indicating a supported + /// attribute. + /// * Each time this operation is called, it must return the same List with + /// the same contents in the same order. + /// + /// The default implementation of HostGetSupportedImportAttributes is to + /// return a new empty List. + /// + /// > Note: The purpose of requiring the host to specify its supported + /// > import attributes, rather than passing all attributes to the host and + /// > letting it then choose which ones it wants to handle, is to ensure + /// > that unsupported attributes are handled in a consistent way across + /// > different hosts. + fn get_supported_import_attributes(&self) -> &[&'static str] { + &[] + } + /// ### [13.3.12.1.1 HostGetImportMetaProperties ( moduleRecord )](https://tc39.es/ecma262/#sec-hostgetimportmetaproperties) /// /// The host-defined abstract operation HostGetImportMetaProperties takes diff --git a/nova_vm/src/ecmascript/scripts_and_modules/module.rs b/nova_vm/src/ecmascript/scripts_and_modules/module.rs index 91bb96118..0d11b7a06 100644 --- a/nova_vm/src/ecmascript/scripts_and_modules/module.rs +++ b/nova_vm/src/ecmascript/scripts_and_modules/module.rs @@ -13,8 +13,14 @@ use module_semantics::{ use crate::{ ecmascript::{ - abstract_operations::type_conversion::{to_string, to_string_primitive}, + abstract_operations::{ + operations_on_objects::{ + enumerable_own_properties, enumerable_properties_kind::EnumerateKeysAndValues, get, + }, + type_conversion::to_string, + }, builtins::{ + Array, promise::Promise, promise_objects::{ promise_abstract_operations::{ @@ -26,13 +32,16 @@ use crate::{ }, execution::{ Agent, JsResult, - agent::{get_active_script_or_module, unwrap_try}, + agent::{ExceptionType, get_active_script_or_module, unwrap_try}, }, - types::{IntoValue, Primitive, Value}, + scripts_and_modules::module::module_semantics::all_import_attributes_supported, + types::{BUILTIN_STRING_MEMORY, IntoValue, Object, String, Value}, }, engine::{ + Scoped, context::{Bindable, GcScope, NoGcScope}, rootable::Scopable, + typeof_operator, }, }; pub mod module_semantics; @@ -54,14 +63,15 @@ pub(crate) fn evaluate_import_call<'gc>( ) -> Promise<'gc> { let specifier = specifier.bind(gc.nogc()); let mut options = options.bind(gc.nogc()); + if options.is_some_and(|opt| opt.is_undefined()) { + options.take(); + } // 7. Let promiseCapability be ! NewPromiseCapability(%Promise%). let promise_capability = PromiseCapability::new(agent, gc.nogc()); let scoped_promise = promise_capability.promise.scope(agent, gc.nogc()); // 8. Let specifierString be Completion(ToString(specifier)). - let specifier = if let Ok(specifier) = Primitive::try_from(specifier) { - to_string_primitive(agent, specifier, gc.nogc()) - .unbind() - .bind(gc.nogc()) + let specifier = if let Ok(specifier) = String::try_from(specifier) { + specifier } else { let scoped_options = options.map(|o| o.scope(agent, gc.nogc())); let specifier = to_string(agent, specifier.unbind(), gc.reborrow()) @@ -69,48 +79,142 @@ pub(crate) fn evaluate_import_call<'gc>( .bind(gc.nogc()); // SAFETY: not shared. options = scoped_options.map(|o| unsafe { o.take(agent) }.bind(gc.nogc())); - specifier + // 9. IfAbruptRejectPromise(specifierString, promiseCapability). + let promise_capability = PromiseCapability { + promise: scoped_promise.get(agent).bind(gc.nogc()), + must_be_unresolved: true, + }; + if_abrupt_reject_promise_m!(agent, specifier, promise_capability, gc) }; - // 9. IfAbruptRejectPromise(specifierString, promiseCapability). - let promise_capability = PromiseCapability { - promise: scoped_promise.get(agent).bind(gc.nogc()), - must_be_unresolved: true, - }; - let specifier = if_abrupt_reject_promise_m!(agent, specifier, promise_capability, gc); // 10. Let attributes be a new empty List. - let attributes: Vec = vec![]; // 11. If options is not undefined, then - if let Some(_options) = options { + let (promise, specifier, attributes, gc) = if let Some(options) = options { // a. If options is not an Object, then - // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). - // ii. Return promiseCapability.[[Promise]]. + let Ok(options) = Object::try_from(options) else { + // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). + // ii. Return promiseCapability.[[Promise]]. + return reject_import_not_object_or_undefined( + agent, + scoped_promise, + options.unbind(), + gc.into_nogc(), + ); + }; + let specifier = specifier.scope(agent, gc.nogc()); // b. Let attributesObj be Completion(Get(options, "with")). + let attributes_obj = get( + agent, + options.unbind(), + BUILTIN_STRING_MEMORY.with.to_property_key(), + gc.reborrow(), + ) + .unbind() + .bind(gc.nogc()); + + let promise_capability = PromiseCapability { + promise: scoped_promise.get(agent).bind(gc.nogc()), + must_be_unresolved: true, + }; // c. IfAbruptRejectPromise(attributesObj, promiseCapability). + let attributes_obj = + if_abrupt_reject_promise_m!(agent, attributes_obj, promise_capability, gc); // d. If attributesObj is not undefined, then - // i. If attributesObj is not an Object, then - // 1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). - // 2. Return promiseCapability.[[Promise]]. - // ii. Let entries be Completion(EnumerableOwnProperties(attributesObj, key+value)). - // iii. IfAbruptRejectPromise(entries, promiseCapability). - // iv. For each element entry of entries, do - // 1. Let key be ! Get(entry, "0"). - // 2. Let value be ! Get(entry, "1"). - // 3. If key is a String, then - // a. If value is not a String, then - // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). - // ii. Return promiseCapability.[[Promise]]. - // b. Append the ImportAttribute Record { [[Key]]: key, [[Value]]: value } to attributes. - // e. If AllImportAttributesSupported(attributes) is false, then - // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). - // ii. Return promiseCapability.[[Promise]]. - // f. Sort attributes according to the lexicographic order of their [[Key]] field, treating the value of each such field as a sequence of UTF-16 code unit values. NOTE: This sorting is observable only in that hosts are prohibited from changing behaviour based on the order in which attributes are enumerated. - todo!() - } - let specifier = specifier.unbind(); - let attributes = attributes.unbind(); - let gc = gc.into_nogc(); - let specifier = specifier.bind(gc); - let attributes = attributes.bind(gc); + if !attributes_obj.is_undefined() { + // i. If attributesObj is not an Object, then + let Ok(attributes_obj) = Object::try_from(attributes_obj) else { + // 1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). + // 2. Return promiseCapability.[[Promise]]. + return reject_import_not_object_or_undefined( + agent, + scoped_promise, + attributes_obj.unbind(), + gc.into_nogc(), + ); + }; + // ii. Let entries be Completion(EnumerableOwnProperties(attributesObj, key+value)). + let entries = enumerable_own_properties::( + agent, + attributes_obj.unbind(), + gc.reborrow(), + ) + .unbind(); + let gc = gc.into_nogc(); + let entries = entries.bind(gc); + + let promise = unsafe { scoped_promise.take(agent) }.bind(gc); + let promise_capability = PromiseCapability { + promise, + must_be_unresolved: true, + }; + // iii. IfAbruptRejectPromise(entries, promiseCapability). + // 1. Assert: value is a Completion Record. + let entries = match entries { + // 2. If value is an abrupt completion, then + Err(err) => { + // a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). + promise_capability.reject(agent, err.value().unbind(), gc); + // b. Return capability.[[Promise]]. + return promise_capability.promise; + } + // 3. Else, + Ok(value) => { + // a. Set value to ! value. + value + } + }; + let mut attributes: Vec = Vec::with_capacity(entries.len()); + // iv. For each element entry of entries, do + for entry in entries { + let entry = Array::try_from(entry).unwrap(); + let entry = entry.get_storage(agent).values; + // 1. Let key be ! Get(entry, "0"). + let key = entry[0].unwrap(); + // 2. Let value be ! Get(entry, "1"). + let value = entry[0].unwrap(); + // 3. If key is a String, then + if let Ok(key) = String::try_from(key) { + // a. If value is not a String, then + let Ok(value) = String::try_from(value) else { + // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). + // ii. Return promiseCapability.[[Promise]]. + return reject_unsupported_import_attribute( + agent, + promise_capability, + key.unbind(), + gc.into_nogc(), + ); + }; + // b. Append the ImportAttribute Record { [[Key]]: key, [[Value]]: value } to attributes. + attributes.push(ImportAttributeRecord { key, value }); + } + } + // e. If AllImportAttributesSupported(attributes) is false, then + if !all_import_attributes_supported(agent, &attributes) { + // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). + // ii. Return promiseCapability.[[Promise]]. + return reject_unsupported_import_attributes(agent, promise_capability, gc); + } + // f. Sort attributes according to the lexicographic order of their + // [[Key]] field, treating the value of each such field as a sequence + // of UTF-16 code unit values. NOTE: This sorting is observable only + // in that hosts are prohibited from changing behaviour based on the + // order in which attributes are enumerated. + attributes.sort_by(|a, b| a.key.as_wtf8(agent).cmp(b.key.as_wtf8(agent))); + let specifier = unsafe { specifier.take(agent) }.bind(gc); + (promise, specifier, attributes.into_boxed_slice(), gc) + } else { + let gc = gc.into_nogc(); + let specifier = unsafe { specifier.take(agent) }.bind(gc); + let promise = unsafe { scoped_promise.take(agent) }.bind(gc); + (promise, specifier, Default::default(), gc) + } + } else { + let specifier = specifier.unbind(); + let gc = gc.into_nogc(); + let specifier = specifier.bind(gc); + let promise = unsafe { scoped_promise.take(agent) }.bind(gc); + (promise, specifier, Default::default(), gc) + }; // 12. Let moduleRequest be a new ModuleRequest Record { let module_request = ModuleRequest::new_dynamic( agent, // [[Specifier]]: specifierString, @@ -125,8 +229,6 @@ pub(crate) fn evaluate_import_call<'gc>( .unwrap_or_else(|| agent.current_realm(gc).into()); // 13. Perform HostLoadImportedModule(referrer, moduleRequest, empty, promiseCapability). // Note: this is against the spec. We'll fix it in post. - // SAFETY: scoped_promise is not shared. - let promise = unsafe { scoped_promise.take(agent) }.bind(gc); let mut payload = GraphLoadingStateRecord::from_promise(promise); agent .host_hooks @@ -135,6 +237,68 @@ pub(crate) fn evaluate_import_call<'gc>( promise } +#[cold] +#[inline(never)] +fn reject_import_not_object_or_undefined<'gc>( + agent: &mut Agent, + scoped_promise: Scoped, + value: Value, + gc: NoGcScope<'gc, '_>, +) -> Promise<'gc> { + let value = value.bind(gc); + let promise_capability = PromiseCapability { + // SAFETY: not shared. + promise: unsafe { scoped_promise.take(agent) }.bind(gc), + must_be_unresolved: true, + }; + // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). + let message = format!( + "import: expected object or undefined, got {}", + typeof_operator(agent, value, gc).to_string_lossy(agent) + ); + let error = agent.throw_exception(ExceptionType::TypeError, message, gc); + promise_capability.reject(agent, error.value(), gc); + // ii. Return promiseCapability.[[Promise]]. + promise_capability.promise +} + +#[cold] +#[inline(never)] +fn reject_unsupported_import_attribute<'gc>( + agent: &mut Agent, + promise_capability: PromiseCapability<'gc>, + key: String<'gc>, + gc: NoGcScope<'gc, '_>, +) -> Promise<'gc> { + // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). + let message = format!( + "Unsupported import attribute: {}", + key.to_string_lossy(agent) + ); + let error = agent.throw_exception(ExceptionType::TypeError, message, gc); + promise_capability.reject(agent, error.value(), gc); + // ii. Return promiseCapability.[[Promise]]. + promise_capability.promise +} + +#[cold] +#[inline(never)] +fn reject_unsupported_import_attributes<'gc>( + agent: &mut Agent, + promise_capability: PromiseCapability<'gc>, + gc: NoGcScope<'gc, '_>, +) -> Promise<'gc> { + // i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). + let error = agent.throw_exception_with_static_message( + ExceptionType::TypeError, + "Unsupported import attributes", + gc, + ); + promise_capability.reject(agent, error.value(), gc); + // ii. Return promiseCapability.[[Promise]]. + promise_capability.promise +} + /// ### [13.3.10.3 ContinueDynamicImport ( promiseCapability, moduleCompletion )](https://tc39.es/ecma262/#sec-ContinueDynamicImport) /// /// The abstract operation ContinueDynamicImport takes arguments diff --git a/nova_vm/src/ecmascript/scripts_and_modules/module/module_semantics.rs b/nova_vm/src/ecmascript/scripts_and_modules/module/module_semantics.rs index 68f1b4e5c..62dab3c71 100644 --- a/nova_vm/src/ecmascript/scripts_and_modules/module/module_semantics.rs +++ b/nova_vm/src/ecmascript/scripts_and_modules/module/module_semantics.rs @@ -149,11 +149,10 @@ impl<'r> ModuleRequest<'r> { pub(super) fn new_dynamic( agent: &mut Agent, specifier: String, - attributes: Vec, + attributes: Box<[ImportAttributeRecord]>, gc: NoGcScope<'r, '_>, ) -> Self { let mut state = AHasher::default(); - let attributes = attributes.into_boxed_slice(); specifier.to_string_lossy(agent).hash(&mut state); for attribute in attributes.iter() { attribute.key.to_string_lossy(agent).hash(&mut state); @@ -217,15 +216,14 @@ pub struct ImportAttributeRecord<'a> { /// a String /// /// The attribute key - key: String<'a>, + pub(crate) key: String<'a>, /// ### \[\[Value]] /// /// a String /// /// The attribute value - value: String<'a>, + pub(crate) value: String<'a>, } - bindable_handle!(ImportAttributeRecord); /// ### \[\[LoadedModules]] @@ -535,6 +533,28 @@ pub fn finish_loading_imported_module<'a>( // 4. Return unused. } +/// ### [16.2.1.12 AllImportAttributesSupported ( attributes )](https://tc39.es/ecma262/#sec-AllImportAttributesSupported) +/// +/// The abstract operation AllImportAttributesSupported takes argument +/// _attributes_ (a List of ImportAttribute Records) and returns a Boolean. +pub(crate) fn all_import_attributes_supported( + agent: &Agent, + attributes: &[ImportAttributeRecord], +) -> bool { + // 1. Let supported be HostGetSupportedImportAttributes(). + let supported = agent.host_hooks.get_supported_import_attributes(); + // 2. For each ImportAttribute Record attribute of attributes, do + for attribute in attributes { + let key = attribute.key.to_string_lossy(agent); + // a. If supported does not contain attribute.[[Key]], return false. + if !supported.contains(&key.as_ref()) { + return false; + } + } + // 3. Return true. + true +} + /// ### [16.2.1.13 GetModuleNamespace ( module )](https://tc39.es/ecma262/#sec-getmodulenamespace) /// /// The abstract operation GetModuleNamespace takes argument module (an diff --git a/nova_vm/src/engine/bytecode.rs b/nova_vm/src/engine/bytecode.rs index 59381fee2..9c7a20518 100644 --- a/nova_vm/src/engine/bytecode.rs +++ b/nova_vm/src/engine/bytecode.rs @@ -16,4 +16,4 @@ pub(crate) use executable::{ }; pub(crate) use instructions::{Instruction, InstructionIter}; pub(crate) use iterator::VmIteratorRecord; -pub(crate) use vm::{ExecutionResult, SuspendedVm, Vm, instanceof_operator}; +pub(crate) use vm::{ExecutionResult, SuspendedVm, Vm, instanceof_operator, typeof_operator}; diff --git a/nova_vm/src/engine/bytecode/vm.rs b/nova_vm/src/engine/bytecode/vm.rs index b2453c372..37cd037db 100644 --- a/nova_vm/src/engine/bytecode/vm.rs +++ b/nova_vm/src/engine/bytecode/vm.rs @@ -1270,7 +1270,7 @@ fn number_binary_operator<'a>( /// ### [13.5.3 The typeof operator](https://tc39.es/ecma262/#sec-typeof-operator) #[inline] -fn typeof_operator(agent: &Agent, val: Value, gc: NoGcScope) -> String<'static> { +pub(crate) fn typeof_operator(agent: &Agent, val: Value, gc: NoGcScope) -> String<'static> { match val { // 4. If val is undefined, return "undefined". Value::Undefined => BUILTIN_STRING_MEMORY.undefined, diff --git a/tests/expectations.json b/tests/expectations.json index fc9b28e33..1d0aa5926 100644 --- a/tests/expectations.json +++ b/tests/expectations.json @@ -6256,69 +6256,39 @@ "language/expressions/delete/super-property-uninitialized-this.js": "FAIL", "language/expressions/division/S11.5.2_A4_T10.js": "FAIL", "language/expressions/dynamic-import/assignment-expression/await-identifier.js": "FAIL", - "language/expressions/dynamic-import/catch/nested-arrow-import-catch-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-arrow-import-catch-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-arrow-import-catch-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-async-arrow-function-await-eval-script-code-target.js": "FAIL", - "language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-async-function-await-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-async-function-await-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-async-function-await-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-async-function-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-async-function-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-async-function-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-async-function-return-await-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-async-function-return-await-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-async-function-return-await-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-async-gen-await-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-async-gen-await-import-source-source-text-module.js": "FAIL", "language/expressions/dynamic-import/catch/nested-async-gen-await-import-source-specifier-tostring.js": "FAIL", - "language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-async-gen-return-await-import-source-source-text-module.js": "FAIL", "language/expressions/dynamic-import/catch/nested-async-gen-return-await-import-source-specifier-tostring.js": "FAIL", - "language/expressions/dynamic-import/catch/nested-block-import-catch-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-block-import-catch-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-block-import-catch-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-block-labeled-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-block-labeled-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-block-labeled-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-do-while-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-do-while-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-do-while-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-else-import-catch-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-else-import-catch-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-else-import-catch-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-function-import-catch-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-function-import-catch-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-function-import-catch-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-if-import-catch-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-if-import-catch-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-if-import-catch-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/nested-while-import-catch-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/nested-while-import-catch-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/nested-while-import-catch-import-source-specifier-tostring.js": "UNRESOLVED", - "language/expressions/dynamic-import/catch/top-level-import-catch-eval-script-code-target.js": "FAIL", "language/expressions/dynamic-import/catch/top-level-import-catch-import-source-source-text-module.js": "UNRESOLVED", "language/expressions/dynamic-import/catch/top-level-import-catch-import-source-specifier-tostring.js": "UNRESOLVED", "language/expressions/dynamic-import/for-await-resolution-and-error-agen-yield.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-await-expr.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-await-ident.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-evaluation-sequence.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-get-with-error.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-in.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-non-object.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-trailing-comma-fulfill.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-with-enumeration-abrupt.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-with-enumeration-enumerable.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-with-enumeration.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-with-non-object.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-with-undefined.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-with-value-abrupt.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-with-value-non-string.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-yield-expr.js": "CRASH", - "language/expressions/dynamic-import/import-attributes/2nd-param-yield-ident-valid.js": "CRASH", + "language/expressions/dynamic-import/import-attributes/2nd-param-await-ident.js": "FAIL", + "language/expressions/dynamic-import/import-attributes/2nd-param-with-enumeration-enumerable.js": "FAIL", "language/expressions/dynamic-import/import-defer/import-defer-transitive-async-module/main.js": "FAIL", "language/expressions/dynamic-import/import-defer/sync-dependency-of-deferred-async-module/main.js": "FAIL", "language/expressions/dynamic-import/import-defer/sync/main.js": "FAIL", @@ -6339,45 +6309,35 @@ "language/expressions/dynamic-import/syntax/valid/nested-async-function-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-script-code-valid.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-block-import-attributes-trailing-comma-second.js": "CRASH", "language/expressions/dynamic-import/syntax/valid/nested-block-import-source-script-code-valid.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-attributes-trailing-comma-second.js": "CRASH", "language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-block-labeled-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-block-script-code-valid.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-do-while-import-attributes-trailing-comma-second.js": "CRASH", "language/expressions/dynamic-import/syntax/valid/nested-do-while-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-do-while-script-code-valid.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-attributes-trailing-comma-second.js": "CRASH", "language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-else-braceless-script-code-valid.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-else-import-attributes-trailing-comma-second.js": "CRASH", "language/expressions/dynamic-import/syntax/valid/nested-else-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-else-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-function-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-function-return-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-function-return-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-function-script-code-valid.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-attributes-trailing-comma-second.js": "CRASH", "language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-if-braceless-script-code-valid.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-if-import-attributes-trailing-comma-second.js": "CRASH", "language/expressions/dynamic-import/syntax/valid/nested-if-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-if-script-code-valid.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-while-import-attributes-trailing-comma-second.js": "CRASH", "language/expressions/dynamic-import/syntax/valid/nested-while-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-while-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-with-expression-empty-str-is-valid-assign-expr.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-attributes-trailing-comma-first.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-attributes-trailing-comma-second.js": "CRASH", + "language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-attributes-trailing-comma-second.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-defer-empty-str-is-valid-assign-expr.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-defer-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-source-empty-str-is-valid-assign-expr.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-with-expression-nested-imports.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/nested-with-expression-script-code-valid.js": "FAIL", - "language/expressions/dynamic-import/syntax/valid/nested-with-import-attributes-trailing-comma-second.js": "CRASH", - "language/expressions/dynamic-import/syntax/valid/top-level-import-attributes-trailing-comma-second.js": "CRASH", "language/expressions/dynamic-import/syntax/valid/top-level-import-source-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/syntax/valid/top-level-script-code-valid.js": "FAIL", "language/expressions/dynamic-import/update-to-dynamic-import.js": "FAIL", diff --git a/tests/metrics.json b/tests/metrics.json index e10d25960..dd0589ba2 100644 --- a/tests/metrics.json +++ b/tests/metrics.json @@ -1,8 +1,8 @@ { "results": { - "crash": 67, - "fail": 7434, - "pass": 39851, + "crash": 40, + "fail": 7421, + "pass": 39891, "skip": 3326, "timeout": 18, "unresolved": 37