diff options
| author | Lars Knoll <lars.knoll@qt.io> | 2018-03-28 10:58:58 +0200 |
|---|---|---|
| committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-02 14:17:21 +0000 |
| commit | 851c28d140c398990513640047a20aab36ccc655 (patch) | |
| tree | dd9391f74c6a98a234cf2b5ac09bc41b7b7d3b98 /src/qml/compiler/qv4compilerscanfunctions.cpp | |
| parent | 13cc936859518b5fa378c7b8242d56ebf49ebce9 (diff) | |
Refactor variable resolving
Move variable resolving into the context, and avoid creating
ExecutionContext's whereever we can. This prepares things for
block scoping, where this becomes rather important to be
able to achieve decent performance.
Change-Id: Idf3d3c12cf348a2c3da01989c26c8529ceb36c12
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compilerscanfunctions.cpp')
| -rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index b779e37946..0feba7bb61 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -474,13 +474,17 @@ void ScanFunctions::calcEscapingVariables() while (c) { Context::MemberMap::const_iterator it = c->members.find(var); if (it != c->members.end()) { - if (c != inner) + if (c != inner) { it->canEscape = true; + c->requiresExecutionContext = true; + } break; } if (c->findArgument(var) != -1) { - if (c != inner) + if (c != inner) { c->argumentsCanEscape = true; + c->requiresExecutionContext = true; + } break; } c = c->parent; @@ -489,16 +493,44 @@ void ScanFunctions::calcEscapingVariables() Context *c = inner->parent; while (c) { c->hasDirectEval |= inner->hasDirectEval; + c->hasWith |= inner->hasWith; c = c->parent; } } + for (Context *c : qAsConst(m->contextMap)) { + bool allVarsEscape = c->hasWith || c->hasTry || c->hasDirectEval || m->debugMode; + if (allVarsEscape) { + c->requiresExecutionContext = true; + c->argumentsCanEscape = true; + for (auto &m : c->members) { + m.canEscape = true; + } + } + // ### for now until we have lexically scoped vars that'll require it + if (c->type == ContextType::Global) + c->requiresExecutionContext = false; + // ### Shouldn't be required, we could probably rather change the ContextType to FunctionCode for strict eval + if (c->type == ContextType::Eval && c->isStrict) + c->requiresExecutionContext = true; + if (!c->parent || c->usesArgumentsObject == Context::ArgumentsObjectUnknown) + c->usesArgumentsObject = Context::ArgumentsObjectNotUsed; + if (c->usesArgumentsObject == Context::ArgumentsObjectUsed) { + QString arguments = QStringLiteral("arguments"); + c->addLocalVar(arguments, Context::VariableDeclaration, AST::VariableScope::Var); + if (!c->isStrict) { + c->argumentsCanEscape = true; + c->requiresExecutionContext = true; + } + } + } static const bool showEscapingVars = qEnvironmentVariableIsSet("QV4_SHOW_ESCAPING_VARS"); if (showEscapingVars) { qDebug() << "==== escaping variables ===="; for (Context *c : qAsConst(m->contextMap)) { qDebug() << "Context" << c->name << ":"; - qDebug() << " Arguments escape" << c->argumentsCanEscape; + if (c->argumentsCanEscape) + qDebug() << " Arguments escape"; for (auto it = c->members.constBegin(); it != c->members.constEnd(); ++it) { qDebug() << " " << it.key() << it.value().canEscape; } |
