aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4engine_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4engine_p.h')
-rw-r--r--src/qml/jsruntime/qv4engine_p.h48
1 files changed, 38 insertions, 10 deletions
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 57a5952a6d..933241ea27 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -58,6 +58,10 @@
#include "qv4runtimeapi_p.h"
#include <private/qintrusivelist_p.h>
+#ifndef V4_BOOTSTRAP
+# include <private/qv8engine_p.h>
+#endif
+
namespace WTF {
class BumpPointerAllocator;
class PageAllocation;
@@ -82,15 +86,11 @@ namespace CompiledData {
struct CompilationUnit;
}
-#define CHECK_STACK_LIMITS(v4) \
- if ((v4->jsStackTop <= v4->jsStackLimit) && (reinterpret_cast<quintptr>(&v4) >= v4->cStackLimit || v4->recheckCStackLimits())) {} \
- else \
- return v4->throwRangeError(QStringLiteral("Maximum call stack size exceeded."))
-
-
struct Q_QML_EXPORT ExecutionEngine
{
private:
+ static qint32 maxCallDepth;
+
friend struct ExecutionContextSaver;
friend struct ExecutionContext;
friend struct Heap::ExecutionContext;
@@ -99,6 +99,7 @@ public:
Value *jsStackTop;
quint32 hasException;
+ qint32 callDepth;
MemoryManager *memoryManager;
ExecutableAllocator *executableAllocator;
@@ -108,7 +109,6 @@ public:
ExecutionContext *currentContext;
Value *jsStackLimit;
- quintptr cStackLimit;
Runtime runtime;
@@ -142,8 +142,13 @@ public:
Function *globalCode;
+#ifdef V4_BOOTSTRAP
QJSEngine *jsEngine() const;
QQmlEngine *qmlEngine() const;
+#else // !V4_BOOTSTRAP
+ QJSEngine *jsEngine() const { return v8Engine->publicEngine(); }
+ QQmlEngine *qmlEngine() const { return v8Engine->engine(); }
+#endif // V4_BOOTSTRAP
QV8Engine *v8Engine;
enum JSObjects {
@@ -440,8 +445,6 @@ public:
InternalClass *newClass(const InternalClass &other);
- bool recheckCStackLimits();
-
// Exception handling
Value *exceptionValue;
StackTrace exceptionStackTrace;
@@ -474,13 +477,19 @@ public:
QV4::ReturnedValue metaTypeToJS(int type, const void *data);
void assertObjectBelongsToEngine(const Heap::Base &baseObject);
+
+ bool checkStackLimits(ReturnedValue &exception);
};
// This is a trick to tell the code generators that functions taking a NoThrowContext won't
// throw exceptions and therefore don't need a check after the call.
+#ifndef V4_BOOTSTRAP
struct NoThrowEngine : public ExecutionEngine
{
};
+#else
+struct NoThrowEngine;
+#endif
inline void ExecutionEngine::pushContext(Heap::ExecutionContext *context)
@@ -526,7 +535,7 @@ inline Heap::QmlContext *ExecutionEngine::qmlContext() const
if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer)
ctx = parentContext(currentContext)->d();
- if (!ctx->outer)
+ if (ctx->type != Heap::ExecutionContext::Type_QmlContext && !ctx->outer)
return 0;
while (ctx->outer && ctx->outer->type != Heap::ExecutionContext::Type_GlobalContext)
@@ -562,7 +571,26 @@ inline void Value::mark(ExecutionEngine *e)
o->mark(e);
}
+#define CHECK_STACK_LIMITS(v4) { ReturnedValue e; if ((v4)->checkStackLimits(e)) return e; } \
+ ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4);
+struct ExecutionEngineCallDepthRecorder
+{
+ ExecutionEngine *ee;
+
+ ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ++ee->callDepth; }
+ ~ExecutionEngineCallDepthRecorder() { --ee->callDepth; }
+};
+
+inline bool ExecutionEngine::checkStackLimits(ReturnedValue &exception)
+{
+ if (Q_UNLIKELY((jsStackTop > jsStackLimit) || (callDepth >= maxCallDepth))) {
+ exception = throwRangeError(QStringLiteral("Maximum call stack size exceeded."));
+ return true;
+ }
+
+ return false;
+}
} // namespace QV4