aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4compilercontext.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-04-06 10:20:08 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-02 14:17:51 +0000
commit922e6f42b4fa9b9fa87246c577c13bb945bd4bc4 (patch)
tree182cf430b7340c4f34c0cb350af1c15fd41b6648 /src/qml/compiler/qv4compilercontext.cpp
parent20d30b6b3a253eebedc927dbb91685bbec52cfee (diff)
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/qv4compilercontext.cpp')
-rw-r--r--src/qml/compiler/qv4compilercontext.cpp34
1 files changed, 22 insertions, 12 deletions
diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp
index 4893a06af8..f340d62e52 100644
--- a/src/qml/compiler/qv4compilercontext.cpp
+++ b/src/qml/compiler/qv4compilercontext.cpp
@@ -84,15 +84,17 @@ bool Context::addLocalVar(const QString &name, Context::MemberType type, Variabl
if (formals && formals->containsName(name))
return (scope == QQmlJS::AST::VariableScope::Var);
}
- MemberMap::iterator it = members.find(name);
- if (it != members.end()) {
- if (scope != QQmlJS::AST::VariableScope::Var || (*it).scope != QQmlJS::AST::VariableScope::Var)
- return false;
- if ((*it).type <= type) {
- (*it).type = type;
- (*it).function = function;
+ if (!isCatchBlock || name != catchedVariable) {
+ MemberMap::iterator it = members.find(name);
+ if (it != members.end()) {
+ if (scope != VariableScope::Var || (*it).scope != VariableScope::Var)
+ return false;
+ if ((*it).type <= type) {
+ (*it).type = type;
+ (*it).function = function;
+ }
+ return true;
}
- return true;
}
Member m;
m.type = type;
@@ -164,10 +166,18 @@ int Context::emitBlockHeader(Codegen *codegen)
if (requiresExecutionContext ||
contextType == ContextType::Binding) { // we don't really need this for bindings, but we do for signal handlers, and we don't know if the code is a signal handler or not.
if (contextType == ContextType::Block) {
- Instruction::PushBlockContext blockContext;
- blockContext.index = blockIndex;
- blockContext.reg = contextReg = bytecodeGenerator->newRegister();
- bytecodeGenerator->addInstruction(blockContext);
+ if (isCatchBlock) {
+ Instruction::PushCatchContext catchContext;
+ catchContext.index = blockIndex;
+ catchContext.reg = contextReg = bytecodeGenerator->newRegister();
+ catchContext.name = codegen->registerString(catchedVariable);
+ bytecodeGenerator->addInstruction(catchContext);
+ } else {
+ Instruction::PushBlockContext blockContext;
+ blockContext.index = blockIndex;
+ blockContext.reg = contextReg = bytecodeGenerator->newRegister();
+ bytecodeGenerator->addInstruction(blockContext);
+ }
} else {
Instruction::CreateCallContext createContext;
bytecodeGenerator->addInstruction(createContext);