diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2019-04-18 15:37:17 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-04-30 16:24:45 +0000 |
commit | 9b6c20cb719542cfcf3e031afd5b2b0b1cd3833e (patch) | |
tree | 2130fe9f9179eccb604c3e3eacc18cbd62202b0b /src/qml/jsruntime/qv4vme_moth.cpp | |
parent | d7db2ef07bf6f0f7c39f342aed94d51cca42df11 (diff) |
Make JavaScript execution interruptible
Add an atomic isInterrupted flag to BaseEngine and check that in
addition to the hasException flag on checkException(). Add some more
exception checks to cover all possible infinite loops. Also, remove the
writeBarrierActive member from QV4::EngineBase. It isn't used.
Fixes: QTBUG-49080
Change-Id: I86b3114e3e61aff3e5eb9b020749a908ed801c2b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4vme_moth.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 4c292d429a..ec44f42933 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -347,7 +347,7 @@ static struct InstrCount { #undef CHECK_EXCEPTION #endif #define CHECK_EXCEPTION \ - if (engine->hasException) \ + if (engine->hasException || engine->isInterrupted) \ goto handleUnwind static inline Heap::CallContext *getScope(QV4::Value *stack, int level) @@ -1013,6 +1013,10 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, code += offset; MOTH_END_INSTR(JumpNotUndefined) + MOTH_BEGIN_INSTR(CheckException) + CHECK_EXCEPTION; + MOTH_END_INSTR(CheckException) + MOTH_BEGIN_INSTR(CmpEqNull) acc = Encode(ACC.isNullOrUndefined()); MOTH_END_INSTR(CmpEqNull) @@ -1363,7 +1367,10 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, MOTH_END_INSTR(Debug) handleUnwind: - Q_ASSERT(engine->hasException || frame->unwindLevel); + // We do start the exception handler in case of isInterrupted. The exception handler will + // immediately abort, due to the same isInterrupted. We don't skip the exception handler + // because the current behavior is easier to implement in the JIT. + Q_ASSERT(engine->hasException || engine->isInterrupted || frame->unwindLevel); if (!frame->unwindHandler) { acc = Encode::undefined(); return acc; |