Pārlūkot izejas kodu

LibJS: Implement the ImportMeta MetaProperty

This "standard" implementation of this is to do nothing.
davidot 3 gadi atpakaļ
vecāks
revīzija
91b3e5b31f

+ 42 - 2
Userland/Libraries/LibJS/AST.cpp

@@ -3167,8 +3167,48 @@ Completion MetaProperty::execute(Interpreter& interpreter, GlobalObject& global_
 
     // ImportMeta : import . meta
     if (m_type == MetaProperty::Type::ImportMeta) {
-        // TODO: Implement me :^)
-        return interpreter.vm().throw_completion<InternalError>(global_object, ErrorType::NotImplemented, "'import.meta' in modules");
+        // 1. Let module be ! GetActiveScriptOrModule().
+        auto script_or_module = interpreter.vm().get_active_script_or_module();
+
+        // 2. Assert: module is a Source Text Module Record.
+        VERIFY(script_or_module.has<Module*>());
+        VERIFY(is<SourceTextModule>(*script_or_module.get<Module*>()));
+        auto& module = static_cast<SourceTextModule&>(*script_or_module.get<Module*>());
+
+        // 3. Let importMeta be module.[[ImportMeta]].
+        auto* import_meta = module.import_meta();
+
+        // 4. If importMeta is empty, then
+        if (import_meta == nullptr) {
+            // a. Set importMeta to ! OrdinaryObjectCreate(null).
+            import_meta = Object::create(global_object, nullptr);
+
+            // b. Let importMetaValues be ! HostGetImportMetaProperties(module).
+            auto import_meta_values = interpreter.vm().host_get_import_meta_properties(module);
+
+            // c. For each Record { [[Key]], [[Value]] } p of importMetaValues, do
+            for (auto& entry : import_meta_values) {
+                // i. Perform ! CreateDataPropertyOrThrow(importMeta, p.[[Key]], p.[[Value]]).
+                MUST(import_meta->create_data_property_or_throw(entry.key, entry.value));
+            }
+
+            // d. Perform ! HostFinalizeImportMeta(importMeta, module).
+            interpreter.vm().host_finalize_import_meta(import_meta, module);
+
+            // e. Set module.[[ImportMeta]] to importMeta.
+            module.set_import_meta({}, import_meta);
+
+            // f. Return importMeta.
+            return Value { import_meta };
+        }
+        // 5. Else,
+        else {
+            // a. Assert: Type(importMeta) is Object.
+            // Note: This is always true by the type.
+
+            // b. Return importMeta.
+            return Value { import_meta };
+        }
     }
 
     VERIFY_NOT_REACHED();

+ 7 - 0
Userland/Libraries/LibJS/Runtime/VM.cpp

@@ -81,6 +81,13 @@ VM::VM(OwnPtr<CustomData> custom_data)
         return finish_dynamic_import(move(referencing_script_or_module), specifier, promise_capability, promise);
     };
 
+    host_get_import_meta_properties = [&](SourceTextModule const&) -> HashMap<PropertyKey, Value> {
+        return {};
+    };
+
+    host_finalize_import_meta = [&](Object*, SourceTextModule const&) {
+    };
+
 #define __JS_ENUMERATE(SymbolName, snake_name) \
     m_well_known_symbol_##snake_name = js_symbol(*this, "Symbol." #SymbolName, false);
     JS_ENUMERATE_WELL_KNOWN_SYMBOLS