From 2b5e0f90112fe85872894fb16e811203d4d3671f Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 17 Feb 2020 15:30:54 +0100 Subject: V4: Fix mark stack overruns Instead of applying a heuristic on when to call drain() in unrelated code, we check the stack limit on each push(). If the soft limit is reached we try to drain. As drain() itself can push again, we try to limit the stack size by allowing at most 65 recursions of drain(). If none of that helps, we crash with a meaningful error message. This allows us to remove all the hacky drain() calls in other parts of the code. Change-Id: Ib979339470da0e85981de8131e7997755b757c71 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4engine.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'src/qml/jsruntime/qv4engine.cpp') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index f1b20ce53b..e9cc789607 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1266,20 +1266,15 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file) void ExecutionEngine::markObjects(MarkStack *markStack) { - for (int i = 0; i < NClasses; ++i) - if (classes[i]) { - classes[i]->mark(markStack); - if (markStack->top >= markStack->limit) - markStack->drain(); - } - markStack->drain(); + for (int i = 0; i < NClasses; ++i) { + if (Heap::InternalClass *c = classes[i]) + c->mark(markStack); + } identifierTable->markObjects(markStack); - for (auto compilationUnit: compilationUnits) { + for (auto compilationUnit: compilationUnits) compilationUnit->markObjects(markStack); - markStack->drain(); - } } ReturnedValue ExecutionEngine::throwError(const Value &value) -- cgit v1.2.3