diff --git a/common.gypi b/common.gypi index 4c856c0912260c..dd79c43462bec9 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.17', + 'v8_embedder_string': '-node.18', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/include/v8-script.h b/deps/v8/include/v8-script.h index 4a8ccab7e28d1d..f15d148b28d85c 100644 --- a/deps/v8/include/v8-script.h +++ b/deps/v8/include/v8-script.h @@ -142,10 +142,9 @@ class V8_EXPORT ModuleRequest : public Data { * * All assertions present in the module request will be supplied in this * list, regardless of whether they are supported by the host. Per - * https://tc39.es/proposal-import-assertions/#sec-hostgetsupportedimportassertions, - * hosts are expected to ignore assertions that they do not support (as - * opposed to, for example, triggering an error if an unsupported assertion is - * present). + * https://tc39.es/proposal-import-attributes/#sec-hostgetsupportedimportattributes, + * hosts are expected to throw for assertions that they do not support (as + * opposed to, for example, ignoring them). */ Local GetImportAssertions() const; diff --git a/deps/v8/src/execution/isolate.cc b/deps/v8/src/execution/isolate.cc index 06c707da96ca34..1c63f0c56bf719 100644 --- a/deps/v8/src/execution/isolate.cc +++ b/deps/v8/src/execution/isolate.cc @@ -5156,7 +5156,8 @@ MaybeHandle Isolate::GetImportAssertionsFromArgument( // The parser shouldn't have allowed the second argument to import() if // the flag wasn't enabled. - DCHECK(v8_flags.harmony_import_assertions); + DCHECK(v8_flags.harmony_import_assertions || + v8_flags.harmony_import_attributes); if (!import_assertions_argument->IsJSReceiver()) { this->Throw( @@ -5166,18 +5167,35 @@ MaybeHandle Isolate::GetImportAssertionsFromArgument( Handle import_assertions_argument_receiver = Handle::cast(import_assertions_argument); - Handle key = factory()->assert_string(); Handle import_assertions_object; - if (!JSReceiver::GetProperty(this, import_assertions_argument_receiver, key) - .ToHandle(&import_assertions_object)) { - // This can happen if the property has a getter function that throws - // an error. - return MaybeHandle(); + + if (v8_flags.harmony_import_attributes) { + Handle with_key = factory()->with_string(); + if (!JSReceiver::GetProperty(this, import_assertions_argument_receiver, + with_key) + .ToHandle(&import_assertions_object)) { + // This can happen if the property has a getter function that throws + // an error. + return MaybeHandle(); + } } - // If there is no 'assert' option in the options bag, it's not an error. Just - // do the import() as if no assertions were provided. + if (v8_flags.harmony_import_assertions && + (!v8_flags.harmony_import_attributes || + import_assertions_object->IsUndefined())) { + Handle assert_key = factory()->assert_string(); + if (!JSReceiver::GetProperty(this, import_assertions_argument_receiver, + assert_key) + .ToHandle(&import_assertions_object)) { + // This can happen if the property has a getter function that throws + // an error. + return MaybeHandle(); + } + } + + // If there is no 'with' or 'assert' option in the options bag, it's not an + // error. Just do the import() as if no assertions were provided. if (import_assertions_object->IsUndefined()) return import_assertions_array; if (!import_assertions_object->IsJSReceiver()) { @@ -5199,6 +5217,8 @@ MaybeHandle Isolate::GetImportAssertionsFromArgument( return MaybeHandle(); } + bool has_non_string_attribute = false; + // The assertions will be passed to the host in the form: [key1, // value1, key2, value2, ...]. constexpr size_t kAssertionEntrySizeForDynamicImport = 2; @@ -5216,9 +5236,7 @@ MaybeHandle Isolate::GetImportAssertionsFromArgument( } if (!assertion_value->IsString()) { - this->Throw(*factory()->NewTypeError( - MessageTemplate::kNonStringImportAssertionValue)); - return MaybeHandle(); + has_non_string_attribute = true; } import_assertions_array->set((i * kAssertionEntrySizeForDynamicImport), @@ -5227,6 +5245,12 @@ MaybeHandle Isolate::GetImportAssertionsFromArgument( *assertion_value); } + if (has_non_string_attribute) { + this->Throw(*factory()->NewTypeError( + MessageTemplate::kNonStringImportAssertionValue)); + return MaybeHandle(); + } + return import_assertions_array; } diff --git a/deps/v8/src/flags/flag-definitions.h b/deps/v8/src/flags/flag-definitions.h index 8a3ab897c67e98..1bb489833b81f8 100644 --- a/deps/v8/src/flags/flag-definitions.h +++ b/deps/v8/src/flags/flag-definitions.h @@ -235,6 +235,7 @@ DEFINE_BOOL(harmony_shipping, true, "enable all shipped harmony features") // Features that are still work in progress (behind individual flags). #define HARMONY_INPROGRESS_BASE(V) \ + V(harmony_import_attributes, "harmony import attributes") \ V(harmony_weak_refs_with_cleanup_some, \ "harmony weak references with FinalizationRegistry.prototype.cleanupSome") \ V(harmony_temporal, "Temporal") \ diff --git a/deps/v8/src/init/bootstrapper.cc b/deps/v8/src/init/bootstrapper.cc index 69d01ff33902aa..c468c502e703df 100644 --- a/deps/v8/src/init/bootstrapper.cc +++ b/deps/v8/src/init/bootstrapper.cc @@ -4523,6 +4523,7 @@ void Genesis::InitializeConsole(Handle extras_binding) { void Genesis::InitializeGlobal_##id() {} EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_import_assertions) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_import_attributes) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_symbol_as_weakmap_key) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_rab_gsab_transfer) diff --git a/deps/v8/src/init/heap-symbols.h b/deps/v8/src/init/heap-symbols.h index 5388b88d4e7599..1ca46fdc81faa4 100644 --- a/deps/v8/src/init/heap-symbols.h +++ b/deps/v8/src/init/heap-symbols.h @@ -462,6 +462,7 @@ V(_, week_string, "week") \ V(_, weeks_string, "weeks") \ V(_, weekOfYear_string, "weekOfYear") \ + V(_, with_string, "with") \ V(_, word_string, "word") \ V(_, yearMonthFromFields_string, "yearMonthFromFields") \ V(_, year_string, "year") \ diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h index ff5af7dfec9204..cfba92d7e884b8 100644 --- a/deps/v8/src/parsing/parser-base.h +++ b/deps/v8/src/parsing/parser-base.h @@ -3774,7 +3774,9 @@ ParserBase::ParseImportExpressions() { AcceptINScope scope(this, true); ExpressionT specifier = ParseAssignmentExpressionCoverGrammar(); - if (v8_flags.harmony_import_assertions && Check(Token::COMMA)) { + if ((v8_flags.harmony_import_assertions || + v8_flags.harmony_import_attributes) && + Check(Token::COMMA)) { if (Check(Token::RPAREN)) { // A trailing comma allowed after the specifier. return factory()->NewImportCallExpression(specifier, pos); diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc index 6886e037ac2f97..336d88b2ea195b 100644 --- a/deps/v8/src/parsing/parser.cc +++ b/deps/v8/src/parsing/parser.cc @@ -1344,27 +1344,28 @@ ZonePtrList* Parser::ParseNamedImports(int pos) { } ImportAssertions* Parser::ParseImportAssertClause() { - // AssertClause : - // assert '{' '}' - // assert '{' AssertEntries '}' + // WithClause : + // with '{' '}' + // with '{' WithEntries ','? '}' - // AssertEntries : - // IdentifierName: AssertionKey - // IdentifierName: AssertionKey , AssertEntries + // WithEntries : + // LiteralPropertyName + // LiteralPropertyName ':' StringLiteral , WithEntries - // AssertionKey : - // IdentifierName - // StringLiteral + // (DEPRECATED) + // AssertClause : + // assert '{' '}' + // assert '{' WithEntries ','? '}' auto import_assertions = zone()->New(zone()); - if (!v8_flags.harmony_import_assertions) { - return import_assertions; - } - - // Assert clause is optional, and cannot be preceded by a LineTerminator. - if (scanner()->HasLineTerminatorBeforeNext() || - !CheckContextualKeyword(ast_value_factory()->assert_string())) { + if (v8_flags.harmony_import_attributes && Check(Token::WITH)) { + // 'with' keyword consumed + } else if (v8_flags.harmony_import_assertions && + !scanner()->HasLineTerminatorBeforeNext() && + CheckContextualKeyword(ast_value_factory()->assert_string())) { + // 'assert' keyword consumed + } else { return import_assertions; } @@ -1372,8 +1373,12 @@ ImportAssertions* Parser::ParseImportAssertClause() { while (peek() != Token::RBRACE) { const AstRawString* attribute_key = nullptr; - if (Check(Token::STRING)) { + if (Check(Token::STRING) || Check(Token::SMI)) { attribute_key = GetSymbol(); + } else if (Check(Token::NUMBER)) { + attribute_key = GetNumberAsSymbol(); + } else if (Check(Token::BIGINT)) { + attribute_key = GetBigIntAsSymbol(); } else { attribute_key = ParsePropertyName(); } diff --git a/deps/v8/src/roots/static-roots.h b/deps/v8/src/roots/static-roots.h index df53f43736888f..16729572de88fc 100644 --- a/deps/v8/src/roots/static-roots.h +++ b/deps/v8/src/roots/static-roots.h @@ -693,82 +693,83 @@ struct StaticReadOnlyRoot { static constexpr Tagged_t kweek_string = 0x5a55; static constexpr Tagged_t kweeks_string = 0x5a65; static constexpr Tagged_t kweekOfYear_string = 0x5a79; - static constexpr Tagged_t kword_string = 0x5a91; - static constexpr Tagged_t kyearMonthFromFields_string = 0x5aa1; - static constexpr Tagged_t kyear_string = 0x5ac1; - static constexpr Tagged_t kyears_string = 0x5ad1; - static constexpr Tagged_t kUninitializedValue = 0x5af5; - static constexpr Tagged_t kArgumentsMarker = 0x5b2d; - static constexpr Tagged_t kTerminationException = 0x5b65; - static constexpr Tagged_t kException = 0x5ba5; - static constexpr Tagged_t kOptimizedOut = 0x5bc1; - static constexpr Tagged_t kStaleRegister = 0x5bf9; - static constexpr Tagged_t kSelfReferenceMarker = 0x5c31; - static constexpr Tagged_t kBasicBlockCountersMarker = 0x5c71; - static constexpr Tagged_t karray_buffer_wasm_memory_symbol = 0x5cb5; - static constexpr Tagged_t kcall_site_info_symbol = 0x5cc5; - static constexpr Tagged_t kconsole_context_id_symbol = 0x5cd5; - static constexpr Tagged_t kconsole_context_name_symbol = 0x5ce5; - static constexpr Tagged_t kclass_fields_symbol = 0x5cf5; - static constexpr Tagged_t kclass_positions_symbol = 0x5d05; - static constexpr Tagged_t kerror_end_pos_symbol = 0x5d15; - static constexpr Tagged_t kerror_script_symbol = 0x5d25; - static constexpr Tagged_t kerror_stack_symbol = 0x5d35; - static constexpr Tagged_t kerror_start_pos_symbol = 0x5d45; - static constexpr Tagged_t kfrozen_symbol = 0x5d55; - static constexpr Tagged_t kinterpreter_trampoline_symbol = 0x5d65; - static constexpr Tagged_t knative_context_index_symbol = 0x5d75; - static constexpr Tagged_t knonextensible_symbol = 0x5d85; - static constexpr Tagged_t kpromise_debug_marker_symbol = 0x5d95; - static constexpr Tagged_t kpromise_debug_message_symbol = 0x5da5; - static constexpr Tagged_t kpromise_forwarding_handler_symbol = 0x5db5; - static constexpr Tagged_t kpromise_handled_by_symbol = 0x5dc5; - static constexpr Tagged_t kpromise_awaited_by_symbol = 0x5dd5; - static constexpr Tagged_t kregexp_result_names_symbol = 0x5de5; - static constexpr Tagged_t kregexp_result_regexp_input_symbol = 0x5df5; - static constexpr Tagged_t kregexp_result_regexp_last_index_symbol = 0x5e05; - static constexpr Tagged_t ksealed_symbol = 0x5e15; - static constexpr Tagged_t kstrict_function_transition_symbol = 0x5e25; + static constexpr Tagged_t kwith_string = 0x5a91; + static constexpr Tagged_t kword_string = 0x5aa1; + static constexpr Tagged_t kyearMonthFromFields_string = 0x5ab1; + static constexpr Tagged_t kyear_string = 0x5ad1; + static constexpr Tagged_t kyears_string = 0x5ae1; + static constexpr Tagged_t kUninitializedValue = 0x5b05; + static constexpr Tagged_t kArgumentsMarker = 0x5b3d; + static constexpr Tagged_t kTerminationException = 0x5b75; + static constexpr Tagged_t kException = 0x5bb5; + static constexpr Tagged_t kOptimizedOut = 0x5bd1; + static constexpr Tagged_t kStaleRegister = 0x5c09; + static constexpr Tagged_t kSelfReferenceMarker = 0x5c41; + static constexpr Tagged_t kBasicBlockCountersMarker = 0x5c81; + static constexpr Tagged_t karray_buffer_wasm_memory_symbol = 0x5cc5; + static constexpr Tagged_t kcall_site_info_symbol = 0x5cd5; + static constexpr Tagged_t kconsole_context_id_symbol = 0x5ce5; + static constexpr Tagged_t kconsole_context_name_symbol = 0x5cf5; + static constexpr Tagged_t kclass_fields_symbol = 0x5d05; + static constexpr Tagged_t kclass_positions_symbol = 0x5d15; + static constexpr Tagged_t kerror_end_pos_symbol = 0x5d25; + static constexpr Tagged_t kerror_script_symbol = 0x5d35; + static constexpr Tagged_t kerror_stack_symbol = 0x5d45; + static constexpr Tagged_t kerror_start_pos_symbol = 0x5d55; + static constexpr Tagged_t kfrozen_symbol = 0x5d65; + static constexpr Tagged_t kinterpreter_trampoline_symbol = 0x5d75; + static constexpr Tagged_t knative_context_index_symbol = 0x5d85; + static constexpr Tagged_t knonextensible_symbol = 0x5d95; + static constexpr Tagged_t kpromise_debug_marker_symbol = 0x5da5; + static constexpr Tagged_t kpromise_debug_message_symbol = 0x5db5; + static constexpr Tagged_t kpromise_forwarding_handler_symbol = 0x5dc5; + static constexpr Tagged_t kpromise_handled_by_symbol = 0x5dd5; + static constexpr Tagged_t kpromise_awaited_by_symbol = 0x5de5; + static constexpr Tagged_t kregexp_result_names_symbol = 0x5df5; + static constexpr Tagged_t kregexp_result_regexp_input_symbol = 0x5e05; + static constexpr Tagged_t kregexp_result_regexp_last_index_symbol = 0x5e15; + static constexpr Tagged_t ksealed_symbol = 0x5e25; + static constexpr Tagged_t kstrict_function_transition_symbol = 0x5e35; static constexpr Tagged_t ktemplate_literal_function_literal_id_symbol = - 0x5e35; - static constexpr Tagged_t ktemplate_literal_slot_id_symbol = 0x5e45; - static constexpr Tagged_t kwasm_exception_tag_symbol = 0x5e55; - static constexpr Tagged_t kwasm_exception_values_symbol = 0x5e65; - static constexpr Tagged_t kwasm_uncatchable_symbol = 0x5e75; - static constexpr Tagged_t kwasm_wrapped_object_symbol = 0x5e85; - static constexpr Tagged_t kwasm_debug_proxy_cache_symbol = 0x5e95; - static constexpr Tagged_t kwasm_debug_proxy_names_symbol = 0x5ea5; - static constexpr Tagged_t kasync_iterator_symbol = 0x5eb5; - static constexpr Tagged_t kintl_fallback_symbol = 0x5ee5; - static constexpr Tagged_t kmatch_all_symbol = 0x5f1d; - static constexpr Tagged_t kmatch_symbol = 0x5f49; - static constexpr Tagged_t ksearch_symbol = 0x5f71; - static constexpr Tagged_t ksplit_symbol = 0x5f9d; - static constexpr Tagged_t kto_primitive_symbol = 0x5fc5; - static constexpr Tagged_t kunscopables_symbol = 0x5ff5; - static constexpr Tagged_t khas_instance_symbol = 0x6025; - static constexpr Tagged_t kto_string_tag_symbol = 0x6055; - static constexpr Tagged_t kconstructor_string = 0x60ad; - static constexpr Tagged_t knext_string = 0x60c5; - static constexpr Tagged_t kresolve_string = 0x60d5; - static constexpr Tagged_t kthen_string = 0x60e9; - static constexpr Tagged_t kiterator_symbol = 0x60f9; - static constexpr Tagged_t kreplace_symbol = 0x6109; - static constexpr Tagged_t kspecies_symbol = 0x6119; - static constexpr Tagged_t kis_concat_spreadable_symbol = 0x6129; - static constexpr Tagged_t kEmptySlowElementDictionary = 0x6139; - static constexpr Tagged_t kEmptySymbolTable = 0x615d; - static constexpr Tagged_t kEmptyOrderedHashMap = 0x6179; - static constexpr Tagged_t kEmptyOrderedHashSet = 0x618d; - static constexpr Tagged_t kEmptyFeedbackMetadata = 0x61a1; - static constexpr Tagged_t kGlobalThisBindingScopeInfo = 0x61ad; - static constexpr Tagged_t kEmptyFunctionScopeInfo = 0x61cd; - static constexpr Tagged_t kNativeScopeInfo = 0x61f1; - static constexpr Tagged_t kShadowRealmScopeInfo = 0x6209; + 0x5e45; + static constexpr Tagged_t ktemplate_literal_slot_id_symbol = 0x5e55; + static constexpr Tagged_t kwasm_exception_tag_symbol = 0x5e65; + static constexpr Tagged_t kwasm_exception_values_symbol = 0x5e75; + static constexpr Tagged_t kwasm_uncatchable_symbol = 0x5e85; + static constexpr Tagged_t kwasm_wrapped_object_symbol = 0x5e95; + static constexpr Tagged_t kwasm_debug_proxy_cache_symbol = 0x5ea5; + static constexpr Tagged_t kwasm_debug_proxy_names_symbol = 0x5eb5; + static constexpr Tagged_t kasync_iterator_symbol = 0x5ec5; + static constexpr Tagged_t kintl_fallback_symbol = 0x5ef5; + static constexpr Tagged_t kmatch_all_symbol = 0x5f2d; + static constexpr Tagged_t kmatch_symbol = 0x5f59; + static constexpr Tagged_t ksearch_symbol = 0x5f81; + static constexpr Tagged_t ksplit_symbol = 0x5fad; + static constexpr Tagged_t kto_primitive_symbol = 0x5fd5; + static constexpr Tagged_t kunscopables_symbol = 0x6005; + static constexpr Tagged_t khas_instance_symbol = 0x6035; + static constexpr Tagged_t kto_string_tag_symbol = 0x6065; + static constexpr Tagged_t kconstructor_string = 0x60bd; + static constexpr Tagged_t knext_string = 0x60d5; + static constexpr Tagged_t kresolve_string = 0x60e5; + static constexpr Tagged_t kthen_string = 0x60f9; + static constexpr Tagged_t kiterator_symbol = 0x6109; + static constexpr Tagged_t kreplace_symbol = 0x6119; + static constexpr Tagged_t kspecies_symbol = 0x6129; + static constexpr Tagged_t kis_concat_spreadable_symbol = 0x6139; + static constexpr Tagged_t kEmptySlowElementDictionary = 0x6149; + static constexpr Tagged_t kEmptySymbolTable = 0x616d; + static constexpr Tagged_t kEmptyOrderedHashMap = 0x6189; + static constexpr Tagged_t kEmptyOrderedHashSet = 0x619d; + static constexpr Tagged_t kEmptyFeedbackMetadata = 0x61b1; + static constexpr Tagged_t kGlobalThisBindingScopeInfo = 0x61bd; + static constexpr Tagged_t kEmptyFunctionScopeInfo = 0x61dd; + static constexpr Tagged_t kNativeScopeInfo = 0x6201; + static constexpr Tagged_t kShadowRealmScopeInfo = 0x6219; static constexpr Tagged_t kWasmNull = 0xfffd; }; -static constexpr std::array StaticReadOnlyRootsPointerTable = { +static constexpr std::array StaticReadOnlyRootsPointerTable = { StaticReadOnlyRoot::kFreeSpaceMap, StaticReadOnlyRoot::kOnePointerFillerMap, StaticReadOnlyRoot::kTwoPointerFillerMap, @@ -1365,6 +1366,7 @@ static constexpr std::array StaticReadOnlyRootsPointerTable = { StaticReadOnlyRoot::kweek_string, StaticReadOnlyRoot::kweeks_string, StaticReadOnlyRoot::kweekOfYear_string, + StaticReadOnlyRoot::kwith_string, StaticReadOnlyRoot::kword_string, StaticReadOnlyRoot::kyearMonthFromFields_string, StaticReadOnlyRoot::kyear_string, diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-1.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-1.mjs new file mode 100644 index 00000000000000..3cf6bac870b80f --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-1.mjs @@ -0,0 +1,9 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-import-attributes + +import { life } from 'modules-skip-1.mjs' with { }; + +assertEquals(42, life()); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-2.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-2.mjs new file mode 100644 index 00000000000000..63f5859ca0f1d0 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-2.mjs @@ -0,0 +1,9 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-import-attributes + +import json from 'modules-skip-1.json' with { type: 'json' }; + +assertEquals(42, json.life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-3.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-3.mjs new file mode 100644 index 00000000000000..34db1852367c19 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-3.mjs @@ -0,0 +1,9 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-import-attributes + +import {life} from 'modules-skip-imports-json-1.mjs'; + +assertEquals(42, life()); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-4.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-4.mjs new file mode 100644 index 00000000000000..66bdc11c359ed4 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-4.mjs @@ -0,0 +1,9 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-import-attributes + +import json from 'modules-skip-1.json' with { type: 'json', notARealAssertion: 'value'}; + +assertEquals(42, json.life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-1.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-1.mjs new file mode 100644 index 00000000000000..644fc96a6e2111 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-1.mjs @@ -0,0 +1,12 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var life; +import('modules-skip-1.mjs', { }).then(namespace => life = namespace.life()); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-10.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-10.mjs new file mode 100644 index 00000000000000..972fbed24bfff2 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-10.mjs @@ -0,0 +1,19 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var result1; +var result2; +import('modules-skip-1.json', { get with() { throw 'bad \'with\' getter!'; } }).then( + () => assertUnreachable('Should have failed due to throwing getter'), + error => result1 = error); +import('modules-skip-1.json', { with: { get assertionKey() { throw 'bad \'assertionKey\' getter!'; } } }).then( + () => assertUnreachable('Should have failed due to throwing getter'), + error => result2 = error); + +%PerformMicrotaskCheckpoint(); + +assertEquals('bad \'with\' getter!', result1); +assertEquals('bad \'assertionKey\' getter!', result2); \ No newline at end of file diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-11.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-11.mjs new file mode 100644 index 00000000000000..c39a5f9d4e2e06 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-11.mjs @@ -0,0 +1,19 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes --harmony-top-level-await + +var life1; +var life2; +import('modules-skip-1.json', { with: { type: 'json' } }).then( + namespace => life1 = namespace.default.life); + +// Try loading the same module a second time. +import('modules-skip-1.json', { with: { type: 'json' } }).then( + namespace => life2 = namespace.default.life); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life1); +assertEquals(42, life2); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-12.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-12.mjs new file mode 100644 index 00000000000000..1d8fb21a502237 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-12.mjs @@ -0,0 +1,26 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +let result1; +let result2; + +let badAssertProxy1 = new Proxy({}, { ownKeys() { throw "bad ownKeys!"; } }); +import('./modules-skip-1.mjs', { with: badAssertProxy1 }).then( + () => assertUnreachable('Should have failed due to throwing ownKeys'), + error => result1 = error); + +let badAssertProxy2 = new Proxy( + {foo: "bar"}, + { getOwnPropertyDescriptor() { throw "bad getOwnPropertyDescriptor!"; } }); +import('./modules-skip-1.mjs', { with: badAssertProxy2 }).then( + () => assertUnreachable( + 'Should have failed due to throwing getOwnPropertyDescriptor'), + error => result2 = error); + +%PerformMicrotaskCheckpoint(); + +assertEquals('bad ownKeys!', result1); +assertEquals('bad getOwnPropertyDescriptor!', result2); \ No newline at end of file diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-13.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-13.mjs new file mode 100644 index 00000000000000..6e23c07c281db1 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-13.mjs @@ -0,0 +1,26 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +let getters = 0; +let result; + +import('./modules-skip-1.mjs', { with: { + get attr1() { + getters++; + return {}; + }, + get attr2() { + getters++; + return {}; + }, +} }).then( + () => assertUnreachable('Should have failed due to invalid attributes values'), + error => result = error); + +%PerformMicrotaskCheckpoint(); + +assertEquals(2, getters); +assertInstanceof(result, TypeError); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-2.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-2.mjs new file mode 100644 index 00000000000000..b8e59fb0bfe9c3 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-2.mjs @@ -0,0 +1,13 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var life; +import('modules-skip-1.mjs', { with: { } }).then( + namespace => life = namespace.life()); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-3.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-3.mjs new file mode 100644 index 00000000000000..da570eb2836edd --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-3.mjs @@ -0,0 +1,13 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var life; +import('modules-skip-1.json', { with: { type: 'json' } }).then( + namespace => life = namespace.default.life); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-4.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-4.mjs new file mode 100644 index 00000000000000..fff6fe2bbef84c --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-4.mjs @@ -0,0 +1,14 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var result; +import('modules-skip-1.json', { with: { type: 'notARealType' } }).then( + () => assertUnreachable('Should have failed due to bad module type'), + error => result = error.message); + +%PerformMicrotaskCheckpoint(); + +assertEquals('Invalid module type was asserted', result); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-5.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-5.mjs new file mode 100644 index 00000000000000..cdb1567c330764 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-5.mjs @@ -0,0 +1,12 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var life; +import('modules-skip-imports-json-1.mjs',).then(namespace => life = namespace.life()); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-6.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-6.mjs new file mode 100644 index 00000000000000..ad84e3edd5ffe1 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-6.mjs @@ -0,0 +1,18 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var life; +import('modules-skip-1.json', { with: { type: 'json', notARealAssertion: 'value' } }).then( + namespace => life = namespace.default.life); + +var life2; +import('modules-skip-1.json', { with: { 0: 'value', type: 'json' } }).then( + namespace => life2 = namespace.default.life); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life); +assertEquals(42, life2); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-7.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-7.mjs new file mode 100644 index 00000000000000..530d833cce5a4d --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-7.mjs @@ -0,0 +1,63 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var result1; +var result2; +var result3; +var result4; +var result5; +var result6; +var result7; +var result8; +var result9; +var result10; +import('modules-skip-1.json', null).then( + () => assertUnreachable('Should have failed due to non-object parameter'), + error => result1 = error.message); +import('modules-skip-1.json', 7).then( + () => assertUnreachable('Should have failed due to non-object parameter'), + error => result2 = error.message); +import('modules-skip-1.json', 'string').then( + () => assertUnreachable('Should have failed due to non-object parameter'), + error => result3 = error.message); +import('modules-skip-1.json', { with: null}).then( + () => assertUnreachable('Should have failed due to bad with object'), + error => result4 = error.message); +import('modules-skip-1.json', { with: 7}).then( + () => assertUnreachable('Should have failed due to bad with object'), + error => result5 = error.message); +import('modules-skip-1.json', { with: 'string'}).then( + () => assertUnreachable('Should have failed due to bad with object'), + error => result6 = error.message); +import('modules-skip-1.json', { with: { a: null }}).then( + () => assertUnreachable('Should have failed due to bad with object'), + error => result7 = error.message); +import('modules-skip-1.json', { with: { a: undefined }}).then( + () => assertUnreachable('Should have failed due to bad assertion value'), + error => result8 = error.message); +import('modules-skip-1.json', { with: { a: 7 }}).then( + () => assertUnreachable('Should have failed due to bad assertion value'), + error => result9 = error.message); + import('modules-skip-1.json', { with: { a: { } }}).then( + () => assertUnreachable('Should have failed due to bad assertion value'), + error => result10 = error.message); + +%PerformMicrotaskCheckpoint(); + +const argumentNotObjectError = 'The second argument to import() must be an object'; +const assertOptionNotObjectError = 'The \'assert\' option must be an object'; +const assertionValueNotStringError = 'Import assertion value must be a string'; + +assertEquals(argumentNotObjectError, result1); +assertEquals(argumentNotObjectError, result2); +assertEquals(argumentNotObjectError, result3); +assertEquals(assertOptionNotObjectError, result4); +assertEquals(assertOptionNotObjectError, result5); +assertEquals(assertOptionNotObjectError, result6); +assertEquals(assertionValueNotStringError, result7); +assertEquals(assertionValueNotStringError, result8); +assertEquals(assertionValueNotStringError, result9); +assertEquals(assertionValueNotStringError, result10); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-8.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-8.mjs new file mode 100644 index 00000000000000..74a4504e253d6a --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-8.mjs @@ -0,0 +1,13 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var life; +import('modules-skip-1.mjs', undefined).then( + namespace => life = namespace.life()); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-9.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-9.mjs new file mode 100644 index 00000000000000..1b56c70df61682 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-9.mjs @@ -0,0 +1,13 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes + +var life; +import('modules-skip-1.mjs', { with: undefined }).then( + namespace => life = namespace.life()); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-assertions-fallback-1.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-assertions-fallback-1.mjs new file mode 100644 index 00000000000000..3faaf0dccea1c9 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-assertions-fallback-1.mjs @@ -0,0 +1,15 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes --harmony-import-assertions + +var life; +import('modules-skip-1.mjs', { + with: {}, + get assert() { throw 'Should not read assert'; } +}).then(namespace => life = namespace.life()); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-assertions-fallback-2.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-assertions-fallback-2.mjs new file mode 100644 index 00000000000000..4c83d2fbd716cc --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-dynamic-assertions-fallback-2.mjs @@ -0,0 +1,15 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-import-attributes --harmony-import-assertions + +var life; +import('modules-skip-1.json', { + with: undefined, + assert: { type: 'json' } +}).then(namespace => life = namespace.default.life); + +%PerformMicrotaskCheckpoint(); + +assertEquals(42, life); diff --git a/deps/v8/test/unittests/parser/parsing-unittest.cc b/deps/v8/test/unittests/parser/parsing-unittest.cc index 9048d7f1faf674..24e178e2ca5eb6 100644 --- a/deps/v8/test/unittests/parser/parsing-unittest.cc +++ b/deps/v8/test/unittests/parser/parsing-unittest.cc @@ -4876,6 +4876,11 @@ TEST_F(ParsingTest, BasicImportAssertionParsing) { "import { a as b } from 'm.js' assert { \nc: 'd'};", "import { a as b } from 'm.js' assert { c:\n 'd'};", "import { a as b } from 'm.js' assert { c:'d'\n};", + + "import { a as b } from 'm.js' assert { 0: 'b', };", + "import { a as b } from 'm.js' assert { 0n: 'b', };", + "import { a as b } from 'm.js' assert { '0': 'b', };", + "import { a as b } from 'm.js' assert { 0.0: 'b', };", }; // clang-format on @@ -4943,10 +4948,234 @@ TEST_F(ParsingTest, ImportAssertionParsingErrors) { "import { a } from 'm.js' assert { , b: c };", "import { a } from 'm.js' assert { a: 'b', a: 'c' };", "import { a } from 'm.js' assert { a: 'b', 'a': 'c' };", + + "import { a } from 'm.js' assert { 0: 'b', '0': 'c' };", + "import { a } from 'm.js' assert { 0n: 'b', '0': 'c' };", + "import { a } from 'm.js' assert { 0: 'b', 0n: 'c' };", + "import { a } from 'm.js' assert { 0: 'b', 0.0: 'c' };", + "import { a } from 'm.js' assert { '0': 'b', 0n: 'c' };", + + "import 'm.js' with { a: 'b' };" + }; + // clang-format on + + i::v8_flags.harmony_import_assertions = true; + i::Isolate* isolate = i_isolate(); + i::Factory* factory = isolate->factory(); + + isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - + 128 * 1024); + + for (unsigned i = 0; i < arraysize(kErrorSources); ++i) { + i::Handle source = + factory->NewStringFromAsciiChecked(kErrorSources[i]); + + i::Handle script = factory->NewScript(source); + i::UnoptimizedCompileState compile_state; + i::ReusableUnoptimizedCompileState reusable_state(isolate); + i::UnoptimizedCompileFlags flags = + i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); + flags.set_is_module(true); + i::ParseInfo info(isolate, flags, &compile_state, &reusable_state); + CHECK(!i::parsing::ParseProgram(&info, script, isolate, + parsing::ReportStatisticsMode::kYes)); + CHECK(info.pending_error_handler()->has_pending_error()); + } +} + +TEST_F(ParsingTest, BasicImportAttributesParsing) { + // clang-format off + const char* kSources[] = { + "import { a as b } from 'm.js' with { };", + "import n from 'n.js' with { };", + "export { a as b } from 'm.js' with { };", + "export * from 'm.js' with { };", + "import 'm.js' with { };", + "import * as foo from 'bar.js' with { };", + + "import { a as b } from 'm.js' with { a: 'b' };", + "import { a as b } from 'm.js' with { c: 'd' };", + "import { a as b } from 'm.js' with { 'c': 'd' };", + "import { a as b } from 'm.js' with { a: 'b', 'c': 'd', e: 'f' };", + "import { a as b } from 'm.js' with { 'c': 'd', };", + "import n from 'n.js' with { 'c': 'd' };", + "export { a as b } from 'm.js' with { 'c': 'd' };", + "export * from 'm.js' with { 'c': 'd' };", + "import 'm.js' with { 'c': 'd' };", + "import * as foo from 'bar.js' with { 'c': 'd' };", + + "import { a as b } from 'm.js' with { \nc: 'd'};", + "import { a as b } from 'm.js' with { c:\n 'd'};", + "import { a as b } from 'm.js' with { c:'d'\n};", + + "import { a as b } from 'm.js' with { 0: 'b', };", + "import { a as b } from 'm.js' with { 0n: 'b', };", + "import { a as b } from 'm.js' with { '0': 'b', };", + "import { a as b } from 'm.js' with { 0.0: 'b', };", + + "import 'm.js'\n with { };", + "import 'm.js' \nwith { };", + "import { a } from 'm.js'\n with { };", + "export * from 'm.js'\n with { };" + }; + // clang-format on + + i::v8_flags.harmony_import_attributes = true; + i::Isolate* isolate = i_isolate(); + i::Factory* factory = isolate->factory(); + + isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - + 128 * 1024); + + for (unsigned i = 0; i < arraysize(kSources); ++i) { + i::Handle source = + factory->NewStringFromAsciiChecked(kSources[i]); + + // Show that parsing as a module works + { + i::Handle script = factory->NewScript(source); + i::UnoptimizedCompileState compile_state; + i::ReusableUnoptimizedCompileState reusable_state(isolate); + i::UnoptimizedCompileFlags flags = + i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); + flags.set_is_module(true); + i::ParseInfo info(isolate, flags, &compile_state, &reusable_state); + CHECK_PARSE_PROGRAM(&info, script, isolate); + } + + // And that parsing a script does not. + { + i::UnoptimizedCompileState compile_state; + i::ReusableUnoptimizedCompileState reusable_state(isolate); + i::Handle script = factory->NewScript(source); + i::UnoptimizedCompileFlags flags = + i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); + i::ParseInfo info(isolate, flags, &compile_state, &reusable_state); + CHECK(!i::parsing::ParseProgram(&info, script, isolate, + parsing::ReportStatisticsMode::kYes)); + CHECK(info.pending_error_handler()->has_pending_error()); + } + } +} + +TEST_F(ParsingTest, ImportAttributesParsingErrors) { + // clang-format off + const char* kErrorSources[] = { + "import { a } from 'm.js' with {;", + "import { a } from 'm.js' with };", + "import { a } from 'm.js' , with { };", + "import { a } from 'm.js' with , { };", + "import { a } from 'm.js' with { , };", + "import { a } from 'm.js' with { b };", + "import { a } from 'm.js' with { 'b' };", + "import { a } from 'm.js' with { for };", + "import { a } from 'm.js' with { with };", + "export { a } with { };", + "export * with { };", + + "import { a } from 'm.js' with { 1: 2 };", + "import { a } from 'm.js' with { b: c };", + "import { a } from 'm.js' with { 'b': c };", + "import { a } from 'm.js' with { , b: c };", + "import { a } from 'm.js' with { a: 'b', a: 'c' };", + "import { a } from 'm.js' with { a: 'b', 'a': 'c' };", + + "import { a } from 'm.js' with { 0: 'b', '0': 'c' };", + "import { a } from 'm.js' with { 0n: 'b', '0': 'c' };", + "import { a } from 'm.js' with { 0: 'b', 0n: 'c' };", + "import { a } from 'm.js' with { 0: 'b', 0.0: 'c' };", + "import { a } from 'm.js' with { '0': 'b', 0n: 'c' };", + + "import 'm.js' assert { a: 'b' };" + }; + // clang-format on + + i::v8_flags.harmony_import_assertions = false; + i::v8_flags.harmony_import_attributes = true; + i::Isolate* isolate = i_isolate(); + i::Factory* factory = isolate->factory(); + + isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - + 128 * 1024); + + for (unsigned i = 0; i < arraysize(kErrorSources); ++i) { + i::Handle source = + factory->NewStringFromAsciiChecked(kErrorSources[i]); + + i::Handle script = factory->NewScript(source); + i::UnoptimizedCompileState compile_state; + i::ReusableUnoptimizedCompileState reusable_state(isolate); + i::UnoptimizedCompileFlags flags = + i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); + flags.set_is_module(true); + i::ParseInfo info(isolate, flags, &compile_state, &reusable_state); + CHECK(!i::parsing::ParseProgram(&info, script, isolate, + parsing::ReportStatisticsMode::kYes)); + CHECK(info.pending_error_handler()->has_pending_error()); + } +} + +TEST_F(ParsingTest, BasicImportAttributesAndAssertionsParsing) { + // clang-format off + const char* kSources[] = { + "import { a } from 'm.js' assert { };", + "import { a } from 'm.js' with { };", + "import { a } from 'm.js'\n with { };", + }; + // clang-format on + + i::v8_flags.harmony_import_assertions = true; + i::v8_flags.harmony_import_attributes = true; + i::Isolate* isolate = i_isolate(); + i::Factory* factory = isolate->factory(); + + isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - + 128 * 1024); + + for (unsigned i = 0; i < arraysize(kSources); ++i) { + i::Handle source = + factory->NewStringFromAsciiChecked(kSources[i]); + + // Show that parsing as a module works + { + i::Handle script = factory->NewScript(source); + i::UnoptimizedCompileState compile_state; + i::ReusableUnoptimizedCompileState reusable_state(isolate); + i::UnoptimizedCompileFlags flags = + i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); + flags.set_is_module(true); + i::ParseInfo info(isolate, flags, &compile_state, &reusable_state); + CHECK_PARSE_PROGRAM(&info, script, isolate); + } + + // And that parsing a script does not. + { + i::UnoptimizedCompileState compile_state; + i::ReusableUnoptimizedCompileState reusable_state(isolate); + i::Handle script = factory->NewScript(source); + i::UnoptimizedCompileFlags flags = + i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); + i::ParseInfo info(isolate, flags, &compile_state, &reusable_state); + CHECK(!i::parsing::ParseProgram(&info, script, isolate, + parsing::ReportStatisticsMode::kYes)); + CHECK(info.pending_error_handler()->has_pending_error()); + } + } +} + +TEST_F(ParsingTest, ImportAttributesAndAssertionsParsingErrors) { + // clang-format off + const char* kErrorSources[] = { + "import { a } from 'm.js'\n assert { };", + "import { a } from 'm.js' with { } assert { };", + "import { a } from 'm.js' with assert { };", + "import { a } from 'm.js' assert { } with { };", + "import { a } from 'm.js' assert with { };", }; // clang-format on i::v8_flags.harmony_import_assertions = true; + i::v8_flags.harmony_import_attributes = true; i::Isolate* isolate = i_isolate(); i::Factory* factory = isolate->factory();