diff --git a/Libraries/LibJS/SourceTextModule.cpp b/Libraries/LibJS/SourceTextModule.cpp index 21fe337112..f6c086c3ef 100644 --- a/Libraries/LibJS/SourceTextModule.cpp +++ b/Libraries/LibJS/SourceTextModule.cpp @@ -108,7 +108,7 @@ static Vector module_requests(Program& program) SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr body, Vector requested_modules, Vector import_entries, Vector local_export_entries, Vector indirect_export_entries, Vector star_export_entries, - RefPtr default_export) + Optional default_export_binding_name) : CyclicModule(realm, filename, has_top_level_await, move(requested_modules), host_defined) , m_ecmascript_code(move(body)) , m_execution_context(ExecutionContext::create(0, 0, 0)) @@ -116,7 +116,7 @@ SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::Ho , m_local_export_entries(move(local_export_entries)) , m_indirect_export_entries(move(indirect_export_entries)) , m_star_export_entries(move(star_export_entries)) - , m_default_export(move(default_export)) + , m_default_export_binding_name(move(default_export_binding_name)) { auto& vm = realm.vm(); @@ -148,13 +148,6 @@ SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::Ho }); })); - // Pre-compute default export binding name (initialize_environment default export block). - if (m_default_export) { - VERIFY(m_default_export->has_statement()); - if (!is(m_default_export->statement())) - m_default_export_binding_name = m_default_export->entries()[0].local_or_import_name.value(); - } - // For TLA modules, pre-create the SharedFunctionInstanceData for the // async wrapper function so that execute_module() doesn't need the AST. if (has_top_level_await) { @@ -164,9 +157,10 @@ SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::Ho m_tla_shared_data = vm.heap().allocate( vm, FunctionKind::Async, "module code with top-level await"_utf16_fly_string, - 0, FunctionParameters::empty(), m_ecmascript_code, + 0, FunctionParameters::empty(), *m_ecmascript_code, Utf16View {}, true, false, parsing_insights, Vector {}); m_tla_shared_data->m_is_module_wrapper = true; + m_ecmascript_code = nullptr; } } @@ -216,13 +210,13 @@ Result, Vector> SourceTextModule::parse(S Vector star_export_entries; // NOTE: Not in the spec but makes it easier to find the default. - RefPtr default_export; + Optional default_export_binding_name; // 9. Let exportEntries be ExportEntries of body. // 10. For each ExportEntry Record ee of exportEntries, do for (auto const& export_statement : body->exports()) { if (export_statement->is_default_export()) { - VERIFY(!default_export); + VERIFY(!default_export_binding_name.has_value()); VERIFY(export_statement->entries().size() == 1); VERIFY(export_statement->has_statement()); @@ -234,7 +228,10 @@ Result, Vector> SourceTextModule::parse(S return import_entry.local_name == entry.local_or_import_name; }) .is_end()); - default_export = export_statement; + + // Extract the binding name if the default export is a non-declaration statement. + if (!is(export_statement->statement())) + default_export_binding_name = entry.local_or_import_name.value(); } for (auto const& export_entry : export_statement->entries()) { @@ -313,7 +310,7 @@ Result, Vector> SourceTextModule::parse(S move(local_export_entries), move(indirect_export_entries), move(star_export_entries), - move(default_export)); + move(default_export_binding_name)); } // 16.2.1.7.2.1 GetExportedNames ( [ exportStarSet ] ), https://tc39.es/ecma262/#sec-getexportednames @@ -710,10 +707,11 @@ ThrowCompletionOr SourceTextModule::execute_module(VM& vm, GC::Ptr, Vector> parse(StringView source_text, Realm&, StringView filename = {}, Script::HostDefined* host_defined = nullptr); - Program const& parse_node() const { return *m_ecmascript_code; } + Program const* parse_node() const { return m_ecmascript_code; } virtual Vector get_exported_names(VM& vm, HashTable& export_star_set) override; virtual ResolvedBinding resolve_export(VM& vm, Utf16FlyString const& export_name, Vector resolve_set = {}) override; @@ -37,11 +37,11 @@ protected: virtual ThrowCompletionOr execute_module(VM& vm, GC::Ptr capability) override; private: - SourceTextModule(Realm&, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr body, Vector requested_modules, Vector import_entries, Vector local_export_entries, Vector indirect_export_entries, Vector star_export_entries, RefPtr default_export); + SourceTextModule(Realm&, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr body, Vector requested_modules, Vector import_entries, Vector local_export_entries, Vector indirect_export_entries, Vector star_export_entries, Optional default_export_binding_name); virtual void visit_edges(Cell::Visitor&) override; - NonnullRefPtr m_ecmascript_code; // [[ECMAScriptCode]] + RefPtr m_ecmascript_code; // [[ECMAScriptCode]] NonnullOwnPtr m_execution_context; // [[Context]] GC::Ptr m_import_meta; // [[ImportMeta]] Vector m_import_entries; // [[ImportEntries]] @@ -49,8 +49,6 @@ private: Vector m_indirect_export_entries; // [[IndirectExportEntries]] Vector m_star_export_entries; // [[StarExportEntries]] - RefPtr m_default_export; // Note: Not from the spec - // Pre-computed module declaration instantiation data. // These are extracted from the AST at construction time so that // initialize_environment() can run without walking the AST. diff --git a/Utilities/js.cpp b/Utilities/js.cpp index 026e230c8a..c216fd3c08 100644 --- a/Utilities/js.cpp +++ b/Utilities/js.cpp @@ -233,8 +233,8 @@ static ErrorOr parse_and_run(JS::Realm& realm, StringView source, StringVi result = vm.throw_completion(move(error_string)); } else { auto module = module_or_error.release_value(); - if (s_dump_ast) - dump_ast(module->parse_node()); + if (s_dump_ast && module->parse_node()) + dump_ast(*module->parse_node()); if (!parse_only) result = vm.bytecode_interpreter().run(*module); }