/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtScript module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL-ONLY$ ** GNU Lesser General Public License Usage ** 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. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QSCRIPTENGINE_P_H #define QSCRIPTENGINE_P_H #include #include #include #include #include #include #include #include "qscriptengine.h" #include "qscriptconverter_p.h" #include "qscriptshareddata_p.h" #include "qscriptoriginalglobalobject_p.h" #include "qscriptvalue.h" #include "qscriptprogram_p.h" #include "qscripttools_p.h" #include "qscriptengineagent_p.h" #include Q_DECLARE_METATYPE(QScriptValue) Q_DECLARE_METATYPE(QObjectList) Q_DECLARE_METATYPE(QList) QT_BEGIN_NAMESPACE class QDateTime; class QScriptContextPrivate; class QScriptClassPrivate; class QScriptablePrivate; class QtDataBase; class QScriptEngineAgentPrivate; class QScriptEnginePrivate : public QObjectPrivate { class Exception { typedef QPair, v8::Persistent > ValueMessagePair; v8::Persistent m_value; v8::Persistent m_message; QStack m_stack; Q_DISABLE_COPY(Exception) public: inline Exception(); inline ~Exception(); inline void set(v8::Handle value, v8::Handle message); inline void clear(); inline operator bool() const; inline operator v8::Handle() const; inline int lineNumber() const; inline QStringList backtrace() const; inline void push(); inline void pop(); }; // FIXME: This can go away as bug http://code.google.com/p/v8/issues/detail?id=1205 // will be resolved and we can store QScriptEnginePrivate* in v8::Isolate class Isolates { public: static v8::Isolate *createEnterIsolate(QScriptEnginePrivate *engine); static QScriptEnginePrivate *engine(v8::Isolate *isolate); private: Q_GLOBAL_STATIC(Isolates, isolates); typedef QHash QHashIsolateEngine; QHashIsolateEngine m_mapping; QMutex m_protector; }; Q_DECLARE_PUBLIC(QScriptEngine) public: static QScriptEnginePrivate* get(QScriptEngine* q) { Q_ASSERT(q); return q->d_func(); } static QScriptEngine* get(QScriptEnginePrivate* d) { Q_ASSERT(d); return d->q_func(); } QScriptEnginePrivate(QScriptEngine::ContextOwnership ownership = QScriptEngine::CreateNewContext); ~QScriptEnginePrivate(); inline QScriptPassPointer evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1); inline QScriptPassPointer evaluate(QScriptProgramPrivate* program); QScriptPassPointer evaluate(v8::Handle script, v8::TryCatch& tryCatch); inline bool isEvaluating() const; inline bool isDestroyed() const; inline void collectGarbage(); static void GCEpilogueCallback(v8::GCType type, v8::GCCallbackFlags flags); inline void reportAdditionalMemoryCost(int cost); inline void abortEvaluation(v8::Handle result); inline void updateGlobalObjectCache(); inline v8::Handle globalObject() const; void setGlobalObject(QScriptValuePrivate* newGlobalObjectValue); inline void setAgent(QScriptEngineAgentPrivate *agent); inline QScriptEngineAgentPrivate *agent() const; QScriptPassPointer newArray(uint length); QScriptPassPointer newObject(); QScriptPassPointer newObject(QScriptClassPrivate* scriptclass, QScriptValuePrivate* data); QScriptPassPointer newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate *prototype, int length); QScriptPassPointer newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg); v8::Handle newVariant(const QVariant &variant); QScriptPassPointer newVariant(QScriptValuePrivate* value, const QVariant &variant); v8::Handle newQObject(QObject *object, QScriptEngine::ValueOwnership own = QScriptEngine::QtOwnership, const QScriptEngine::QObjectWrapOptions &opt = 0); QScriptPassPointer newQObject(QScriptValuePrivate *scriptObject, QObject *qtObject, QScriptEngine::ValueOwnership ownership, const QScriptEngine::QObjectWrapOptions &options); v8::Handle newQMetaObject(const QMetaObject* mo, const QScriptValue &ctor); v8::Handle qtClassTemplate(const QMetaObject *, const QScriptEngine::QObjectWrapOptions &); v8::Handle qobjectTemplate(); v8::Handle scriptClassToStringTemplate(); inline v8::Handle makeJSValue(bool value); inline v8::Handle makeJSValue(int value); inline v8::Handle makeJSValue(uint value); inline v8::Handle makeJSValue(qsreal value); inline v8::Handle makeJSValue(QScriptValue::SpecialValue value); inline v8::Handle makeJSValue(const QString& value); inline v8::Local getOwnPropertyNames(v8::Handle object) const; inline QScriptValue::PropertyFlags getPropertyFlags(v8::Handle object, v8::Handle property, const QScriptValue::ResolveFlags& mode); inline v8::Local getOwnProperty(v8::Handle object, v8::Handle property) const; inline v8::Local getOwnProperty(v8::Handle object, uint32_t index) const; QDateTime qtDateTimeFromJS(v8::Handle jsDate); v8::Handle qtDateTimeToJS(const QDateTime &dt); #ifndef QT_NO_REGEXP QScriptPassPointer newRegExp(const QRegExp ®exp); QScriptPassPointer newRegExp(const QString &pattern, const QString &flags); #endif v8::Handle stringListToJS(const QStringList &lst); QStringList stringListFromJS(v8::Handle jsArray); v8::Handle variantListToJS(const QVariantList &lst); QVariantList variantListFromJS(v8::Handle jsArray); v8::Handle variantMapToJS(const QVariantMap &vmap); QVariantMap variantMapFromJS(v8::Handle jsObject); v8::Handle variantToJS(const QVariant &value); QVariant variantFromJS(v8::Handle value); v8::Handle metaTypeToJS(int type, const void *data); bool metaTypeFromJS(v8::Handle value, int type, void *data); bool isQtObject(v8::Handle value); QObject *qtObjectFromJS(v8::Handle value); bool convertToNativeQObject(v8::Handle value, const QByteArray &targetType, void **result); inline bool isQtVariant(v8::Handle value) const; inline bool isQtMetaObject(v8::Handle value) const; QVariant &variantValue(v8::Handle value); void installTranslatorFunctions(QScriptValuePrivate* object); void installTranslatorFunctions(v8::Handle object); QScriptValue scriptValueFromInternal(v8::Handle) const; v8::Persistent v8ObjectForConnectedObject(const QObject *o) const; void addV8ObjectForConnectedObject(const QObject *o, v8::Persistent v8Object); // private slot void _q_removeConnectedObject(QObject*); inline operator v8::Handle(); inline void clearExceptions(); inline void setException(v8::Handle value, v8::Handle message = v8::Handle()); inline v8::Handle throwException(v8::Handle value); inline bool hasUncaughtException() const; inline int uncaughtExceptionLineNumber() const; inline QStringList uncaughtExceptionBacktrace() const; v8::Handle uncaughtException() const; inline void saveException(); inline void restoreException(); v8::Handle qtDataId(); inline void enterIsolate() const; inline void exitIsolate() const; void pushScope(QScriptValuePrivate* value); QScriptPassPointer popScope(); void registerCustomType(int type, QScriptEngine::MarshalFunction mf, QScriptEngine::DemarshalFunction df, const QScriptValuePrivate *prototype); void setDefaultPrototype(int metaTypeId, const QScriptValuePrivate *prototype); QScriptPassPointer defaultPrototype(int metaTypeId); v8::Handle defaultPrototype(const char* metaTypeName); inline QScriptContextPrivate *setCurrentQSContext(QScriptContextPrivate *ctx); inline QScriptContextPrivate *currentContext() const { return m_currentQsContext; } QScriptContextPrivate *pushContext(); void popContext(); void emitSignalHandlerException(); inline bool hasInstance(v8::Handle fun, v8::Handle value) const; inline const QScriptOriginalGlobalObject *originalGlobalObject() const { return &m_originalGlobalObject; } // Additional resources allocated by QSV and kept as weak references can leak if not collected // by GC before context destruction. So we need to track them separetly. // data should be a QtData instance inline void registerAdditionalResources(QtDataBase *data); inline void unregisterAdditionalResources(QtDataBase *data); inline void deallocateAdditionalResources(); inline void registerValue(QScriptValuePrivate *data); inline void unregisterValue(QScriptValuePrivate *data); inline void invalidateAllValues(); inline void registerString(QScriptStringPrivate *data); inline void unregisterString(QScriptStringPrivate *data); inline void invalidateAllString(); inline void registerScriptable(QScriptablePrivate *data); inline void unregisterScriptable(QScriptablePrivate *data); inline void invalidateAllScriptable(); inline void registerAgent(QScriptEngineAgentPrivate *data); inline void unregisterAgent(QScriptEngineAgentPrivate *data); inline void invalidateAllAgents(); inline void registerScript(QScriptEngineAgentPrivate::UnloadData *data); inline void unregisterScript(QScriptEngineAgentPrivate::UnloadData *data); inline void invalidateAllScripts(); bool hasDemarshalFunction(int metaTypeId) const; v8::Persistent declarativeClassTemplate; v8::Persistent scriptClassTemplate; v8::Persistent metaMethodTemplate; v8::Persistent signalTemplate; class TypeInfos { public: struct TypeInfo { TypeInfo() : marshal(0), demarshal(0) { } QScriptEngine::MarshalFunction marshal; QScriptEngine::DemarshalFunction demarshal; // This is a persistent and it should be deleted in ~TypeInfos v8::Handle prototype; }; inline TypeInfos() {}; inline ~TypeInfos(); inline void clear(); inline TypeInfo value(int type) const; inline void registerCustomType(int type, QScriptEngine::MarshalFunction mf, QScriptEngine::DemarshalFunction df, v8::Handle prototype = v8::Handle()); private: Q_DISABLE_COPY(TypeInfos) QHash m_infos; }; struct EvaluateScope { QScriptEnginePrivate *engine; bool wasEvaluating; EvaluateScope(QScriptEnginePrivate *engine); ~EvaluateScope(); }; private: Q_DISABLE_COPY(QScriptEnginePrivate) v8::Local getOwnPropertyFromScriptClassInstance(v8::Handle object, v8::Handle property) const; QScriptValue::PropertyFlags getPropertyFlagsFromScriptClassInstance(v8::Handle object, v8::Handle property, const QScriptValue::ResolveFlags& mode); v8::Handle createMetaObjectTemplate(); v8::Handle createVariantTemplate(); v8::Handle metaObjectTemplate(); v8::Handle variantTemplate(); v8::Isolate *m_isolate; v8::Persistent m_v8Context; Exception m_exception; QScriptOriginalGlobalObject m_originalGlobalObject; v8::Persistent m_currentGlobalObject; v8::Persistent m_qtDataId; int m_reportedAddtionalMemoryCost; typedef QHash, v8::Persistent > ClassTemplateHash; ClassTemplateHash m_qtClassTemplates; v8::Persistent m_qobjectBaseTemplate; v8::Persistent m_variantTemplate; v8::Persistent m_metaObjectTemplate; QScriptContextPrivate *m_currentQsContext; QScopedPointer m_baseQsContext; QSet visitedConversionObjects; TypeInfos m_typeInfos; v8::Persistent m_scriptClassToStringTemplate; QSet importedExtensions; QSet extensionsBeingImported; enum State { Idle, Evaluating, Destroyed } m_state; QScriptBagContainer m_additionalResources; QScriptBagContainer m_values; QScriptBagContainer m_strings; QScriptBagContainer m_scriptable; QScriptBagContainer m_agents; QScriptBagContainer m_scripts; QHash > m_connectedObjects; QScriptEngineAgentPrivate *m_currentAgent; class ProcessEventTimeoutThread; ProcessEventTimeoutThread *m_processEventTimeoutThread; int m_processEventInterval; bool m_shouldAbort; v8::Persistent m_abortResult; }; QT_END_NAMESPACE #endif