diff options
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 42 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4module.cpp | 22 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4module_p.h | 2 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 2 |
7 files changed, 59 insertions, 15 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 46034050e0..a4e49377a8 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -440,6 +440,17 @@ const Value *CompilationUnit::resolveExport(QV4::String *exportName) return resolveExportRecursively(exportName, &resolveSet); } +QStringList CompilationUnit::exportedNames() const +{ + QStringList names; + QVector<const CompiledData::CompilationUnit*> exportNameSet; + getExportedNamesRecursively(&names, &exportNameSet); + names.sort(); + auto last = std::unique(names.begin(), names.end()); + names.erase(last, names.end()); + return names; +} + const Value *CompilationUnit::resolveExportRecursively(QV4::String *exportName, QVector<ResolveSetEntry> *resolveSet) { if (!m_module) @@ -512,6 +523,37 @@ const ExportEntry *CompilationUnit::lookupNameInExportTable(const ExportEntry *f return matchingExport; } +void CompilationUnit::getExportedNamesRecursively(QStringList *names, QVector<const CompilationUnit*> *exportNameSet, bool includeDefaultExport) const +{ + if (exportNameSet->contains(this)) + return; + exportNameSet->append(this); + + const auto append = [names, includeDefaultExport](const QString &name) { + if (!includeDefaultExport && name == QLatin1String("default")) + return; + names->append(name); + }; + + for (uint i = 0; i < data->localExportEntryTableSize; ++i) { + const CompiledData::ExportEntry &entry = data->localExportEntryTable()[i]; + append(stringAt(entry.exportName)); + } + + for (uint i = 0; i < data->indirectExportEntryTableSize; ++i) { + const CompiledData::ExportEntry &entry = data->indirectExportEntryTable()[i]; + append(stringAt(entry.exportName)); + } + + for (uint i = 0; i < data->starExportEntryTableSize; ++i) { + const CompiledData::ExportEntry &entry = data->starExportEntryTable()[i]; + auto dependentModuleUnit = engine->loadModule(QUrl(stringAt(entry.moduleRequest)), this); + if (!dependentModuleUnit) + return; + dependentModuleUnit->getExportedNamesRecursively(names, exportNameSet, /*includeDefaultExport*/false); + } +} + void CompilationUnit::evaluate() { if (m_moduleEvaluated) diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 7581fe3fff..f0043cc6af 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -1169,6 +1169,7 @@ public: QStringList moduleRequests() const; Heap::Module *instantiate(ExecutionEngine *engine); const Value *resolveExport(QV4::String *exportName); + QStringList exportedNames() const; void evaluate(); QV4::Function *linkToEngine(QV4::ExecutionEngine *engine); @@ -1202,6 +1203,7 @@ private: const Value *resolveExportRecursively(QV4::String *exportName, QVector<ResolveSetEntry> *resolveSet); const ExportEntry *lookupNameInExportTable(const ExportEntry *firstExportEntry, int tableSize, QV4::String *name) const; + void getExportedNamesRecursively(QStringList *names, QVector<const CompilationUnit *> *exportNameSet, bool includeDefaultExport = true) const; QString m_fileName; // initialized from data->sourceFileIndex QString m_finalUrlString; // initialized from data->finalUrlIndex diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index e92d7c69ba..90c75b204d 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1700,7 +1700,7 @@ void ExecutionEngine::injectModule(const QQmlRefPointer<CompiledData::Compilatio modules.insert(moduleUnit->finalUrl(), moduleUnit); } -QQmlRefPointer<CompiledData::CompilationUnit> ExecutionEngine::loadModule(const QUrl &_url, CompiledData::CompilationUnit *referrer) +QQmlRefPointer<CompiledData::CompilationUnit> ExecutionEngine::loadModule(const QUrl &_url, const CompiledData::CompilationUnit *referrer) { QUrl url = QQmlTypeLoader::normalize(_url); if (referrer) diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 00879511d3..4cd7e40013 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -582,7 +582,7 @@ public: QHash<QUrl, QQmlRefPointer<CompiledData::CompilationUnit>> modules; void injectModule(const QQmlRefPointer<CompiledData::CompilationUnit> &moduleUnit); - QQmlRefPointer<CompiledData::CompilationUnit> loadModule(const QUrl &_url, CompiledData::CompilationUnit *referrer = nullptr); + QQmlRefPointer<CompiledData::CompilationUnit> loadModule(const QUrl &_url, const CompiledData::CompilationUnit *referrer = nullptr); #endif private: diff --git a/src/qml/jsruntime/qv4module.cpp b/src/qml/jsruntime/qv4module.cpp index e8e84ac965..5974c9be73 100644 --- a/src/qml/jsruntime/qv4module.cpp +++ b/src/qml/jsruntime/qv4module.cpp @@ -162,7 +162,9 @@ bool Module::virtualDeleteProperty(Managed *m, PropertyKey id) struct ModuleNamespaceIterator : ObjectOwnPropertyKeyIterator { - uint exportIndex = 0; + QStringList exportedNames; + int exportIndex = 0; + ModuleNamespaceIterator(const QStringList &names) : exportedNames(names) {} ~ModuleNamespaceIterator() override = default; PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override; @@ -171,23 +173,23 @@ struct ModuleNamespaceIterator : ObjectOwnPropertyKeyIterator PropertyKey ModuleNamespaceIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs) { const Module *module = static_cast<const Module *>(o); - if (exportIndex < module->d()->unit->unitData()->localExportEntryTableSize) { + if (exportIndex < exportedNames.count()) { if (attrs) *attrs = Attr_Data; - if (pd) { - const CompiledData::ExportEntry &entry = module->d()->unit->unitData()->localExportEntryTable()[exportIndex]; - Scope scope(module->engine()); - ScopedString exportName(scope, module->d()->unit->runtimeStrings[entry.exportName]); - pd->value = *module->d()->unit->resolveExport(exportName); - } + Scope scope(module->engine()); + ScopedString exportName(scope, scope.engine->newString(exportedNames.at(exportIndex))); exportIndex++; + if (pd) + pd->value = *module->d()->unit->resolveExport(exportName); + return exportName->toPropertyKey(); } return ObjectOwnPropertyKeyIterator::next(o, pd, attrs); } -OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *) +OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *o) { - return new ModuleNamespaceIterator; + const Module *module = static_cast<const Module *>(o); + return new ModuleNamespaceIterator(module->d()->unit->exportedNames()); } Heap::Object *Module::virtualGetPrototypeOf(const Managed *) diff --git a/src/qml/jsruntime/qv4module_p.h b/src/qml/jsruntime/qv4module_p.h index c22e6cd1c3..bb004b3b44 100644 --- a/src/qml/jsruntime/qv4module_p.h +++ b/src/qml/jsruntime/qv4module_p.h @@ -81,7 +81,7 @@ struct Q_QML_EXPORT Module : public Object { static bool virtualDefineOwnProperty(Managed *, PropertyKey, const Property *, PropertyAttributes); static bool virtualPut(Managed *, PropertyKey, const Value &, Value *); static bool virtualDeleteProperty(Managed *m, PropertyKey id); - static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *); + static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m); static Heap::Object *virtualGetPrototypeOf(const Managed *); static bool virtualSetPrototypeOf(Managed *, const Object *proto); static bool virtualIsExtensible(const Managed *); diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index c183fdb542..f90c3ba88a 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -1969,8 +1969,6 @@ language/module-code/namespace/internals/get-str-found-uninit.js strictFails language/module-code/namespace/internals/object-hasOwnProperty-binding-uninit.js strictFails language/module-code/namespace/internals/object-keys-binding-uninit.js strictFails language/module-code/namespace/internals/object-propertyIsEnumerable-binding-uninit.js strictFails -language/module-code/namespace/internals/own-property-keys-binding-types.js strictFails -language/module-code/namespace/internals/own-property-keys-sort.js strictFails language/statements/async-function/cptn-decl.js fails language/statements/async-function/declaration-returns-promise.js fails language/statements/async-function/evaluation-body.js fails |