Ver Fonte

LibJS: Add [[HostDefined]] field to Modules

This patch adds the [[HostDefined]] field defined in
https://tc39.es/ecma262/#table-module-record-fields to module records.

Co-authored-by: davidot <davidot@serenityos.org>
networkException há 2 anos atrás
pai
commit
fb6de442c6

+ 2 - 2
Userland/Libraries/LibJS/CyclicModule.cpp

@@ -11,8 +11,8 @@
 
 namespace JS {
 
-CyclicModule::CyclicModule(Realm& realm, StringView filename, bool has_top_level_await, Vector<ModuleRequest> requested_modules)
-    : Module(realm, filename)
+CyclicModule::CyclicModule(Realm& realm, StringView filename, bool has_top_level_await, Vector<ModuleRequest> requested_modules, Script::HostDefined* host_defined)
+    : Module(realm, filename, host_defined)
     , m_requested_modules(move(requested_modules))
     , m_has_top_level_await(has_top_level_await)
 {

+ 1 - 1
Userland/Libraries/LibJS/CyclicModule.h

@@ -34,7 +34,7 @@ public:
     virtual ThrowCompletionOr<Promise*> evaluate(VM& vm) override;
 
 protected:
-    CyclicModule(Realm& realm, StringView filename, bool has_top_level_await, Vector<ModuleRequest> requested_modules);
+    CyclicModule(Realm& realm, StringView filename, bool has_top_level_await, Vector<ModuleRequest> requested_modules, Script::HostDefined* host_defined);
 
     virtual void visit_edges(Cell::Visitor&) override;
 

+ 4 - 1
Userland/Libraries/LibJS/Module.cpp

@@ -11,8 +11,9 @@
 
 namespace JS {
 
-Module::Module(Realm& realm, String filename)
+Module::Module(Realm& realm, String filename, Script::HostDefined* host_defined)
     : m_realm(realm)
+    , m_host_defined(host_defined)
     , m_filename(move(filename))
 {
 }
@@ -25,6 +26,8 @@ void Module::visit_edges(Cell::Visitor& visitor)
     visitor.visit(m_realm);
     visitor.visit(m_environment);
     visitor.visit(m_namespace);
+    if (m_host_defined)
+        m_host_defined->visit_host_defined_self(visitor);
 }
 
 // 16.2.1.5.1.1 InnerModuleLinking ( module, stack, index ), https://tc39.es/ecma262/#sec-InnerModuleLinking

+ 8 - 4
Userland/Libraries/LibJS/Module.h

@@ -11,6 +11,7 @@
 #include <LibJS/Heap/GCPtr.h>
 #include <LibJS/Runtime/Environment.h>
 #include <LibJS/Runtime/Realm.h>
+#include <LibJS/Script.h>
 
 namespace JS {
 
@@ -68,6 +69,8 @@ public:
 
     Environment* environment() { return m_environment; }
 
+    Script::HostDefined* host_defined() const { return m_host_defined; }
+
     ThrowCompletionOr<Object*> get_module_namespace(VM& vm);
 
     virtual ThrowCompletionOr<void> link(VM& vm) = 0;
@@ -80,7 +83,7 @@ public:
     virtual ThrowCompletionOr<u32> inner_module_evaluation(VM& vm, Vector<Module*>& stack, u32 index);
 
 protected:
-    Module(Realm&, String filename);
+    Module(Realm&, String filename, Script::HostDefined* host_defined = nullptr);
 
     virtual void visit_edges(Cell::Visitor&) override;
 
@@ -97,9 +100,10 @@ private:
     // destroy the VM but keep the modules this should not happen. Because VM
     // stores modules with a RefPtr we cannot just store the VM as that leads to
     // cycles.
-    GCPtr<Realm> m_realm;             // [[Realm]]
-    GCPtr<Environment> m_environment; // [[Environment]]
-    GCPtr<Object> m_namespace;        // [[Namespace]]
+    GCPtr<Realm> m_realm;                            // [[Realm]]
+    GCPtr<Environment> m_environment;                // [[Environment]]
+    GCPtr<Object> m_namespace;                       // [[Namespace]]
+    Script::HostDefined* m_host_defined { nullptr }; // [[HostDefined]]
 
     // Needed for potential lookups of modules.
     String m_filename;

+ 4 - 3
Userland/Libraries/LibJS/SourceTextModule.cpp

@@ -98,11 +98,11 @@ static Vector<ModuleRequest> module_requests(Program& program, Vector<String> co
     return requested_modules_in_source_order;
 }
 
-SourceTextModule::SourceTextModule(Realm& realm, StringView filename, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules,
+SourceTextModule::SourceTextModule(Realm& realm, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules,
     Vector<ImportEntry> import_entries, Vector<ExportEntry> local_export_entries,
     Vector<ExportEntry> indirect_export_entries, Vector<ExportEntry> star_export_entries,
     RefPtr<ExportStatement> default_export)
-    : CyclicModule(realm, filename, has_top_level_await, move(requested_modules))
+    : CyclicModule(realm, filename, has_top_level_await, move(requested_modules), host_defined)
     , m_ecmascript_code(move(body))
     , m_execution_context(realm.heap())
     , m_import_entries(move(import_entries))
@@ -120,7 +120,7 @@ void SourceTextModule::visit_edges(Cell::Visitor& visitor)
 }
 
 // 16.2.1.6.1 ParseModule ( sourceText, realm, hostDefined ), https://tc39.es/ecma262/#sec-parsemodule
-Result<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> SourceTextModule::parse(StringView source_text, Realm& realm, StringView filename)
+Result<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> SourceTextModule::parse(StringView source_text, Realm& realm, StringView filename, Script::HostDefined* host_defined)
 {
     // 1. Let body be ParseText(sourceText, Module).
     auto parser = Parser(Lexer(source_text, filename), Program::Type::Module);
@@ -248,6 +248,7 @@ Result<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> SourceTextModule::
     return NonnullGCPtr(*realm.heap().allocate_without_realm<SourceTextModule>(
         realm,
         filename,
+        host_defined,
         async,
         move(body),
         move(requested_modules),

+ 2 - 2
Userland/Libraries/LibJS/SourceTextModule.h

@@ -22,7 +22,7 @@ public:
     using ImportEntry = ImportStatement::ImportEntry;
     using ExportEntry = ExportStatement::ExportEntry;
 
-    static Result<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> parse(StringView source_text, Realm&, StringView filename = {});
+    static Result<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> parse(StringView source_text, Realm&, StringView filename = {}, Script::HostDefined* host_defined = nullptr);
 
     Program const& parse_node() const { return *m_ecmascript_code; }
 
@@ -37,7 +37,7 @@ protected:
     virtual ThrowCompletionOr<void> execute_module(VM& vm, GCPtr<PromiseCapability> capability) override;
 
 private:
-    SourceTextModule(Realm&, StringView filename, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules,
+    SourceTextModule(Realm&, StringView filename, Script::HostDefined* host_defined, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules,
         Vector<ImportEntry> import_entries, Vector<ExportEntry> local_export_entries,
         Vector<ExportEntry> indirect_export_entries, Vector<ExportEntry> star_export_entries,
         RefPtr<ExportStatement> default_export);