aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-08-14 15:43:19 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2018-08-14 17:46:03 +0000
commita29ab499a4822014d34d6e9e988600fdb6d60a0d (patch)
treee461872c2e00b7ff958e4469ba0e5485a0cb48ca
parent24a098793481c5e173e4271f775c96a37f0e6e1c (diff)
Fix explicit export of imported variables
Instead of using a re-export, it's also possible to write import { foo } from "./bar.js" and then export it again export { foo } Typically exported variables are referenced from the locals, but since we don't add imports to the locals, we need another way of locating them. This patch uses the index space after the locals in the internal class for imports, so that after we've identifier the export in the local export entry table, we can use the local name to search in the internal class and find imports past the locals. Change-Id: I58ab79ad3df1bbc1b972f0a2771d9ca1268de27b Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/qml/compiler/qv4compileddata.cpp8
-rw-r--r--src/qml/jsruntime/qv4module.cpp19
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations1
3 files changed, 24 insertions, 4 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 52db3100fc..798bfe921e 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -469,9 +469,11 @@ const Value *CompilationUnit::resolveExportRecursively(QV4::String *exportName,
if (auto localExport = lookupNameInExportTable(data->localExportEntryTable(), data->localExportEntryTableSize, exportName)) {
ScopedString localName(scope, runtimeStrings[localExport->localName]);
uint index = m_module->scope->internalClass->find(localName->toPropertyKey());
- if (index < UINT_MAX)
- return &m_module->scope->locals[index];
- return nullptr;
+ if (index >= UINT_MAX)
+ return nullptr;
+ if (index >= m_module->scope->locals.size)
+ return imports[index - m_module->scope->locals.size];
+ return &m_module->scope->locals[index];
}
if (auto indirectExport = lookupNameInExportTable(data->indirectExportEntryTable(), data->indirectExportEntryTableSize, exportName)) {
diff --git a/src/qml/jsruntime/qv4module.cpp b/src/qml/jsruntime/qv4module.cpp
index 4a7d0c19c4..e8e84ac965 100644
--- a/src/qml/jsruntime/qv4module.cpp
+++ b/src/qml/jsruntime/qv4module.cpp
@@ -44,6 +44,7 @@
#include <private/qv4vme_moth_p.h>
#include <private/qv4context_p.h>
#include <private/qv4symbol_p.h>
+#include <private/qv4identifiertable_p.h>
using namespace QV4;
@@ -70,6 +71,24 @@ void Heap::Module::init(ExecutionEngine *engine, CompiledData::CompilationUnit *
scope->nArgs = 0;
Scope valueScope(engine);
+
+ // It's possible for example to re-export an import, for example:
+ // import * as foo from "./bar.js"
+ // export { foo }
+ // Since we don't add imports to the locals, it won't be found typically.
+ // Except now we add imports at the end of the internal class in the index
+ // space past the locals, so that resolveExport can find it.
+ {
+ Scoped<QV4::InternalClass> ic(valueScope, scope->internalClass);
+
+ for (uint i = 0; i < unit->data->importEntryTableSize; ++i) {
+ const CompiledData::ImportEntry &import = unit->data->importEntryTable()[i];
+ ic = ic->addMember(engine->identifierTable->asPropertyKey(unit->runtimeStrings[import.localName]), Attr_NotConfigurable);
+ }
+ scope->internalClass.set(engine, ic->d());
+ }
+
+
Scoped<QV4::Module> This(valueScope, this);
ScopedString name(valueScope, engine->newString(QStringLiteral("Module")));
This->insertMember(engine->symbol_toStringTag(), name, Attr_ReadOnly);
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index fc9149b27e..c8220fe517 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -2179,7 +2179,6 @@ language/module-code/instn-named-bndng-dflt-gen-named.js strictFails
language/module-code/instn-named-bndng-dflt-named.js strictFails
language/module-code/instn-named-bndng-dflt-star.js strictFails
language/module-code/instn-named-bndng-let.js strictFails
-language/module-code/instn-star-equality.js strictFails
language/module-code/namespace/internals/define-own-property.js strictFails
language/module-code/namespace/internals/delete-exported-uninit.js strictFails
language/module-code/namespace/internals/enumerate-binding-uninit.js strictFails