From 9b6c20cb719542cfcf3e031afd5b2b0b1cd3833e Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 18 Apr 2019 15:37:17 +0200 Subject: 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 --- src/qml/jit/qv4assemblercommon_p.h | 5 +++++ src/qml/jit/qv4baselinejit.cpp | 5 +++++ src/qml/jit/qv4baselinejit_p.h | 1 + 3 files changed, 11 insertions(+) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h index e5c2aff1a7..f305213ce2 100644 --- a/src/qml/jit/qv4assemblercommon_p.h +++ b/src/qml/jit/qv4assemblercommon_p.h @@ -619,6 +619,9 @@ public: for (Jump j : catchyJumps) j.link(this); + // We don't need to check for isInterrupted here because if that is set, + // then the first checkException() in any exception handler will find another "exception" + // and jump out of the exception handler. loadPtr(exceptionHandlerAddress(), ScratchRegister); Jump exitFunction = branchPtr(Equal, ScratchRegister, TrustedImmPtr(0)); jump(ScratchRegister); @@ -633,6 +636,8 @@ public: void checkException() { + // This actually reads 4 bytes, starting at hasException. + // Therefore, it also reads the isInterrupted flag, and triggers an exception on that. addCatchyJump( branch32(NotEqual, Address(EngineRegister, offsetof(EngineBase, hasException)), diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp index 517f0940e5..f4807f1917 100644 --- a/src/qml/jit/qv4baselinejit.cpp +++ b/src/qml/jit/qv4baselinejit.cpp @@ -794,6 +794,11 @@ void BaselineJIT::generate_JumpNotUndefined(int offset) labels.insert(as->jumpNotUndefined(absoluteOffset(offset))); } +void BaselineJIT::generate_CheckException() +{ + as->checkException(); +} + void BaselineJIT::generate_CmpEqNull() { as->cmpeqNull(); } void BaselineJIT::generate_CmpNeNull() { as->cmpneNull(); } void BaselineJIT::generate_CmpEqInt(int lhs) { as->cmpeqInt(lhs); } diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h index 46622d29e6..284faf0ff0 100644 --- a/src/qml/jit/qv4baselinejit_p.h +++ b/src/qml/jit/qv4baselinejit_p.h @@ -163,6 +163,7 @@ public: void generate_JumpFalse(int offset) override; void generate_JumpNoException(int offset) override; void generate_JumpNotUndefined(int offset) override; + void generate_CheckException() override; void generate_CmpEqNull() override; void generate_CmpNeNull() override; void generate_CmpEqInt(int lhs) override; -- cgit v1.2.3