Evaluate all shared bindings together using a shared context
authorAaron Kennedy <aaron.kennedy@nokia.com>
Fri, 17 Jun 2011 01:37:17 +0000 (11:37 +1000)
committerAaron Kennedy <aaron.kennedy@nokia.com>
Fri, 17 Jun 2011 01:37:17 +0000 (11:37 +1000)
The vast majority of bindings are capable of being shared (that is, don't
introduce closures themselves) and consequently this improves the
performance of almost every app.

19 files changed:
src/declarative/qml/qdeclarativebinding.cpp
src/declarative/qml/qdeclarativebinding_p.h
src/declarative/qml/qdeclarativebinding_p_p.h
src/declarative/qml/qdeclarativecompileddata.cpp
src/declarative/qml/qdeclarativecompiler.cpp
src/declarative/qml/qdeclarativecompiler_p.h
src/declarative/qml/qdeclarativecontext.cpp
src/declarative/qml/qdeclarativecontext_p.h
src/declarative/qml/qdeclarativeexpression.cpp
src/declarative/qml/qdeclarativeexpression.h
src/declarative/qml/qdeclarativeexpression_p.h
src/declarative/qml/qdeclarativeinstruction.cpp
src/declarative/qml/qdeclarativeinstruction_p.h
src/declarative/qml/qdeclarativerefcount_p.h
src/declarative/qml/qdeclarativevme.cpp
src/declarative/qml/v4/qdeclarativev4bindings.cpp
src/declarative/qml/v8/qv8bindings.cpp [new file with mode: 0644]
src/declarative/qml/v8/qv8bindings_p.h [new file with mode: 0644]
src/declarative/qml/v8/v8.pri

index d1fdec5..fee5554 100644 (file)
@@ -226,15 +226,6 @@ QDeclarativeBindingPrivate::~QDeclarativeBindingPrivate()
 {
 }
 
-QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, 
-                                         QDeclarativeContextData *ctxt, const QString &url, int lineNumber, 
-                                         QObject *parent)
-: QDeclarativeExpression(ctxt, data, rc, obj, url, lineNumber, *new QDeclarativeBindingPrivate)
-{
-    setParent(parent);
-    setNotifyOnValueChanged(true);
-}
-
 QDeclarativeBinding *
 QDeclarativeBinding::createBinding(Identifier id, QObject *obj, QDeclarativeContext *ctxt,
                                    const QString &url, int lineNumber, QObject *parent)
@@ -251,7 +242,7 @@ QDeclarativeBinding::createBinding(Identifier id, QObject *obj, QDeclarativeCont
         typeData = engine->typeLoader.get(ctxtdata->url);
         cdata = typeData->compiledData();
     }
-    QDeclarativeBinding *rv = cdata ? new QDeclarativeBinding((void*)cdata->datas.at(id).constData(), cdata, obj, ctxtdata, url, lineNumber, parent) : 0;
+    QDeclarativeBinding *rv = cdata ? new QDeclarativeBinding(cdata->primitives.at(id), true, obj, ctxtdata, url, lineNumber, parent) : 0;
     if (typeData)
         typeData->release();
     return rv;
@@ -273,6 +264,15 @@ QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDecl
     setNotifyOnValueChanged(true);
 }
 
+QDeclarativeBinding::QDeclarativeBinding(const QString &str, bool isRewritten, QObject *obj, 
+                                         QDeclarativeContextData *ctxt, 
+                                         const QString &url, int lineNumber, QObject *parent)
+: QDeclarativeExpression(ctxt, obj, str, isRewritten, url, lineNumber, *new QDeclarativeBindingPrivate)
+{
+    setParent(parent);
+    setNotifyOnValueChanged(true);
+}
+
 /*!  
     \internal 
 
@@ -413,19 +413,17 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
 
         } else {
             QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context()->engine);
-            ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
+            ep->referenceScarceResources(); 
 
             bool isUndefined = false;
-            QVariant value;
 
             v8::HandleScope handle_scope;
             v8::Context::Scope scope(ep->v8engine.context());
             v8::Local<v8::Value> result = d->v8value(0, &isUndefined);
 
             bool needsErrorData = false;
-            if (!watcher.wasDeleted() && !d->error.isValid()) {
+            if (!watcher.wasDeleted() && !d->error.isValid()) 
                 needsErrorData = !d->writeBindingResult(d, d->property, result, isUndefined, flags);
-            }
 
             if (!watcher.wasDeleted()) {
                
@@ -453,10 +451,15 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
         if (!watcher.wasDeleted())
             d->updating = false;
     } else {
-        qmlInfo(d->property.object()) << tr("Binding loop detected for property \"%1\"").arg(d->property.name());
+        QDeclarativeBindingPrivate::printBindingLoopError(d->property);
     }
 }
 
+void QDeclarativeBindingPrivate::printBindingLoopError(QDeclarativeProperty &prop)
+{
+    qmlInfo(prop.object()) << QDeclarativeBinding::tr("Binding loop detected for property \"%1\"").arg(prop.name());
+}
+
 void QDeclarativeBindingPrivate::emitValueChanged()
 {
     Q_Q(QDeclarativeBinding);
index e646c86..fedd636 100644 (file)
@@ -152,8 +152,8 @@ public:
 
     QDeclarativeBinding(const QString &, QObject *, QDeclarativeContext *, QObject *parent=0);
     QDeclarativeBinding(const QString &, QObject *, QDeclarativeContextData *, QObject *parent=0);
-    QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContextData *, 
-                        const QString &, int, QObject *parent);
+    QDeclarativeBinding(const QString &, bool isRewritten, QObject *, QDeclarativeContextData *, 
+                        const QString &url, int lineNumber, QObject *parent=0);
     QDeclarativeBinding(void *, QObject *, QDeclarativeContextData *, QObject *parent=0);
 
     void setTarget(const QDeclarativeProperty &);
index 1b1b03b..6caf136 100644 (file)
@@ -72,6 +72,7 @@ public:
     static bool writeBindingResult(QDeclarativeJavaScriptExpression *expression,
                                    QDeclarativeProperty &prop, v8::Handle<v8::Value> value, bool isUndefined,
                                    QDeclarativePropertyPrivate::WriteFlags flags);
+    static void printBindingLoopError(QDeclarativeProperty &prop);
 
 protected:
     virtual void refresh();
index 2ea41d8..fc4b28b 100644 (file)
@@ -128,6 +128,8 @@ QDeclarativeCompiledData::~QDeclarativeCompiledData()
 
     qDeleteAll(cachedPrograms);
     qDeleteAll(cachedClosures);
+
+    qPersistentDispose(v8bindings);
 }
 
 void QDeclarativeCompiledData::clear()
index e4ad463..a0a6680 100644 (file)
@@ -708,6 +708,14 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
         init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
     output->addInstruction(init);
 
+    if (!compileState.v8BindingProgram.isEmpty()) {
+        QDeclarativeInstruction bindings;
+        bindings.setType(QDeclarativeInstruction::InitV8Bindings);
+        bindings.initV8Bindings.program = output->indexForString(compileState.v8BindingProgram);
+        bindings.initV8Bindings.line = compileState.v8BindingProgramLine;
+        output->addInstruction(bindings);
+    }
+
     genObject(tree);
 
     QDeclarativeInstruction def;
@@ -1208,6 +1216,14 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
         init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
     output->addInstruction(init);
 
+    if (!compileState.v8BindingProgram.isEmpty()) {
+        QDeclarativeInstruction bindings;
+        bindings.setType(QDeclarativeInstruction::InitV8Bindings);
+        bindings.initV8Bindings.program = output->indexForString(compileState.v8BindingProgram);
+        bindings.initV8Bindings.line = compileState.v8BindingProgramLine;
+        output->addInstruction(bindings);
+    }
+
     genObject(root);
 
     QDeclarativeInstruction def;
@@ -2311,33 +2327,15 @@ const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) con
 }
 
 // similar to logic of completeComponentBuild, but also sticks data
-// into datas at the end
+// into primitives at the end
 int QDeclarativeCompiler::rewriteBinding(const QString& expression, const QByteArray& name)
 {
     QDeclarativeRewrite::RewriteBinding rewriteBinding;
     rewriteBinding.setName('$' + name.mid(name.lastIndexOf('.') + 1));
-    bool isSharable = false;
-    QString rewrite = rewriteBinding(expression, 0, &isSharable);
-
-    quint32 length = rewrite.length();
-    quint32 pc;
-
-    if (isSharable) {
-        pc = output->cachedClosures.count();
-        pc |= 0x80000000;
-        output->cachedClosures.append(0);
-    } else {
-        pc = output->cachedPrograms.length();
-        output->cachedPrograms.append(0);
-    }
 
-    QByteArray compiledData =
-        QByteArray((const char *)&pc, sizeof(quint32)) +
-        QByteArray((const char *)&length, sizeof(quint32)) +
-        QByteArray((const char *)rewrite.constData(),
-                   rewrite.length() * sizeof(QChar));
+    QString rewrite = rewriteBinding(expression, 0, 0);
 
-    return output->indexForByteArray(compiledData);
+    return output->indexForString(rewrite);
 }
 
 // Ensures that the dynamic meta specification on obj is valid
@@ -2841,9 +2839,9 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi
     Q_ASSERT(compileState.bindings.contains(binding));
 
     const BindingReference &ref = compileState.bindings.value(binding);
-    if (ref.dataType == BindingReference::Experimental) {
+    if (ref.dataType == BindingReference::V4) {
         QDeclarativeInstruction store;
-        store.setType(QDeclarativeInstruction::StoreCompiledBinding);
+        store.setType(QDeclarativeInstruction::StoreV4Binding);
         store.assignBinding.value = ref.compiledIndex;
         store.assignBinding.context = ref.bindingContext.stack;
         store.assignBinding.owner = ref.bindingContext.owner;
@@ -2855,28 +2853,43 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi
             store.assignBinding.property = prop->index;
         store.assignBinding.line = binding->location.start.line;
         output->addInstruction(store);
-        return;
-    }
+    } else if (ref.dataType == BindingReference::V8) {
+        QDeclarativeInstruction store;
+        store.setType(QDeclarativeInstruction::StoreV8Binding);
+        store.assignBinding.value = ref.compiledIndex;
+        store.assignBinding.context = ref.bindingContext.stack;
+        store.assignBinding.owner = ref.bindingContext.owner;
+        store.assignBinding.line = binding->location.start.line;
 
-    QDeclarativeInstruction store;
-    if (!prop->isAlias)
-        store.setType(QDeclarativeInstruction::StoreBinding);
-    else
-        store.setType(QDeclarativeInstruction::StoreBindingOnAlias);
-    store.assignBinding.value = output->indexForByteArray(ref.compiledData);
-    store.assignBinding.context = ref.bindingContext.stack;
-    store.assignBinding.owner = ref.bindingContext.owner;
-    store.assignBinding.line = binding->location.start.line;
-
-    Q_ASSERT(ref.bindingContext.owner == 0 ||
-             (ref.bindingContext.owner != 0 && valueTypeProperty));
-    if (ref.bindingContext.owner) {
-        store.assignBinding.property = genValueTypeData(prop, valueTypeProperty);
+        Q_ASSERT(ref.bindingContext.owner == 0 ||
+                 (ref.bindingContext.owner != 0 && valueTypeProperty));
+        if (ref.bindingContext.owner) {
+            store.assignBinding.property = genValueTypeData(prop, valueTypeProperty);
+        } else {
+            store.assignBinding.property = genPropertyData(prop);
+        }
+
+        output->addInstruction(store);
     } else {
-        store.assignBinding.property = genPropertyData(prop);
-    }
+        QDeclarativeInstruction store;
+        if (!prop->isAlias)
+            store.setType(QDeclarativeInstruction::StoreBinding);
+        else
+            store.setType(QDeclarativeInstruction::StoreBindingOnAlias);
+        store.assignBinding.value = output->indexForString(ref.rewrittenExpression);
+        store.assignBinding.context = ref.bindingContext.stack;
+        store.assignBinding.owner = ref.bindingContext.owner;
+        store.assignBinding.line = binding->location.start.line;
 
-    output->addInstruction(store);
+        Q_ASSERT(ref.bindingContext.owner == 0 ||
+                 (ref.bindingContext.owner != 0 && valueTypeProperty));
+        if (ref.bindingContext.owner) {
+            store.assignBinding.property = genValueTypeData(prop, valueTypeProperty);
+        } else {
+            store.assignBinding.property = genPropertyData(prop);
+        }
+        output->addInstruction(store);
+    }
 }
 
 int QDeclarativeCompiler::genContextCache()
@@ -2929,6 +2942,8 @@ bool QDeclarativeCompiler::completeComponentBuild()
 
     QDeclarativeV4Compiler bindingCompiler;
 
+    QList<BindingReference*> sharedBindings;
+
     for (QHash<QDeclarativeParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin(); 
          iter != compileState.bindings.end(); ++iter) {
 
@@ -2943,44 +2958,67 @@ bool QDeclarativeCompiler::completeComponentBuild()
 
             int index = bindingCompiler.compile(expr, enginePrivate);
             if (index != -1) {
-                binding.dataType = BindingReference::Experimental;
+                binding.dataType = BindingReference::V4;
                 binding.compiledIndex = index;
                 componentStat.optimizedBindings.append(iter.key()->location);
                 continue;
             } 
         }
 
-        binding.dataType = BindingReference::QtScript;
-
         // Pre-rewrite the expression
         QString expression = binding.expression.asScript();
 
         QDeclarativeRewrite::RewriteBinding rewriteBinding;
         rewriteBinding.setName('$'+binding.property->name);
         bool isSharable = false;
-        expression = rewriteBinding(binding.expression.asAST(), expression, &isSharable);
-
-        quint32 length = expression.length();
-        quint32 pc; 
-        
-        if (isSharable) {
-            pc = output->cachedClosures.count();
-            pc |= 0x80000000;
-            output->cachedClosures.append(0);
+        binding.rewrittenExpression = rewriteBinding(binding.expression.asAST(), expression, &isSharable);
+
+        if (isSharable && !binding.property->isAlias /* See above re alias */ &&
+            binding.property->type != qMetaTypeId<QDeclarativeBinding*>()) {
+            binding.dataType = BindingReference::V8;
+            sharedBindings.append(&iter.value());
         } else {
-            pc = output->cachedPrograms.length();
-            output->cachedPrograms.append(0);
+            binding.dataType = BindingReference::QtScript;
         }
 
-        binding.compiledData =
-            QByteArray((const char *)&pc, sizeof(quint32)) +
-            QByteArray((const char *)&length, sizeof(quint32)) +
-            QByteArray((const char *)expression.constData(), 
-                       expression.length() * sizeof(QChar));
-
         componentStat.scriptBindings.append(iter.key()->location);
     }
 
+    if (!sharedBindings.isEmpty()) {
+        struct Sort {
+            static bool lt(const BindingReference *lhs, const BindingReference *rhs)
+            {
+                return lhs->value->location.start.line < rhs->value->location.start.line;
+            }
+        };
+
+        qSort(sharedBindings.begin(), sharedBindings.end(), Sort::lt);
+
+        int startLineNumber = sharedBindings.at(0)->value->location.start.line;
+        int lineNumber = startLineNumber;
+
+        QString functionArray(QLatin1String("["));
+        for (int ii = 0; ii < sharedBindings.count(); ++ii) {
+            BindingReference *reference = sharedBindings.at(ii);
+            QDeclarativeParser::Value *value = reference->value;
+            const QString &expression = reference->rewrittenExpression;
+
+            if (ii != 0) functionArray += QLatin1String(",");
+
+            while (lineNumber < value->location.start.line) {
+                lineNumber++;
+                functionArray += QLatin1String("\n");
+            }
+
+            functionArray += expression;
+            reference->compiledIndex = ii;
+        }
+        functionArray += QLatin1String("]");
+
+        compileState.v8BindingProgram = functionArray;
+        compileState.v8BindingProgramLine = startLineNumber;
+    }
+
     if (bindingCompiler.isValid()) 
         compileState.compiledBindingData = bindingCompiler.program();
 
index e4b9240..2756c3f 100644 (file)
@@ -55,6 +55,7 @@
 
 #include "qdeclarative.h"
 #include "qdeclarativeerror.h"
+#include "private/qv8_p.h"
 #include "private/qdeclarativeinstruction_p.h"
 #include "private/qdeclarativeparser_p.h"
 #include "private/qdeclarativeengine_p.h"
@@ -103,6 +104,8 @@ public:
     };
     QList<TypeReference> types;
 
+    v8::Persistent<v8::Array> v8bindings;
+
     const QMetaObject *root;
     QAbstractDynamicMetaObject rootData;
     QDeclarativePropertyCache *rootPropertyCache;
@@ -283,12 +286,12 @@ private:
         QDeclarativeParser::Property *property;
         QDeclarativeParser::Value *value;
 
-        enum DataType { QtScript, Experimental };
+        enum DataType { QtScript, V4, V8 };
         DataType dataType;
 
         int compiledIndex;
 
-        QByteArray compiledData;
+        QString rewrittenExpression;
         BindingContext bindingContext;
     };
     void addBindingReference(const BindingReference &);
@@ -296,7 +299,7 @@ private:
     struct ComponentCompileState
     {
         ComponentCompileState() 
-            : parserStatusCount(0), pushedProperties(0), nested(false), root(0) {}
+            : parserStatusCount(0), pushedProperties(0), nested(false), v8BindingProgramLine(-1), root(0) {}
         QHash<QString, QDeclarativeParser::Object *> ids;
         QHash<int, QDeclarativeParser::Object *> idIndexes;
         int parserStatusCount;
@@ -304,6 +307,8 @@ private:
         bool nested;
 
         QByteArray compiledBindingData;
+        QString v8BindingProgram;
+        int v8BindingProgramLine;
 
         QHash<QDeclarativeParser::Value *, BindingReference> bindings;
         QHash<QDeclarativeParser::Value *, BindingContext> signalExpressions;
index c2c21d3..caa3b0c 100644 (file)
@@ -48,6 +48,7 @@
 #include "qdeclarativeengine.h"
 #include "qdeclarativeinfo.h"
 #include "private/qdeclarativev4bindings_p.h"
+#include "private/qv8bindings_p.h"
 
 #include <qscriptengine.h>
 #include <QtCore/qvarlengtharray.h>
@@ -499,16 +500,16 @@ QObject *QDeclarativeContextPrivate::context_at(QDeclarativeListProperty<QObject
 QDeclarativeContextData::QDeclarativeContextData()
 : parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false), isPragmaLibraryContext(false),
   publicContext(0), propertyNames(0), contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0), 
-  expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), 
-  linkedContext(0), componentAttached(0)
+  expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0), 
+  componentAttached(0), v4bindings(0), v8bindings(0)
 {
 }
 
 QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt)
 : parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false), isPragmaLibraryContext(false),
   publicContext(ctxt), propertyNames(0), contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0), 
-  expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), 
-  linkedContext(0), componentAttached(0)
+  expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0), 
+  componentAttached(0), v4bindings(0), v8bindings(0)
 {
 }
 
@@ -607,8 +608,11 @@ void QDeclarativeContextData::destroy()
     if (imports)
         imports->release();
 
-    if (optimizedBindings)
-        optimizedBindings->release();
+    if (v4bindings)
+        v4bindings->release();
+
+    if (v8bindings)
+        v8bindings->release();
 
     for (int ii = 0; ii < importedScripts.count(); ++ii) {
         qPersistentDispose(importedScripts[ii]);
index ac933a3..59d886c 100644 (file)
@@ -73,6 +73,7 @@
 
 QT_BEGIN_NAMESPACE
 
+class QV8Bindings;
 class QDeclarativeContext;
 class QDeclarativeExpression;
 class QDeclarativeEngine;
@@ -192,9 +193,6 @@ public:
     void setIdProperty(int, QObject *);
     void setIdPropertyData(QDeclarativeIntegerCache *);
 
-    // Optimized binding pointer
-    QDeclarativeV4Bindings *optimizedBindings;
-
     // Linked contexts. this owns linkedContext.
     QDeclarativeContextData *linkedContext;
 
@@ -202,6 +200,10 @@ public:
     // context
     QDeclarativeComponentAttached *componentAttached;
 
+    // Optimized binding objects.  Needed for deferred properties.
+    QDeclarativeV4Bindings *v4bindings;
+    QV8Bindings *v8bindings;
+
     // Return the outermost id for obj, if any.
     QString findObjectId(const QObject *obj) const;
 
index d709d5c..27bd8f8 100644 (file)
@@ -113,32 +113,20 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, v8::Hand
     extractExpressionFromFunction = true;
 }
 
-void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr, 
-                                         QDeclarativeRefCount *rc, 
+void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr, bool isRewritten,
                                          QObject *me, const QString &srcUrl, int lineNumber)
 {
     url = srcUrl;
     line = lineNumber;
 
-    Q_ASSERT(!dataRef);
-
-    dataRef = rc;
-    if (dataRef) dataRef->addref();
-
-    quint32 *exprData = (quint32 *)expr;
-    QDeclarativeCompiledData *dd = (QDeclarativeCompiledData *)rc;
-
-    expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]);
-
-    int progIdx = *(exprData);
-    bool isSharedProgram = progIdx & 0x80000000;
-    progIdx &= 0x7FFFFFFF;
-
-    v8function = evalFunction(ctxt, me, expression, url, line, &v8qmlscope);
-
-    setUseSharedContext(false);
+    expression = expr;
 
-    expressionFunctionValid = true;
+    if (!isRewritten) {
+        expressionFunctionValid = false;
+    } else {
+        v8function = evalFunction(ctxt, me, expression, url, line, &v8qmlscope);
+        expressionFunctionValid = true;
+    }
 
     QDeclarativeAbstractExpression::setContext(ctxt);
     setScopeObject(me);
@@ -214,14 +202,14 @@ QDeclarativeExpression::QDeclarativeExpression()
 }
 
 /*!  \internal */
-QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, void *expr,
-                                               QDeclarativeRefCount *rc, QObject *me, 
-                                               const QString &url, int lineNumber,
+QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, 
+                                               QObject *object, const QString &expr, bool isRewritten,
+                                               const QString &url, int lineNumber, 
                                                QDeclarativeExpressionPrivate &dd)
 : QObject(dd, 0)
 {
     Q_D(QDeclarativeExpression);
-    d->init(ctxt, expr, rc, me, url, lineNumber);
+    d->init(ctxt, expr, isRewritten, object, url, lineNumber);
 
     if (QDeclarativeExpression_notifyIdx == -1) 
         QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
@@ -263,7 +251,7 @@ QDeclarativeExpression::QDeclarativeExpression(const QDeclarativeScriptString &s
         }
 
         if (cdata)
-            d->init(ctxtdata, (void*)cdata->datas.at(id).constData(), cdata, script.scopeObject(),
+            d->init(ctxtdata, cdata->primitives.at(id), cdata, script.scopeObject(),
                     cdata->name, script.d.data()->lineNumber);
         else
            defaultConstruction = true;
@@ -338,7 +326,7 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QO
         new QDeclarativeExpression(ctxt, scope, &function, ...);
  */
 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope, void *functionPtr,
-                       QDeclarativeExpressionPrivate &dd)
+                                               QDeclarativeExpressionPrivate &dd)
 : QObject(dd, 0)
 {
     v8::Handle<v8::Function> function = *(v8::Handle<v8::Function> *)functionPtr;
@@ -476,7 +464,9 @@ v8::Local<v8::Value> QDeclarativeJavaScriptExpression::evaluate(v8::Handle<v8::F
     bool lastCaptureProperties = ep->captureProperties;
     QPODVector<QDeclarativeEnginePrivate::CapturedProperty> lastCapturedProperties;
     ep->captureProperties = notifyOnValueChanged();
-    ep->capturedProperties.copyAndClear(lastCapturedProperties);
+
+    if (ep->capturedProperties.count())
+        ep->capturedProperties.copyAndClear(lastCapturedProperties);
 
     QDeclarativeContextData *lastSharedContext = 0;
     QObject *lastSharedScope = 0;
@@ -532,7 +522,11 @@ v8::Local<v8::Value> QDeclarativeJavaScriptExpression::evaluate(v8::Handle<v8::F
                                ep->capturedProperties);
     }
 
-    lastCapturedProperties.copyAndClear(ep->capturedProperties);
+    if (lastCapturedProperties.count())
+        lastCapturedProperties.copyAndClear(ep->capturedProperties);
+    else
+        ep->capturedProperties.clear();
+
     ep->captureProperties = lastCaptureProperties;
 
     return result;
index 217545e..edd93a1 100644 (file)
@@ -98,8 +98,8 @@ protected:
                            QDeclarativeExpressionPrivate &dd);
     QDeclarativeExpression(QDeclarativeContextData *, QObject *, void *, 
                            QDeclarativeExpressionPrivate &dd);
-    QDeclarativeExpression(QDeclarativeContextData *, void *, QDeclarativeRefCount *rc, 
-                           QObject *me, const QString &, int, QDeclarativeExpressionPrivate &dd);
+    QDeclarativeExpression(QDeclarativeContextData *, QObject *, const QString &, bool,
+                           const QString &, int, QDeclarativeExpressionPrivate &dd);
 
 private:
     QDeclarativeExpression(QDeclarativeContextData *, QObject *, const QString &);
index dcf47c3..2a26c26 100644 (file)
@@ -193,7 +193,7 @@ public:
 
     void init(QDeclarativeContextData *, const QString &, QObject *);
     void init(QDeclarativeContextData *, v8::Handle<v8::Function>, QObject *);
-    void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int);
+    void init(QDeclarativeContextData *, const QString &, bool, QObject *, const QString &, int);
 
     QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0);
 
index 79a2a1c..4f64e4e 100644 (file)
@@ -168,15 +168,21 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
     case QDeclarativeInstruction::AssignCustomType:
         qWarning().nospace() << idx << "\t\t" << "ASSIGN_CUSTOMTYPE\t" << instr->assignCustomType.propertyIndex << "\t" << instr->assignCustomType.primitive << "\t" << instr->assignCustomType.type;
         break;
+    case QDeclarativeInstruction::InitV8Bindings:
+        qWarning().nospace() << idx << "\t\t" << "INIT_V8_BINDING\t" << instr->initV8Bindings.program << "\t" << instr->initV8Bindings.line;
+        break;
     case QDeclarativeInstruction::StoreBinding:
         qWarning().nospace() << idx << "\t\t" << "STORE_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
         break;
     case QDeclarativeInstruction::StoreBindingOnAlias:
         qWarning().nospace() << idx << "\t\t" << "STORE_BINDING_ALIAS\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
         break;
-    case QDeclarativeInstruction::StoreCompiledBinding:
+    case QDeclarativeInstruction::StoreV4Binding:
         qWarning().nospace() << idx << "\t\t" << "STORE_COMPILED_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
         break;
+    case QDeclarativeInstruction::StoreV8Binding:
+        qWarning().nospace() << idx << "\t\t" << "STORE_V8_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
+        break;
     case QDeclarativeInstruction::StoreValueSource:
         qWarning().nospace() << idx << "\t\t" << "STORE_VALUE_SOURCE\t" << instr->assignValueSource.property << "\t" << instr->assignValueSource.castValue;
         break;
index 3db55a6..5c51ea8 100644 (file)
@@ -95,9 +95,11 @@ QT_BEGIN_NAMESPACE
     F(StoreImportedScript, storeScript) \
     F(StoreScriptString, storeScriptString) \
     F(BeginObject, begin) \
+    F(InitV8Bindings, initV8Bindings) \
     F(StoreBinding, assignBinding) \
     F(StoreBindingOnAlias, assignBinding) \
-    F(StoreCompiledBinding, assignBinding) \
+    F(StoreV4Binding, assignBinding) \
+    F(StoreV8Binding, assignBinding) \
     F(StoreValueSource, assignValueSource) \
     F(StoreValueInterceptor, assignValueInterceptor) \
     F(StoreObjectQList, common) \
@@ -182,6 +184,11 @@ union QDeclarativeInstruction
         int owner;
         int castValue;
     };
+    struct instr_initV8Bindings {
+        QML_INSTR_HEADER
+        int program;
+        int line;
+    };
     struct instr_assignBinding {
         QML_INSTR_HEADER
         unsigned int property;
@@ -411,6 +418,7 @@ union QDeclarativeInstruction
     instr_setId setId;
     instr_assignValueSource assignValueSource;
     instr_assignValueInterceptor assignValueInterceptor;
+    instr_initV8Bindings initV8Bindings;
     instr_assignBinding assignBinding;
     instr_fetch fetch;
     instr_fetchValue fetchValue;
index 3bbb7b0..3813270 100644 (file)
@@ -73,6 +73,73 @@ private:
     int refCount;
 };
 
+template<class T>
+class QDeclarativeRefPointer
+{
+public:
+    inline QDeclarativeRefPointer();
+    inline QDeclarativeRefPointer(T *);
+    inline QDeclarativeRefPointer(const QDeclarativeRefPointer<T> &);
+    inline ~QDeclarativeRefPointer();
+
+    inline QDeclarativeRefPointer<T> &operator=(const QDeclarativeRefPointer<T> &o);
+    inline QDeclarativeRefPointer<T> &operator=(T *);
+    
+    inline bool isNull() const { return !o; }
+
+    inline T* operator->() const { return o; }
+    inline T& operator*() const { return *o; }
+    inline operator T*() const { return o; }
+    inline T* data() const { return o; }
+
+private:
+    T *o;
+};
+
+template<class T>
+QDeclarativeRefPointer<T>::QDeclarativeRefPointer()
+: o(0) 
+{
+}
+
+template<class T>
+QDeclarativeRefPointer<T>::QDeclarativeRefPointer(T *o)
+: o(o) 
+{
+    if (o) o->addref();
+}
+
+template<class T>
+QDeclarativeRefPointer<T>::QDeclarativeRefPointer(const QDeclarativeRefPointer<T> &other)
+: o(other.o)
+{
+    if (o) o->addref();
+}
+
+template<class T>
+QDeclarativeRefPointer<T>::~QDeclarativeRefPointer()
+{
+    if (o) o->release();
+}
+
+template<class T>
+QDeclarativeRefPointer<T> &QDeclarativeRefPointer<T>::operator=(const QDeclarativeRefPointer<T> &other)
+{
+    if (other.o) other.o->addref();
+    if (o) o->release();
+    o = other.o;
+    return *this;
+}
+
+template<class T>
+QDeclarativeRefPointer<T> &QDeclarativeRefPointer<T>::operator=(T *other)
+{
+    if (other) other->addref();
+    if (o) o->release();
+    o = other;
+    return *this;
+}
+
 QT_END_NAMESPACE
 
 QT_END_HEADER
index 4d5fa36..377ef9d 100644 (file)
@@ -58,6 +58,7 @@
 #include "private/qdeclarativebinding_p_p.h"
 #include "private/qdeclarativecontext_p.h"
 #include "private/qdeclarativev4bindings_p.h"
+#include "private/qv8bindings_p.h"
 #include "private/qdeclarativeglobal_p.h"
 #include "qdeclarativescriptstring.h"
 #include "qdeclarativescriptstring_p.h"
@@ -191,8 +192,10 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
                 parserStatus = QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus>(instr.parserStatusSize);
             if (instr.contextCache != -1) 
                 ctxt->setIdPropertyData(comp->contextCaches.at(instr.contextCache));
-            if (instr.compiledBinding != -1) 
-                    ctxt->optimizedBindings = new QDeclarativeV4Bindings(datas.at(instr.compiledBinding).constData(), ctxt);
+            if (instr.compiledBinding != -1) {
+                const char *v4data = datas.at(instr.compiledBinding).constData();
+                ctxt->v4bindings = new QDeclarativeV4Bindings(v4data, ctxt);
+            }
         QML_END_INSTR(Init)
 
         QML_BEGIN_INSTR(Done)
@@ -657,6 +660,10 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
             status->classBegin();
         QML_END_INSTR(BeginObject)
 
+        QML_BEGIN_INSTR(InitV8Bindings)
+            ctxt->v8bindings = new QV8Bindings(primitives.at(instr.program), instr.line, comp, ctxt);
+        QML_END_INSTR(InitV8Bindings)
+
         QML_BEGIN_INSTR(StoreBinding)
             QObject *target = 
                 stack.at(stack.count() - 1 - instr.owner);
@@ -671,7 +678,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
             if ((stack.count() - instr.owner) == 1 && bindingSkipList.testBit(coreIndex)) 
                 break;
 
-            QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.value).constData(), comp, context, ctxt, comp->name, instr.line, 0);
+            QDeclarativeBinding *bind = new QDeclarativeBinding(primitives.at(instr.value), true, 
+                                                                context, ctxt, comp->name, instr.line);
             bindValues.append(bind);
             bind->m_mePtr = &bindValues.values[bindValues.count - 1];
             bind->setTarget(mp);
@@ -693,7 +701,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
             if ((stack.count() - instr.owner) == 1 && bindingSkipList.testBit(coreIndex)) 
                 break;
 
-            QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.value).constData(), comp, context, ctxt, comp->name, instr.line, 0);
+            QDeclarativeBinding *bind = new QDeclarativeBinding(primitives.at(instr.value), true,
+                                                                context, ctxt, comp->name, instr.line);
             bindValues.append(bind);
             bind->m_mePtr = &bindValues.values[bindValues.count - 1];
             bind->setTarget(mp);
@@ -702,7 +711,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
             if (old) { old->destroy(); }
         QML_END_INSTR(StoreBindingOnAlias)
 
-        QML_BEGIN_INSTR(StoreCompiledBinding)
+        QML_BEGIN_INSTR(StoreV4Binding)
             QObject *target = 
                 stack.at(stack.count() - 1 - instr.owner);
             QObject *scope = 
@@ -713,11 +722,32 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
                 break;
 
             QDeclarativeAbstractBinding *binding = 
-                ctxt->optimizedBindings->configBinding(instr.value, target, scope, property);
+                ctxt->v4bindings->configBinding(instr.value, target, scope, property);
             bindValues.append(binding);
             binding->m_mePtr = &bindValues.values[bindValues.count - 1];
             binding->addToObject(target, property);
-        QML_END_INSTR(StoreCompiledBinding)
+        QML_END_INSTR(StoreV4Binding)
+
+        QML_BEGIN_INSTR(StoreV8Binding)
+            QObject *target = 
+                stack.at(stack.count() - 1 - instr.owner);
+            QObject *scope = 
+                stack.at(stack.count() - 1 - instr.context);
+
+            QDeclarativeProperty mp = 
+                QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
+
+            int coreIndex = mp.index();
+
+            if ((stack.count() - instr.owner) == 1 && bindingSkipList.testBit(coreIndex))
+                break;
+
+            QDeclarativeAbstractBinding *binding = 
+                ctxt->v8bindings->configBinding(instr.value, target, scope, mp, instr.line);
+            bindValues.append(binding);
+            binding->m_mePtr = &bindValues.values[bindValues.count - 1];
+            binding->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp));
+        QML_END_INSTR(StoreV8Binding)
 
         QML_BEGIN_INSTR(StoreValueSource)
             QObject *obj = stack.pop();
index 0ee7d4d..a7946d4 100644 (file)
@@ -315,6 +315,7 @@ void QDeclarativeV4BindingsPrivate::Binding::destroy()
     enabled = false;
     removeFromObject();
     clear();
+    removeError();
     parent->q_func()->release();
 }
 
diff --git a/src/declarative/qml/v8/qv8bindings.cpp b/src/declarative/qml/v8/qv8bindings.cpp
new file mode 100644 (file)
index 0000000..424d06f
--- /dev/null
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv8bindings_p.h"
+
+#include <private/qv8_p.h>
+#include <private/qdeclarativebinding_p.h>
+#include <private/qdeclarativecompiler_p.h>
+#include <private/qdeclarativebinding_p_p.h>
+#include <private/qdeclarativeexpression_p.h>
+#include <private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QV8BindingsPrivate : public QObjectPrivate
+{
+    Q_DECLARE_PUBLIC(QV8Bindings)
+public:
+    QV8BindingsPrivate();
+
+    struct Binding : public QDeclarativeJavaScriptExpression,
+                     public QDeclarativeAbstractBinding {
+        Binding();
+
+        // Inherited from QDeclarativeAbstractBinding
+        virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags);
+        virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
+        virtual void destroy();
+
+        int index:30;
+        bool enabled:1;
+        bool updating:1;
+        int line;
+        QDeclarativeProperty property;
+        QV8BindingsPrivate *parent;
+    };
+
+    QUrl url;
+    int bindingsCount;
+    Binding *bindings;
+    v8::Persistent<v8::Array> functions;
+};
+
+QV8BindingsPrivate::QV8BindingsPrivate()
+: bindingsCount(0), bindings(0)
+{
+}
+
+QV8BindingsPrivate::Binding::Binding()
+: index(-1), enabled(false), updating(false), line(-1), parent(0)
+{
+}
+
+void QV8BindingsPrivate::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
+{
+    if (enabled != e) {
+        enabled = e;
+
+        if (e) update(flags);
+    }
+}
+
+void QV8BindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
+{
+    if (!enabled)
+        return;
+
+    QDeclarativeContextData *context = QDeclarativeAbstractExpression::context();
+    if (!context || !context->isValid())
+        return;
+
+    if (!updating) {
+        updating = true;
+        QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
+
+        bool isUndefined = false;
+
+        QDeclarativeDeleteWatcher watcher(this);
+        ep->referenceScarceResources(); 
+
+        v8::HandleScope handle_scope;
+        v8::Context::Scope scope(ep->v8engine.context());
+        v8::Local<v8::Value> result = evaluate(v8::Handle<v8::Function>::Cast(parent->functions->Get(index)), 
+                                               &isUndefined);
+
+        bool needsErrorData = false;
+        if (!watcher.wasDeleted() && !error.isValid()) 
+            needsErrorData = !QDeclarativeBindingPrivate::writeBindingResult(this, property, result, 
+                                                                             isUndefined, flags);
+
+        if (!watcher.wasDeleted()) {
+
+            if (needsErrorData) {
+                QUrl url = QUrl(parent->url);
+                if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>"));
+
+                error.setUrl(url);
+                error.setLine(line);
+                error.setColumn(-1);
+            }
+
+            if (error.isValid()) {
+                if (!addError(ep)) ep->warning(error);
+            } else {
+                removeError();
+            }
+
+            updating = false;
+        }
+
+        ep->dereferenceScarceResources(); 
+
+    } else {
+        QDeclarativeBindingPrivate::printBindingLoopError(property);
+    }
+}
+
+void QV8BindingsPrivate::Binding::destroy()
+{
+    enabled = false;
+    removeFromObject();
+    clear();
+    removeError();
+    parent->q_func()->release();
+}
+
+QV8Bindings::QV8Bindings(const QString &program, int line,
+                         QDeclarativeCompiledData *compiled, 
+                         QDeclarativeContextData *context)
+: QObject(*(new QV8BindingsPrivate))
+{
+    Q_D(QV8Bindings);
+
+    QV8Engine *engine = QDeclarativeEnginePrivate::getV8Engine(context->engine);
+
+    if (compiled->v8bindings.IsEmpty()) {
+        v8::HandleScope handle_scope;
+        v8::Context::Scope scope(engine->context());
+
+        v8::Local<v8::Script> script = engine->qmlModeCompile(program, compiled->name, line);
+        v8::Local<v8::Value> result = script->Run(engine->contextWrapper()->sharedContext());
+
+        if (result->IsArray()) 
+            compiled->v8bindings = qPersistentNew(v8::Local<v8::Array>::Cast(result));
+    }
+
+    d->url = compiled->url;
+    d->functions = qPersistentNew(compiled->v8bindings);
+    d->bindingsCount = d->functions->Length();
+    d->bindings = new QV8BindingsPrivate::Binding[d->bindingsCount];
+    
+    setContext(context);
+}
+
+QV8Bindings::~QV8Bindings()
+{
+    Q_D(QV8Bindings);
+    qPersistentDispose(d->functions);
+
+    delete [] d->bindings;
+    d->bindings = 0;
+    d->bindingsCount = 0;
+}
+
+QDeclarativeAbstractBinding *QV8Bindings::configBinding(int index, QObject *target, QObject *scope, 
+                                                        const QDeclarativeProperty &property, int line)
+{
+    Q_D(QV8Bindings);
+    QV8BindingsPrivate::Binding *rv = d->bindings + index;
+
+    rv->line = line;
+    rv->index = index;
+    rv->property = property;
+    rv->setContext(context());
+    rv->setScopeObject(scope);
+    rv->setUseSharedContext(true);
+    rv->setNotifyOnValueChanged(true);
+    rv->setNotifyObject(this, index);
+    rv->parent = d;
+
+    addref(); // This is decremented in Binding::destroy()
+
+    return rv;
+}
+
+int QV8Bindings::qt_metacall(QMetaObject::Call c, int id, void **)
+{
+    Q_D(QV8Bindings);
+
+    if (c == QMetaObject::InvokeMetaMethod) {
+        QV8BindingsPrivate::Binding *binding = d->bindings + id;
+        binding->update(QDeclarativePropertyPrivate::DontRemoveBinding);
+    }
+    return -1;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/v8/qv8bindings_p.h b/src/declarative/qml/v8/qv8bindings_p.h
new file mode 100644 (file)
index 0000000..e99e3c8
--- /dev/null
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV8BINDINGS_P_H
+#define QV8BINDINGS_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qdeclarativeexpression_p.h"
+#include "private/qdeclarativebinding_p.h"
+#include "private/qdeclarativev4instruction_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeCompiledData;
+
+class QV8BindingsPrivate;
+class QV8Bindings : public QObject, 
+                    public QDeclarativeAbstractExpression, 
+                    public QDeclarativeRefCount
+{
+public:
+    QV8Bindings(const QString &program, int line,
+                QDeclarativeCompiledData *compiled,
+                QDeclarativeContextData *context);
+    virtual ~QV8Bindings();
+
+    QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, 
+                                               const QDeclarativeProperty &prop, int line);
+
+protected:
+    int qt_metacall(QMetaObject::Call, int, void **);
+
+private:
+    Q_DISABLE_COPY(QV8Bindings)
+    Q_DECLARE_PRIVATE(QV8Bindings)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QV8BINDINGS_P_H
+
+
index d91acd7..61e0184 100644 (file)
@@ -14,6 +14,7 @@ HEADERS += \
     $$PWD/qv8valuetypewrapper_p.h \
     $$PWD/qv8include_p.h \
     $$PWD/qv8worker_p.h \
+    $$PWD/qv8bindings_p.h \
     $$PWD/../../../3rdparty/javascriptcore/DateMath.h \
 
 SOURCES += \
@@ -28,5 +29,6 @@ SOURCES += \
     $$PWD/qv8valuetypewrapper.cpp \
     $$PWD/qv8include.cpp \
     $$PWD/qv8worker.cpp \
+    $$PWD/qv8bindings.cpp \
     $$PWD/../../../3rdparty/javascriptcore/DateMath.cpp \