/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtQml module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QV4ENGINE_H #define QV4ENGINE_H #include "qv4global_p.h" #include "private/qv4isel_p.h" #include "qv4util_p.h" #include "qv4context_p.h" #include "qv4property_p.h" #include namespace WTF { class BumpPointerAllocator; class PageAllocation; } QT_BEGIN_NAMESPACE class QV8Engine; class QQmlError; namespace QV4 { namespace Debugging { class Debugger; } // namespace Debugging namespace CompiledData { struct CompilationUnit; } } namespace QV4 { struct Function; struct Object; struct BooleanObject; struct NumberObject; struct StringObject; struct ArrayObject; struct DateObject; struct FunctionObject; struct BoundFunction; struct RegExpObject; struct ErrorObject; struct SyntaxErrorObject; struct ArgumentsObject; struct ExecutionContext; struct ExecutionEngine; class MemoryManager; class UnwindHelper; class ExecutableAllocator; struct ObjectPrototype; struct StringPrototype; struct NumberPrototype; struct BooleanPrototype; struct ArrayPrototype; struct FunctionPrototype; struct DatePrototype; struct RegExpPrototype; struct ErrorPrototype; struct EvalErrorPrototype; struct RangeErrorPrototype; struct ReferenceErrorPrototype; struct SyntaxErrorPrototype; struct TypeErrorPrototype; struct URIErrorPrototype; struct VariantPrototype; struct SequencePrototype; struct EvalFunction; struct IdentifierTable; struct InternalClass; class MultiplyWrappedQObjectMap; class RegExp; class RegExpCache; struct QmlExtensions; struct Exception; struct Q_QML_EXPORT ExecutionEngine { MemoryManager *memoryManager; ExecutableAllocator *executableAllocator; ExecutableAllocator *regExpAllocator; QScopedPointer iselFactory; ExecutionContext *current; GlobalContext *rootContext; WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine. WTF::PageAllocation *jsStack; SafeValue *jsStackBase; SafeValue *jsStackTop; SafeValue *stackPush(uint nValues) { SafeValue *ptr = jsStackTop; jsStackTop = ptr + nValues; return ptr; } void stackPop(uint nValues) { jsStackTop -= nValues; } IdentifierTable *identifierTable; QV4::Debugging::Debugger *debugger; Object *globalObject; Function *globalCode; QV8Engine *v8Engine; SafeValue objectCtor; SafeValue stringCtor; SafeValue numberCtor; SafeValue booleanCtor; SafeValue arrayCtor; SafeValue functionCtor; SafeValue dateCtor; SafeValue regExpCtor; SafeValue errorCtor; SafeValue evalErrorCtor; SafeValue rangeErrorCtor; SafeValue referenceErrorCtor; SafeValue syntaxErrorCtor; SafeValue typeErrorCtor; SafeValue uRIErrorCtor; QQmlJS::MemoryPool classPool; InternalClass *emptyClass; InternalClass *objectClass; InternalClass *arrayClass; InternalClass *stringClass; InternalClass *booleanClass; InternalClass *numberClass; InternalClass *dateClass; InternalClass *functionClass; InternalClass *functionWithProtoClass; InternalClass *protoClass; InternalClass *regExpClass; InternalClass *regExpExecArrayClass; InternalClass *errorClass; InternalClass *evalErrorClass; InternalClass *rangeErrorClass; InternalClass *referenceErrorClass; InternalClass *syntaxErrorClass; InternalClass *typeErrorClass; InternalClass *uriErrorClass; InternalClass *argumentsObjectClass; InternalClass *strictArgumentsObjectClass; InternalClass *variantClass; InternalClass *sequenceClass; EvalFunction *evalFunction; FunctionObject *thrower; QVector argumentsAccessors; SafeString id_undefined; SafeString id_null; SafeString id_true; SafeString id_false; SafeString id_boolean; SafeString id_number; SafeString id_string; SafeString id_object; SafeString id_function; SafeString id_length; SafeString id_prototype; SafeString id_constructor; SafeString id_arguments; SafeString id_caller; SafeString id_callee; SafeString id_this; SafeString id___proto__; SafeString id_enumerable; SafeString id_configurable; SafeString id_writable; SafeString id_value; SafeString id_get; SafeString id_set; SafeString id_eval; SafeString id_uintMax; SafeString id_name; SafeString id_index; SafeString id_input; SafeString id_toString; SafeString id_valueOf; QSet compilationUnits; QMap allFunctions; quint32 m_engineId; RegExpCache *regExpCache; // Scarce resources are "exceptionally high cost" QVariant types where allowing the // normal JavaScript GC to clean them up is likely to lead to out-of-memory or other // out-of-resource situations. When such a resource is passed into JavaScript we // add it to the scarceResources list and it is destroyed when we return from the // JavaScript execution that created it. The user can prevent this behavior by // calling preserve() on the object which removes it from this scarceResource list. class ScarceResourceData { public: ScarceResourceData(const QVariant &data) : data(data) {} QVariant data; QIntrusiveListNode node; }; QIntrusiveList scarceResources; // Normally the JS wrappers for QObjects are stored in the QQmlData/QObjectPrivate, // but any time a QObject is wrapped a second time in another engine, we have to do // bookkeeping. MultiplyWrappedQObjectMap *m_multiplyWrappedQObjects; ExecutionEngine(QQmlJS::EvalISelFactory *iselFactory = 0); ~ExecutionEngine(); void enableDebugger(); ExecutionContext *pushGlobalContext(); void pushContext(SimpleCallContext *context); ExecutionContext *popContext(); Returned *newBuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(SimpleCallContext *)); Returned *newBoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector &boundArgs); Returned *newObject(); Returned *newObject(InternalClass *internalClass); Returned *newString(const QString &s); String *newIdentifier(const QString &text); Returned *newStringObject(const ValueRef value); Returned *newNumberObject(const ValueRef value); Returned *newBooleanObject(const ValueRef value); Returned *newArrayObject(int count = 0); Returned *newArrayObject(const QStringList &list); Returned *newArrayObject(InternalClass *ic); Returned *newDateObject(const ValueRef value); Returned *newDateObject(const QDateTime &dt); Returned *newRegExpObject(const QString &pattern, int flags); Returned *newRegExpObject(Referenced re, bool global); Returned *newRegExpObject(const QRegExp &re); Returned *newErrorObject(const ValueRef value); Returned *newSyntaxErrorObject(const QString &message, const QString &fileName, int line, int column); Returned *newSyntaxErrorObject(const QString &message); Returned *newReferenceErrorObject(const QString &message); Returned *newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber); Returned *newTypeErrorObject(const QString &message); Returned *newRangeErrorObject(const QString &message); Returned *newURIErrorObject(const ValueRef message); Returned *newVariantObject(const QVariant &v); Returned *newForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o); Returned *qmlContextObject() const; StackTrace stackTrace(int frameLimit = -1) const; StackFrame currentStackFrame() const; QUrl resolvedUrl(const QString &file); void requireArgumentsAccessors(int n); void markObjects(); void initRootContext(); InternalClass *newClass(const InternalClass &other); Function *functionForProgramCounter(quintptr pc) const; QmlExtensions *qmlExtensions(); // Exception handling SafeValue exceptionValue; bool hasException; StackTrace exceptionStackTrace; void Q_NORETURN throwException(const ValueRef value); ReturnedValue catchException(ExecutionContext *catchingContext, StackTrace *trace); // Use only inside catch(...) -- will re-throw if no JS exception static QQmlError convertJavaScriptException(QV4::ExecutionContext *context); void Q_NORETURN throwInternal(); // ---- private: QmlExtensions *m_qmlExtensions; }; inline void ExecutionEngine::pushContext(SimpleCallContext *context) { context->parent = current; current = context; current->currentEvalCode = 0; } inline ExecutionContext *ExecutionEngine::popContext() { current = current->parent; return current; } struct ExecutionContextSaver { ExecutionEngine *engine; ExecutionContext *savedContext; ExecutionContextSaver(ExecutionContext *context) : engine(context->engine) , savedContext(context) { } ~ExecutionContextSaver() { while (engine->current != savedContext) engine->popContext(); } }; } // namespace QV4 QT_END_NAMESPACE #endif // QV4ENGINE_H