src/declarative/qml/qdeclarativevme.cpp
changeset 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "private/qdeclarativevme_p.h"
       
    43 
       
    44 #include "private/qdeclarativecompiler_p.h"
       
    45 #include "private/qdeclarativeboundsignal_p.h"
       
    46 #include "private/qdeclarativestringconverters_p.h"
       
    47 #include "private/qmetaobjectbuilder_p.h"
       
    48 #include "private/qdeclarativedata_p.h"
       
    49 #include "qdeclarative.h"
       
    50 #include "private/qdeclarativecustomparser_p.h"
       
    51 #include "qdeclarativeengine.h"
       
    52 #include "qdeclarativecontext.h"
       
    53 #include "qdeclarativecomponent.h"
       
    54 #include "private/qdeclarativebinding_p.h"
       
    55 #include "private/qdeclarativeengine_p.h"
       
    56 #include "private/qdeclarativecomponent_p.h"
       
    57 #include "private/qdeclarativevmemetaobject_p.h"
       
    58 #include "private/qdeclarativebinding_p_p.h"
       
    59 #include "private/qdeclarativecontext_p.h"
       
    60 #include "private/qdeclarativecompiledbindings_p.h"
       
    61 #include "private/qdeclarativeglobal_p.h"
       
    62 #include "qdeclarativescriptstring.h"
       
    63 
       
    64 #include <QStack>
       
    65 #include <QWidget>
       
    66 #include <QColor>
       
    67 #include <QPointF>
       
    68 #include <QSizeF>
       
    69 #include <QRectF>
       
    70 #include <QtCore/qdebug.h>
       
    71 #include <QtCore/qvarlengtharray.h>
       
    72 #include <QtCore/qcoreapplication.h>
       
    73 #include <QtCore/qdatetime.h>
       
    74 
       
    75 QT_BEGIN_NAMESPACE
       
    76 
       
    77 QDeclarativeVME::QDeclarativeVME()
       
    78 {
       
    79 }
       
    80 
       
    81 #define VME_EXCEPTION(desc) \
       
    82     { \
       
    83         QDeclarativeError error; \
       
    84         error.setDescription(desc.trimmed()); \
       
    85         error.setLine(instr.line); \
       
    86         error.setUrl(comp->url); \
       
    87         vmeErrors << error; \
       
    88         break; \
       
    89     }
       
    90 
       
    91 struct ListInstance
       
    92 {
       
    93     ListInstance() 
       
    94         : type(0) {}
       
    95     ListInstance(int t) 
       
    96         : type(t) {}
       
    97 
       
    98     int type;
       
    99     QDeclarativeListProperty<void> qListProperty;
       
   100 };
       
   101 
       
   102 QObject *QDeclarativeVME::run(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, 
       
   103                               int start, int count, const QBitField &bindingSkipList)
       
   104 {
       
   105     QDeclarativeVMEStack<QObject *> stack;
       
   106 
       
   107     if (start == -1) start = 0;
       
   108     if (count == -1) count = comp->bytecode.count();
       
   109 
       
   110     return run(stack, ctxt, comp, start, count, bindingSkipList);
       
   111 }
       
   112 
       
   113 void QDeclarativeVME::runDeferred(QObject *object)
       
   114 {
       
   115     QDeclarativeData *data = QDeclarativeData::get(object);
       
   116 
       
   117     if (!data || !data->context || !data->deferredComponent)
       
   118         return;
       
   119 
       
   120     QDeclarativeContextData *ctxt = data->context;
       
   121     QDeclarativeCompiledData *comp = data->deferredComponent;
       
   122     int start = data->deferredIdx + 1;
       
   123     int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount;
       
   124     QDeclarativeVMEStack<QObject *> stack;
       
   125     stack.push(object);
       
   126 
       
   127     run(stack, ctxt, comp, start, count, QBitField());
       
   128 }
       
   129 
       
   130 QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, 
       
   131                               QDeclarativeContextData *ctxt, 
       
   132                               QDeclarativeCompiledData *comp, 
       
   133                               int start, int count, 
       
   134                               const QBitField &bindingSkipList)
       
   135 {
       
   136     Q_ASSERT(comp);
       
   137     Q_ASSERT(ctxt);
       
   138     const QList<QDeclarativeCompiledData::TypeReference> &types = comp->types;
       
   139     const QList<QString> &primitives = comp->primitives;
       
   140     const QList<QByteArray> &datas = comp->datas;
       
   141     const QList<QDeclarativeCompiledData::CustomTypeData> &customTypeData = comp->customTypeData;
       
   142     const QList<int> &intData = comp->intData;
       
   143     const QList<float> &floatData = comp->floatData;
       
   144     const QList<QDeclarativePropertyCache *> &propertyCaches = comp->propertyCaches;
       
   145     const QList<QDeclarativeParser::Object::ScriptBlock> &scripts = comp->scripts;
       
   146     const QList<QUrl> &urls = comp->urls;
       
   147 
       
   148     QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> bindValues;
       
   149     QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus> parserStatus;
       
   150 
       
   151     QDeclarativeVMEStack<ListInstance> qliststack;
       
   152 
       
   153     vmeErrors.clear();
       
   154     QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);
       
   155 
       
   156     int status = -1;    //for dbus
       
   157     QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor;
       
   158 
       
   159     for (int ii = start; !isError() && ii < (start + count); ++ii) {
       
   160         const QDeclarativeInstruction &instr = comp->bytecode.at(ii);
       
   161 
       
   162         switch(instr.type) {
       
   163         case QDeclarativeInstruction::Init:
       
   164             {
       
   165                 if (instr.init.bindingsSize) 
       
   166                     bindValues = QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding>(instr.init.bindingsSize);
       
   167                 if (instr.init.parserStatusSize)
       
   168                     parserStatus = QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus>(instr.init.parserStatusSize);
       
   169                 if (instr.init.contextCache != -1) 
       
   170                     ctxt->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache));
       
   171                 if (instr.init.compiledBinding != -1) 
       
   172                     ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt);
       
   173             }
       
   174             break;
       
   175 
       
   176         case QDeclarativeInstruction::CreateObject:
       
   177             {
       
   178                 QBitField bindings;
       
   179                 if (instr.create.bindingBits != -1) {
       
   180                     const QByteArray &bits = datas.at(instr.create.bindingBits);
       
   181                     bindings = QBitField((const quint32*)bits.constData(),
       
   182                                          bits.size() * 8);
       
   183                 }
       
   184                 if (stack.isEmpty())
       
   185                     bindings = bindings.united(bindingSkipList);
       
   186 
       
   187                 QObject *o = 
       
   188                     types.at(instr.create.type).createInstance(ctxt, bindings);
       
   189 
       
   190                 if (!o) {
       
   191                     if(types.at(instr.create.type).component)
       
   192                         vmeErrors << types.at(instr.create.type).component->errors();
       
   193 
       
   194                     VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create object of type %1").arg(QString::fromLatin1(types.at(instr.create.type).className)));
       
   195                 }
       
   196 
       
   197                 QDeclarativeData *ddata = QDeclarativeData::get(o);
       
   198                 Q_ASSERT(ddata);
       
   199 
       
   200                 if (stack.isEmpty()) {
       
   201                     if (ddata->context) {
       
   202                         Q_ASSERT(ddata->context != ctxt);
       
   203                         Q_ASSERT(ddata->outerContext);
       
   204                         Q_ASSERT(ddata->outerContext != ctxt);
       
   205                         QDeclarativeContextData *c = ddata->context;
       
   206                         while (c->linkedContext) c = c->linkedContext;
       
   207                         c->linkedContext = ctxt;
       
   208                     } else {
       
   209                         ctxt->addObject(o);
       
   210                     }
       
   211 
       
   212                     ddata->ownContext = true;
       
   213                 } else if (!ddata->context) {
       
   214                     ctxt->addObject(o);
       
   215                 }
       
   216 
       
   217                 ddata->setImplicitDestructible();
       
   218                 ddata->outerContext = ctxt;
       
   219                 ddata->lineNumber = instr.line;
       
   220                 ddata->columnNumber = instr.create.column;
       
   221 
       
   222                 if (instr.create.data != -1) {
       
   223                     QDeclarativeCustomParser *customParser =
       
   224                         types.at(instr.create.type).type->customParser();
       
   225                     customParser->setCustomData(o, datas.at(instr.create.data));
       
   226                 }
       
   227                 if (!stack.isEmpty()) {
       
   228                     QObject *parent = stack.top();
       
   229                     if (o->isWidgetType()) { 
       
   230                         QWidget *widget = static_cast<QWidget*>(o); 
       
   231                         if (parent->isWidgetType()) { 
       
   232                             QWidget *parentWidget = static_cast<QWidget*>(parent); 
       
   233                             widget->setParent(parentWidget); 
       
   234                         } else { 
       
   235                             // TODO: parent might be a layout 
       
   236                         } 
       
   237                     } else { 
       
   238 			    QDeclarative_setParent_noEvent(o, parent);
       
   239                     } 
       
   240                 }
       
   241                 stack.push(o);
       
   242             }
       
   243             break;
       
   244 
       
   245         case QDeclarativeInstruction::CreateSimpleObject:
       
   246             {
       
   247                 QObject *o = (QObject *)operator new(instr.createSimple.typeSize + 
       
   248                                                      sizeof(QDeclarativeData));   
       
   249                 ::memset(o, 0, instr.createSimple.typeSize + sizeof(QDeclarativeData));
       
   250                 instr.createSimple.create(o);
       
   251 
       
   252                 QDeclarativeData *ddata = 
       
   253                     (QDeclarativeData *)(((const char *)o) + instr.createSimple.typeSize);
       
   254                 ddata->lineNumber = instr.line;
       
   255                 ddata->columnNumber = instr.createSimple.column;
       
   256 
       
   257                 QObjectPrivate::get(o)->declarativeData = ddata;                                                      
       
   258                 ddata->context = ddata->outerContext = ctxt;
       
   259                 ddata->nextContextObject = ctxt->contextObjects; 
       
   260                 if (ddata->nextContextObject) 
       
   261                     ddata->nextContextObject->prevContextObject = &ddata->nextContextObject; 
       
   262                 ddata->prevContextObject = &ctxt->contextObjects; 
       
   263                 ctxt->contextObjects = ddata; 
       
   264 
       
   265                 QObject *parent = stack.top();                                                                    
       
   266                 QDeclarative_setParent_noEvent(o, parent);                                                        
       
   267 
       
   268                 stack.push(o);
       
   269             }
       
   270             break;
       
   271 
       
   272         case QDeclarativeInstruction::SetId:
       
   273             {
       
   274                 QObject *target = stack.top();
       
   275                 ctxt->setIdProperty(instr.setId.index, target);
       
   276             }
       
   277             break;
       
   278 
       
   279 
       
   280         case QDeclarativeInstruction::SetDefault:
       
   281             {
       
   282                 ctxt->contextObject = stack.top();
       
   283             }
       
   284             break;
       
   285 
       
   286         case QDeclarativeInstruction::CreateComponent:
       
   287             {
       
   288                 QDeclarativeComponent *qcomp = 
       
   289                     new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count,
       
   290                                               stack.isEmpty() ? 0 : stack.top());
       
   291 
       
   292                 QDeclarativeData *ddata = QDeclarativeData::get(qcomp, true);
       
   293                 Q_ASSERT(ddata);
       
   294 
       
   295                 ctxt->addObject(qcomp);
       
   296 
       
   297                 if (stack.isEmpty()) 
       
   298                     ddata->ownContext = true;
       
   299 
       
   300                 ddata->setImplicitDestructible();
       
   301                 ddata->outerContext = ctxt;
       
   302                 ddata->lineNumber = instr.line;
       
   303                 ddata->columnNumber = instr.create.column;
       
   304 
       
   305                 QDeclarativeComponentPrivate::get(qcomp)->creationContext = ctxt;
       
   306 
       
   307                 stack.push(qcomp);
       
   308                 ii += instr.createComponent.count;
       
   309             }
       
   310             break;
       
   311 
       
   312         case QDeclarativeInstruction::StoreMetaObject:
       
   313             {
       
   314                 QObject *target = stack.top();
       
   315 
       
   316                 QMetaObject mo;
       
   317                 const QByteArray &metadata = datas.at(instr.storeMeta.data);
       
   318                 QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata);
       
   319 
       
   320                 const QDeclarativeVMEMetaData *data = 
       
   321                     (const QDeclarativeVMEMetaData *)datas.at(instr.storeMeta.aliasData).constData();
       
   322 
       
   323                 (void)new QDeclarativeVMEMetaObject(target, &mo, data, comp);
       
   324 
       
   325                 QDeclarativeData *ddata = QDeclarativeData::get(target, true);
       
   326                 if (ddata->propertyCache) ddata->propertyCache->release();
       
   327                 ddata->propertyCache = propertyCaches.at(instr.storeMeta.propertyCache);
       
   328                 ddata->propertyCache->addref();
       
   329             }
       
   330             break;
       
   331 
       
   332         case QDeclarativeInstruction::StoreVariant:
       
   333             {
       
   334                 QObject *target = stack.top();
       
   335                 // XXX - can be more efficient
       
   336                 QVariant v = QDeclarativeStringConverters::variantFromString(primitives.at(instr.storeString.value));
       
   337                 void *a[] = { &v, 0, &status, &flags };
       
   338                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   339                                       instr.storeString.propertyIndex, a);
       
   340             }
       
   341             break;
       
   342 
       
   343         case QDeclarativeInstruction::StoreVariantInteger:
       
   344             {
       
   345                 QObject *target = stack.top();
       
   346                 QVariant v(instr.storeInteger.value);
       
   347                 void *a[] = { &v, 0, &status, &flags };
       
   348                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   349                                       instr.storeString.propertyIndex, a);
       
   350             }
       
   351             break;
       
   352 
       
   353         case QDeclarativeInstruction::StoreVariantDouble:
       
   354             {
       
   355                 QObject *target = stack.top();
       
   356                 QVariant v(instr.storeDouble.value);
       
   357                 void *a[] = { &v, 0, &status, &flags };
       
   358                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   359                                       instr.storeString.propertyIndex, a);
       
   360             }
       
   361             break;
       
   362 
       
   363         case QDeclarativeInstruction::StoreVariantBool:
       
   364             {
       
   365                 QObject *target = stack.top();
       
   366                 QVariant v(instr.storeBool.value);
       
   367                 void *a[] = { &v, 0, &status, &flags };
       
   368                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   369                                       instr.storeString.propertyIndex, a);
       
   370             }
       
   371             break;
       
   372 
       
   373         case QDeclarativeInstruction::StoreString:
       
   374             {
       
   375                 QObject *target = stack.top();
       
   376                 void *a[] = { (void *)&primitives.at(instr.storeString.value), 0, &status, &flags };
       
   377                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   378                                       instr.storeString.propertyIndex, a);
       
   379             }
       
   380             break;
       
   381 
       
   382         case QDeclarativeInstruction::StoreUrl:
       
   383             {
       
   384                 QObject *target = stack.top();
       
   385                 void *a[] = { (void *)&urls.at(instr.storeUrl.value), 0, &status, &flags };
       
   386                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   387                                       instr.storeUrl.propertyIndex, a);
       
   388             }
       
   389             break;
       
   390 
       
   391         case QDeclarativeInstruction::StoreFloat:
       
   392             {
       
   393                 QObject *target = stack.top();
       
   394                 float f = instr.storeFloat.value;
       
   395                 void *a[] = { &f, 0, &status, &flags };
       
   396                 QMetaObject::metacall(target, QMetaObject::WriteProperty,
       
   397                                       instr.storeFloat.propertyIndex, a);
       
   398             }
       
   399             break;
       
   400 
       
   401         case QDeclarativeInstruction::StoreDouble:
       
   402             {
       
   403                 QObject *target = stack.top();
       
   404                 double d = instr.storeDouble.value;
       
   405                 void *a[] = { &d, 0, &status, &flags };
       
   406                 QMetaObject::metacall(target, QMetaObject::WriteProperty,
       
   407                                       instr.storeDouble.propertyIndex, a);
       
   408             }
       
   409             break;
       
   410 
       
   411         case QDeclarativeInstruction::StoreBool:
       
   412             {
       
   413                 QObject *target = stack.top();
       
   414                 void *a[] = { (void *)&instr.storeBool.value, 0, &status, &flags };
       
   415                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   416                                       instr.storeBool.propertyIndex, a);
       
   417             }
       
   418             break;
       
   419 
       
   420         case QDeclarativeInstruction::StoreInteger:
       
   421             {
       
   422                 QObject *target = stack.top();
       
   423                 void *a[] = { (void *)&instr.storeInteger.value, 0, &status, &flags };
       
   424                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   425                                       instr.storeInteger.propertyIndex, a);
       
   426             }
       
   427             break;
       
   428 
       
   429         case QDeclarativeInstruction::StoreColor:
       
   430             {
       
   431                 QObject *target = stack.top();
       
   432                 QColor c = QColor::fromRgba(instr.storeColor.value);
       
   433                 void *a[] = { &c, 0, &status, &flags };
       
   434                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   435                                       instr.storeColor.propertyIndex, a);
       
   436             }
       
   437             break;
       
   438 
       
   439         case QDeclarativeInstruction::StoreDate:
       
   440             {
       
   441                 QObject *target = stack.top();
       
   442                 QDate d = QDate::fromJulianDay(instr.storeDate.value);
       
   443                 void *a[] = { &d, 0, &status, &flags };
       
   444                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   445                                       instr.storeDate.propertyIndex, a);
       
   446             }
       
   447             break;
       
   448 
       
   449         case QDeclarativeInstruction::StoreTime:
       
   450             {
       
   451                 QObject *target = stack.top();
       
   452                 QTime t;
       
   453                 t.setHMS(intData.at(instr.storeTime.valueIndex),
       
   454                          intData.at(instr.storeTime.valueIndex+1),
       
   455                          intData.at(instr.storeTime.valueIndex+2),
       
   456                          intData.at(instr.storeTime.valueIndex+3));
       
   457                 void *a[] = { &t, 0, &status, &flags };
       
   458                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   459                                       instr.storeTime.propertyIndex, a);
       
   460             }
       
   461             break;
       
   462 
       
   463         case QDeclarativeInstruction::StoreDateTime:
       
   464             {
       
   465                 QObject *target = stack.top();
       
   466                 QTime t;
       
   467                 t.setHMS(intData.at(instr.storeDateTime.valueIndex+1),
       
   468                          intData.at(instr.storeDateTime.valueIndex+2),
       
   469                          intData.at(instr.storeDateTime.valueIndex+3),
       
   470                          intData.at(instr.storeDateTime.valueIndex+4));
       
   471                 QDateTime dt(QDate::fromJulianDay(intData.at(instr.storeDateTime.valueIndex)), t);
       
   472                 void *a[] = { &dt, 0, &status, &flags };
       
   473                 QMetaObject::metacall(target, QMetaObject::WriteProperty,
       
   474                                       instr.storeDateTime.propertyIndex, a);
       
   475             }
       
   476             break;
       
   477 
       
   478         case QDeclarativeInstruction::StorePoint:
       
   479             {
       
   480                 QObject *target = stack.top();
       
   481                 QPoint p = QPointF(floatData.at(instr.storeRealPair.valueIndex),
       
   482                                    floatData.at(instr.storeRealPair.valueIndex+1)).toPoint();
       
   483                 void *a[] = { &p, 0, &status, &flags };
       
   484                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   485                                       instr.storeRealPair.propertyIndex, a);
       
   486             }
       
   487             break;
       
   488 
       
   489         case QDeclarativeInstruction::StorePointF:
       
   490             {
       
   491                 QObject *target = stack.top();
       
   492                 QPointF p(floatData.at(instr.storeRealPair.valueIndex),
       
   493                           floatData.at(instr.storeRealPair.valueIndex+1));
       
   494                 void *a[] = { &p, 0, &status, &flags };
       
   495                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   496                                       instr.storeRealPair.propertyIndex, a);
       
   497             }
       
   498             break;
       
   499 
       
   500         case QDeclarativeInstruction::StoreSize:
       
   501             {
       
   502                 QObject *target = stack.top();
       
   503                 QSize p = QSizeF(floatData.at(instr.storeRealPair.valueIndex),
       
   504                                  floatData.at(instr.storeRealPair.valueIndex+1)).toSize();
       
   505                 void *a[] = { &p, 0, &status, &flags };
       
   506                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   507                                       instr.storeRealPair.propertyIndex, a);
       
   508             }
       
   509             break;
       
   510 
       
   511         case QDeclarativeInstruction::StoreSizeF:
       
   512             {
       
   513                 QObject *target = stack.top();
       
   514                 QSizeF s(floatData.at(instr.storeRealPair.valueIndex),
       
   515                          floatData.at(instr.storeRealPair.valueIndex+1));
       
   516                 void *a[] = { &s, 0, &status, &flags };
       
   517                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   518                                       instr.storeRealPair.propertyIndex, a);
       
   519             }
       
   520             break;
       
   521 
       
   522         case QDeclarativeInstruction::StoreRect:
       
   523             {
       
   524                 QObject *target = stack.top();
       
   525                 QRect r = QRectF(floatData.at(instr.storeRect.valueIndex),
       
   526                                  floatData.at(instr.storeRect.valueIndex+1),
       
   527                                  floatData.at(instr.storeRect.valueIndex+2),
       
   528                                  floatData.at(instr.storeRect.valueIndex+3)).toRect();
       
   529                 void *a[] = { &r, 0, &status, &flags };
       
   530                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   531                                       instr.storeRect.propertyIndex, a);
       
   532             }
       
   533             break;
       
   534 
       
   535         case QDeclarativeInstruction::StoreRectF:
       
   536             {
       
   537                 QObject *target = stack.top();
       
   538                 QRectF r(floatData.at(instr.storeRect.valueIndex),
       
   539                          floatData.at(instr.storeRect.valueIndex+1),
       
   540                          floatData.at(instr.storeRect.valueIndex+2),
       
   541                          floatData.at(instr.storeRect.valueIndex+3));
       
   542                 void *a[] = { &r, 0, &status, &flags };
       
   543                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   544                                       instr.storeRect.propertyIndex, a);
       
   545             }
       
   546             break;
       
   547 
       
   548         case QDeclarativeInstruction::StoreVector3D:
       
   549             {
       
   550                 QObject *target = stack.top();
       
   551                 QVector3D p(floatData.at(instr.storeVector3D.valueIndex),
       
   552                             floatData.at(instr.storeVector3D.valueIndex+1),
       
   553                             floatData.at(instr.storeVector3D.valueIndex+2));
       
   554                 void *a[] = { &p, 0, &status, &flags };
       
   555                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   556                                       instr.storeVector3D.propertyIndex, a);
       
   557             }
       
   558             break;
       
   559 
       
   560         case QDeclarativeInstruction::StoreObject:
       
   561             {
       
   562                 QObject *assignObj = stack.pop();
       
   563                 QObject *target = stack.top();
       
   564 
       
   565                 void *a[] = { (void *)&assignObj, 0, &status, &flags };
       
   566                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   567                                       instr.storeObject.propertyIndex, a);
       
   568             }
       
   569             break;
       
   570 
       
   571 
       
   572         case QDeclarativeInstruction::AssignCustomType:
       
   573             {
       
   574                 QObject *target = stack.top();
       
   575                 QDeclarativeCompiledData::CustomTypeData data = customTypeData.at(instr.assignCustomType.valueIndex);
       
   576                 const QString &primitive = primitives.at(data.index);
       
   577                 QDeclarativeMetaType::StringConverter converter = 
       
   578                     QDeclarativeMetaType::customStringConverter(data.type);
       
   579                 QVariant v = (*converter)(primitive);
       
   580 
       
   581                 QMetaProperty prop = 
       
   582                         target->metaObject()->property(instr.assignCustomType.propertyIndex);
       
   583                 if (v.isNull() || ((int)prop.type() != data.type && prop.userType() != data.type)) 
       
   584                     VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign value %1 to property %2").arg(primitive).arg(QString::fromUtf8(prop.name())));
       
   585 
       
   586                 void *a[] = { (void *)v.data(), 0, &status, &flags };
       
   587                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   588                                       instr.assignCustomType.propertyIndex, a);
       
   589             }
       
   590             break;
       
   591 
       
   592         case QDeclarativeInstruction::AssignSignalObject:
       
   593             {
       
   594                 // XXX optimize
       
   595 
       
   596                 QObject *assign = stack.pop();
       
   597                 QObject *target = stack.top();
       
   598                 int sigIdx = instr.assignSignalObject.signal;
       
   599                 const QByteArray &pr = datas.at(sigIdx);
       
   600 
       
   601                 QDeclarativeProperty prop(target, QString::fromUtf8(pr));
       
   602                 if (prop.type() & QDeclarativeProperty::SignalProperty) {
       
   603 
       
   604                     QMetaMethod method = QDeclarativeMetaType::defaultMethod(assign);
       
   605                     if (method.signature() == 0)
       
   606                         VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object type %1 with no default method").arg(QString::fromLatin1(assign->metaObject()->className())));
       
   607 
       
   608                     if (!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature()))
       
   609                         VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature())));
       
   610 
       
   611                     QMetaObject::connect(target, prop.index(), assign, method.methodIndex());
       
   612 
       
   613                 } else {
       
   614                     VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign an object to signal property %1").arg(QString::fromUtf8(pr)));
       
   615                 }
       
   616 
       
   617 
       
   618             }
       
   619             break;
       
   620 
       
   621         case QDeclarativeInstruction::StoreSignal:
       
   622             {
       
   623                 QObject *target = stack.top();
       
   624                 QObject *context = stack.at(stack.count() - 1 - instr.assignBinding.context);
       
   625                 
       
   626                 QMetaMethod signal = target->metaObject()->method(instr.storeSignal.signalIndex);
       
   627 
       
   628                 QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target);
       
   629                 QDeclarativeExpression *expr = 
       
   630                     new QDeclarativeExpression(ctxt, context, primitives.at(instr.storeSignal.value));
       
   631                 expr->setSourceLocation(comp->name, instr.line);
       
   632                 bs->setExpression(expr);
       
   633             }
       
   634             break;
       
   635 
       
   636         case QDeclarativeInstruction::StoreImportedScript:
       
   637             {
       
   638                 ctxt->addImportedScript(scripts.at(instr.storeScript.value));
       
   639             }
       
   640             break;
       
   641 
       
   642         case QDeclarativeInstruction::StoreScriptString:
       
   643             {
       
   644                 QObject *target = stack.top();
       
   645                 QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope);
       
   646                 QDeclarativeScriptString ss;
       
   647                 ss.setContext(ctxt->asQDeclarativeContext());
       
   648                 ss.setScopeObject(scope);
       
   649                 ss.setScript(primitives.at(instr.storeScriptString.value));
       
   650 
       
   651                 void *a[] = { &ss, 0, &status, &flags };
       
   652                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   653                                       instr.storeScriptString.propertyIndex, a);
       
   654             }
       
   655             break;
       
   656 
       
   657         case QDeclarativeInstruction::BeginObject:
       
   658             {
       
   659                 QObject *target = stack.top();
       
   660                 QDeclarativeParserStatus *status = reinterpret_cast<QDeclarativeParserStatus *>(reinterpret_cast<char *>(target) + instr.begin.castValue);
       
   661                 parserStatus.append(status);
       
   662                 status->d = &parserStatus.values[parserStatus.count - 1];
       
   663 
       
   664                 status->classBegin();
       
   665             }
       
   666             break;
       
   667 
       
   668         case QDeclarativeInstruction::StoreBinding:
       
   669             {
       
   670                 QObject *target = 
       
   671                     stack.at(stack.count() - 1 - instr.assignBinding.owner);
       
   672                 QObject *context = 
       
   673                     stack.at(stack.count() - 1 - instr.assignBinding.context);
       
   674 
       
   675                 QDeclarativeProperty mp = 
       
   676                     QDeclarativePropertyPrivate::restore(datas.at(instr.assignBinding.property), target, ctxt);
       
   677 
       
   678                 int coreIndex = mp.index();
       
   679 
       
   680                 if (stack.count() == 1 && bindingSkipList.testBit(coreIndex))  
       
   681                     break;
       
   682 
       
   683                 QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, comp->name, instr.line, 0);
       
   684                 bindValues.append(bind);
       
   685                 bind->m_mePtr = &bindValues.values[bindValues.count - 1];
       
   686                 bind->setTarget(mp);
       
   687                 bind->addToObject(target);
       
   688             }
       
   689             break;
       
   690 
       
   691         case QDeclarativeInstruction::StoreCompiledBinding:
       
   692             {
       
   693                 QObject *target = 
       
   694                     stack.at(stack.count() - 1 - instr.assignBinding.owner);
       
   695                 QObject *scope = 
       
   696                     stack.at(stack.count() - 1 - instr.assignBinding.context);
       
   697 
       
   698                 int property = instr.assignBinding.property;
       
   699                 if (stack.count() == 1 && bindingSkipList.testBit(property & 0xFFFF))  
       
   700                     break;
       
   701 
       
   702                 QDeclarativeAbstractBinding *binding = 
       
   703                     ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property);
       
   704                 bindValues.append(binding);
       
   705                 binding->m_mePtr = &bindValues.values[bindValues.count - 1];
       
   706                 binding->addToObject(target);
       
   707             }
       
   708             break;
       
   709 
       
   710         case QDeclarativeInstruction::StoreValueSource:
       
   711             {
       
   712                 QObject *obj = stack.pop();
       
   713                 QDeclarativePropertyValueSource *vs = reinterpret_cast<QDeclarativePropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.assignValueSource.castValue);
       
   714                 QObject *target = stack.at(stack.count() - 1 - instr.assignValueSource.owner);
       
   715 
       
   716                 QDeclarativeProperty prop = 
       
   717                     QDeclarativePropertyPrivate::restore(datas.at(instr.assignValueSource.property), target, ctxt);
       
   718                 obj->setParent(target);
       
   719                 vs->setTarget(prop);
       
   720             }
       
   721             break;
       
   722 
       
   723         case QDeclarativeInstruction::StoreValueInterceptor:
       
   724             {
       
   725                 QObject *obj = stack.pop();
       
   726                 QDeclarativePropertyValueInterceptor *vi = reinterpret_cast<QDeclarativePropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.assignValueInterceptor.castValue);
       
   727                 QObject *target = stack.at(stack.count() - 1 - instr.assignValueInterceptor.owner);
       
   728                 QDeclarativeProperty prop = 
       
   729                     QDeclarativePropertyPrivate::restore(datas.at(instr.assignValueInterceptor.property), target, ctxt);
       
   730                 obj->setParent(target);
       
   731                 vi->setTarget(prop);
       
   732                 QDeclarativeVMEMetaObject *mo = static_cast<QDeclarativeVMEMetaObject *>((QMetaObject*)target->metaObject());
       
   733                 mo->registerInterceptor(prop.index(), QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), vi);
       
   734             }
       
   735             break;
       
   736 
       
   737         case QDeclarativeInstruction::StoreObjectQList:
       
   738             {
       
   739                 QObject *assign = stack.pop();
       
   740 
       
   741                 const ListInstance &list = qliststack.top();
       
   742                 list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, assign);
       
   743             }
       
   744             break;
       
   745 
       
   746         case QDeclarativeInstruction::AssignObjectList:
       
   747             {
       
   748                 // This is only used for assigning interfaces
       
   749                 QObject *assign = stack.pop();
       
   750                 const ListInstance &list = qliststack.top();
       
   751 
       
   752                 int type = list.type;
       
   753 
       
   754                 void *ptr = 0;
       
   755 
       
   756                 const char *iid = QDeclarativeMetaType::interfaceIId(type);
       
   757                 if (iid) 
       
   758                     ptr = assign->qt_metacast(iid);
       
   759                 if (!ptr) 
       
   760                     VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to list"));
       
   761 
       
   762 
       
   763                 list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, ptr);
       
   764             }
       
   765             break;
       
   766 
       
   767         case QDeclarativeInstruction::StoreVariantObject:
       
   768             {
       
   769                 QObject *assign = stack.pop();
       
   770                 QObject *target = stack.top();
       
   771 
       
   772                 QVariant v = QVariant::fromValue(assign);
       
   773                 void *a[] = { &v, 0, &status, &flags };
       
   774                 QMetaObject::metacall(target, QMetaObject::WriteProperty, 
       
   775                                       instr.storeObject.propertyIndex, a);
       
   776             }
       
   777             break;
       
   778 
       
   779         case QDeclarativeInstruction::StoreInterface:
       
   780             {
       
   781                 QObject *assign = stack.pop();
       
   782                 QObject *target = stack.top();
       
   783 
       
   784                 int coreIdx = instr.storeObject.propertyIndex;
       
   785                 QMetaProperty prop = target->metaObject()->property(coreIdx);
       
   786                 int t = prop.userType();
       
   787                 const char *iid = QDeclarativeMetaType::interfaceIId(t);
       
   788                 bool ok = false;
       
   789                 if (iid) {
       
   790                     void *ptr = assign->qt_metacast(iid);
       
   791                     if (ptr) {
       
   792                         void *a[] = { &ptr, 0, &status, &flags };
       
   793                         QMetaObject::metacall(target, 
       
   794                                               QMetaObject::WriteProperty,
       
   795                                               coreIdx, a);
       
   796                         ok = true;
       
   797                     }
       
   798                 } 
       
   799 
       
   800                 if (!ok) 
       
   801                     VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to interface property"));
       
   802             }
       
   803             break;
       
   804             
       
   805         case QDeclarativeInstruction::FetchAttached:
       
   806             {
       
   807                 QObject *target = stack.top();
       
   808 
       
   809                 QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.fetchAttached.id, target);
       
   810 
       
   811                 if (!qmlObject)
       
   812                     VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create attached object"));
       
   813 
       
   814                 stack.push(qmlObject);
       
   815             }
       
   816             break;
       
   817 
       
   818         case QDeclarativeInstruction::FetchQList:
       
   819             {
       
   820                 QObject *target = stack.top();
       
   821 
       
   822                 qliststack.push(ListInstance(instr.fetchQmlList.type));
       
   823 
       
   824                 void *a[1];
       
   825                 a[0] = (void *)&(qliststack.top().qListProperty);
       
   826                 QMetaObject::metacall(target, QMetaObject::ReadProperty, 
       
   827                                       instr.fetchQmlList.property, a);
       
   828             }
       
   829             break;
       
   830 
       
   831         case QDeclarativeInstruction::FetchObject:
       
   832             {
       
   833                 QObject *target = stack.top();
       
   834 
       
   835                 QObject *obj = 0;
       
   836                 // NOTE: This assumes a cast to QObject does not alter the 
       
   837                 // object pointer
       
   838                 void *a[1];
       
   839                 a[0] = &obj;
       
   840                 QMetaObject::metacall(target, QMetaObject::ReadProperty, 
       
   841                                       instr.fetch.property, a);
       
   842 
       
   843                 if (!obj)
       
   844                     VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot set properties on %1 as it is null").arg(QString::fromUtf8(target->metaObject()->property(instr.fetch.property).name())));
       
   845 
       
   846                 stack.push(obj);
       
   847             }
       
   848             break;
       
   849 
       
   850         case QDeclarativeInstruction::PopQList:
       
   851             {
       
   852                 qliststack.pop();
       
   853             }
       
   854             break;
       
   855 
       
   856         case QDeclarativeInstruction::Defer:
       
   857             {
       
   858                 if (instr.defer.deferCount) {
       
   859                     QObject *target = stack.top();
       
   860                     QDeclarativeData *data = 
       
   861                         QDeclarativeData::get(target, true);
       
   862                     comp->addref();
       
   863                     data->deferredComponent = comp;
       
   864                     data->deferredIdx = ii;
       
   865                     ii += instr.defer.deferCount;
       
   866                 }
       
   867             }
       
   868             break;
       
   869 
       
   870         case QDeclarativeInstruction::PopFetchedObject:
       
   871             {
       
   872                 stack.pop();
       
   873             }
       
   874             break;
       
   875 
       
   876         case QDeclarativeInstruction::FetchValueType:
       
   877             {
       
   878                 QObject *target = stack.top();
       
   879                 QDeclarativeValueType *valueHandler = 
       
   880                     ep->valueTypes[instr.fetchValue.type];
       
   881                 valueHandler->read(target, instr.fetchValue.property);
       
   882                 stack.push(valueHandler);
       
   883             }
       
   884             break;
       
   885 
       
   886         case QDeclarativeInstruction::PopValueType:
       
   887             {
       
   888                 QDeclarativeValueType *valueHandler = 
       
   889                     static_cast<QDeclarativeValueType *>(stack.pop());
       
   890                 QObject *target = stack.top();
       
   891                 valueHandler->write(target, instr.fetchValue.property, 
       
   892                                     QDeclarativePropertyPrivate::BypassInterceptor);
       
   893             }
       
   894             break;
       
   895 
       
   896         default:
       
   897             qFatal("QDeclarativeCompiledData: Internal error - unknown instruction %d", instr.type);
       
   898             break;
       
   899         }
       
   900     }
       
   901 
       
   902     if (isError()) {
       
   903         if (!stack.isEmpty()) {
       
   904             delete stack.at(0); // ### What about failures in deferred creation?
       
   905         } else {
       
   906             ctxt->destroy();
       
   907         }
       
   908 
       
   909         QDeclarativeEnginePrivate::clear(bindValues);
       
   910         QDeclarativeEnginePrivate::clear(parserStatus);
       
   911         ep->finalizedParserStatus.clear();
       
   912         return 0;
       
   913     }
       
   914 
       
   915     if (bindValues.count)
       
   916         ep->bindValues << bindValues;
       
   917     if (parserStatus.count)
       
   918         ep->parserStatus << parserStatus;
       
   919 
       
   920     Q_ASSERT(stack.count() == 1);
       
   921     return stack.top();
       
   922 }
       
   923 
       
   924 bool QDeclarativeVME::isError() const
       
   925 {
       
   926     return !vmeErrors.isEmpty();
       
   927 }
       
   928 
       
   929 QList<QDeclarativeError> QDeclarativeVME::errors() const
       
   930 {
       
   931     return vmeErrors;
       
   932 }
       
   933 
       
   934 QObject *
       
   935 QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData *ctxt, 
       
   936                                                         const QBitField &bindings) const
       
   937 {
       
   938     if (type) {
       
   939         QObject *rv = 0;
       
   940         void *memory = 0;
       
   941 
       
   942         type->create(&rv, &memory, sizeof(QDeclarativeData));
       
   943         QDeclarativeData *ddata = new (memory) QDeclarativeData;
       
   944         ddata->ownMemory = false;
       
   945         QObjectPrivate::get(rv)->declarativeData = ddata;
       
   946 
       
   947         return rv;
       
   948     } else {
       
   949         Q_ASSERT(component);
       
   950         return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings);
       
   951     } 
       
   952 }
       
   953 
       
   954 
       
   955 QT_END_NAMESPACE