summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qmlbasicscript.cpp2
-rw-r--r--src/declarative/qml/qmlcompileddata.cpp7
-rw-r--r--src/declarative/qml/qmlcompiler.cpp49
-rw-r--r--src/declarative/qml/qmlcomponent.cpp5
-rw-r--r--src/declarative/qml/qmlcontext.cpp81
-rw-r--r--src/declarative/qml/qmlcontext.h3
-rw-r--r--src/declarative/qml/qmlcontext_p.h24
-rw-r--r--src/declarative/qml/qmlengine.cpp62
-rw-r--r--src/declarative/qml/qmlexpression.cpp47
-rw-r--r--src/declarative/qml/qmlexpression.h1
-rw-r--r--src/declarative/qml/qmlexpression_p.h12
-rw-r--r--src/declarative/qml/qmlinstruction.cpp3
-rw-r--r--src/declarative/qml/qmlinstruction_p.h3
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp2
-rw-r--r--src/declarative/qml/qmlvaluetype.cpp124
-rw-r--r--src/declarative/qml/qmlvaluetype_p.h55
-rw-r--r--src/declarative/qml/qmlvme.cpp30
17 files changed, 327 insertions, 183 deletions
diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp
index b940d61..ca137c7 100644
--- a/src/declarative/qml/qmlbasicscript.cpp
+++ b/src/declarative/qml/qmlbasicscript.cpp
@@ -668,7 +668,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c
switch(instr.type) {
case ScriptInstruction::LoadIdObject:
{
- stack.push(contextPrivate->propertyValues.at(instr.fetch.idx));
+ stack.push(QVariant::fromValue(contextPrivate->idValues[instr.fetch.idx].data()));
enginePrivate->capturedProperties <<
QmlEnginePrivate::CapturedProperty(context, -1, contextPrivate->notifyIndex + instr.fetch.idx);
state = Reset;
diff --git a/src/declarative/qml/qmlcompileddata.cpp b/src/declarative/qml/qmlcompileddata.cpp
index 0563891..ffb89b3 100644
--- a/src/declarative/qml/qmlcompileddata.cpp
+++ b/src/declarative/qml/qmlcompileddata.cpp
@@ -170,12 +170,7 @@ QObject *QmlCompiledData::TypeReference::createInstance(QmlContext *ctxt) const
return rv;
} else {
Q_ASSERT(component);
- QObject *rv = component->create(ctxt);
- QmlContext *ctxt = qmlContext(rv);
- if(ctxt) {
- static_cast<QmlContextPrivate *>(QObjectPrivate::get(ctxt))->typeName = className;
- }
- return rv;
+ return component->create(ctxt);
}
}
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 091b7bb..6ef7cc2 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -64,7 +64,9 @@
#include <private/qmlcomponent_p.h>
#include "parser/qmljsast_p.h"
#include <private/qmlvmemetaobject_p.h>
+#include <private/qmlexpression_p.h>
#include "qmlmetaproperty_p.h"
+#include "qmlrewrite_p.h"
#include "qmlscriptparser_p.h"
@@ -603,6 +605,7 @@ void QmlCompiler::compileTree(Object *tree)
init.line = 0;
init.init.bindingsSize = compileState.bindings.count();
init.init.parserStatusSize = compileState.parserStatusCount;
+ init.init.idSize = compileState.ids.count();
output->bytecode << init;
genObject(tree);
@@ -774,6 +777,7 @@ void QmlCompiler::genObject(QmlParser::Object *obj)
id.type = QmlInstruction::SetId;
id.line = -1;
id.setId.value = output->indexForString(obj->id);
+ id.setId.index = obj->idIndex;
output->bytecode << id;
}
@@ -917,6 +921,7 @@ void QmlCompiler::genComponent(QmlParser::Object *obj)
init.type = QmlInstruction::Init;
init.init.bindingsSize = compileState.bindings.count();
init.init.parserStatusSize = compileState.parserStatusCount;
+ init.init.idSize = compileState.ids.count();
init.line = obj->location.start.line;
output->bytecode << init;
@@ -936,7 +941,8 @@ void QmlCompiler::genComponent(QmlParser::Object *obj)
QmlInstruction id;
id.type = QmlInstruction::SetId;
id.line = -1;
- id.setId.value = output->indexForString(obj->id);;
+ id.setId.value = output->indexForString(obj->id);
+ id.setId.index = obj->idIndex;
output->bytecode << id;
}
}
@@ -2058,14 +2064,11 @@ void QmlCompiler::genBindingAssignment(QmlParser::Value *binding,
const BindingReference &ref = compileState.bindings.value(binding);
QmlInstruction store;
- int dataRef;
- if (ref.compiledData.isEmpty()) {
- dataRef = output->indexForString(ref.expression.asScript());
- store.type = QmlInstruction::StoreBinding;
- } else {
- dataRef = output->indexForByteArray(ref.compiledData);
- store.type = QmlInstruction::StoreCompiledBinding;
- }
+ store.type = QmlInstruction::StoreCompiledBinding;
+ store.assignBinding.value = output->indexForByteArray(ref.compiledData);
+ store.assignBinding.context = ref.bindingContext.stack;
+ store.assignBinding.owner = ref.bindingContext.owner;
+ store.line = prop->location.end.line;
Q_ASSERT(ref.bindingContext.owner == 0 ||
(ref.bindingContext.owner != 0 && valueTypeProperty));
@@ -2077,18 +2080,12 @@ void QmlCompiler::genBindingAssignment(QmlParser::Value *binding,
store.assignBinding.property =
QmlMetaPropertyPrivate::saveProperty(prop->index);
}
- store.assignBinding.value = dataRef;
- store.assignBinding.context = ref.bindingContext.stack;
- store.assignBinding.owner = ref.bindingContext.owner;
- store.line = prop->location.end.line;
output->bytecode << store;
}
bool QmlCompiler::completeComponentBuild()
{
- saveComponentState();
-
for (int ii = 0; ii < compileState.aliasingObjects.count(); ++ii) {
Object *aliasObject = compileState.aliasingObjects.at(ii);
COMPILE_CHECK(buildDynamicMeta(aliasObject, ResolveAliases));
@@ -2107,11 +2104,31 @@ bool QmlCompiler::completeComponentBuild()
expr.expression = binding.expression;
bs.compile(expr);
- if (bs.isValid())
+ quint32 type;
+ if (bs.isValid()) {
binding.compiledData =
QByteArray(bs.compileData(), bs.compileDataSize());
+ type = QmlExpressionPrivate::BasicScriptEngineData;
+ } else {
+ type = QmlExpressionPrivate::PreTransformedQtScriptData;
+
+ // Pre-rewrite the expression
+ QString expression = binding.expression.asScript();
+ QmlRewrite::RewriteBinding rewriteBinding;
+ expression = rewriteBinding(expression);
+
+ quint32 length = expression.length();
+ binding.compiledData =
+ QByteArray((const char *)&length, sizeof(quint32)) +
+ QByteArray((const char *)expression.constData(),
+ expression.length() * sizeof(QChar));
+ }
+ binding.compiledData.prepend(QByteArray((const char *)&type,
+ sizeof(quint32)));
}
+ saveComponentState();
+
return true;
}
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index 8fb7736..d4e383d 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -488,11 +488,6 @@ QObject *QmlComponent::beginCreate(QmlContext *context)
static_cast<QmlContextPrivate *>(QObjectPrivate::get(context));
QmlContext *ctxt = new QmlContext(context, 0, true);
static_cast<QmlContextPrivate*>(ctxt->d_ptr)->url = d->cc->url;
- if(d->start != -1) {
- // ### FIXME
- static_cast<QmlContextPrivate*>(ctxt->d_ptr)->startLine = d->cc->bytecode.at(d->start - 1).line;
- static_cast<QmlContextPrivate*>(ctxt->d_ptr)->endLine = d->cc->bytecode.at(d->start - 1).createComponent.endLine;
- }
QmlVME vme;
QObject *rv = vme.run(ctxt, d->cc, d->start, d->count);
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index f347cf3..8a2732d 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
QmlContextPrivate::QmlContextPrivate()
: parent(0), engine(0), isInternal(false), notifyIndex(-1),
- highPriorityCount(0), startLine(-1), endLine(-1)
+ highPriorityCount(0), expressions(0), idValues(0), idValueCount(0)
{
}
@@ -71,29 +71,21 @@ void QmlContextPrivate::dump(int depth)
parent->d_func()->dump(depth + 1);
}
-void QmlContextPrivate::destroyed(QObject *obj)
+void QmlContextPrivate::destroyed(ContextGuard *guard)
{
Q_Q(QmlContext);
- defaultObjects.removeAll(obj);
-
- QVariant variantObject = QVariant::fromValue(obj);
- QVarLengthArray<int> notifies;
- for (int ii = 0; ii < propertyValues.count(); ++ii) {
- if (propertyValues.at(ii) == variantObject) {
- propertyValues[ii] = QVariant();
- notifies.append(ii);
- }
- }
-
- // There is no need to emit these notifications if our parent is in the
// process of being deleted (which is *probably* why obj has been destroyed
// anyway), as we're about to get deleted which will invalidate all the
// expressions that could depend on us
QObject *parent = q->parent();
- if (!parent || !QObjectPrivate::get(parent)->wasDeleted) {
- for (int ii = 0; ii < notifies.count(); ++ii) {
- QMetaObject::activate(q, notifies[ii] + notifyIndex, 0);
+ if (parent && QObjectPrivate::get(parent)->wasDeleted)
+ return;
+
+ for (int ii = 0; ii < idValueCount; ++ii) {
+ if (&idValues[ii] == guard) {
+ QMetaObject::activate(q, ii + notifyIndex, 0);
+ return;
}
}
}
@@ -131,8 +123,6 @@ void QmlContextPrivate::addDefaultObject(QObject *object, Priority priority)
} else {
defaultObjects.append(object);
}
- QObject::connect(object, SIGNAL(destroyed(QObject*)),
- q_ptr, SLOT(objectDestroyed(QObject*)));
}
@@ -288,11 +278,15 @@ QmlContext::~QmlContext()
(*iter)->d_func()->parent = 0;
}
- for (QSet<QmlExpression *>::ConstIterator iter =
- d->childExpressions.begin();
- iter != d->childExpressions.end();
- ++iter) {
- (*iter)->d_func()->ctxt = 0;
+ QmlExpressionPrivate *expression = d->expressions;
+ while (expression) {
+ QmlExpressionPrivate *nextExpression = expression->nextExpression;
+
+ expression->ctxt = 0;
+ expression->prevExpression = 0;
+ expression->nextExpression = 0;
+
+ expression = nextExpression;
}
for (int ii = 0; ii < d->contextObjects.count(); ++ii) {
@@ -306,6 +300,8 @@ QmlContext::~QmlContext()
}
}
d->contextObjects.clear();
+
+ delete [] d->idValues;
}
void QmlContextPrivate::invalidateEngines()
@@ -365,7 +361,7 @@ void QmlContext::setContextProperty(const QString &name, const QVariant &value)
} else {
QHash<QString, int>::ConstIterator iter = d->propertyNames.find(name);
if(iter == d->propertyNames.end()) {
- d->propertyNames.insert(name, d->propertyValues.count());
+ d->propertyNames.insert(name, d->idValueCount + d->propertyValues.count());
d->propertyValues.append(value);
} else {
d->propertyValues[*iter] = value;
@@ -374,6 +370,25 @@ void QmlContext::setContextProperty(const QString &name, const QVariant &value)
}
}
+void QmlContextPrivate::setIdProperty(const QString &name, int idx,
+ QObject *obj)
+{
+ if (notifyIndex == -1) {
+ Q_Q(QmlContext);
+ notifyIndex = q->metaObject()->methodCount();
+ }
+
+ propertyNames.insert(name, idx);
+ idValues[idx].priv = this;
+ idValues[idx] = obj;
+}
+
+void QmlContextPrivate::setIdPropertyCount(int count)
+{
+ idValues = new ContextGuard[count];
+ idValueCount = count;
+}
+
/*!
Set a the \a value of the \a name property on this context.
@@ -385,20 +400,12 @@ void QmlContext::setContextProperty(const QString &name, QObject *value)
if (d->notifyIndex == -1)
d->notifyIndex = this->metaObject()->methodCount();
- QObject::connect(value, SIGNAL(destroyed(QObject*)),
- this, SLOT(objectDestroyed(QObject*)));
-
QHash<QString, int>::ConstIterator iter = d->propertyNames.find(name);
if(iter == d->propertyNames.end()) {
- d->propertyNames.insert(name, d->propertyValues.count());
+ d->propertyNames.insert(name, d->idValueCount + d->propertyValues.count());
d->propertyValues.append(QVariant::fromValue(value));
} else {
int idx = *iter;
- if (QmlMetaType::isObject(d->propertyValues.at(idx).userType())) {
- QObject *old = QmlMetaType::toQObject(d->propertyValues.at(idx));
- QObject::disconnect(old, SIGNAL(destroyed(QObject*)),
- this, SLOT(objectDestroyed(QObject*)));
- }
d->propertyValues[*iter] = QVariant::fromValue(value);
QMetaObject::activate(this, *iter + d->notifyIndex, 0);
}
@@ -445,10 +452,4 @@ void QmlContext::setBaseUrl(const QUrl &baseUrl)
d_func()->url = baseUrl;
}
-void QmlContext::objectDestroyed(QObject *object)
-{
- Q_D(QmlContext);
- d->destroyed(object);
-}
-
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlcontext.h b/src/declarative/qml/qmlcontext.h
index 877ff0f..1f29ca2 100644
--- a/src/declarative/qml/qmlcontext.h
+++ b/src/declarative/qml/qmlcontext.h
@@ -77,9 +77,6 @@ public:
void setBaseUrl(const QUrl &);
-private Q_SLOTS:
- void objectDestroyed(QObject *);
-
private:
friend class QmlVME;
friend class QmlEngine;
diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h
index fc615b6..60655ae 100644
--- a/src/declarative/qml/qmlcontext_p.h
+++ b/src/declarative/qml/qmlcontext_p.h
@@ -59,6 +59,7 @@
#include <QtCore/qhash.h>
#include <QtScript/qscriptvalue.h>
#include <QtCore/qset.h>
+#include <private/qguard_p.h>
QT_BEGIN_NAMESPACE
@@ -66,6 +67,7 @@ class QmlContext;
class QmlExpression;
class QmlEngine;
class QmlExpression;
+class QmlExpressionPrivate;
class QmlContextPrivate : public QObjectPrivate
{
@@ -87,17 +89,12 @@ public:
QScriptValueList scopeChain;
QUrl url;
- QByteArray typeName;
- int startLine;
- int endLine;
void init();
void dump();
void dump(int depth);
- void destroyed(QObject *);
-
enum Priority {
HighPriority,
NormalPriority
@@ -106,11 +103,26 @@ public:
void invalidateEngines();
QSet<QmlContext *> childContexts;
- QSet<QmlExpression *> childExpressions;
+
+ QmlExpressionPrivate *expressions;
QmlSimpleDeclarativeData contextData;
QObjectList contextObjects;
+ struct ContextGuard : public QGuard<QObject>
+ {
+ QmlContextPrivate *priv;
+ ContextGuard &operator=(QObject *obj) {
+ (QGuard<QObject>&)*this = obj; return *this;
+ }
+ void objectDestroyed(QObject *o) { priv->destroyed(this); }
+ };
+ ContextGuard *idValues;
+ int idValueCount;
+ void setIdProperty(const QString &, int, QObject *);
+ void setIdPropertyCount(int);
+ void destroyed(ContextGuard *);
+
// Only used for debugging
QList<QPointer<QObject> > instances;
};
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index f6d70e0..68ad655 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -747,10 +747,6 @@ QmlContextScriptClass::queryProperty(const QScriptValue &object,
QString propName = name.toString();
-#ifdef PROPERTY_DEBUG
- qWarning() << "Query Context:" << propName << bindContext;
-#endif
-
*id = InvalidId;
if (bindContext->d_func()->propertyNames.contains(propName)) {
rv |= HandlesReadAccess;
@@ -767,17 +763,12 @@ QmlContextScriptClass::queryProperty(const QScriptValue &object,
}
QScriptValue QmlContextScriptClass::property(const QScriptValue &object,
- const QScriptString &name,
- uint id)
+ const QScriptString &name,
+ uint id)
{
QmlContext *bindContext =
static_cast<QmlContext*>(object.data().toQObject());
-#ifdef PROPERTY_DEBUG
- QString propName = name.toString();
- qWarning() << "Context Property:" << propName << bindContext;
-#endif
-
uint basicId = id & QmlScriptClass::ClassIdMask;
QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
@@ -786,18 +777,20 @@ QScriptValue QmlContextScriptClass::property(const QScriptValue &object,
switch (basicId) {
case VariantPropertyId:
{
+ QmlContextPrivate *contextPrivate = bindContext->d_func();
QString propName = name.toString();
- int index = bindContext->d_func()->propertyNames.value(propName);
- QVariant value = bindContext->d_func()->propertyValues.at(index);
-#ifdef PROPERTY_DEBUG
- qWarning() << "Context Property: Resolved property" << propName
- << "to context variant property list" << bindContext <<". Value:" << rv.toVariant();
-#endif
+ int index = contextPrivate->propertyNames.value(propName);
+
QScriptValue rv;
- if (QmlMetaType::isObject(value.userType())) {
- rv = scriptEngine->newObject(ep->objectClass, scriptEngine->newVariant(value));
+ if (index < contextPrivate->idValueCount) {
+ rv = scriptEngine->newObject(ep->objectClass, scriptEngine->newVariant(QVariant::fromValue(contextPrivate->idValues[index].data())));
} else {
- rv = scriptEngine->newVariant(value);
+ QVariant value = contextPrivate->propertyValues.at(index);
+ if (QmlMetaType::isObject(value.userType())) {
+ rv = scriptEngine->newObject(ep->objectClass, scriptEngine->newVariant(value));
+ } else {
+ rv = scriptEngine->newVariant(value);
+ }
}
ep->capturedProperties << QmlEnginePrivate::CapturedProperty(bindContext, -1, index + bindContext->d_func()->notifyIndex);
return rv;
@@ -809,10 +802,6 @@ QScriptValue QmlContextScriptClass::property(const QScriptValue &object,
QScriptValue rv = ep->propertyObject(name, obj,
id & ~QmlScriptClass::ClassIdSelectorMask);
if (rv.isValid()) {
-#ifdef PROPERTY_DEBUG
- qWarning() << "~Property: Resolved property" << propName
- << "to context default object" << bindContext << obj <<". Value:" << rv.toVariant();
-#endif
return rv;
}
break;
@@ -832,10 +821,6 @@ void QmlContextScriptClass::setProperty(QScriptValue &object,
QmlContext *bindContext =
static_cast<QmlContext*>(object.data().toQObject());
-#ifdef PROPERTY_DEBUG
- QString propName = name.toString();
- qWarning() << "Set QmlObject Property" << name.toString() << value.toVariant();
-#endif
int objIdx = (id & QmlScriptClass::ClassIdSelectorMask) >> 24;
QObject *obj = bindContext->d_func()->defaultObjects.at(objIdx);
@@ -975,10 +960,6 @@ QScriptClass::QueryFlags QmlObjectScriptClass::queryProperty(const QScriptValue
QueryFlags rv = 0;
QString propName = name.toString();
-#ifdef PROPERTY_DEBUG
- qWarning() << "Query QmlObject:" << propName << obj;
-#endif
-
if (obj)
rv = QmlEnginePrivate::get(engine)->queryObject(propName, id, obj);
@@ -991,20 +972,10 @@ QScriptValue QmlObjectScriptClass::property(const QScriptValue &object,
{
QObject *obj = object.data().toQObject();
-#ifdef PROPERTY_DEBUG
- QString propName = name.toString();
- qWarning() << "QmlObject Property:" << propName << obj;
-#endif
-
QScriptValue rv =
QmlEnginePrivate::get(engine)->propertyObject(name, obj, id);
- if (rv.isValid()) {
-#ifdef PROPERTY_DEBUG
- qWarning() << "~Property: Resolved property" << propName
- << "to object" << obj <<". Value:" << rv.toVariant();
-#endif
+ if (rv.isValid())
return rv;
- }
return QScriptValue();
}
@@ -1018,11 +989,6 @@ void QmlObjectScriptClass::setProperty(QScriptValue &object,
QObject *obj = object.data().toQObject();
-#ifdef PROPERTY_DEBUG
- QString propName = name.toString();
- qWarning() << "Set QmlObject Property" << name.toString() << value.toVariant();
-#endif
-
QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
QScriptValue oldact = scriptEngine->currentContext()->activationObject();
scriptEngine->currentContext()->setActivationObject(scriptEngine->globalObject());
diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp
index 2c06efa..3206734 100644
--- a/src/declarative/qml/qmlexpression.cpp
+++ b/src/declarative/qml/qmlexpression.cpp
@@ -51,7 +51,7 @@ Q_DECLARE_METATYPE(QList<QObject *>);
QT_BEGIN_NAMESPACE
QmlExpressionPrivate::QmlExpressionPrivate()
-: ctxt(0), expressionFunctionValid(false), sseData(0), me(0), trackChange(true), line(-1), guardList(0), guardListLength(0)
+: nextExpression(0), prevExpression(0), ctxt(0), expressionFunctionValid(false), expressionRewritten(false), sseData(0), me(0), trackChange(true), line(-1), guardList(0), guardListLength(0)
{
}
@@ -63,8 +63,12 @@ void QmlExpressionPrivate::init(QmlContext *ctxt, const QString &expr,
expression = expr;
this->ctxt = ctxt;
- if (ctxt)
- ctxt->d_func()->childExpressions.insert(q);
+ if (ctxt) {
+ QmlContextPrivate *cp = ctxt->d_func();
+ nextExpression = cp->expressions;
+ prevExpression = &cp->expressions;
+ cp->expressions = this;
+ }
this->me = me;
}
@@ -73,11 +77,23 @@ void QmlExpressionPrivate::init(QmlContext *ctxt, void *expr, QmlRefCount *rc,
{
Q_Q(QmlExpression);
- sse.load((const char *)expr, rc);
+ quint32 *data = (quint32 *)expr;
+ Q_ASSERT(*data == BasicScriptEngineData ||
+ *data == PreTransformedQtScriptData);
+ if (*data == BasicScriptEngineData) {
+ sse.load((const char *)(data + 1), rc);
+ } else {
+ expression = QString::fromRawData((QChar *)(data + 2), data[1]);
+ expressionRewritten = true;
+ }
this->ctxt = ctxt;
- if (ctxt)
- ctxt->d_func()->childExpressions.insert(q);
+ if (ctxt) {
+ QmlContextPrivate *cp = ctxt->d_func();
+ nextExpression = cp->expressions;
+ prevExpression = &cp->expressions;
+ cp->expressions = this;
+ }
this->me = me;
}
@@ -144,8 +160,11 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expression,
QmlExpression::~QmlExpression()
{
Q_D(QmlExpression);
- if (d->ctxt)
- d->ctxt->d_func()->childExpressions.remove(this);
+ if (d->prevExpression) {
+ *(d->prevExpression) = d->nextExpression;
+ if (d->nextExpression)
+ d->nextExpression->prevExpression = d->prevExpression;
+ }
}
/*!
@@ -203,6 +222,7 @@ void QmlExpression::setExpression(const QString &expression)
d->expression = expression;
d->expressionFunctionValid = false;
+ d->expressionRewritten = false;
d->expressionFunction = QScriptValue();
d->sse.clear();
@@ -250,10 +270,15 @@ QVariant QmlExpressionPrivate::evalQtScript()
scriptEngine->currentContext()->pushScope(ctxtPriv->scopeChain.at(i));
if (!expressionFunctionValid) {
- QmlRewrite::RewriteBinding rewriteBinding;
- const QString code = rewriteBinding(expression);
- expressionFunction = scriptEngine->evaluate(code, fileName, line);
+ if (expressionRewritten) {
+ expressionFunction = scriptEngine->evaluate(expression, fileName, line);
+ } else {
+ QmlRewrite::RewriteBinding rewriteBinding;
+
+ const QString code = rewriteBinding(expression);
+ expressionFunction = scriptEngine->evaluate(code, fileName, line);
+ }
expressionFunctionValid = true;
}
diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h
index d5f0cbb..c295a1c 100644
--- a/src/declarative/qml/qmlexpression.h
+++ b/src/declarative/qml/qmlexpression.h
@@ -97,7 +97,6 @@ private Q_SLOTS:
private:
Q_DECLARE_PRIVATE(QmlExpression)
- friend class QmlExpressionBindProxy;
friend class QmlDebugger;
friend class QmlContext;
};
diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h
index cb89ce0..f607898 100644
--- a/src/declarative/qml/qmlexpression_p.h
+++ b/src/declarative/qml/qmlexpression_p.h
@@ -70,12 +70,22 @@ public:
QmlExpressionPrivate();
~QmlExpressionPrivate();
+ // Forms the QmlContext "expressions" linked list
+ QmlExpressionPrivate *nextExpression;
+ QmlExpressionPrivate **prevExpression;
+
+ enum CompiledDataType {
+ BasicScriptEngineData = 1,
+ PreTransformedQtScriptData = 2
+ };
+
void init(QmlContext *, const QString &, QObject *);
void init(QmlContext *, void *, QmlRefCount *, QObject *);
QmlContext *ctxt;
QString expression;
- bool expressionFunctionValid;
+ bool expressionFunctionValid:1;
+ bool expressionRewritten:1;
QScriptValue expressionFunction;
QmlBasicScript sse;
diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index 9f77bc0..889a057 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -140,9 +140,6 @@ void QmlCompiledData::dump(QmlInstruction *instr, int idx)
case QmlInstruction::AssignCustomType:
qWarning() << idx << "\t" << line << "\t" << "ASSIGN_CUSTOMTYPE\t\t" << instr->assignCustomType.propertyIndex << "\t" << instr->assignCustomType.valueIndex;
break;
- case QmlInstruction::StoreBinding:
- qWarning() << idx << "\t" << line << "\t" << "STORE_BINDING\t\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t\t" << instr->assignBinding.context << primitives.at(instr->assignBinding.value);
- break;
case QmlInstruction::StoreCompiledBinding:
qWarning() << idx << "\t" << line << "\t" << "STORE_COMPILED_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t\t" << instr->assignBinding.context;
break;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index d4fe68c..e6b8de6 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -124,7 +124,6 @@ public:
AssignSignalObject, /* assignSignalObject */
AssignCustomType, /* assignCustomType */
- StoreBinding, /* assignBinding */
StoreCompiledBinding, /* assignBinding */
StoreValueSource, /* assignValueSource */
@@ -163,6 +162,7 @@ public:
struct {
int bindingsSize;
int parserStatusSize;
+ int idSize;
} init;
struct {
int type;
@@ -175,6 +175,7 @@ public:
} storeMeta;
struct {
int value;
+ int index;
} setId;
struct {
int property;
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index afd28bb..350d84b 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -287,6 +287,8 @@ QmlMetaPropertyPrivate::propertyCategory() const
int type = propertyType();
if (type == QmlMetaProperty::Invalid)
category = QmlMetaProperty::InvalidProperty;
+ else if (type < QVariant::UserType)
+ category = QmlMetaProperty::Normal;
else if (type == qMetaTypeId<QmlBinding *>())
category = QmlMetaProperty::Bindable;
else if (QmlMetaType::isList(type))
diff --git a/src/declarative/qml/qmlvaluetype.cpp b/src/declarative/qml/qmlvaluetype.cpp
index ca968fc..b827572 100644
--- a/src/declarative/qml/qmlvaluetype.cpp
+++ b/src/declarative/qml/qmlvaluetype.cpp
@@ -60,11 +60,13 @@ QmlValueType *QmlValueTypeFactory::valueType(int t)
{
switch (t) {
case QVariant::Point:
- case QVariant::PointF:
return new QmlPointValueType;
+ case QVariant::PointF:
+ return new QmlPointFValueType;
case QVariant::Rect:
- case QVariant::RectF:
return new QmlRectValueType;
+ case QVariant::RectF:
+ return new QmlRectFValueType;
case QVariant::Vector3D:
return new QmlVector3DValueType;
default:
@@ -77,6 +79,43 @@ QmlValueType::QmlValueType(QObject *parent)
{
}
+QmlPointFValueType::QmlPointFValueType(QObject *parent)
+: QmlValueType(parent)
+{
+}
+
+void QmlPointFValueType::read(QObject *obj, int idx)
+{
+ void *a[] = { &point, 0 };
+ QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
+}
+
+void QmlPointFValueType::write(QObject *obj, int idx)
+{
+ void *a[] = { &point, 0 };
+ QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
+}
+
+qreal QmlPointFValueType::x() const
+{
+ return point.x();
+}
+
+qreal QmlPointFValueType::y() const
+{
+ return point.y();
+}
+
+void QmlPointFValueType::setX(qreal x)
+{
+ point.setX(x);
+}
+
+void QmlPointFValueType::setY(qreal y)
+{
+ point.setY(y);
+}
+
QmlPointValueType::QmlPointValueType(QObject *parent)
: QmlValueType(parent)
{
@@ -94,26 +133,83 @@ void QmlPointValueType::write(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
-qreal QmlPointValueType::x() const
+int QmlPointValueType::x() const
{
return point.x();
}
-qreal QmlPointValueType::y() const
+int QmlPointValueType::y() const
{
return point.y();
}
-void QmlPointValueType::setX(qreal x)
+void QmlPointValueType::setX(int x)
{
point.setX(x);
}
-void QmlPointValueType::setY(qreal y)
+void QmlPointValueType::setY(int y)
{
point.setY(y);
}
+QmlRectFValueType::QmlRectFValueType(QObject *parent)
+: QmlValueType(parent)
+{
+}
+
+void QmlRectFValueType::read(QObject *obj, int idx)
+{
+ void *a[] = { &rect, 0 };
+ QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
+}
+
+void QmlRectFValueType::write(QObject *obj, int idx)
+{
+ void *a[] = { &rect, 0 };
+ QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
+}
+
+qreal QmlRectFValueType::x() const
+{
+ return rect.x();
+}
+
+qreal QmlRectFValueType::y() const
+{
+ return rect.y();
+}
+
+void QmlRectFValueType::setX(qreal x)
+{
+ rect.moveLeft(x);
+}
+
+void QmlRectFValueType::setY(qreal y)
+{
+ rect.moveTop(y);
+}
+
+qreal QmlRectFValueType::width() const
+{
+ return rect.width();
+}
+
+qreal QmlRectFValueType::height() const
+{
+ return rect.height();
+}
+
+void QmlRectFValueType::setWidth(qreal w)
+{
+ rect.setWidth(w);
+}
+
+void QmlRectFValueType::setHeight(qreal h)
+{
+ rect.setHeight(h);
+}
+
QmlRectValueType::QmlRectValueType(QObject *parent)
: QmlValueType(parent)
{
@@ -131,42 +227,42 @@ void QmlRectValueType::write(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
-qreal QmlRectValueType::x() const
+int QmlRectValueType::x() const
{
return rect.x();
}
-qreal QmlRectValueType::y() const
+int QmlRectValueType::y() const
{
return rect.y();
}
-void QmlRectValueType::setX(qreal x)
+void QmlRectValueType::setX(int x)
{
rect.moveLeft(x);
}
-void QmlRectValueType::setY(qreal y)
+void QmlRectValueType::setY(int y)
{
rect.moveTop(y);
}
-qreal QmlRectValueType::width() const
+int QmlRectValueType::width() const
{
return rect.width();
}
-qreal QmlRectValueType::height() const
+int QmlRectValueType::height() const
{
return rect.height();
}
-void QmlRectValueType::setWidth(qreal w)
+void QmlRectValueType::setWidth(int w)
{
rect.setWidth(w);
}
-void QmlRectValueType::setHeight(qreal h)
+void QmlRectValueType::setHeight(int h)
{
rect.setHeight(h);
}
diff --git a/src/declarative/qml/qmlvaluetype_p.h b/src/declarative/qml/qmlvaluetype_p.h
index 9195c61..0c9e279 100644
--- a/src/declarative/qml/qmlvaluetype_p.h
+++ b/src/declarative/qml/qmlvaluetype_p.h
@@ -80,13 +80,13 @@ public:
QmlValueType *operator[](int idx) const { return valueTypes[idx]; }
};
-class QmlPointValueType : public QmlValueType
+class QmlPointFValueType : public QmlValueType
{
Q_PROPERTY(qreal x READ x WRITE setX);
Q_PROPERTY(qreal y READ y WRITE setY);
Q_OBJECT
public:
- QmlPointValueType(QObject *parent = 0);
+ QmlPointFValueType(QObject *parent = 0);
virtual void read(QObject *, int);
virtual void write(QObject *, int);
@@ -100,7 +100,27 @@ private:
QPointF point;
};
-class QmlRectValueType : public QmlValueType
+class QmlPointValueType : public QmlValueType
+{
+ Q_PROPERTY(int x READ x WRITE setX);
+ Q_PROPERTY(int y READ y WRITE setY);
+ Q_OBJECT
+public:
+ QmlPointValueType(QObject *parent = 0);
+
+ virtual void read(QObject *, int);
+ virtual void write(QObject *, int);
+
+ int x() const;
+ int y() const;
+ void setX(int);
+ void setY(int);
+
+private:
+ QPoint point;
+};
+
+class QmlRectFValueType : public QmlValueType
{
Q_PROPERTY(qreal x READ x WRITE setX);
Q_PROPERTY(qreal y READ y WRITE setY);
@@ -108,7 +128,7 @@ class QmlRectValueType : public QmlValueType
Q_PROPERTY(qreal height READ height WRITE setHeight);
Q_OBJECT
public:
- QmlRectValueType(QObject *parent = 0);
+ QmlRectFValueType(QObject *parent = 0);
virtual void read(QObject *, int);
virtual void write(QObject *, int);
@@ -127,6 +147,33 @@ private:
QRectF rect;
};
+class QmlRectValueType : public QmlValueType
+{
+ Q_PROPERTY(int x READ x WRITE setX);
+ Q_PROPERTY(int y READ y WRITE setY);
+ Q_PROPERTY(int width READ width WRITE setWidth);
+ Q_PROPERTY(int height READ height WRITE setHeight);
+ Q_OBJECT
+public:
+ QmlRectValueType(QObject *parent = 0);
+
+ virtual void read(QObject *, int);
+ virtual void write(QObject *, int);
+
+ int x() const;
+ int y() const;
+ void setX(int);
+ void setY(int);
+
+ int width() const;
+ int height() const;
+ void setWidth(int);
+ void setHeight(int);
+
+private:
+ QRect rect;
+};
+
class QmlVector3DValueType : public QmlValueType
{
Q_PROPERTY(qreal x READ x WRITE setX);
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index ee41fe4..bf3b31a 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -64,6 +64,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/qvarlengtharray.h>
#include <private/qmlbinding_p.h>
+#include <private/qmlcontext_p.h>
QT_BEGIN_NAMESPACE
@@ -144,6 +145,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
vmeErrors.clear();
QmlEnginePrivate *ep = QmlEnginePrivate::get(ctxt->engine());
+ QmlContextPrivate *cp = (QmlContextPrivate *)QObjectPrivate::get(ctxt);
for (int ii = start; !isError() && ii < (start + count); ++ii) {
QmlInstruction &instr = comp->bytecode[ii];
@@ -155,6 +157,9 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
bindValues = QmlEnginePrivate::SimpleList<QmlBinding>(instr.init.bindingsSize);
if (instr.init.parserStatusSize)
parserStatus = QmlEnginePrivate::SimpleList<QmlParserStatus>(instr.init.parserStatusSize);
+
+ if (instr.init.idSize)
+ cp->setIdPropertyCount(instr.init.idSize);
}
break;
@@ -194,7 +199,8 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
case QmlInstruction::SetId:
{
QObject *target = stack.top();
- ctxt->setContextProperty(primitives.at(instr.setId.value), target);
+// ctxt->setContextProperty(primitives.at(instr.setId.value), target);
+ cp->setIdProperty(primitives.at(instr.setId.value), instr.setId.index, target);
}
break;
@@ -543,28 +549,6 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
}
break;
- case QmlInstruction::StoreBinding:
- {
- QObject *target =
- stack.at(stack.count() - 1 - instr.assignBinding.owner);
- QObject *context =
- stack.at(stack.count() - 1 - instr.assignBinding.context);
-
- QmlMetaProperty mp;
- mp.restore(instr.assignBinding.property, target, ctxt);
-
- QmlBinding *bind = new QmlBinding(primitives.at(instr.assignBinding.value), context, ctxt);
- bindValues.append(bind);
- QmlBindingPrivate *p =
- static_cast<QmlBindingPrivate *>(QObjectPrivate::get(bind));
- p->mePtr = &bindValues.values[bindValues.count - 1];
- QFx_setParent_noEvent(bind, target);
-
- bind->setTarget(mp);
- bind->setSourceLocation(comp->url, instr.line);
- }
- break;
-
case QmlInstruction::StoreValueSource:
{
QmlPropertyValueSource *vs =