diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-05-26 06:39:12 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-05-26 06:39:12 (GMT) |
commit | 6fb3a8884701b3a08607d0d8ec2e67fabf56d468 (patch) | |
tree | 334cc85e7565fedfddb73357dcdbe22a37f42cf3 | |
parent | 3aff93a5bba79bdf45f13e4c9f8c66c9a9ed47b4 (diff) | |
download | Qt-6fb3a8884701b3a08607d0d8ec2e67fabf56d468.zip Qt-6fb3a8884701b3a08607d0d8ec2e67fabf56d468.tar.gz Qt-6fb3a8884701b3a08607d0d8ec2e67fabf56d468.tar.bz2 |
Remove AssignObject instruction
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 65 | ||||
-rw-r--r-- | src/declarative/qml/qmlinstruction.cpp | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlinstruction_p.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlvme.cpp | 142 | ||||
-rw-r--r-- | tests/auto/declarative/qmlparser/assignObjectToVariant.txt | 4 | ||||
-rw-r--r-- | tests/auto/declarative/qmlparser/tst_qmlparser.cpp | 10 |
6 files changed, 85 insertions, 142 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 73c50e8..1022028 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -1102,8 +1102,40 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop, { if (v->object->type != -1) v->object->metatype = output->types.at(v->object->type).metaObject(); + Q_ASSERT(v->object->metaObject()); - if (v->object->metaObject()) { + if (prop->index == -1) + COMPILE_EXCEPTION2(prop, "Cannot assign object to non-existant property" << prop->name); + + + if (QmlMetaType::isInterface(prop->type)) { + + COMPILE_CHECK(compileObject(v->object, ctxt)); + + QmlInstruction assign; + assign.type = QmlInstruction::StoreInterface; + assign.line = v->object->location.start.line; + assign.storeObject.propertyIndex = prop->index; + assign.storeObject.cast = 0; + output->bytecode << assign; + + v->type = Value::CreatedObject; + + } else if (prop->type == -1) { + + // Variant + // ### Is it always? + COMPILE_CHECK(compileObject(v->object, ctxt)); + + QmlInstruction assign; + assign.type = QmlInstruction::StoreVariantObject; + assign.line = v->object->location.start.line; + assign.storeObject.propertyIndex = prop->index; + assign.storeObject.cast = 0; + output->bytecode << assign; + + v->type = Value::CreatedObject; + } else { const QMetaObject *propmo = QmlMetaType::rawMetaObjectForType(prop->type); @@ -1128,22 +1160,7 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop, } } - if (!propmo && !isPropertyValue) { - COMPILE_CHECK(compileObject(v->object, ctxt)); - - QmlInstruction assign; - assign.type = QmlInstruction::AssignObject; - assign.line = v->object->location.start.line; - assign.assignObject.castValue = 0; - if (prop->isDefault) - assign.assignObject.property = -1; - else - assign.assignObject.property = - output->indexForByteArray(prop->name); - output->bytecode << assign; - - v->type = Value::CreatedObject; - } else if (isAssignable) { + if (isAssignable) { COMPILE_CHECK(compileObject(v->object, ctxt)); QmlInstruction assign; @@ -1187,20 +1204,8 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop, v->type = Value::ValueSource; } else { - COMPILE_EXCEPTION("Unassignable object"); + COMPILE_EXCEPTION2(v->object, "Unassignable object"); } - - } else { - COMPILE_CHECK(compileObject(v->object, ctxt)); - - QmlInstruction assign; - assign.type = QmlInstruction::AssignObject; - assign.line = v->object->location.start.line; - assign.assignObject.property = output->indexForByteArray(prop->name); - assign.assignObject.castValue = 0; - output->bytecode << assign; - - v->type = Value::CreatedObject; } return true; diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp index 143dc9b..99f6253 100644 --- a/src/declarative/qml/qmlinstruction.cpp +++ b/src/declarative/qml/qmlinstruction.cpp @@ -145,9 +145,6 @@ void QmlCompiledComponent::dump(QmlInstruction *instr, int idx) case QmlInstruction::CompleteObject: qWarning() << idx << "\t" << line << "\t" << "COMPLETE\t\t" << instr->complete.castValue; break; - case QmlInstruction::AssignObject: - qWarning() << idx << "\t" << line << "\t" << "ASSIGN_OBJECT\t\t" << instr->assignObject.property << "\t" << instr->assignObject.castValue << "\t\t" << ((instr->assignObject.property == -1)?QByteArray("default"):datas.at(instr->assignObject.property)); - break; case QmlInstruction::AssignObjectList: qWarning() << idx << "\t" << line << "\t" << "ASSIGN_OBJECT_LIST\t" << instr->assignObject.property << "\t" << instr->assignObject.castValue << "\t\t" << ((instr->assignObject.property == -1)?QByteArray("default"):datas.at(instr->assignObject.property)); break; diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h index a2f7ede..8959794 100644 --- a/src/declarative/qml/qmlinstruction_p.h +++ b/src/declarative/qml/qmlinstruction_p.h @@ -100,6 +100,8 @@ public: StoreVariant, /* storeString */ StoreObject, /* storeObject */ StoreInstructionsEnd = StoreObject, + StoreVariantObject, /* storeObject */ + StoreInterface, /* storeObject */ StoreSignal, /* storeSignal */ @@ -121,7 +123,6 @@ public: BeginObject, /* begin */ CompleteObject, /* complete */ - AssignObject, /* assignObject */ AssignObjectList, /* assignObject */ FetchAttached, /* fetchAttached */ diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 2a5a042..299b969 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -94,7 +94,6 @@ Q_DECLARE_PERFORMANCE_LOG(QFxCompiler) { Q_DECLARE_PERFORMANCE_METRIC(InstrStoreValueSource); Q_DECLARE_PERFORMANCE_METRIC(InstrBeginObject); Q_DECLARE_PERFORMANCE_METRIC(InstrCompleteObject); - Q_DECLARE_PERFORMANCE_METRIC(InstrAssignObject); Q_DECLARE_PERFORMANCE_METRIC(InstrAssignObjectList); Q_DECLARE_PERFORMANCE_METRIC(InstrFetchAttached); Q_DECLARE_PERFORMANCE_METRIC(InstrFetchQmlList); @@ -138,7 +137,6 @@ Q_DEFINE_PERFORMANCE_LOG(QFxCompiler, "QFxCompiler") { Q_DEFINE_PERFORMANCE_METRIC(InstrStoreValueSource, "StoreValueSource"); Q_DEFINE_PERFORMANCE_METRIC(InstrBeginObject, "BeginObject"); Q_DEFINE_PERFORMANCE_METRIC(InstrCompleteObject, "CompleteObject"); - Q_DEFINE_PERFORMANCE_METRIC(InstrAssignObject, "AssignObject"); Q_DEFINE_PERFORMANCE_METRIC(InstrAssignObjectList, "AssignObjectList"); Q_DEFINE_PERFORMANCE_METRIC(InstrFetchAttached, "FetchAttached"); Q_DEFINE_PERFORMANCE_METRIC(InstrFetchQmlList, "FetchQmlList"); @@ -369,10 +367,14 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in QMetaObject::connect(target, prop.coreIndex(), assign, method.methodIndex()); } else if (prop.type() & QmlMetaProperty::Property) { + // ### FIXME + /* instr.type = QmlInstruction::AssignObject; instr.assignObject.castValue = 0; instr.assignObject.property = sigIdx; --ii; + */ + VME_EXCEPTION("Cannot assign an object to signal property" << pr); } else { VME_EXCEPTION("Cannot assign an object to signal property" << pr); } @@ -589,122 +591,46 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in } break; - case QmlInstruction::AssignObject: + case QmlInstruction::StoreVariantObject: { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QFxCompilerTimer<QFxCompiler::InstrAssignObject> cc; -#endif QObject *assign = stack.pop(); QObject *target = stack.top(); - QByteArray property; - if (instr.assignObject.property == -1) { - // XXX - optimize! - property = - QmlMetaType::defaultProperty(target).name(); - } else { - property = datas.at(instr.assignObject.property); - } - - int coreIdx = qIndexOfProperty(target, property); - - if (coreIdx != -1) { - QMetaProperty prop = - target->metaObject()->property(coreIdx); - int t = prop.userType(); - // XXX - optimize! - if (QmlMetaType::isList(t)) { - QVariant list = prop.read(target); - int listtype = QmlMetaType::listType(t); - QVariant v = QmlMetaType::fromObject(assign, listtype); - QmlMetaType::append(list, v); - } else if (QmlMetaType::isQmlList(t)) { - - // XXX - optimize! - QVariant list = prop.read(target); - QmlPrivate::ListInterface *li = - *(QmlPrivate::ListInterface **)list.constData(); - - int type = li->type(); - - const QMetaObject *mo = - QmlMetaType::rawMetaObjectForType(type); - - const QMetaObject *assignMo = assign->metaObject(); - bool found = false; - while(!found && assignMo) { - if (assignMo == mo) - found = true; - else - assignMo = assignMo->superClass(); - } - - if (!found) - VME_EXCEPTION("Cannot assign object to list"); - - // NOTE: This assumes a cast to QObject does not alter - // the object pointer - void *d = (void *)&assign; - li->append(d); - - } else if (QmlMetaType::isInterface(t)) { - const char *iid = QmlMetaType::interfaceIId(t); - bool ok = false; - if (iid) { - void *ptr = assign->qt_metacast(iid); - if (ptr) { - void *a[1]; - a[0] = &ptr; - QMetaObject::metacall(target, QMetaObject::WriteProperty, - coreIdx, a); - ok = true; - } - } - - if (!ok) - VME_EXCEPTION("Cannot assign object to interface property" << property); - - } else if (prop.userType() == -1 /* means qvariant */) { - prop.write(target, qVariantFromValue(assign)); - } else { - const QMetaObject *propmo = - QmlMetaType::rawMetaObjectForType(t); - - bool isPropertyValue = false; - bool isAssignable = false; - const QMetaObject *c = assign->metaObject(); - while(c) { - isPropertyValue = isPropertyValue || (c == &QmlPropertyValueSource::staticMetaObject); - isAssignable = isAssignable || (c == propmo); - c = c->superClass(); - } - - if (isAssignable) { - // XXX - optimize! - QVariant v = QmlMetaType::fromObject(assign, t); - prop.write(target, v); - } else if (isPropertyValue) { - QmlPropertyValueSource *vs = - static_cast<QmlPropertyValueSource *>(assign); - vs->setParent(target); - vs->setTarget(QmlMetaProperty(target, coreIdx)); - } else { - VME_EXCEPTION("Cannot assign to" << property); - } - } + QVariant v = QVariant::fromValue(assign); + void *a[1]; + a[0] = (void *)&v; + QMetaObject::metacall(target, QMetaObject::WriteProperty, + instr.storeObject.propertyIndex, a); + } + break; + case QmlInstruction::StoreInterface: + { + QObject *assign = stack.pop(); + QObject *target = stack.top(); - } else { - if (instr.assignObject.property == -1) { - VME_EXCEPTION("Cannot assign to default property"); - } else { - VME_EXCEPTION("Cannot assign to non-existant property" << property); + int coreIdx = instr.storeObject.propertyIndex; + QMetaProperty prop = target->metaObject()->property(coreIdx); + int t = prop.userType(); + const char *iid = QmlMetaType::interfaceIId(t); + bool ok = false; + if (iid) { + void *ptr = assign->qt_metacast(iid); + if (ptr) { + void *a[1]; + a[0] = &ptr; + QMetaObject::metacall(target, + QMetaObject::WriteProperty, + coreIdx, a); + ok = true; } - } + } + if (!ok) + VME_EXCEPTION("Cannot assign object to interface property"); } break; - + case QmlInstruction::FetchAttached: { #ifdef Q_ENABLE_PERFORMANCE_LOG diff --git a/tests/auto/declarative/qmlparser/assignObjectToVariant.txt b/tests/auto/declarative/qmlparser/assignObjectToVariant.txt new file mode 100644 index 0000000..180221d --- /dev/null +++ b/tests/auto/declarative/qmlparser/assignObjectToVariant.txt @@ -0,0 +1,4 @@ +Object { + property var a; + a: MyQmlObject {} +} diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp index 0852d35..cdc2a72 100644 --- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp +++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp @@ -26,6 +26,7 @@ private slots: void interfaceQmlList(); void interfaceQList(); void assignObjectToSignal(); + void assignObjectToVariant(); void assignLiteralSignalProperty(); void assignQmlComponent(); void assignBasicTypes(); @@ -208,6 +209,15 @@ void tst_qmlparser::assignObjectToSignal() emit object->basicSignal(); } +void tst_qmlparser::assignObjectToVariant() +{ + QmlComponent component(&engine, TEST_FILE("assignObjectToVariant.txt")); + QObject *object = component.create(); + QVERIFY(object != 0); + QVariant v = object->property("a"); + QVERIFY(v.userType() == qMetaTypeId<QObject *>()); +} + void tst_qmlparser::assignLiteralSignalProperty() { QmlComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.txt")); |