aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jit/qv4unop.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2016-08-10 11:45:24 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-08-10 13:20:54 +0000
commit6fe7ccf59b917e9383c07c1e7a71631200590e3a (patch)
tree90ff95735566e64b098be0fd11633457ee09b1b7 /src/qml/jit/qv4unop.cpp
parent9425f832cdc036818cb08d1bd1328345fcb6f2ff (diff)
V4: Fix JavaScript finally-block execution
After moving all runtime functions into the Runtime class and doing indirect function calls, the code generation would always emit code to check for an exception after a call. This is problematic for methods that do not throw, but might be called when an exception is thrown. I.e. in a finally block. This is especially problematic for methods like popScope, the very first runtime method that is called in a finally block. The result was that after popScope, execution was passed over to the exception handler block for that finally block (meaning: the body of the finally block was never executed). The fix is to declare an enumerator in an anonymous enum for each runtime method that indicates if an exception check is needed. The existing ExceptionCheck templates are used to set the value. Change-Id: I5bd8bcf2a92acabf2a33b3764447de6cc364bba9 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/jit/qv4unop.cpp')
-rw-r--r--src/qml/jit/qv4unop.cpp8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/qml/jit/qv4unop.cpp b/src/qml/jit/qv4unop.cpp
index 6a32069ac4..799103849b 100644
--- a/src/qml/jit/qv4unop.cpp
+++ b/src/qml/jit/qv4unop.cpp
@@ -47,10 +47,14 @@ using namespace JIT;
#define stringIfyx(s) #s
#define stringIfy(s) stringIfyx(s)
#define setOp(operation) \
- do { call = RuntimeCall(qOffsetOf(QV4::Runtime, operation)); name = "Runtime::" stringIfy(operation); } while (0)
+ do { \
+ call = RuntimeCall(qOffsetOf(QV4::Runtime, operation)); name = "Runtime::" stringIfy(operation); \
+ needsExceptionCheck = Runtime::Method_##operation##_NeedsExceptionCheck; \
+ } while (0)
void Unop::generate(IR::Expr *source, IR::Expr *target)
{
+ bool needsExceptionCheck;
RuntimeCall call;
const char *name = 0;
switch (op) {
@@ -71,7 +75,7 @@ void Unop::generate(IR::Expr *source, IR::Expr *target)
} // switch
Q_ASSERT(call.isValid());
- _as->generateFunctionCallImp(target, name, call, Assembler::PointerToValue(source));
+ _as->generateFunctionCallImp(needsExceptionCheck, target, name, call, Assembler::PointerToValue(source));
}
void Unop::generateUMinus(IR::Expr *source, IR::Expr *target)