aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/v4
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2012-05-11 12:01:41 +0100
committerQt by Nokia <qt-info@nokia.com>2012-05-24 12:52:43 +0200
commitd2e557c2c2d7fcf3bf7c1676df3902e115986dc2 (patch)
tree65f47e443efa9635a2634880c01dc439817f9566 /src/qml/qml/v4
parent0a3ff88f851771e52d119fab90c0254de6950585 (diff)
Lazily create QMetaObjects
For internal QML built types, creating a metaobject each time is just wasteful. Additionally, as the property caches were always created from the intermediate QMetaObject, it was difficult to pass information directly from the compiler to the property cache. Change-Id: I769526b0edaaf16a86883f3065b75618b94e4077 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/qml/qml/v4')
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp23
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp2
-rw-r--r--src/qml/qml/v4/qv4ir.cpp8
-rw-r--r--src/qml/qml/v4/qv4ir_p.h11
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp46
5 files changed, 49 insertions, 41 deletions
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index 3c03edbca6..95eb0b9984 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -424,7 +424,7 @@ void QV4Bindings::run(Binding *binding, QQmlPropertyPrivate::WriteFlags flags)
QQmlData *data = QQmlData::get(*binding->target);
QQmlPropertyData *propertyData = (data && data->propertyCache ? data->propertyCache->property(binding->property) : 0);
- if (propertyData && propertyData->isVMEProperty()) {
+ if (propertyData && propertyData->isVarProperty()) {
// We will allocate a V8 handle in this conversion/store
v8::HandleScope handle_scope;
v8::Context::Scope context_scope(QQmlEnginePrivate::get(context->engine)->v8engine()->context());
@@ -2116,18 +2116,27 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
if (data.gettype() == QObjectStarType) {
if (QObject *dataObject = data.getQObject()) {
- const QMetaObject *dataMo = dataObject->metaObject();
+ QQmlMetaObject dataMo(dataObject);
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine);
- QMetaProperty receiver = output->metaObject()->property(instr->store.index);
- const QMetaObject *receiverMo = QQmlPropertyPrivate::rawMetaObjectForType(ep, receiver.userType());
+
+ QQmlMetaObject receiverMo;
+
+ if (QQmlData::get(output, false) && QQmlData::get(output, false)->propertyCache) {
+ QQmlPropertyData *receiver =
+ QQmlData::get(output, false)->propertyCache->property(instr->store.index);
+ receiverMo = ep->rawMetaObjectForType(receiver->propType);
+ } else {
+ QMetaProperty receiver = output->metaObject()->property(instr->store.index);
+ receiverMo = ep->rawMetaObjectForType(receiver.userType());
+ }
// Verify that these types are compatible
- if (!QQmlPropertyPrivate::canConvert(dataMo, receiverMo)) {
+ if (!QQmlMetaObject::canConvert(dataMo, receiverMo)) {
THROW_EXCEPTION_STR(instr->store.exceptionId, QLatin1String("Unable to assign ") +
- QLatin1String(dataMo->className()) +
+ QLatin1String(dataMo.className()) +
QLatin1String(" to ") +
- QLatin1String(receiverMo->className()));
+ QLatin1String(receiverMo.className()));
}
}
}
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index 1c163364a3..bac1f2c131 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -386,7 +386,7 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
default:
if (propTy == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
regType = PODValueType;
- } else if (engine->metaObjectForType(propTy)) {
+ } else if (!engine->metaObjectForType(propTy).isNull()) {
regType = QObjectStarType;
} else {
if (qmlVerboseCompiler())
diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp
index bb4a0d8df0..ed25f28fa3 100644
--- a/src/qml/qml/v4/qv4ir.cpp
+++ b/src/qml/qml/v4/qv4ir.cpp
@@ -496,7 +496,7 @@ Name *BasicBlock::NAME(Name *base, const QString &id, quint32 line, quint32 colu
return e;
}
-Name *BasicBlock::SYMBOL(Type type, const QString &id, const QMetaObject *meta, QQmlPropertyData *property, Name::Storage storage,
+Name *BasicBlock::SYMBOL(Type type, const QString &id, const QQmlMetaObject &meta, QQmlPropertyData *property, Name::Storage storage,
quint32 line, quint32 column)
{
Name *name = SYMBOL(/*base = */ 0, type, id, meta, property, line, column);
@@ -504,7 +504,7 @@ Name *BasicBlock::SYMBOL(Type type, const QString &id, const QMetaObject *meta,
return name;
}
-Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, QQmlPropertyData *property, Name::Storage storage,
+Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QQmlMetaObject &meta, QQmlPropertyData *property, Name::Storage storage,
quint32 line, quint32 column)
{
Name *name = function->pool->New<Name>();
@@ -516,7 +516,7 @@ Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QMetaOb
return name;
}
-Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, QQmlPropertyData *property,
+Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QQmlMetaObject &meta, QQmlPropertyData *property,
quint32 line, quint32 column)
{
Name *name = function->pool->New<Name>();
@@ -551,7 +551,7 @@ Name *BasicBlock::ATTACH_TYPE(const QString &id, const QQmlType *attachType, Nam
return name;
}
-Name *BasicBlock::MODULE_OBJECT(const QString &id, const QMetaObject *meta, Name::Storage storage,
+Name *BasicBlock::MODULE_OBJECT(const QString &id, const QQmlMetaObject &meta, Name::Storage storage,
quint32 line, quint32 column)
{
Name *name = function->pool->New<Name>();
diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h
index 982acc5a44..9b36762356 100644
--- a/src/qml/qml/v4/qv4ir_p.h
+++ b/src/qml/qml/v4/qv4ir_p.h
@@ -275,10 +275,11 @@ struct Name: Expr {
Symbol symbol;
union {
void *ptr;
- const QMetaObject *meta;
const QQmlType *declarativeType;
const QQmlScript::Object *idObject;
};
+
+ QQmlMetaObject meta;
QQmlPropertyData *property;
Storage storage;
BuiltinSymbol builtin;
@@ -539,12 +540,12 @@ struct BasicBlock {
Name *NAME(const QString &id, quint32 line, quint32 column);
Name *NAME(Name *base, const QString &id, quint32 line, quint32 column);
- Name *SYMBOL(Type type, const QString &id, const QMetaObject *meta, QQmlPropertyData *property, Name::Storage storage, quint32 line, quint32 column);
- Name *SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, QQmlPropertyData *property, quint32 line, quint32 column);
- Name *SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, QQmlPropertyData *property, Name::Storage storage, quint32 line, quint32 column);
+ Name *SYMBOL(Type type, const QString &id, const QQmlMetaObject &meta, QQmlPropertyData *property, Name::Storage storage, quint32 line, quint32 column);
+ Name *SYMBOL(Name *base, Type type, const QString &id, const QQmlMetaObject &meta, QQmlPropertyData *property, quint32 line, quint32 column);
+ Name *SYMBOL(Name *base, Type type, const QString &id, const QQmlMetaObject &meta, QQmlPropertyData *property, Name::Storage storage, quint32 line, quint32 column);
Name *ID_OBJECT(const QString &id, const QQmlScript::Object *object, quint32 line, quint32 column);
Name *ATTACH_TYPE(const QString &id, const QQmlType *attachType, Name::Storage storage, quint32 line, quint32 column);
- Name *MODULE_OBJECT(const QString &id, const QMetaObject *meta, Name::Storage storage, quint32 line, quint32 column);
+ Name *MODULE_OBJECT(const QString &id, const QQmlMetaObject &meta, Name::Storage storage, quint32 line, quint32 column);
Expr *UNOP(AluOp op, Expr *expr);
Expr *BINOP(AluOp op, Expr *left, Expr *right);
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 47acaaf67c..354a8cd70c 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
using namespace QQmlJS;
-static IR::Type irTypeFromVariantType(int t, QQmlEnginePrivate *engine, const QMetaObject * /* meta */)
+static IR::Type irTypeFromVariantType(int t, QQmlEnginePrivate *engine)
{
switch (t) {
case QMetaType::Bool:
@@ -81,7 +81,7 @@ static IR::Type irTypeFromVariantType(int t, QQmlEnginePrivate *engine, const QM
default:
if (t == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
return IR::SGAnchorLineType;
- } else if (engine->metaObjectForType(t)) {
+ } else if (!engine->metaObjectForType(t).isNull()) {
return IR::ObjectType;
} else if (t == qMetaTypeId<QJSValue>()) {
return IR::JSValueType;
@@ -125,9 +125,9 @@ bool QV4IRBuilder::operator()(QQmlJS::IR::Function *function,
// This is the only operation where variant is supported:
QQmlPropertyData *data = &m_expression->property->core;
if (data->propType == QMetaType::QVariant) {
- targetType = (data->isVMEProperty() ? IR::VarType : IR::VariantType);
+ targetType = (data->isVarProperty() ? IR::VarType : IR::VariantType);
} else {
- targetType = irTypeFromVariantType(data->propType, m_engine, 0);
+ targetType = irTypeFromVariantType(data->propType, m_engine);
}
if (targetType != r.type()) {
@@ -462,8 +462,7 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
if (m_expression->context != m_expression->component) {
// RootStorage is more efficient than ScopeStorage, so prefer that if they are the same
QQmlPropertyCache *cache = m_expression->context->synthCache;
- const QMetaObject *metaObject = m_expression->context->metaObject();
- if (!cache) cache = m_engine->cache(metaObject);
+ if (!cache) cache = m_expression->context->metatype;
QQmlPropertyData *data = cache->property(name);
@@ -475,16 +474,15 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
}
if (data && !data->isFunction()) {
- IR::Type irType = irTypeFromVariantType(data->propType, m_engine, metaObject);
- _expr.code = _block->SYMBOL(irType, name, metaObject, data, IR::Name::ScopeStorage, line, column);
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine);
+ _expr.code = _block->SYMBOL(irType, name, QQmlMetaObject(), data, IR::Name::ScopeStorage, line, column);
found = true;
}
}
if (!found) {
QQmlPropertyCache *cache = m_expression->component->synthCache;
- const QMetaObject *metaObject = m_expression->component->metaObject();
- if (!cache) cache = m_engine->cache(metaObject);
+ if (!cache) cache = m_expression->component->metatype;
QQmlPropertyData *data = cache->property(name);
@@ -496,8 +494,8 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
}
if (data && !data->isFunction()) {
- IR::Type irType = irTypeFromVariantType(data->propType, m_engine, metaObject);
- _expr.code = _block->SYMBOL(irType, name, metaObject, data, IR::Name::RootStorage, line, column);
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine);
+ _expr.code = _block->SYMBOL(irType, name, QQmlMetaObject(), data, IR::Name::RootStorage, line, column);
found = true;
}
}
@@ -624,7 +622,7 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
return false; // We don't know enough about this property
}
- IR::Type irType = irTypeFromVariantType(data->propType, m_engine, attachedMeta);
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine);
_expr.code = _block->SYMBOL(baseName, irType, name, attachedMeta, data, line, column);
}
break;
@@ -634,7 +632,7 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
QByteArray utf8Name = name.toUtf8();
const char *enumName = utf8Name.constData();
- const QMetaObject *meta = baseName->meta;
+ const QMetaObject *meta = baseName->meta.metaObject(); // XXX - firstCppMetaObject
bool found = false;
for (int ii = 0; !found && ii < meta->enumeratorCount(); ++ii) {
QMetaEnum e = meta->enumerator(ii);
@@ -649,7 +647,7 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
qWarning() << "*** unresolved enum:"
<< (*baseName->id + QLatin1Char('.') + ast->name.toString());
} else {
- QQmlPropertyCache *cache = m_engine->cache(baseName->meta);
+ QQmlPropertyCache *cache = baseName->meta.propertyCache(m_engine);
if (!cache) return false;
QQmlPropertyData *data = cache->property(name);
@@ -663,7 +661,7 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
return false; // We don't know enough about this property
}
- IR::Type irType = irTypeFromVariantType(data->propType, m_engine, baseName->meta);
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine);
_expr.code = _block->SYMBOL(baseName, irType, name, baseName->meta, data, line, column);
}
}
@@ -672,7 +670,7 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
case IR::Name::IdObject: {
const QQmlScript::Object *idObject = baseName->idObject;
QQmlPropertyCache *cache =
- idObject->synthCache?idObject->synthCache:m_engine->cache(idObject->metaObject());
+ idObject->synthCache?idObject->synthCache:idObject->metatype;
QQmlPropertyData *data = cache->property(name);
@@ -686,16 +684,16 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
return false;
}
- IR::Type irType = irTypeFromVariantType(data->propType, m_engine, idObject->metaObject());
- _expr.code = _block->SYMBOL(baseName, irType, name,
- idObject->metaObject(), data, line, column);
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine);
+ _expr.code = _block->SYMBOL(baseName, irType, name, QQmlMetaObject(), data, line, column);
}
break;
case IR::Name::Property:
- if (baseName->type == IR::ObjectType && baseName->meta && baseName->property->isFinal()) {
- const QMetaObject *meta = m_engine->metaObjectForType(baseName->property->propType);
- QQmlPropertyCache *cache = m_engine->cache(meta);
+ if (baseName->type == IR::ObjectType && !baseName->meta.isNull() &&
+ baseName->property->isFinal()) {
+ QQmlMetaObject meta = m_engine->metaObjectForType(baseName->property->propType);
+ QQmlPropertyCache *cache = meta.propertyCache(m_engine);
if (!cache)
return false;
@@ -707,7 +705,7 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
return false; // We don't know enough about this property
}
- IR::Type irType = irTypeFromVariantType(data->propType, m_engine, meta);
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine);
_expr.code = _block->SYMBOL(baseName, irType, name,
meta, data, line, column);
}