aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4compilerscanfunctions.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-04 15:16:08 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-11 07:17:05 +0000
commit4cf7e80c5740912804383e4d866ba12b2520d0e6 (patch)
tree143d960492aa166a7f3d7111b64151c42234a81f /src/qml/compiler/qv4compilerscanfunctions.cpp
parent2fc50421c86134b5b42a4ba68aa7f6b87cfd7d74 (diff)
Ensure we have a lexical scope for global code
This requires a bit more work than simply pushing a new BlockContext for the lexically declared variables, as eval() and the Function constructor operate on the global scope (including the lexically declared names). To fix this introduce Push/PopScriptContext instructions, that create a BlockContext for the lexically declared vars and pushes that one as a global script context that eval and friends use. Change-Id: I0fd0b0f682f82e250545e874fe93978449fe5e46 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compilerscanfunctions.cpp')
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp30
1 files changed, 16 insertions, 14 deletions
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp
index 47329e978b..f7100a1d1a 100644
--- a/src/qml/compiler/qv4compilerscanfunctions.cpp
+++ b/src/qml/compiler/qv4compilerscanfunctions.cpp
@@ -522,20 +522,19 @@ void ScanFunctions::calcEscapingVariables()
if (current->isWithBlock || current->contextType != ContextType::Block)
break;
}
+ Q_ASSERT(c != inner);
while (c) {
Context::MemberMap::const_iterator it = c->members.find(var);
if (it != c->members.end()) {
- if (c != inner) {
+ if (c->parent || it->isLexicallyScoped()) {
it->canEscape = true;
c->requiresExecutionContext = true;
}
break;
}
if (c->findArgument(var) != -1) {
- if (c != inner) {
- c->argumentsCanEscape = true;
- c->requiresExecutionContext = true;
- }
+ c->argumentsCanEscape = true;
+ c->requiresExecutionContext = true;
break;
}
c = c->parent;
@@ -551,18 +550,21 @@ void ScanFunctions::calcEscapingVariables()
bool allVarsEscape = c->hasDirectEval;
if (allVarsEscape && c->contextType == ContextType::Block && c->members.isEmpty())
allVarsEscape = false;
- if (m->debugMode)
+ if (!c->parent || m->debugMode)
allVarsEscape = true;
if (allVarsEscape) {
- c->requiresExecutionContext = true;
- c->argumentsCanEscape = true;
+ if (c->parent) {
+ c->requiresExecutionContext = true;
+ c->argumentsCanEscape = true;
+ } else {
+ for (const auto &m : qAsConst(c->members)) {
+ if (m.isLexicallyScoped()) {
+ c->requiresExecutionContext = true;
+ break;
+ }
+ }
+ }
}
- // ### for now until we have lexically scoped vars that'll require it
- if (c->contextType == ContextType::Global)
- c->requiresExecutionContext = false;
- // ### Shouldn't be required, we could probably rather change the ContextType to FunctionCode for strict eval
- if (c->contextType == ContextType::Eval && c->isStrict)
- c->requiresExecutionContext = true;
if (c->contextType == ContextType::Block && c->isCatchBlock) {
c->requiresExecutionContext = true;
auto m = c->members.find(c->catchedVariable);