diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-04-06 10:20:08 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-02 14:17:51 +0000 |
commit | 922e6f42b4fa9b9fa87246c577c13bb945bd4bc4 (patch) | |
tree | 182cf430b7340c4f34c0cb350af1c15fd41b6648 /src/qml/compiler/qv4compilerscanfunctions.cpp | |
parent | 20d30b6b3a253eebedc927dbb91685bbec52cfee (diff) | |
download | qtdeclarative-922e6f42b4fa9b9fa87246c577c13bb945bd4bc4.tar.gz |
Rework catch context handling
Remove the need for a specialized catch context, instead
use a regular block context, that also captures the
catched variable.
This also removes the need to do lookups by name inside
a catch expression.
Change-Id: I8b037add7f423922e2a76b4c0da646ca7e25813a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compilerscanfunctions.cpp')
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index 312f07e254..120c606f91 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -317,13 +317,6 @@ void ScanFunctions::endVisit(FunctionDeclaration *) leaveEnvironment(); } -bool ScanFunctions::visit(TryStatement *) -{ - // ### should limit to catch(), as try{} finally{} should be ok without - _context->hasTry = true; - return true; -} - bool ScanFunctions::visit(WithStatement *ast) { if (_context->isStrict) { @@ -406,6 +399,23 @@ void ScanFunctions::endVisit(Block *) leaveEnvironment(); } +bool ScanFunctions::visit(Catch *ast) +{ + TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls); + enterEnvironment(ast, ContextType::Block); + _context->name = QLatin1String("CatchBlock"); + _context->isCatchBlock = true; + _context->catchedVariable = ast->name.toString(); + _context->addLocalVar(ast->name.toString(), Context::MemberType::VariableDefinition, VariableScope::Let); + Node::accept(ast->statement->statements, this); + return false; +} + +void ScanFunctions::endVisit(Catch *) +{ + leaveEnvironment(); +} + bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, bool enterName) { Context *outerContext = _context; @@ -513,7 +523,7 @@ void ScanFunctions::calcEscapingVariables() } } for (Context *c : qAsConst(m->contextMap)) { - bool allVarsEscape = c->hasWith || c->hasTry || c->hasDirectEval; + bool allVarsEscape = c->hasWith || c->hasDirectEval; if (allVarsEscape && c->contextType == ContextType::Block && c->members.isEmpty()) allVarsEscape = false; if (m->debugMode) @@ -528,6 +538,11 @@ void ScanFunctions::calcEscapingVariables() // ### 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); + m->canEscape = true; + } if (!c->parent || c->usesArgumentsObject == Context::ArgumentsObjectUnknown) c->usesArgumentsObject = Context::ArgumentsObjectNotUsed; if (c->usesArgumentsObject == Context::ArgumentsObjectUsed) { |