diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2012-05-11 12:01:41 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-05-24 12:52:43 +0200 |
commit | d2e557c2c2d7fcf3bf7c1676df3902e115986dc2 (patch) | |
tree | 65f47e443efa9635a2634880c01dc439817f9566 /src/qml/qml/v4 | |
parent | 0a3ff88f851771e52d119fab90c0254de6950585 (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.cpp | 23 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4compiler.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4ir.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4ir_p.h | 11 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4irbuilder.cpp | 46 |
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); } |