Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / v8 / qv8engine_p.h
index 43ef982..f46a660 100644 (file)
@@ -1,8 +1,7 @@
 /****************************************************************************
 **
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
 **
 ** This file is part of the QtDeclarative module of the Qt Toolkit.
 **
@@ -35,6 +34,7 @@
 **
 **
 **
+**
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
@@ -59,6 +59,8 @@
 #include <QtCore/qmutex.h>
 #include <QtCore/qstack.h>
 #include <QtCore/qstringlist.h>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QThreadStorage>
 
 #include <private/qv8_p.h>
 #include <qjsengine.h>
@@ -77,6 +79,7 @@
 #include "qv8listwrapper_p.h"
 #include "qv8variantwrapper_p.h"
 #include "qv8valuetypewrapper_p.h"
+#include "qv8sequencewrapper_p.h"
 
 QT_BEGIN_NAMESPACE
 
@@ -135,7 +138,9 @@ public:
     QV8ObjectResource(QV8Engine *engine) : engine(engine) { Q_ASSERT(engine); }
     enum ResourceType { ContextType, QObjectType, TypeType, ListType, VariantType, 
                         ValueTypeType, XMLHttpRequestType, DOMNodeType, SQLDatabaseType,
-                        ListModelType, Context2DType, ParticleDataType };
+                        ListModelType, Context2DType, Context2DStyleType, Context2DPixelArrayType, 
+                        ParticleDataType, SignalHandlerType, IncubatorType, VisualDataItemType,
+                        SequenceType, LocaleDataType };
     virtual ResourceType resourceType() const = 0;
 
     QV8Engine *engine;
@@ -218,6 +223,27 @@ class QDeclarativeValueType;
 class QNetworkAccessManager;
 class QDeclarativeContextData;
 
+class Q_AUTOTEST_EXPORT QV8GCCallback
+{
+private:
+    class ThreadData;
+public:
+    static void garbageCollectorPrologueCallback(v8::GCType, v8::GCCallbackFlags);
+    static void registerGcPrologueCallback();
+
+    class Q_AUTOTEST_EXPORT Node {
+    public:
+        typedef void (*PrologueCallback)(Node *node);
+        Node(PrologueCallback callback);
+        ~Node();
+
+        QIntrusiveListNode node;
+        PrologueCallback prologueCallback;
+    };
+
+    static void addGcCallbackNode(Node *node);
+};
+
 class Q_DECLARATIVE_EXPORT QV8Engine
 {
 public:
@@ -227,6 +253,10 @@ public:
     QV8Engine(QJSEngine* qq,QJSEngine::ContextOwnership ownership = QJSEngine::CreateNewContext);
     ~QV8Engine();
 
+    // ### TODO get rid of it, do we really need CppOwnership?
+    // This enum should be in sync with QDeclarativeEngine::ObjectOwnership
+    enum ObjectOwnership { CppOwnership, JavaScriptOwnership };
+
     struct Deletable {
         virtual ~Deletable() {}
     };
@@ -274,6 +304,7 @@ public:
     QV8ListWrapper *listWrapper() { return &m_listWrapper; }
     QV8VariantWrapper *variantWrapper() { return &m_variantWrapper; }
     QV8ValueTypeWrapper *valueTypeWrapper() { return &m_valueTypeWrapper; }
+    QV8SequenceWrapper *sequenceWrapper() { return &m_sequenceWrapper; }
 
     void *xmlHttpRequestData() { return m_xmlHttpRequestData; }
     void *sqlDatabaseData() { return m_sqlDatabaseData; }
@@ -310,6 +341,7 @@ public:
 
     // Return a JS wrapper for the given QObject \a object
     inline v8::Handle<v8::Value> newQObject(QObject *object);
+    inline v8::Handle<v8::Value> newQObject(QObject *object, const ObjectOwnership ownership);
     inline bool isQObject(v8::Handle<v8::Value>);
     inline QObject *toQObject(v8::Handle<v8::Value>);
 
@@ -320,6 +352,9 @@ public:
     inline v8::Handle<v8::Value> newValueType(QObject *, int coreIndex, QDeclarativeValueType *);
     inline v8::Handle<v8::Value> newValueType(const QVariant &, QDeclarativeValueType *);
 
+    // Create a new sequence type object
+    inline v8::Handle<v8::Value> newSequence(int sequenceType, QObject *, int coreIndex, bool *succeeded);
+
     // Create a new QVariant object.  This doesn't examine the type of the variant, but always returns
     // a QVariant wrapper
     inline v8::Handle<v8::Value> newQVariant(const QVariant &);
@@ -330,7 +365,7 @@ public:
     virtual QNetworkAccessManager *networkAccessManager();
 
     // Return the list of illegal id names (the names of the properties on the global object)
-    const QSet<QString> &illegalNames() const;
+    const QStringHash<bool> &illegalNames() const;
 
     inline void collectGarbage() { gc(); }
     static void gc();
@@ -358,23 +393,23 @@ public:
     void setExtensionData(int, Deletable *);
 
     inline v8::Handle<v8::Value> makeJSValue(bool value);
-    inline v8::Handle<v8::Value> makeJSValue(int value);
-    inline v8::Handle<v8::Value> makeJSValue(uint value);
-    inline v8::Handle<v8::Value> makeJSValue(double value);
+    inline v8::Local<v8::Value> makeJSValue(int value);
+    inline v8::Local<v8::Value> makeJSValue(uint value);
+    inline v8::Local<v8::Value> makeJSValue(double value);
     inline v8::Handle<v8::Value> makeJSValue(QJSValue::SpecialValue value);
-    inline v8::Handle<v8::Value> makeJSValue(const QString& value);
+    inline v8::Local<v8::Value> makeJSValue(const QString &value);
 
     inline QScriptPassPointer<QJSValuePrivate> evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1);
     QScriptPassPointer<QJSValuePrivate> evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch);
 
     QScriptPassPointer<QJSValuePrivate> newArray(uint length);
-    v8::Handle<v8::Object> newVariant(const QVariant &variant);
+    v8::Local<v8::Object> newVariant(const QVariant &variant);
     QScriptPassPointer<QJSValuePrivate> newVariant(QJSValuePrivate* value, const QVariant &variant);
 
-    v8::Handle<v8::Array> variantListToJS(const QVariantList &lst);
+    v8::Local<v8::Array> variantListToJS(const QVariantList &lst);
     QVariantList variantListFromJS(v8::Handle<v8::Array> jsArray);
 
-    v8::Handle<v8::Object> variantMapToJS(const QVariantMap &vmap);
+    v8::Local<v8::Object> variantMapToJS(const QVariantMap &vmap);
     QVariantMap variantMapFromJS(v8::Handle<v8::Object> jsObject);
 
     v8::Handle<v8::Value> variantToJS(const QVariant &value);
@@ -393,8 +428,35 @@ public:
 
     void emitSignalHandlerException();
 
+    // used for console.time(), console.timeEnd()
+    void startTimer(const QString &timerName);
+    qint64 stopTimer(const QString &timerName, bool *wasRunning);
+
+    // used for console.count()
+    int consoleCountHelper(const QString &file, int line, int column);
+
     QObject *qtObjectFromJS(v8::Handle<v8::Value> value);
     QSet<int> visitedConversionObjects;
+
+    static QDateTime qtDateTimeFromJsDate(double jsDate);
+
+    void addRelationshipForGC(QObject *object, v8::Persistent<v8::Value> handle);
+    void addRelationshipForGC(QObject *object, QObject *other);
+
+    struct ThreadData {
+        ThreadData();
+        ~ThreadData();
+        v8::Isolate* isolate;
+        bool gcPrologueCallbackRegistered;
+        QIntrusiveList<QV8GCCallback::Node, &QV8GCCallback::Node::node> gcCallbackNodes;
+    };
+
+    static bool hasThreadData();
+    static ThreadData* threadData();
+    static void ensurePerThreadIsolate();
+
+    v8::Persistent<v8::Object> m_strongReferencer;
+
 protected:
     QJSEngine* q;
     QDeclarativeEngine *m_engine;
@@ -409,6 +471,7 @@ protected:
     QV8ListWrapper m_listWrapper;
     QV8VariantWrapper m_variantWrapper;
     QV8ValueTypeWrapper m_valueTypeWrapper;
+    QV8SequenceWrapper m_sequenceWrapper;
 
     v8::Persistent<v8::Function> m_getOwnPropertyNames;
     v8::Persistent<v8::Function> m_freezeObject;
@@ -419,58 +482,30 @@ protected:
     QVector<Deletable *> m_extensionData;
     Deletable *m_listModelData;
 
-    QSet<QString> m_illegalNames;
+    QStringHash<bool> m_illegalNames;
 
     Exception m_exception;
 
+    QElapsedTimer m_time;
+    QHash<QString, qint64> m_startedTimers;
+
+    QHash<QString, quint32> m_consoleCount;
+
     QVariant toBasicVariant(v8::Handle<v8::Value>);
 
     void initializeGlobal(v8::Handle<v8::Object>);
 
-    static v8::Handle<v8::Value> gc(const v8::Arguments &args);
-    static v8::Handle<v8::Value> print(const v8::Arguments &args);
-    static v8::Handle<v8::Value> isQtObject(const v8::Arguments &args);
-    static v8::Handle<v8::Value> rgba(const v8::Arguments &args);
-    static v8::Handle<v8::Value> hsla(const v8::Arguments &args);
-    static v8::Handle<v8::Value> rect(const v8::Arguments &args);
-    static v8::Handle<v8::Value> point(const v8::Arguments &args);
-    static v8::Handle<v8::Value> size(const v8::Arguments &args);
-    static v8::Handle<v8::Value> vector3d(const v8::Arguments &args);
-    static v8::Handle<v8::Value> vector4d(const v8::Arguments &args);
-    static v8::Handle<v8::Value> lighter(const v8::Arguments &args);
-    static v8::Handle<v8::Value> darker(const v8::Arguments &args);
-    static v8::Handle<v8::Value> tint(const v8::Arguments &args);
-    static v8::Handle<v8::Value> formatDate(const v8::Arguments &args);
-    static v8::Handle<v8::Value> formatTime(const v8::Arguments &args);
-    static v8::Handle<v8::Value> formatDateTime(const v8::Arguments &args);
-    static v8::Handle<v8::Value> openUrlExternally(const v8::Arguments &args);
-    static v8::Handle<v8::Value> fontFamilies(const v8::Arguments &args);
-    static v8::Handle<v8::Value> md5(const v8::Arguments &args);
-    static v8::Handle<v8::Value> btoa(const v8::Arguments &args);
-    static v8::Handle<v8::Value> atob(const v8::Arguments &args);
-    static v8::Handle<v8::Value> quit(const v8::Arguments &args);
-    static v8::Handle<v8::Value> resolvedUrl(const v8::Arguments &args);
-    static v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args);
-    static v8::Handle<v8::Value> createComponent(const v8::Arguments &args);
-    static v8::Handle<v8::Value> qsTranslate(const v8::Arguments &args);
-    static v8::Handle<v8::Value> qsTranslateNoOp(const v8::Arguments &args);
-    static v8::Handle<v8::Value> qsTr(const v8::Arguments &args);
-    static v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args);
-    static v8::Handle<v8::Value> qsTrId(const v8::Arguments &args);
-    static v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args);
-    static v8::Handle<v8::Value> stringArg(const v8::Arguments &args);
-
     double qtDateTimeToJsDate(const QDateTime &dt);
-    QDateTime qtDateTimeFromJsDate(double jsDate);
 
 private:
+    static v8::Persistent<v8::Object> *findOwnerAndStrength(QObject *object, bool *shouldBeStrong);
+
     typedef QScriptIntrusiveList<QJSValuePrivate, &QJSValuePrivate::m_node> ValueList;
     ValueList m_values;
     typedef QScriptIntrusiveList<QJSValueIteratorPrivate, &QJSValueIteratorPrivate::m_node> ValueIteratorList;
     ValueIteratorList m_valueIterators;
 
     Q_DISABLE_COPY(QV8Engine)
-    friend class QV8DebugService;
 };
 
 // Allocate a new Persistent handle.  *ALL* persistent handles in QML must be allocated
@@ -544,6 +579,20 @@ v8::Handle<v8::Value> QV8Engine::newQObject(QObject *object)
     return m_qobjectWrapper.newQObject(object);
 }
 
+v8::Handle<v8::Value> QV8Engine::newQObject(QObject *object, const ObjectOwnership ownership)
+{
+    if (!object)
+        return v8::Null();
+
+    v8::Handle<v8::Value> result = newQObject(object);
+    QDeclarativeData *ddata = QDeclarativeData::get(object, true);
+    if (ownership == JavaScriptOwnership && ddata) {
+        ddata->indestructible = false;
+        ddata->explicitIndestructibleSet = true;
+    }
+    return result;
+}
+
 v8::Local<v8::String> QV8Engine::toString(const QString &string)
 {
     return m_stringWrapper.toString(string);
@@ -559,6 +608,11 @@ v8::Handle<v8::Value> QV8Engine::newValueType(const QVariant &value, QDeclarativ
     return m_valueTypeWrapper.newValueType(value, type);
 }
 
+v8::Handle<v8::Value> QV8Engine::newSequence(int sequenceType, QObject *object, int property, bool *succeeded)
+{
+    return m_sequenceWrapper.newSequence(sequenceType, object, property, succeeded);
+}
+
 // XXX Can this be made more optimal?  It is called prior to resolving each and every 
 // unqualified name in QV8ContextWrapper.
 bool QV8Engine::startsWithUpper(v8::Handle<v8::String> string)