diff options
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 16 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast.cpp | 6 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 8 |
3 files changed, 23 insertions, 7 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index be0de09d79..fca97d2e0c 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -216,15 +216,19 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) memoryManager = new QV4::MemoryManager(this); if (maxCallDepth == -1) { - ok = false; - maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok); - if (!ok || maxCallDepth <= 0) { + if (qEnvironmentVariableIsSet("QV4_CRASH_ON_STACKOVERFLOW")) { + maxCallDepth = std::numeric_limits<qint32>::max(); + } else { + ok = false; + maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok); + if (!ok || maxCallDepth <= 0) { #if defined(QT_NO_DEBUG) && !defined(__SANITIZE_ADDRESS__) && !QT_HAS_FEATURE(address_sanitizer) - maxCallDepth = 1234; + maxCallDepth = 1234; #else - // no (tail call) optimization is done, so there'll be a lot mare stack frames active - maxCallDepth = 200; + // no (tail call) optimization is done, so there'll be a lot mare stack frames active + maxCallDepth = 200; #endif + } } } Q_ASSERT(maxCallDepth > 0); diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp index b63b2191b9..03355b3e38 100644 --- a/src/qml/parser/qqmljsast.cpp +++ b/src/qml/parser/qqmljsast.cpp @@ -105,6 +105,12 @@ ClassExpression *Node::asClassDefinition() return nullptr; } +bool Node::ignoreRecursionDepth() const +{ + static const bool doIgnore = qEnvironmentVariableIsSet("QV4_CRASH_ON_STACKOVERFLOW"); + return doIgnore; +} + ExpressionNode *ExpressionNode::expressionCast() { return this; diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index 4247785905..bdda46da90 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -275,10 +275,16 @@ public: virtual FunctionExpression *asFunctionDefinition(); virtual ClassExpression *asClassDefinition(); + bool ignoreRecursionDepth() const; + inline void accept(Visitor *visitor) { Visitor::RecursionDepthCheck recursionCheck(visitor); - if (recursionCheck()) { + + // Stack overflow is uncommon, ignoreRecursionDepth() only returns true if + // QV4_CRASH_ON_STACKOVERFLOW is set, and ignoreRecursionDepth() needs to be out of line. + // Therefore, check for ignoreRecursionDepth() _after_ calling the inline recursionCheck(). + if (recursionCheck() || ignoreRecursionDepth()) { if (visitor->preVisit(this)) accept0(visitor); visitor->postVisit(this); |