diff options
Diffstat (limited to 'src/qml/jsruntime/qv4engine_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 48 |
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 |