summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qmlvme.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qmlvme.cpp')
-rw-r--r--src/declarative/qml/qmlvme.cpp1345
1 files changed, 1345 insertions, 0 deletions
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
new file mode 100644
index 0000000..966ef8a
--- /dev/null
+++ b/src/declarative/qml/qmlvme.cpp
@@ -0,0 +1,1345 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlvme_p.h"
+#include <qfxperf.h>
+#include <private/qmlboundsignal_p.h>
+#include <private/qmlstringconverters_p.h>
+#include "private/qmetaobjectbuilder_p.h"
+#include <qml.h>
+#include <qmlcustomparser.h>
+#include <qperformancelog.h>
+#include <QStack>
+#include <private/qmlcompiledcomponent_p.h>
+#include <QColor>
+#include <QPointF>
+#include <QSizeF>
+#include <QRectF>
+#include <qmlengine.h>
+#include <qmlcontext.h>
+#include <qmlcomponent.h>
+#include <qmlbindablevalue.h>
+#include <private/qmlengine_p.h>
+#include <private/qmlcomponent_p.h>
+#include "private/qmlvmemetaobject_p.h"
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+Q_DECLARE_PERFORMANCE_LOG(QFxCompiler) {
+ Q_DECLARE_PERFORMANCE_METRIC(InstrCreateObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrCreateCustomObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrSetId);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrSetDefault);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrCreateComponent);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreMetaObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreReal);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreInteger);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreBool);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreString);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreColor);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreDate);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreDateTime);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreTime);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStorePoint);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreSize);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreVariant);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreSignal);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreObjectQmlList);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrAssignConstant);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrAssignSignal);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrAssignSignalObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrAssignBinding);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrAssignCompiledBinding);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrAssignValueSource);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreBinding);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreCompiledBinding);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreValueSource);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrTryBeginObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrBeginObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrTryCompleteObject);
+ 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);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrFetchQList);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrFetchObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrResolveFetchObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrPopFetchedObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrPopQList);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrPushProperty);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrAssignStackObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrStoreStackObject);
+ Q_DECLARE_PERFORMANCE_METRIC(InstrNoOp);
+ Q_DECLARE_PERFORMANCE_METRIC(Dummy);
+}
+
+Q_DEFINE_PERFORMANCE_LOG(QFxCompiler, "QFxCompiler") {
+ Q_DEFINE_PERFORMANCE_METRIC(InstrCreateObject, "CreateObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrCreateCustomObject, "CreateCustomObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrSetId, "SetId");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrSetDefault, "SetDefault");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrCreateComponent, "CreateComponent");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreMetaObject, "StoreMetaObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreReal, "StoreReal");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreInteger, "StoreInteger");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreBool, "StoreBool");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreString, "StoreString");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreColor, "StoreColor");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreDate, "StoreDate");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreDateTime, "StoreDateTime");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreTime, "StoreTime");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStorePoint, "StorePoint(F)");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreSize, "StoreSize(F)");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreVariant, "StoreVariant");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreObject, "StoreObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreSignal, "StoreSignal");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreObjectQmlList, "StoreObjectQmlList");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrAssignConstant, "AssignConstant");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrAssignSignal, "AssignSignal");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrAssignSignalObject, "AssignSignalObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrAssignBinding, "AssignBinding");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrAssignCompiledBinding, "AssignCompiledBinding");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrAssignValueSource, "AssignValueSource");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreBinding, "StoreBinding");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreCompiledBinding, "StoreCompiledBinding");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreValueSource, "StoreValueSource");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrTryBeginObject, "TryBeginObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrBeginObject, "BeginObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrTryCompleteObject, "TryCompleteObject");
+ 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");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrFetchQList, "FetchQList");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrFetchObject, "FetchObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrResolveFetchObject, "ResolveFetchObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrPopFetchedObject, "PopFetchedObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrPopQList, "PopQList");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrPushProperty, "PushProperty");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrAssignStackObject, "AssignStackObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrStoreStackObject, "StoreStackObject");
+ Q_DEFINE_PERFORMANCE_METRIC(InstrNoOp, "NoOp");
+ Q_DEFINE_PERFORMANCE_METRIC(Dummy, "Dummy");
+}
+
+static inline int qIndexOfProperty(QObject *o, const char *name)
+{
+ int idx = o->metaObject()->indexOfProperty(name);
+ return idx;
+}
+
+QmlVME::QmlVME()
+: exceptionLine(-1)
+{
+}
+
+#define VME_EXCEPTION(desc) \
+ { \
+ exceptionLine = instr.line; \
+ QDebug d(&exceptionDescription); \
+ d << desc; \
+ break; \
+ }
+
+struct ListInstance
+{
+ ListInstance() {}
+ ListInstance(const QVariant &l, int t)
+ : list(l), type(t), qmlListInterface(0) {}
+ ListInstance(QmlPrivate::ListInterface *q, int t)
+ : type(t), qmlListInterface(q) {}
+
+ QVariant list;
+ int type;
+ QmlPrivate::ListInterface *qmlListInterface;
+};
+
+QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, int count)
+{
+ // XXX - All instances of QmlContext::activeContext() here should be
+ // replaced with the use of ctxt. However, this cannot be done until
+ // behaviours stop modifying the active context and expecting the
+ // instantiation to notice. Instead, QmlParserStatus::beginClass() should
+ // be able to return a QmlContext that is used for expressions and
+ // sub-instances on that type.
+ Q_ASSERT(comp);
+ Q_ASSERT(ctxt);
+ const QList<QmlCompiledComponent::TypeReference> &types = comp->types;
+ const QList<QString> &primitives = comp->primitives;
+ const QList<QByteArray> &datas = comp->datas;
+ const QList<QMetaObject *> &mos = comp->mos;
+ const QList<QmlCompiledData::CustomTypeData> &customTypeData = comp->customTypeData;
+
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxPerfTimer<QFxPerf::CompileRun> cr;
+#endif
+
+ QList<QmlParserStatus *> parserStatuses;
+ QList<QmlBindableValue *> bindableValues;
+
+ QStack<QObject *> stack;
+ QStack<ListInstance> qliststack;
+
+ QStack<QmlMetaProperty> pushedProperties;
+ QObject **savedObjects = 0;
+
+ if(start == -1) start = 0;
+ if(count == -1) count = comp->bytecode.count();
+
+ for(int ii = start; !isError() && ii < (start + count); ++ii) {
+ QmlInstruction &instr = comp->bytecode[ii];
+
+ if(instr.type >= QmlInstruction::StoreInstructionsStart &&
+ instr.type <= QmlInstruction::StoreInstructionsEnd) {
+
+ runStoreInstruction(stack, instr, comp);
+
+ } else {
+
+ switch(instr.type) {
+ case QmlInstruction::Init:
+ {
+ if(instr.init.dataSize) {
+ savedObjects = new QObject*[instr.init.dataSize];
+ ::memset(savedObjects, 0,
+ sizeof(QObject *)*instr.init.dataSize);
+ }
+ }
+ break;
+
+ case QmlInstruction::CreateObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrCreateObject> cc;
+#endif
+ QObject *o = types.at(instr.create.type).createInstance();
+ if(!o)
+ VME_EXCEPTION("Unable to create object of type" << types.at(instr.create.type).className);
+
+ if(!stack.isEmpty()) {
+ QObject *parent = stack.top();
+ o->setParent(parent);
+ }
+ stack.push(o);
+ }
+ break;
+
+ case QmlInstruction::CreateCustomObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrCreateCustomObject> cc;
+#endif
+ QVariant v =
+ types.at(instr.createCustom.type).parser->create(datas.at(instr.createCustom.data));
+ // XXX
+ QObject *o = QmlMetaType::toQObject(v);
+ if(!o)
+ VME_EXCEPTION("Unable to create" << types.at(instr.create.type).className);
+
+ if(!stack.isEmpty()) {
+ QObject *parent = stack.top();
+ o->setParent(parent);
+ }
+ stack.push(o);
+ }
+ break;
+
+ case QmlInstruction::SetId:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrSetId> cc;
+#endif
+ QObject *target = stack.top();
+ QmlContext *ctxt =
+ QmlContext::activeContext();
+ ctxt->setContextProperty(primitives.at(instr.setId.value), target);
+
+ if(instr.setId.save != -1)
+ savedObjects[instr.setId.save] = target;
+ }
+ break;
+
+
+ case QmlInstruction::SetDefault:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrSetDefault> cc;
+#endif
+ QObject *target = stack.top();
+ QmlContext::activeContext()->addDefaultObject(target);
+ }
+ break;
+
+ case QmlInstruction::CreateComponent:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrCreateComponent> cc;
+#endif
+ QObject *qcomp = new QmlComponent(ctxt->engine(), comp, ii + 1, instr.createComponent.count, stack.isEmpty() ? 0 : stack.top());
+ stack.push(qcomp);
+ ii += instr.createComponent.count;
+ }
+ break;
+
+ case QmlInstruction::StoreMetaObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreMetaObject> cc;
+#endif
+ QObject *target = stack.top();
+ new QmlVMEMetaObject(target, mos.at(instr.storeMeta.data), comp);
+ }
+ break;
+
+ case QmlInstruction::AssignCustomType:
+ {
+ QObject *target = stack.top();
+ void *a[1];
+ QmlCompiledComponent::CustomTypeData data = customTypeData.at(instr.assignCustomType.valueIndex);
+ const QString &primitive = primitives.at(data.index);
+ QmlMetaType::StringConverter converter =
+ QmlMetaType::customStringConverter(data.type);
+ QVariant v = (*converter)(primitive);
+
+ QMetaProperty prop =
+ target->metaObject()->property(instr.assignCustomType.propertyIndex);
+ if (v.isNull() || ((int)prop.type() != data.type && prop.userType() != data.type))
+ VME_EXCEPTION("Cannot assign value" << primitive << "to property" << prop.name());
+
+ a[0] = (void *)v.data();
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.assignCustomType.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::AssignSignal:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrAssignSignal> cc;
+#endif
+ // Fixup instruction
+ QObject *target = stack.top();
+ int sigIdx = instr.assignSignal.signal;
+ const QByteArray &pr = datas.at(sigIdx);
+
+ QmlMetaProperty prop(target, QLatin1String(pr));
+ if(prop.type() & QmlMetaProperty::SignalProperty) {
+ int coreIdx = prop.coreIndex();
+ int primRef = instr.assignSignal.value;
+ instr.type = QmlInstruction::StoreSignal;
+ instr.storeSignal.signalIndex = coreIdx;
+ instr.storeSignal.value = primRef;
+ --ii;
+ } else if(prop.type() & QmlMetaProperty::Property) {
+ int prop = sigIdx;
+ int primRef = instr.assignSignal.value;
+ instr.type = QmlInstruction::AssignConstant;
+ instr.assignConstant.property = prop;
+ instr.assignConstant.constant = primRef;
+ --ii;
+ } else {
+ VME_EXCEPTION("Cannot assign a signal to property" << pr);
+ }
+ }
+ break;
+
+ case QmlInstruction::AssignSignalObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrAssignSignalObject> cc;
+#endif
+ // XXX optimize
+
+ QObject *assign = stack.pop();
+ QObject *target = stack.top();
+ int sigIdx = instr.assignSignalObject.signal;
+ const QByteArray &pr = datas.at(sigIdx);
+
+ QmlMetaProperty prop(target, QLatin1String(pr));
+ if(prop.type() & QmlMetaProperty::SignalProperty) {
+
+ QMetaMethod method = QmlMetaType::defaultMethod(assign);
+ if(method.signature() == 0)
+ VME_EXCEPTION("Cannot assign object type" << assign->metaObject()->className() << "with no default method");
+
+ if(!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature()))
+ VME_EXCEPTION("Cannot connect mismatched signal/slot" << method.signature() << prop.method().signature());
+
+ QMetaObject::connect(target, prop.coreIndex(), assign, method.methodIndex());
+
+ } else if(prop.type() & QmlMetaProperty::Property) {
+ instr.type = QmlInstruction::AssignObject;
+ instr.assignObject.castValue = 0;
+ instr.assignObject.property = sigIdx;
+ --ii;
+ } else {
+ VME_EXCEPTION("Cannot assign an object to signal property" << pr);
+ }
+
+
+ }
+ break;
+
+ case QmlInstruction::StoreSignal:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreSignal> cc;
+#endif
+ QObject *target = stack.top();
+ // XXX scope
+ QMetaMethod signal =
+ target->metaObject()->method(instr.storeSignal.signalIndex);
+
+ if(signal.parameterTypes().isEmpty()) {
+ (void *)new QmlBoundSignal(QmlContext::activeContext(), primitives.at(instr.storeSignal.value), target, instr.storeSignal.signalIndex, target);
+ } else {
+ (void *)new QmlBoundSignalProxy(new QmlContext(QmlContext::activeContext(), target), primitives.at(instr.storeSignal.value), target, instr.storeSignal.signalIndex, target);
+ }
+ }
+ break;
+
+ case QmlInstruction::AssignConstant:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrAssignConstant> cc;
+#endif
+ // Fixup instruction
+ QObject *target = stack.top();
+ int propIdx = instr.assignConstant.property;
+ int idx = instr.assignConstant.constant;
+ QByteArray pr;
+ if(propIdx == -1) {
+ pr = QmlMetaType::defaultProperty(target).name();
+ if(pr.isEmpty())
+ VME_EXCEPTION("Cannot resolve defalt property on type" << target->metaObject()->className());
+ } else {
+ pr = datas.at(propIdx);
+ }
+
+ int coreIdx = qIndexOfProperty(target, pr);
+
+ if(coreIdx != -1) {
+ QMetaProperty prop =
+ target->metaObject()->property(coreIdx);
+ bool replace = !prop.isDynamic();
+
+ QmlInstruction *writeInstr = 0;
+ QmlInstruction dummy;
+ if(replace) {
+ writeInstr = &instr;
+ } else {
+ writeInstr = &dummy;
+ dummy = instr;
+ }
+
+ QmlCompiler::StoreInstructionResult r = QmlCompiler::generateStoreInstruction(*comp, *writeInstr, prop,
+ coreIdx, idx, &primitives.at(idx));
+ if(r != QmlCompiler::Ok) {
+ if(prop.isEnumType()){
+ VME_EXCEPTION(primitives.at(idx) << "is not a valid enumeration value");
+ } else if (r == QmlCompiler::UnknownType) {
+ VME_EXCEPTION("Property" << prop.name() << "is of an unknown type");
+ } else if (r == QmlCompiler::InvalidData) {
+ VME_EXCEPTION("Cannot assign value" << primitives.at(idx) << "to property" << prop.name());
+ } else if (r == QmlCompiler::ReadOnly) {
+ VME_EXCEPTION("Cannot assign value" << primitives.at(idx) << "to read-only property" << prop.name());
+ } else {
+ VME_EXCEPTION("Invalid property assignment for property" << prop.name());
+ }
+ } else {
+ runStoreInstruction(stack, *writeInstr, comp);
+ }
+
+ } else {
+ VME_EXCEPTION("Unknown property" << pr);
+ }
+ }
+ break;
+
+ case QmlInstruction::TryBeginObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrTryBeginObject> cc;
+#endif
+ QObject *target = stack.top();
+ QmlParserStatus *status =
+ qobject_cast<QmlParserStatus *>(target);
+
+ if(status) {
+ instr.type = QmlInstruction::BeginObject;
+ instr.begin.castValue = int(reinterpret_cast<char *>(status) - reinterpret_cast<char *>(target));
+ --ii;
+ } else {
+ instr.type = QmlInstruction::NoOp;
+ }
+ }
+ break;
+
+ case QmlInstruction::BeginObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrBeginObject> cc;
+#endif
+ QObject *target = stack.top();
+ QmlParserStatus *status = reinterpret_cast<QmlParserStatus *>(reinterpret_cast<char *>(target) + instr.begin.castValue);
+ status->classBegin();
+ parserStatuses << status;
+ }
+ break;
+
+ case QmlInstruction::TryCompleteObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrTryCompleteObject> cc;
+#endif
+ QObject *target = stack.top();
+ QmlParserStatus *status =
+ qobject_cast<QmlParserStatus *>(target);
+
+ if(status) {
+ instr.type = QmlInstruction::CompleteObject;
+ instr.complete.castValue = int(reinterpret_cast<char *>(status) - reinterpret_cast<char *>(target));
+ --ii;
+ } else {
+ instr.type = QmlInstruction::NoOp;
+ }
+ }
+ break;
+
+ case QmlInstruction::CompleteObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrCompleteObject> cc;
+#endif
+ QObject *target = stack.top();
+ QmlParserStatus *status = reinterpret_cast<QmlParserStatus *>(reinterpret_cast<char *>(target) + instr.complete.castValue);
+ status->classComplete();
+ }
+ break;
+
+ case QmlInstruction::AssignCompiledBinding:
+ case QmlInstruction::AssignBinding:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrAssignBinding> cc;
+#endif
+ QObject *target = stack.top();
+ const QByteArray &pr = datas.at(instr.fetch.property);
+ int idx = qIndexOfProperty(target, pr);
+
+ // XXX - need to check if the type is QmlBindableValue*
+ if(idx == -1) {
+ VME_EXCEPTION("Unknown property" << pr);
+ } else {
+ if(QmlInstruction::AssignCompiledBinding == instr.type)
+ instr.type = QmlInstruction::StoreCompiledBinding;
+ else
+ instr.type = QmlInstruction::StoreBinding;
+ instr.assignBinding.property = idx;
+ instr.assignBinding.category = QmlMetaProperty::Unknown;
+ }
+ ii--;
+ }
+ break;
+
+ case QmlInstruction::AssignValueSource:
+ {
+ QObject *target = stack.at(stack.count() - 2);
+ int propIdx = instr.assignValueSource.property;
+ QByteArray pr;
+ if(propIdx == -1) {
+ pr = QmlMetaType::defaultProperty(target).name();
+ if(pr.isEmpty())
+ VME_EXCEPTION("Unable to resolve default property");
+ } else {
+ pr = datas.at(propIdx);
+ }
+
+ int coreIdx = qIndexOfProperty(target, pr);
+ if(coreIdx != -1) {
+ instr.type = QmlInstruction::StoreValueSource;
+ instr.assignValueSource.property = coreIdx;
+ ii--;
+ } else {
+ VME_EXCEPTION("Unknown property" << pr);
+ }
+ }
+ break;
+
+ case QmlInstruction::PushProperty:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrPushProperty> cc;
+#endif
+ QObject *target = stack.top();
+ QmlMetaProperty mp(target, instr.pushProperty.property,
+ QmlMetaProperty::Object);
+ pushedProperties.push(mp);
+ }
+ break;
+
+ case QmlInstruction::StoreCompiledBinding:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreCompiledBinding> cc;
+#endif
+ QObject *target = stack.top();
+ QObject *context =
+ stack.at(stack.count() - 1 - instr.assignBinding.context);
+
+ QmlMetaProperty mp(target, instr.assignBinding.property,
+ (QmlMetaProperty::PropertyCategory)instr.assignBinding.category);
+ if (!mp.isWritable())
+ VME_EXCEPTION("Cannot assign a binding to read-only property" << mp.name());
+
+ QmlBindableValue *bind = new QmlBindableValue((void *)datas.at(instr.assignBinding.value).constData(), comp, context, 0);
+ QFx_setParent_noEvent(bind, target);
+
+ bind->setTarget(mp);
+ bindableValues << bind;
+ }
+ break;
+
+ case QmlInstruction::StoreBinding:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreBinding> cc;
+#endif
+ QObject *target = stack.top();
+ QObject *context =
+ stack.at(stack.count() - 1 - instr.assignBinding.context);
+
+ QmlMetaProperty mp(target, instr.assignBinding.property,
+ (QmlMetaProperty::PropertyCategory)instr.assignBinding.category);
+ if (!mp.isWritable())
+ VME_EXCEPTION("Cannot assign a binding to read-only property" << mp.name());
+
+ QmlBindableValue *bind = new QmlBindableValue(primitives.at(instr.assignBinding.value), context, false);
+ QFx_setParent_noEvent(bind, target);
+
+ bind->setTarget(mp);
+ bindableValues << bind;
+ }
+ break;
+
+ case QmlInstruction::StoreValueSource:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreValueSource> cc;
+#endif
+ QObject *assign = stack.pop();
+ QmlPropertyValueSource *vs =
+ static_cast<QmlPropertyValueSource *>(assign);
+ QObject *target = stack.top();
+ vs->setParent(target);
+ vs->setTarget(QmlMetaProperty(target, instr.assignValueSource.property));
+ }
+ break;
+
+ case QmlInstruction::AssignObjectList:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrAssignObjectList> cc;
+#endif
+ QObject *assign = stack.pop();
+ const ListInstance &list = qliststack.top();
+ if(list.qmlListInterface) {
+ int type = list.type;
+
+ void *d = 0;
+ void *ptr = 0;
+ bool found = false;
+
+ if(QmlMetaType::isInterface(type)) {
+ const char *iid = QmlMetaType::interfaceIId(type);
+ if(iid)
+ ptr = assign->qt_metacast(iid);
+ if(ptr) {
+ d = &ptr;
+ found = true;
+ }
+ } else {
+ const QMetaObject *mo =
+ QmlMetaType::rawMetaObjectForType(type);
+
+ const QMetaObject *assignMo = assign->metaObject();
+ while(!found && assignMo) {
+ if(assignMo == mo)
+ found = true;
+ else
+ assignMo = assignMo->superClass();
+ }
+
+ // NOTE: This assumes a cast to QObject does not alter
+ // the object pointer
+ d = (void *)&assign;
+ }
+
+
+ if(!found)
+ VME_EXCEPTION("Cannot assign object to list");
+
+ list.qmlListInterface->append(d);
+
+ } else {
+ int type = list.type;
+
+ if(QmlMetaType::isInterface(type)) {
+ void *ptr = 0;
+ const char *iid = QmlMetaType::interfaceIId(type);
+ if(iid)
+ ptr = assign->qt_metacast(iid);
+ QVariant v(list.type, &ptr);
+ QmlMetaType::append(list.list, v);
+ } else {
+ QVariant v = QmlMetaType::fromObject(assign, list.type);
+ QmlMetaType::append(list.list, v);
+ }
+ }
+ }
+ break;
+
+ case QmlInstruction::AssignObject:
+ {
+#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);
+ }
+ }
+
+
+ } else {
+ VME_EXCEPTION("Cannot assign to non-existant property" << property);
+ }
+
+ }
+ break;
+
+ case QmlInstruction::FetchAttached:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrFetchAttached> cc;
+#endif
+ QObject *target = stack.top();
+
+ QmlAttachedPropertiesFunc attachFunc =
+ QmlMetaType::attachedPropertiesFunc(datas.at(instr.fetchAttached.idx));
+ if(!attachFunc)
+ VME_EXCEPTION("No such attached object" << primitives.at(instr.fetchAttached.idx));
+
+ QObject *qmlObject = attachFunc(target);
+ if(!qmlObject)
+ VME_EXCEPTION("Internal error - unable to create attached object" << primitives.at(instr.fetchAttached.idx));
+
+ stack.push(qmlObject);
+ }
+ break;
+
+ case QmlInstruction::FetchQmlList:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrFetchQmlList> cc;
+#endif
+ QObject *target = stack.top();
+
+ void *a[1];
+ // We know that QmlList<*> can be converted to
+ // QmlPrivate::ListInterface
+ QmlPrivate::ListInterface *list = 0;
+ a[0] = &list;
+ QMetaObject::metacall(target, QMetaObject::ReadProperty,
+ instr.fetchQmlList.property, a);
+ if(!list)
+ VME_EXCEPTION("Cannot assign to null list");
+
+ qliststack.push(ListInstance(list, instr.fetchQmlList.type));
+ }
+ break;
+
+ case QmlInstruction::FetchQList:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrFetchQList> cc;
+#endif
+ QObject *target = stack.top();
+ QMetaProperty prop =
+ target->metaObject()->property(instr.fetch.property);
+ QVariant v = prop.read(target);
+ qliststack.push(ListInstance(v, QmlMetaType::listType(prop.userType())));
+ }
+ break;
+
+ case QmlInstruction::ResolveFetchObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrResolveFetchObject> cc;
+#endif
+ QObject *target = stack.top();
+ const QByteArray &pr = datas.at(instr.fetch.property);
+ int idx = qIndexOfProperty(target, pr);
+ if(idx == -1)
+ VME_EXCEPTION("Cannot resolve property" << pr);
+ QMetaProperty prop = target->metaObject()->property(idx);
+ instr.type = QmlInstruction::FetchObject;
+ instr.fetch.property = idx;
+ if(QmlMetaType::isObject(prop.userType())) {
+ instr.fetch.isObject = true;
+ } else if(prop.userType() == -1) {
+ instr.fetch.isObject = false;
+ } else {
+ VME_EXCEPTION("Cannot set properties on" << prop.name() << "as it is of unknown type");
+ }
+ ii--;
+ }
+ break;
+
+ case QmlInstruction::FetchObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrFetchObject> cc;
+#endif
+ QObject *target = stack.top();
+
+ QObject *obj = 0;
+ if(instr.fetch.isObject) {
+ // NOTE: This assumes a cast to QObject does not alter the
+ // object pointer
+ void *a[1];
+ a[0] = &obj;
+ QMetaObject::metacall(target, QMetaObject::ReadProperty,
+ instr.fetch.property, a);
+ } else {
+ void *a[1];
+ QVariant var;
+ a[0] = &var;
+ QMetaObject::metacall(target, QMetaObject::ReadProperty,
+ instr.fetch.property, a);
+ obj = QmlMetaType::toQObject(var);
+
+ }
+
+ if(!obj)
+ VME_EXCEPTION("Cannot set properties on" << target->metaObject()->property(instr.fetch.property).name() << "as it is null");
+
+ stack.push(obj);
+ }
+ break;
+
+ case QmlInstruction::PopQList:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrPopQList> cc;
+#endif
+ qliststack.pop();
+ }
+ break;
+
+ case QmlInstruction::PopFetchedObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrPopFetchedObject> cc;
+#endif
+ stack.pop();
+ }
+ break;
+
+ case QmlInstruction::AssignStackObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrAssignStackObject> cc;
+#endif
+
+ QObject *obj = savedObjects[instr.assignStackObject.object];
+ const QmlMetaProperty &prop =
+ pushedProperties.at(instr.assignStackObject.property);
+
+
+ const QMetaObject *mo =
+ QmlMetaType::rawMetaObjectForType(prop.propertyType());
+ const QMetaObject *assignMo = obj->metaObject();
+
+ bool found = false;
+ while(!found && assignMo) {
+ if(assignMo == mo)
+ found = true;
+ else
+ assignMo = assignMo->superClass();
+ }
+
+ if(!found)
+ VME_EXCEPTION("Unable to assign object");
+
+ instr.type = QmlInstruction::StoreStackObject;
+ --ii;
+ }
+ break;
+
+ case QmlInstruction::StoreStackObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreStackObject> cc;
+#endif
+
+ const QmlMetaProperty &prop =
+ pushedProperties.at(instr.assignStackObject.property);
+ QObject *obj = savedObjects[instr.assignStackObject.object];
+
+ // NOTE: This assumes a cast to QObject does not alter the
+ // object pointer
+ void *a[1];
+ a[0] = (void *)&obj;
+ QMetaObject::metacall(prop.object(), QMetaObject::WriteProperty,
+ prop.coreIndex(), a);
+ }
+ break;
+
+ case QmlInstruction::NoOp:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrNoOp> cc;
+#endif
+ }
+ break;
+
+ default:
+ qFatal("QmlCompiledComponent: Internal error - unknown instruction %d", instr.type);
+ break;
+ }
+ }
+ }
+
+ if(isError()) {
+ if(!stack.isEmpty()) {
+ delete stack.at(0);
+ }
+ return 0;
+ }
+
+ QmlEnginePrivate *ep = ctxt->engine()->d_func();
+ ep->currentBindValues << bindableValues;
+ ep->currentParserStatus << parserStatuses;
+
+ comp->dumpPost();
+
+ if(savedObjects)
+ delete [] savedObjects;
+
+ if(stack.isEmpty())
+ return 0;
+ else
+ return stack.top();
+ return 0;
+}
+
+bool QmlVME::isError() const
+{
+ return exceptionLine != -1;
+}
+
+qint64 QmlVME::errorLine() const
+{
+ return exceptionLine;
+}
+
+QString QmlVME::errorDescription() const
+{
+ return exceptionDescription;
+}
+
+void QmlVME::runStoreInstruction(QStack<QObject *> &stack,
+ QmlInstruction &instr,
+ QmlCompiledData *comp)
+{
+ const QList<QString> &primitives = comp->primitives;
+ const QList<int> &intData = comp->intData;
+ const QList<float> &floatData = comp->floatData;
+
+ switch(instr.type) {
+ case QmlInstruction::StoreVariant:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreVariant> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ // XXX - can be more efficient
+ QVariant v = QmlStringConverters::variantFromString(primitives.at(instr.storeString.value));
+ a[0] = (void *)&v;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeString.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreString:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreString> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ a[0] = (void *)&primitives.at(instr.storeString.value);
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeString.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreReal:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreReal> cc;
+#endif
+ QObject *target = stack.top();
+ qreal r = instr.storeReal.value;
+ void *a[1];
+ a[0] = &r;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeReal.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreBool:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreBool> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ a[0] = (void *)&instr.storeBool.value;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeBool.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreInteger:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreInteger> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ a[0] = (void *)&instr.storeInteger.value;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeReal.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreColor:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreColor> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QColor c = QColor::fromRgba(instr.storeColor.value);
+ a[0] = (void *)&c;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeColor.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreDate:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreDate> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QDate d = QDate::fromJulianDay(instr.storeDate.value);
+ a[0] = (void *)&d;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeDate.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreTime:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ //QFxCompilerTimer<QFxCompiler::InstrStoreTime> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QTime t;
+ t.setHMS(intData.at(instr.storeTime.valueIndex),
+ intData.at(instr.storeTime.valueIndex+1),
+ intData.at(instr.storeTime.valueIndex+2),
+ intData.at(instr.storeTime.valueIndex+3));
+ a[0] = (void *)&t;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeTime.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreDateTime:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ //QFxCompilerTimer<QFxCompiler::InstrStoreDateTime> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QTime t;
+ t.setHMS(intData.at(instr.storeDateTime.valueIndex+1),
+ intData.at(instr.storeDateTime.valueIndex+2),
+ intData.at(instr.storeDateTime.valueIndex+3),
+ intData.at(instr.storeDateTime.valueIndex+4));
+ QDateTime dt(QDate::fromJulianDay(intData.at(instr.storeDateTime.valueIndex)), t);
+ a[0] = (void *)&dt;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeDateTime.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StorePoint:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStorePoint> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QPoint p = QPointF(floatData.at(instr.storeRealPair.valueIndex),
+ floatData.at(instr.storeRealPair.valueIndex+1)).toPoint();
+ a[0] = (void *)&p;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeRealPair.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StorePointF:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStorePoint> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QPointF p(floatData.at(instr.storeRealPair.valueIndex),
+ floatData.at(instr.storeRealPair.valueIndex+1));
+ a[0] = (void *)&p;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeRealPair.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreSize:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreSize> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QSize p = QSizeF(floatData.at(instr.storeRealPair.valueIndex),
+ floatData.at(instr.storeRealPair.valueIndex+1)).toSize();
+ a[0] = (void *)&p;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeRealPair.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreSizeF:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreSize> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QSizeF s(floatData.at(instr.storeRealPair.valueIndex),
+ floatData.at(instr.storeRealPair.valueIndex+1));
+ a[0] = (void *)&s;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeRealPair.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreRect:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ //QFxCompilerTimer<QFxCompiler::InstrStoreRect> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QRect r = QRectF(floatData.at(instr.storeRect.valueIndex),
+ floatData.at(instr.storeRect.valueIndex+1),
+ floatData.at(instr.storeRect.valueIndex+2),
+ floatData.at(instr.storeRect.valueIndex+3)).toRect();
+ a[0] = (void *)&r;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeRect.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreRectF:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ //QFxCompilerTimer<QFxCompiler::InstrStoreRect> cc;
+#endif
+ QObject *target = stack.top();
+ void *a[1];
+ QRectF r(floatData.at(instr.storeRect.valueIndex),
+ floatData.at(instr.storeRect.valueIndex+1),
+ floatData.at(instr.storeRect.valueIndex+2),
+ floatData.at(instr.storeRect.valueIndex+3));
+ a[0] = (void *)&r;
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeRect.propertyIndex, a);
+ }
+ break;
+
+ case QmlInstruction::StoreObject:
+ {
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxCompilerTimer<QFxCompiler::InstrStoreObject> cc;
+#endif
+ QObject *assignObj = stack.pop();
+ QObject *target = stack.top();
+
+ void *a[1];
+ void *obj = (void *)(((char *)assignObj) + instr.storeObject.cast);
+ a[0] = (void *)&obj;
+
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeObject.propertyIndex, a);
+ }
+ break;
+ default:
+ qFatal("QmlCompiledComponent: Internal error - unknown instruction %d", instr.type);
+ break;
+ }
+
+}
+
+QT_END_NAMESPACE