summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-05-26 06:39:12 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-05-26 06:39:12 (GMT)
commit6fb3a8884701b3a08607d0d8ec2e67fabf56d468 (patch)
tree334cc85e7565fedfddb73357dcdbe22a37f42cf3
parent3aff93a5bba79bdf45f13e4c9f8c66c9a9ed47b4 (diff)
downloadQt-6fb3a8884701b3a08607d0d8ec2e67fabf56d468.zip
Qt-6fb3a8884701b3a08607d0d8ec2e67fabf56d468.tar.gz
Qt-6fb3a8884701b3a08607d0d8ec2e67fabf56d468.tar.bz2
Remove AssignObject instruction
-rw-r--r--src/declarative/qml/qmlcompiler.cpp65
-rw-r--r--src/declarative/qml/qmlinstruction.cpp3
-rw-r--r--src/declarative/qml/qmlinstruction_p.h3
-rw-r--r--src/declarative/qml/qmlvme.cpp142
-rw-r--r--tests/auto/declarative/qmlparser/assignObjectToVariant.txt4
-rw-r--r--tests/auto/declarative/qmlparser/tst_qmlparser.cpp10
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"));