diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2011-06-08 13:18:35 +1000 |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2011-06-09 10:10:09 +1000 |
commit | ccf706d0bb2d9f70f5a8c18e4aab8ee7e6369817 (patch) | |
tree | 7019d21c843ad3c4e02fdff38d81615b56f56ee0 /src | |
parent | b8154d2b6b1a6c0145a099554c9166b4d35630fe (diff) |
Optimized QDeclarativeScriptString constructor for QDeclarativeExpression.
When the compiler sees a script string, it will attempt to rewrite it
and store the id for the rewrite in the script string. We can then
create a QDeclarativeExpression using the id, which saves us a rewrite
at runtime.
Reviewed-by: Aaron Kennedy
Diffstat (limited to 'src')
-rw-r--r-- | src/declarative/qml/qdeclarativecompiler.cpp | 6 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeexpression.cpp | 53 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeexpression.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeinstruction.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeinstruction_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativescriptstring.cpp | 15 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativescriptstring.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativescriptstring_p.h | 63 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativevme.cpp | 3 | ||||
-rw-r--r-- | src/declarative/qml/qml.pri | 1 |
10 files changed, 135 insertions, 15 deletions
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index e66a3fe792..72010c0ef2 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -1012,12 +1012,14 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) { typedef QPair<Property *, int> PropPair; foreach(const PropPair &prop, obj->scriptStringProperties) { + const QString &script = prop.first->values.at(0)->value.asScript(); QDeclarativeInstruction ss; ss.setType(QDeclarativeInstruction::StoreScriptString); ss.storeScriptString.propertyIndex = prop.first->index; - ss.storeScriptString.value = - output->indexForString(prop.first->values.at(0)->value.asScript()); + ss.storeScriptString.value = output->indexForString(script); ss.storeScriptString.scope = prop.second; + ss.storeScriptString.bindingId = rewriteBinding(script, prop.first->name); + ss.storeScriptString.line = prop.first->location.start.line; output->addInstruction(ss); } diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 247bde9a6c..8079cf3eea 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -45,6 +45,7 @@ #include "private/qdeclarativeengine_p.h" #include "private/qdeclarativecontext_p.h" #include "private/qdeclarativerewrite_p.h" +#include "private/qdeclarativescriptstring_p.h" #include "private/qdeclarativecompiler_p.h" #include "private/qdeclarativeglobalscriptclass_p.h" @@ -271,6 +272,58 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, vo /*! Create a QDeclarativeExpression object that is a child of \a parent. + The \script provides the expression to be evaluated, the context to evaluate it in, + and the scope object to evaluate it with. + + This constructor is functionally equivalent to the following, but in most cases + is more efficient. + \code + QDeclarativeExpression expression(script.context(), script.scopeObject(), script.script(), parent); + \endcode + + \sa QDeclarativeScriptString +*/ +QDeclarativeExpression::QDeclarativeExpression(const QDeclarativeScriptString &script, QObject *parent) +: QObject(*new QDeclarativeExpressionPrivate, parent) +{ + Q_D(QDeclarativeExpression); + bool defaultConstruction = false; + + int id = script.d.data()->bindingId; + if (id < 0) { + defaultConstruction = true; + } else { + QDeclarativeContextData *ctxtdata = QDeclarativeContextData::get(script.context()); + + QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(qmlEngine(script.scopeObject())); + QDeclarativeCompiledData *cdata = 0; + QDeclarativeTypeData *typeData = 0; + if (engine && ctxtdata && !ctxtdata->url.isEmpty()) { + typeData = engine->typeLoader.get(ctxtdata->url); + cdata = typeData->compiledData(); + } + + if (cdata) + d->init(ctxtdata, (void*)cdata->datas.at(id).constData(), cdata, script.scopeObject(), + cdata->name, script.d.data()->lineNumber); + else + defaultConstruction = true; + + if (typeData) + typeData->release(); + } + + if (defaultConstruction) + d->init(QDeclarativeContextData::get(script.context()), script.script(), script.scopeObject()); + + if (QDeclarativeExpression_notifyIdx == -1) + QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()"); + d->setNotifyObject(this, QDeclarativeExpression_notifyIdx); +} + +/*! + Create a QDeclarativeExpression object that is a child of \a parent. + The \a expression JavaScript will be executed in the \a ctxt QDeclarativeContext. If specified, the \a scope object's properties will also be in scope during the expression's execution. diff --git a/src/declarative/qml/qdeclarativeexpression.h b/src/declarative/qml/qdeclarativeexpression.h index fef97de2b2..b76205c82e 100644 --- a/src/declarative/qml/qdeclarativeexpression.h +++ b/src/declarative/qml/qdeclarativeexpression.h @@ -43,6 +43,7 @@ #define QDECLARATIVEEXPRESSION_H #include <QtDeclarative/qdeclarativeerror.h> +#include <QtDeclarative/qdeclarativescriptstring.h> #include <QtCore/qobject.h> #include <QtCore/qvariant.h> @@ -66,6 +67,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeExpression : public QObject public: QDeclarativeExpression(); QDeclarativeExpression(QDeclarativeContext *, QObject *, const QString &, QObject * = 0); + explicit QDeclarativeExpression(const QDeclarativeScriptString &, QObject * = 0); virtual ~QDeclarativeExpression(); QDeclarativeEngine *engine() const; diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index fa0d8ea6f4..79a2a1cc34 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -160,7 +160,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) qWarning().nospace() << idx << "\t\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value; break; case QDeclarativeInstruction::StoreScriptString: - qWarning().nospace() << idx << "\t\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope; + qWarning().nospace() << idx << "\t\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope << "\t" << instr->storeScriptString.bindingId; break; case QDeclarativeInstruction::AssignSignalObject: qWarning().nospace() << idx << "\t\t" << "ASSIGN_SIGNAL_OBJECT\t" << instr->assignSignalObject.signal << "\t\t\t" << datas.at(instr->assignSignalObject.signal); diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index d040967882..3db55a66d3 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -245,6 +245,8 @@ union QDeclarativeInstruction int propertyIndex; int value; int scope; + int bindingId; + ushort line; }; struct instr_storeScript { QML_INSTR_HEADER diff --git a/src/declarative/qml/qdeclarativescriptstring.cpp b/src/declarative/qml/qdeclarativescriptstring.cpp index f544393b9b..02d6e5603e 100644 --- a/src/declarative/qml/qdeclarativescriptstring.cpp +++ b/src/declarative/qml/qdeclarativescriptstring.cpp @@ -40,19 +40,10 @@ ****************************************************************************/ #include "qdeclarativescriptstring.h" +#include "qdeclarativescriptstring_p.h" QT_BEGIN_NAMESPACE -class QDeclarativeScriptStringPrivate : public QSharedData -{ -public: - QDeclarativeScriptStringPrivate() : context(0), scope(0) {} - - QDeclarativeContext *context; - QObject *scope; - QString script; -}; - /*! \class QDeclarativeScriptString \since 4.7 @@ -75,8 +66,8 @@ and the class could choose how to handle it. Typically, the class will evaluate the script at some later time using a QDeclarativeExpression. \code -QDeclarativeExpression expr(scriptString.context(), scriptString.script(), scriptStr.scopeObject()); -expr.value(); +QDeclarativeExpression expr(scriptString); +expr.evaluate(); \endcode \sa QDeclarativeExpression diff --git a/src/declarative/qml/qdeclarativescriptstring.h b/src/declarative/qml/qdeclarativescriptstring.h index 5408dd404d..5f3a2fe73f 100644 --- a/src/declarative/qml/qdeclarativescriptstring.h +++ b/src/declarative/qml/qdeclarativescriptstring.h @@ -75,6 +75,9 @@ public: private: QSharedDataPointer<QDeclarativeScriptStringPrivate> d; + + friend class QDeclarativeVME; + friend class QDeclarativeExpression; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativescriptstring_p.h b/src/declarative/qml/qdeclarativescriptstring_p.h new file mode 100644 index 0000000000..cd0cc43995 --- /dev/null +++ b/src/declarative/qml/qdeclarativescriptstring_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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$ +** 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. +** +** 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. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVESCRIPTSTRING_P_H +#define QDECLARATIVESCRIPTSTRING_P_H + +#include <QtDeclarative/qdeclarativecontext.h> + +QT_BEGIN_NAMESPACE + +class QDeclarativeScriptStringPrivate : public QSharedData +{ +public: + QDeclarativeScriptStringPrivate() : context(0), scope(0), bindingId(-1), lineNumber(-1) {} + + QDeclarativeContext *context; + QObject *scope; + QString script; + int bindingId; + int lineNumber; +}; + +QT_END_NAMESPACE + +#endif // QDECLARATIVESCRIPTSTRING_P_H diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index dd080a85e9..a9b303c94f 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -61,6 +61,7 @@ #include "private/qdeclarativeglobal_p.h" #include "private/qdeclarativeglobalscriptclass_p.h" #include "qdeclarativescriptstring.h" +#include "qdeclarativescriptstring_p.h" #include <QStack> #include <QWidget> @@ -640,6 +641,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, ss.setContext(ctxt->asQDeclarativeContext()); ss.setScopeObject(scope); ss.setScript(primitives.at(instr.value)); + ss.d.data()->bindingId = instr.bindingId; + ss.d.data()->lineNumber = instr.line; void *a[] = { &ss, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index 233359079d..5d56b300ba 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -129,6 +129,7 @@ HEADERS += \ $$PWD/qdeclarativeimport_p.h \ $$PWD/qdeclarativeextensionplugin.h \ $$PWD/qintrusivelist_p.h \ + $$PWD/qdeclarativescriptstring_p.h QT += sql include(parser/parser.pri) |