diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-10-23 14:03:09 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-29 10:38:50 +0100 |
commit | 4f8df70107d17922303bb21db5a2cf92aa1aff99 (patch) | |
tree | e59fc784bf25c29f667d8f83fdddc156dffe1339 /src/qml/compiler/qv4isel_moth.cpp | |
parent | 34bf0139c75de861c948391737af3c8c2a42703c (diff) |
Implement new exception handling for moth
Add the required instructions and check for
exceptions in the engine before storing any
results.
Change-Id: Ibfaf904d659859e8012920270825211ba202c63d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/compiler/qv4isel_moth.cpp')
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 06fb9caac8..835f0a8a23 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -263,6 +263,8 @@ void InstructionSelection::run(int functionIndex) int locals = frameSize(); assert(locals >= 0); + V4IR::BasicBlock *exceptionHandler = 0; + Instruction::Push push; push.value = quint32(locals); addInstruction(push); @@ -275,6 +277,18 @@ void InstructionSelection::run(int functionIndex) _nextBlock = (i < ei - 1) ? _function->basicBlocks[i + 1] : 0; _addrs.insert(_block, _codeNext - _codeStart); + if (_block->catchBlock != exceptionHandler) { + Instruction::SetExceptionHandler set; + set.offset = 0; + if (_block->catchBlock) { + ptrdiff_t loc = addInstruction(set) + (((const char *)&set.offset) - ((const char *)&set)); + _patches[_block->catchBlock].append(loc); + } else { + addInstruction(set); + } + exceptionHandler = _block->catchBlock; + } + foreach (V4IR::Stmt *s, _block->statements) { _currentStatement = s; @@ -774,18 +788,33 @@ void InstructionSelection::callBuiltinThrow(V4IR::Expr *arg) void InstructionSelection::callBuiltinReThrow() { - // ### + if (_block->catchBlock) { + // jump to exception handler + Instruction::Jump jump; + jump.offset = 0; + ptrdiff_t loc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump)); + + _patches[_block->catchBlock].append(loc); + } else { + Instruction::Ret ret; + ret.result = Param::createValue(QV4::Primitive::undefinedValue()); + addInstruction(ret); + } } -void InstructionSelection::callBuiltinUnwindException(V4IR::Temp *) +void InstructionSelection::callBuiltinUnwindException(V4IR::Temp *result) { - // ### + Instruction::CallBuiltinUnwindException call; + call.result = getResultParam(result); + addInstruction(call); } void InstructionSelection::callBuiltinPushCatchScope(const QString &exceptionName) { - // #### + Instruction::CallBuiltinPushCatchScope call; + call.name = registerString(exceptionName); + addInstruction(call); } void InstructionSelection::callBuiltinForeachIteratorObject(V4IR::Temp *arg, V4IR::Temp *result) |