diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-05-04 15:16:08 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-11 07:17:05 +0000 |
commit | 4cf7e80c5740912804383e4d866ba12b2520d0e6 (patch) | |
tree | 143d960492aa166a7f3d7111b64151c42234a81f /src/qml/compiler/qv4compilerscanfunctions.cpp | |
parent | 2fc50421c86134b5b42a4ba68aa7f6b87cfd7d74 (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.cpp | 30 |
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); |