Qt 4.8
qdeclarativevme.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
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"
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 
76 
77 // A simple stack wrapper around QVarLengthArray
78 template<typename T>
79 class QDeclarativeVMEStack : private QVarLengthArray<T, 128>
80 {
81 private:
83  int _index;
84 
85 public:
86  inline QDeclarativeVMEStack();
87  inline bool isEmpty() const;
88  inline const T &top() const;
89  inline void push(const T &o);
90  inline T pop();
91  inline int count() const;
92  inline const T &at(int index) const;
93 };
94 
95 // We do this so we can forward declare the type in the qdeclarativevme_p.h header
96 class QDeclarativeVMEObjectStack : public QDeclarativeVMEStack<QObject *> {};
97 
99 {
100 }
101 
102 #define VME_EXCEPTION(desc) \
103  { \
104  QDeclarativeError error; \
105  error.setDescription(desc.trimmed()); \
106  error.setLine(instr.line); \
107  error.setUrl(comp->url); \
108  vmeErrors << error; \
109  break; \
110  }
111 
113 {
115  : type(0) {}
116  ListInstance(int t)
117  : type(t) {}
118 
119  int type;
121 };
122 
124 
126  int start, int count, const QBitField &bindingSkipList)
127 {
129 
130  if (start == -1) start = 0;
131  if (count == -1) count = comp->bytecode.count();
132 
133  return run(stack, ctxt, comp, start, count, bindingSkipList);
134 }
135 
137 {
139 
140  if (!data || !data->context || !data->deferredComponent)
141  return;
142 
143  QDeclarativeContextData *ctxt = data->context;
145  int start = data->deferredIdx + 1;
148  stack.push(object);
149 
150  run(stack, ctxt, comp, start, count, QBitField());
151 }
152 
153 inline bool fastHasBinding(QObject *o, int index)
154 {
156 
157  return ddata && (ddata->bindingBitsSize > index) &&
158  (ddata->bindingBits[index / 32] & (1 << (index % 32)));
159 }
160 
162 {
164  if (binding) binding->destroy();
165 }
166 
167 #define CLEAN_PROPERTY(o, index) if (fastHasBinding(o, index)) removeBindingOnProperty(o, index)
168 
172  int start, int count,
173  const QBitField &bindingSkipList)
174 {
175  Q_ASSERT(comp);
176  Q_ASSERT(ctxt);
178  const QList<QString> &primitives = comp->primitives;
179  const QList<QByteArray> &datas = comp->datas;
181  const QList<int> &intData = comp->intData;
182  const QList<float> &floatData = comp->floatData;
183  const QList<QDeclarativePropertyCache *> &propertyCaches = comp->propertyCaches;
185  const QList<QUrl> &urls = comp->urls;
186 
189 
191 
192  vmeErrors.clear();
194 
195  int status = -1; //for dbus
196  QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor |
198 
199  for (int ii = start; !isError() && ii < (start + count); ++ii) {
200  const QDeclarativeInstruction &instr = comp->bytecode.at(ii);
201 
202  switch(instr.type) {
204  {
205  if (instr.init.bindingsSize)
207  if (instr.init.parserStatusSize)
209  if (instr.init.contextCache != -1)
210  ctxt->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache));
211  if (instr.init.compiledBinding != -1)
212  ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt, comp);
213  }
214  break;
215 
217  {
218  QBitField bindings;
219  if (instr.create.bindingBits != -1) {
220  const QByteArray &bits = datas.at(instr.create.bindingBits);
221  bindings = QBitField((const quint32*)bits.constData(),
222  bits.size() * 8);
223  }
224  if (stack.isEmpty())
225  bindings = bindings.united(bindingSkipList);
226 
227  QObject *o =
228  types.at(instr.create.type).createInstance(ctxt, bindings, &vmeErrors);
229 
230  if (!o) {
231  VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create object of type %1").arg(QString::fromLatin1(types.at(instr.create.type).className)));
232  }
233 
235  Q_ASSERT(ddata);
236 
237  if (stack.isEmpty()) {
238  if (ddata->context) {
239  Q_ASSERT(ddata->context != ctxt);
240  Q_ASSERT(ddata->outerContext);
241  Q_ASSERT(ddata->outerContext != ctxt);
242  QDeclarativeContextData *c = ddata->context;
243  while (c->linkedContext) c = c->linkedContext;
244  c->linkedContext = ctxt;
245  } else {
246  ctxt->addObject(o);
247  }
248 
249  ddata->ownContext = true;
250  } else if (!ddata->context) {
251  ctxt->addObject(o);
252  }
253 
254  ddata->setImplicitDestructible();
255  ddata->outerContext = ctxt;
256  ddata->lineNumber = instr.line;
257  ddata->columnNumber = instr.create.column;
258 
259  if (instr.create.data != -1) {
260  QDeclarativeCustomParser *customParser =
261  types.at(instr.create.type).type->customParser();
262  customParser->setCustomData(o, datas.at(instr.create.data));
263  }
264  if (!stack.isEmpty()) {
265  QObject *parent = stack.top();
266  if (o->isWidgetType()) {
267  QWidget *widget = static_cast<QWidget*>(o);
268  if (parent->isWidgetType()) {
269  QWidget *parentWidget = static_cast<QWidget*>(parent);
270  widget->setParent(parentWidget);
271  } else {
272  // TODO: parent might be a layout
273  }
274  } else {
276  }
277  }
278  stack.push(o);
279  }
280  break;
281 
283  {
284  QObject *o = (QObject *)operator new(instr.createSimple.typeSize +
285  sizeof(QDeclarativeData));
286  ::memset(static_cast<void *>(o), 0, instr.createSimple.typeSize + sizeof(QDeclarativeData));
287  instr.createSimple.create(o);
288 
289  QDeclarativeData *ddata = (QDeclarativeData *)(((const char *)o) + instr.createSimple.typeSize);
291  if (!ddata->propertyCache && ref.typePropertyCache) {
292  ddata->propertyCache = ref.typePropertyCache;
293  ddata->propertyCache->addref();
294  }
295  ddata->lineNumber = instr.line;
296  ddata->columnNumber = instr.createSimple.column;
297 
299  ddata->context = ddata->outerContext = ctxt;
300  ddata->nextContextObject = ctxt->contextObjects;
301  if (ddata->nextContextObject)
303  ddata->prevContextObject = &ctxt->contextObjects;
304  ctxt->contextObjects = ddata;
305 
306  QObject *parent = stack.top();
307  QDeclarative_setParent_noEvent(o, parent);
308 
309  stack.push(o);
310  }
311  break;
312 
314  {
315  QObject *target = stack.top();
316  ctxt->setIdProperty(instr.setId.index, target);
317  }
318  break;
319 
320 
322  {
323  ctxt->contextObject = stack.top();
324  }
325  break;
326 
328  {
329  QDeclarativeComponent *qcomp =
330  new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count,
331  stack.isEmpty() ? 0 : stack.top());
332 
333  QDeclarativeData *ddata = QDeclarativeData::get(qcomp, true);
334  Q_ASSERT(ddata);
335 
336  ctxt->addObject(qcomp);
337 
338  if (stack.isEmpty())
339  ddata->ownContext = true;
340 
341  ddata->setImplicitDestructible();
342  ddata->outerContext = ctxt;
343  ddata->lineNumber = instr.line;
344  ddata->columnNumber = instr.create.column;
345 
347 
348  stack.push(qcomp);
349  ii += instr.createComponent.count;
350  }
351  break;
352 
354  {
355  QObject *target = stack.top();
356 
357  QMetaObject mo;
358  const QByteArray &metadata = datas.at(instr.storeMeta.data);
359  QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata);
360 
361  const QDeclarativeVMEMetaData *data =
362  (const QDeclarativeVMEMetaData *)datas.at(instr.storeMeta.aliasData).constData();
363 
364  (void)new QDeclarativeVMEMetaObject(target, &mo, data, comp);
365 
366  if (instr.storeMeta.propertyCache != -1) {
367  QDeclarativeData *ddata = QDeclarativeData::get(target, true);
368  if (ddata->propertyCache) ddata->propertyCache->release();
369  ddata->propertyCache = propertyCaches.at(instr.storeMeta.propertyCache);
370  ddata->propertyCache->addref();
371  }
372  }
373  break;
374 
376  {
377  QObject *target = stack.top();
379 
380  // XXX - can be more efficient
382  void *a[] = { &v, 0, &status, &flags };
384  instr.storeString.propertyIndex, a);
385  }
386  break;
387 
389  {
390  QObject *target = stack.top();
392 
393  QVariant v(instr.storeInteger.value);
394  void *a[] = { &v, 0, &status, &flags };
396  instr.storeString.propertyIndex, a);
397  }
398  break;
399 
401  {
402  QObject *target = stack.top();
404 
405  QVariant v(instr.storeDouble.value);
406  void *a[] = { &v, 0, &status, &flags };
408  instr.storeString.propertyIndex, a);
409  }
410  break;
411 
413  {
414  QObject *target = stack.top();
416 
417  QVariant v(instr.storeBool.value);
418  void *a[] = { &v, 0, &status, &flags };
420  instr.storeString.propertyIndex, a);
421  }
422  break;
423 
425  {
426  QObject *target = stack.top();
428 
429  void *a[] = { (void *)&primitives.at(instr.storeString.value), 0, &status, &flags };
431  instr.storeString.propertyIndex, a);
432  }
433  break;
434 
436  {
437  QObject *target = stack.top();
438  CLEAN_PROPERTY(target, instr.storeUrl.propertyIndex);
439 
440  void *a[] = { (void *)&urls.at(instr.storeUrl.value), 0, &status, &flags };
442  instr.storeUrl.propertyIndex, a);
443  }
444  break;
445 
447  {
448  QObject *target = stack.top();
449  CLEAN_PROPERTY(target, instr.storeFloat.propertyIndex);
450 
451  float f = instr.storeFloat.value;
452  void *a[] = { &f, 0, &status, &flags };
454  instr.storeFloat.propertyIndex, a);
455  }
456  break;
457 
459  {
460  QObject *target = stack.top();
462 
463  double d = instr.storeDouble.value;
464  void *a[] = { &d, 0, &status, &flags };
466  instr.storeDouble.propertyIndex, a);
467  }
468  break;
469 
471  {
472  QObject *target = stack.top();
473  CLEAN_PROPERTY(target, instr.storeBool.propertyIndex);
474 
475  void *a[] = { (void *)&instr.storeBool.value, 0, &status, &flags };
477  instr.storeBool.propertyIndex, a);
478  }
479  break;
480 
482  {
483  QObject *target = stack.top();
485 
486  void *a[] = { (void *)&instr.storeInteger.value, 0, &status, &flags };
488  instr.storeInteger.propertyIndex, a);
489  }
490  break;
491 
493  {
494  QObject *target = stack.top();
495  CLEAN_PROPERTY(target, instr.storeColor.propertyIndex);
496 
498  void *a[] = { &c, 0, &status, &flags };
500  instr.storeColor.propertyIndex, a);
501  }
502  break;
503 
505  {
506  QObject *target = stack.top();
507  CLEAN_PROPERTY(target, instr.storeDate.propertyIndex);
508 
510  void *a[] = { &d, 0, &status, &flags };
512  instr.storeDate.propertyIndex, a);
513  }
514  break;
515 
517  {
518  QObject *target = stack.top();
519  CLEAN_PROPERTY(target, instr.storeTime.propertyIndex);
520 
521  QTime t;
522  t.setHMS(intData.at(instr.storeTime.valueIndex),
523  intData.at(instr.storeTime.valueIndex+1),
524  intData.at(instr.storeTime.valueIndex+2),
525  intData.at(instr.storeTime.valueIndex+3));
526  void *a[] = { &t, 0, &status, &flags };
528  instr.storeTime.propertyIndex, a);
529  }
530  break;
531 
533  {
534  QObject *target = stack.top();
536 
537  QTime t;
538  t.setHMS(intData.at(instr.storeDateTime.valueIndex+1),
539  intData.at(instr.storeDateTime.valueIndex+2),
540  intData.at(instr.storeDateTime.valueIndex+3),
541  intData.at(instr.storeDateTime.valueIndex+4));
543  void *a[] = { &dt, 0, &status, &flags };
545  instr.storeDateTime.propertyIndex, a);
546  }
547  break;
548 
550  {
551  QObject *target = stack.top();
553 
554  QPoint p = QPointF(floatData.at(instr.storeRealPair.valueIndex),
555  floatData.at(instr.storeRealPair.valueIndex+1)).toPoint();
556  void *a[] = { &p, 0, &status, &flags };
558  instr.storeRealPair.propertyIndex, a);
559  }
560  break;
561 
563  {
564  QObject *target = stack.top();
566 
567  QPointF p(floatData.at(instr.storeRealPair.valueIndex),
568  floatData.at(instr.storeRealPair.valueIndex+1));
569  void *a[] = { &p, 0, &status, &flags };
571  instr.storeRealPair.propertyIndex, a);
572  }
573  break;
574 
576  {
577  QObject *target = stack.top();
579 
580  QSize p = QSizeF(floatData.at(instr.storeRealPair.valueIndex),
581  floatData.at(instr.storeRealPair.valueIndex+1)).toSize();
582  void *a[] = { &p, 0, &status, &flags };
584  instr.storeRealPair.propertyIndex, a);
585  }
586  break;
587 
589  {
590  QObject *target = stack.top();
592 
593  QSizeF s(floatData.at(instr.storeRealPair.valueIndex),
594  floatData.at(instr.storeRealPair.valueIndex+1));
595  void *a[] = { &s, 0, &status, &flags };
597  instr.storeRealPair.propertyIndex, a);
598  }
599  break;
600 
602  {
603  QObject *target = stack.top();
604  CLEAN_PROPERTY(target, instr.storeRect.propertyIndex);
605 
606  QRect r = QRectF(floatData.at(instr.storeRect.valueIndex),
607  floatData.at(instr.storeRect.valueIndex+1),
608  floatData.at(instr.storeRect.valueIndex+2),
609  floatData.at(instr.storeRect.valueIndex+3)).toRect();
610  void *a[] = { &r, 0, &status, &flags };
612  instr.storeRect.propertyIndex, a);
613  }
614  break;
615 
617  {
618  QObject *target = stack.top();
619  CLEAN_PROPERTY(target, instr.storeRect.propertyIndex);
620 
621  QRectF r(floatData.at(instr.storeRect.valueIndex),
622  floatData.at(instr.storeRect.valueIndex+1),
623  floatData.at(instr.storeRect.valueIndex+2),
624  floatData.at(instr.storeRect.valueIndex+3));
625  void *a[] = { &r, 0, &status, &flags };
627  instr.storeRect.propertyIndex, a);
628  }
629  break;
630 
632  {
633  QObject *target = stack.top();
635 
636  QVector3D p(floatData.at(instr.storeVector3D.valueIndex),
637  floatData.at(instr.storeVector3D.valueIndex+1),
638  floatData.at(instr.storeVector3D.valueIndex+2));
639  void *a[] = { &p, 0, &status, &flags };
641  instr.storeVector3D.propertyIndex, a);
642  }
643  break;
644 
646  {
647  QObject *assignObj = stack.pop();
648  QObject *target = stack.top();
650 
651  void *a[] = { (void *)&assignObj, 0, &status, &flags };
653  instr.storeObject.propertyIndex, a);
654  }
655  break;
656 
657 
659  {
660  QObject *target = stack.top();
662 
664  const QString &primitive = primitives.at(data.index);
667  QVariant v = (*converter)(primitive);
668 
669  QMetaProperty prop =
671  if (v.isNull() || ((int)prop.type() != data.type && prop.userType() != data.type))
672  VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign value %1 to property %2").arg(primitive).arg(QString::fromUtf8(prop.name())));
673 
674  void *a[] = { (void *)v.data(), 0, &status, &flags };
677  }
678  break;
679 
681  {
682  // XXX optimize
683 
684  QObject *assign = stack.pop();
685  QObject *target = stack.top();
686  int sigIdx = instr.assignSignalObject.signal;
687  const QByteArray &pr = datas.at(sigIdx);
688 
689  QDeclarativeProperty prop(target, QString::fromUtf8(pr));
691 
693  if (method.signature() == 0)
694  VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object type %1 with no default method").arg(QString::fromLatin1(assign->metaObject()->className())));
695 
696  if (!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature()))
697  VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature())));
698 
699  QDeclarativePropertyPrivate::connect(target, prop.index(), assign, method.methodIndex());
700 
701  } else {
702  VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign an object to signal property %1").arg(QString::fromUtf8(pr)));
703  }
704 
705 
706  }
707  break;
708 
710  {
711  QObject *target = stack.top();
712  QObject *context = stack.at(stack.count() - 1 - instr.storeSignal.context);
713 
714  QMetaMethod signal = target->metaObject()->method(instr.storeSignal.signalIndex);
715 
716  QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target);
717  QDeclarativeExpression *expr =
718  new QDeclarativeExpression(ctxt, context, primitives.at(instr.storeSignal.value));
719  expr->setSourceLocation(comp->name, instr.line);
720  static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = datas.at(instr.storeSignal.name);
721  bs->setExpression(expr);
722  }
723  break;
724 
726  {
727  ctxt->addImportedScript(scripts.at(instr.storeScript.value));
728  }
729  break;
730 
732  {
733  QObject *target = stack.top();
734  QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope);
736  ss.setContext(ctxt->asQDeclarativeContext());
737  ss.setScopeObject(scope);
738  ss.setScript(primitives.at(instr.storeScriptString.value));
739 
740  void *a[] = { &ss, 0, &status, &flags };
743  }
744  break;
745 
747  {
748  QObject *target = stack.top();
749  QDeclarativeParserStatus *status = reinterpret_cast<QDeclarativeParserStatus *>(reinterpret_cast<char *>(target) + instr.begin.castValue);
750  parserStatus.append(status);
751  status->d = &parserStatus.values[parserStatus.count - 1];
752 
753  status->classBegin();
754  }
755  break;
756 
759  {
760  QObject *target =
761  stack.at(stack.count() - 1 - instr.assignBinding.owner);
762  QObject *context =
763  stack.at(stack.count() - 1 - instr.assignBinding.context);
764 
767 
768  int coreIndex = mp.index();
769 
770  if ((stack.count() - instr.assignBinding.owner) == 1 && bindingSkipList.testBit(coreIndex))
771  break;
772 
773  QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, comp->name, instr.line, 0);
774  bindValues.append(bind);
775  bind->m_mePtr = &bindValues.values[bindValues.count - 1];
776  bind->setTarget(mp);
777 
780  if (old) { old->destroy(); }
781  } else {
783  }
784  }
785  break;
786 
788  {
789  QObject *target =
790  stack.at(stack.count() - 1 - instr.assignBinding.owner);
791  QObject *scope =
792  stack.at(stack.count() - 1 - instr.assignBinding.context);
793 
794  int property = instr.assignBinding.property;
795  if (stack.count() == 1 && bindingSkipList.testBit(property & 0xFFFF))
796  break;
797 
798  QDeclarativeAbstractBinding *binding =
799  ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property);
800  bindValues.append(binding);
801  binding->m_mePtr = &bindValues.values[bindValues.count - 1];
802  binding->addToObject(target, property);
803  }
804  break;
805 
807  {
808  QObject *obj = stack.pop();
809  QDeclarativePropertyValueSource *vs = reinterpret_cast<QDeclarativePropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.assignValueSource.castValue);
810  QObject *target = stack.at(stack.count() - 1 - instr.assignValueSource.owner);
811 
812  QDeclarativeProperty prop =
814  obj->setParent(target);
815  vs->setTarget(prop);
816  }
817  break;
818 
820  {
821  QObject *obj = stack.pop();
822  QDeclarativePropertyValueInterceptor *vi = reinterpret_cast<QDeclarativePropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.assignValueInterceptor.castValue);
823  QObject *target = stack.at(stack.count() - 1 - instr.assignValueInterceptor.owner);
824  QDeclarativeProperty prop =
826  obj->setParent(target);
827  vi->setTarget(prop);
830  }
831  break;
832 
834  {
835  QObject *assign = stack.pop();
836 
837  const ListInstance &list = qliststack.top();
838  list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, assign);
839  }
840  break;
841 
843  {
844  // This is only used for assigning interfaces
845  QObject *assign = stack.pop();
846  const ListInstance &list = qliststack.top();
847 
848  int type = list.type;
849 
850  void *ptr = 0;
851 
852  const char *iid = QDeclarativeMetaType::interfaceIId(type);
853  if (iid)
854  ptr = assign->qt_metacast(iid);
855  if (!ptr)
856  VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to list"));
857 
858 
860  }
861  break;
862 
864  {
865  QObject *assign = stack.pop();
866  QObject *target = stack.top();
868 
869  QVariant v = QVariant::fromValue(assign);
870  void *a[] = { &v, 0, &status, &flags };
872  instr.storeObject.propertyIndex, a);
873  }
874  break;
875 
877  {
878  QObject *assign = stack.pop();
879  QObject *target = stack.top();
881 
882  int coreIdx = instr.storeObject.propertyIndex;
883  QMetaProperty prop = target->metaObject()->property(coreIdx);
884  int t = prop.userType();
885  const char *iid = QDeclarativeMetaType::interfaceIId(t);
886  bool ok = false;
887  if (iid) {
888  void *ptr = assign->qt_metacast(iid);
889  if (ptr) {
890  void *a[] = { &ptr, 0, &status, &flags };
891  QMetaObject::metacall(target,
893  coreIdx, a);
894  ok = true;
895  }
896  }
897 
898  if (!ok)
899  VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to interface property"));
900  }
901  break;
902 
904  {
905  QObject *target = stack.top();
906 
907  QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.fetchAttached.id, target);
908 
909  if (!qmlObject)
910  VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create attached object"));
911 
912  stack.push(qmlObject);
913  }
914  break;
915 
917  {
918  QObject *target = stack.top();
919 
920  qliststack.push(ListInstance(instr.fetchQmlList.type));
921 
922  void *a[1];
923  a[0] = (void *)&(qliststack.top().qListProperty);
925  instr.fetchQmlList.property, a);
926  }
927  break;
928 
930  {
931  QObject *target = stack.top();
932 
933  QObject *obj = 0;
934  // NOTE: This assumes a cast to QObject does not alter the
935  // object pointer
936  void *a[1];
937  a[0] = &obj;
939  instr.fetch.property, a);
940 
941  if (!obj)
942  VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot set properties on %1 as it is null").arg(QString::fromUtf8(target->metaObject()->property(instr.fetch.property).name())));
943 
944  stack.push(obj);
945  }
946  break;
947 
949  {
950  qliststack.pop();
951  }
952  break;
953 
955  {
956  if (instr.defer.deferCount) {
957  QObject *target = stack.top();
959  QDeclarativeData::get(target, true);
960  comp->addref();
961  data->deferredComponent = comp;
962  data->deferredIdx = ii;
963  ii += instr.defer.deferCount;
964  }
965  }
966  break;
967 
969  {
970  stack.pop();
971  }
972  break;
973 
975  {
976  QObject *target = stack.top();
977 
978  if (instr.fetchValue.bindingSkipList != 0) {
979  // Possibly need to clear bindings
980  QDeclarativeData *targetData = QDeclarativeData::get(target);
981  if (targetData) {
982  QDeclarativeAbstractBinding *binding =
984 
985  if (binding && binding->bindingType() != QDeclarativeAbstractBinding::ValueTypeProxy) {
987  binding->destroy();
988  } else if (binding) {
990  static_cast<QDeclarativeValueTypeProxyBinding *>(binding);
992  }
993  }
994  }
995 
996  QDeclarativeValueType *valueHandler = ep->valueTypes[instr.fetchValue.type];
997  valueHandler->read(target, instr.fetchValue.property);
998  stack.push(valueHandler);
999  }
1000  break;
1001 
1003  {
1004  QDeclarativeValueType *valueHandler =
1005  static_cast<QDeclarativeValueType *>(stack.pop());
1006  QObject *target = stack.top();
1007  valueHandler->write(target, instr.fetchValue.property,
1009  }
1010  break;
1011 
1012  default:
1013  qFatal("QDeclarativeCompiledData: Internal error - unknown instruction %d", instr.type);
1014  break;
1015  }
1016  }
1017 
1018  if (isError()) {
1019  if (!stack.isEmpty()) {
1020  delete stack.at(0); // ### What about failures in deferred creation?
1021  } else {
1022  ctxt->destroy();
1023  }
1024 
1026  QDeclarativeEnginePrivate::clear(parserStatus);
1027  return 0;
1028  }
1029 
1030  if (bindValues.count)
1031  ep->bindValues << bindValues;
1032  else if (bindValues.values)
1033  bindValues.clear();
1034 
1035  if (parserStatus.count)
1036  ep->parserStatus << parserStatus;
1037  else if (parserStatus.values)
1038  parserStatus.clear();
1039 
1040  Q_ASSERT(stack.count() == 1);
1041  return stack.top();
1042 }
1043 
1045 {
1046  return !vmeErrors.isEmpty();
1047 }
1048 
1050 {
1051  return vmeErrors;
1052 }
1053 
1054 QObject *
1056  const QBitField &bindings,
1057  QList<QDeclarativeError> *errors) const
1058 {
1059  if (type) {
1060  QObject *rv = 0;
1061  void *memory = 0;
1062 
1063  type->create(&rv, &memory, sizeof(QDeclarativeData));
1064  QDeclarativeData *ddata = new (memory) QDeclarativeData;
1065  ddata->ownMemory = false;
1066  QObjectPrivate::get(rv)->declarativeData = ddata;
1067 
1068  if (typePropertyCache && !ddata->propertyCache) {
1069  ddata->propertyCache = typePropertyCache;
1070  ddata->propertyCache->addref();
1071  }
1072 
1073  return rv;
1074  } else {
1076  return QDeclarativeComponentPrivate::begin(ctxt, 0, component, -1, -1, 0, errors, bindings);
1077  }
1078 }
1079 
1080 template<typename T>
1082 : _index(-1)
1083 {
1084 }
1085 
1086 template<typename T>
1088  return _index == -1;
1089 }
1090 
1091 template<typename T>
1093  return at(_index);
1094 }
1095 
1096 template<typename T>
1098  _index++;
1099 
1100  Q_ASSERT(_index <= VLA::size());
1101  if (_index == VLA::size())
1102  VLA::append(o);
1103  else
1104  VLA::data()[_index] = o;
1105 }
1106 
1107 template<typename T>
1109  Q_ASSERT(_index >= 0);
1110  --_index;
1111  return VLA::data()[_index + 1];
1112 }
1113 
1114 template<typename T>
1116  return _index + 1;
1117 }
1118 
1119 template<typename T>
1120 const T &QDeclarativeVMEStack<T>::at(int index) const {
1121  return VLA::data()[index];
1122 }
1123 
bool testBit(int) const
Definition: qbitfield_p.h:153
QDeclarativeContextData * outerContext
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QDeclarativeComponentPrivate * get(QDeclarativeComponent *c)
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
static const char * interfaceIId(int)
QDeclarativeContextData * context
QBitField united(const QBitField &)
Definition: qbitfield_p.h:126
QDeclarativePropertyCache * propertyCache
The QVector3D class represents a vector or vertex in 3D space.
Definition: qvector3d.h:60
static QDeclarativeData * get(const QObject *object, bool create=false)
int type
Definition: qmetatype.cpp:239
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void setParent(QWidget *parent)
Sets the parent of the widget to parent, and resets the window flags.
Definition: qwidget.cpp:10479
QVarLengthArray< T, 128 > VLA
QPointer< QWidget > widget
static void fromRelocatableData(QMetaObject *, const QMetaObject *, const QByteArray &)
QDeclarativeParserStatus ** d
QDeclarativeGuardedContextData creationContext
int methodIndex() const
Returns this method&#39;s index.
bool isNull() const
Returns true if this is a NULL variant, false otherwise.
Definition: qvariant.cpp:3102
QDeclarativeEngine * engine
static int metacall(QObject *, Call, int, void **)
QDeclarativeAbstractBinding * configBinding(int index, QObject *target, QObject *scope, int property)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QDeclarativeListProperty< void > qListProperty
FetchAttachedInstruction fetchAttached
void addToObject(QObject *, int)
Add this binding to object.
QDeclarativePropertyCache * typePropertyCache
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
bool isError() const
void setTarget(const QDeclarativeProperty &)
virtual void destroy(DestroyMode mode=DisconnectBinding)
Destroy the binding.
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
static QDeclarativeAbstractBinding * binding(QObject *, int coreIndex, int valueTypeIndex)
void registerInterceptor(int index, int valueIndex, QDeclarativePropertyValueInterceptor *interceptor)
void runDeferred(QObject *)
const T & top() const
QList< QDeclarativeParser::Object::ScriptBlock > scripts
static bool connect(QObject *sender, int signal_index, const QObject *receiver, int method_index, int type=0, int *types=0)
Connect sender signal_index to receiver method_index with the specified type and types.
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
static int valueTypeCoreIndex(const QDeclarativeProperty &that)
The QDate class provides date functions.
Definition: qdatetime.h:55
QList< QDeclarativeError > errors() const
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags flags)=0
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
Type type() const
Returns the type of the property.
unsigned int deferredIdx
The QString class provides a Unicode character string.
Definition: qstring.h:83
static QDate fromJulianDay(int jd)
Converts the Julian day jd to a QDate.
Definition: qdatetime.h:133
QDeclarativeContextData * linkedContext
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define CLEAN_PROPERTY(o, index)
static QDeclarativeEnginePrivate * get(QDeclarativeEngine *e)
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
static QObjectPrivate * get(QObject *o)
Definition: qobject_p.h:177
AssignSignalObjectInstruction assignSignalObject
void setParent(QObject *)
Makes the object a child of parent.
Definition: qobject.cpp:1950
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
QDeclarativeCompiledData * deferredComponent
Q_DECLARATIVE_EXPORT QObject * qmlAttachedPropertiesObjectById(int, const QObject *, bool create=true)
QDeclarativeExpression * setExpression(QDeclarativeExpression *)
Sets the signal expression to e.
bool fastHasBinding(QObject *o, int index)
void * data()
Definition: qvariant.cpp:3077
FetchValueInstruction fetchValue
The QTime class provides clock time functions.
Definition: qdatetime.h:148
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QObject * createInstance(QDeclarativeContextData *, const QBitField &, QList< QDeclarativeError > *) const
The QDeclarativeScriptString class encapsulates a script and its context.
The QDeclarativeComponent class encapsulates a QML component definition.
static QColor fromRgba(QRgb rgba)
Static convenience function that returns a QColor constructed from the given QRgb value rgba...
Definition: qcolor.cpp:1974
int userType() const
Returns this property&#39;s user type.
int index() const
Return the Qt metaobject index of the property.
QMetaMethod method() const
Return the QMetaMethod for this property if it is a SignalProperty, otherwise returns an invalid QMet...
void setScopeObject(QObject *)
Sets the scope object for the script.
StoreRealPairInstruction storeRealPair
The QDeclarativeParserStatus class provides updates on the QML parser state.
const char * name
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
StoreScriptInstruction storeScript
void setContext(QDeclarativeContext *)
Sets the context for the script.
StoreColorInstruction storeColor
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
QVariant Q_DECLARATIVE_PRIVATE_EXPORT variantFromString(const QString &)
QDeclarativeData * contextObjects
StoreDateTimeInstruction storeDateTime
virtual void setTarget(const QDeclarativeProperty &property)=0
Set the target property for the value interceptor.
StoreFloatInstruction storeFloat
static bool checkConnectArgs(const char *signal, const char *method)
Returns true if the signal and method arguments are compatible; otherwise returns false...
QObject * run(QDeclarativeContextData *, QDeclarativeCompiledData *, int start=-1, int count=-1, const QBitField &=QBitField())
QList< QDeclarativePropertyCache * > propertyCaches
static qreal component(const QPointF &point, unsigned int i)
static QDeclarativeAbstractBinding * setBinding(QObject *, int coreIndex, int valueTypeIndex, QDeclarativeAbstractBinding *, WriteFlags flags=DontRemoveBinding)
static QVariant fromValue(const T &value)
Returns a QVariant containing a copy of value.
Definition: qvariant.h:336
The QDeclarativeCustomParser class allows you to add new arbitrary types to QML.
static int bindingIndex(const QDeclarativeProperty &that)
Returns the "property index" for use in bindings.
QList< SimpleList< QDeclarativeAbstractBinding > > bindValues
StoreObjectInstruction storeObject
QAbstractDeclarativeData * declarativeData
Definition: qobject_p.h:214
const T & at(int index) const
static QWidget * parentWidget(const QWidget *w)
void addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script)
QList< QDeclarativeIntegerCache * > contextCaches
void removeBindings(quint32 mask)
Removes a collection of bindings, corresponding to the set bits in mask.
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
Q_CORE_EXPORT void qFatal(const char *,...)
bool isWidgetType() const
Returns true if the object is a widget; otherwise returns false.
Definition: qobject.h:146
static QObject * begin(QDeclarativeContextData *parentContext, QDeclarativeContextData *componentCreationContext, QDeclarativeCompiledData *component, int start, int count, ConstructionState *state, QList< QDeclarativeError > *errors, const QBitField &bindings=QBitField())
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
#define VME_EXCEPTION(desc)
The QDateTime class provides date and time functions.
Definition: qdatetime.h:216
virtual void classBegin()=0
Invoked after class creation, but before any properties have been set.
const char * name() const
Returns this property&#39;s name.
static const struct @32 types[]
static QDeclarativeAbstractBinding * setBindingNoEnable(QObject *, int coreIndex, int valueTypeIndex, QDeclarativeAbstractBinding *)
CreateComponentInstruction createComponent
static void clear(SimpleList< QDeclarativeAbstractBinding > &)
QDeclarativeValueTypeFactory valueTypes
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
void QDeclarative_setParent_noEvent(QObject *object, QObject *parent)
Makes the object a child of parent.
QDeclarativeContext * asQDeclarativeContext()
AssignBindingInstruction assignBinding
static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContextData *)
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
StoreDoubleInstruction storeDouble
unsigned int quint32
Definition: qglobal.h:938
StoreSignalInstruction storeSignal
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
CreateSimpleInstruction createSimple
const char * property
Definition: qwizard.cpp:138
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
static StringConverter customStringConverter(int)
Return the custom string converter for type, previously installed through registerCustomStringConvert...
Q_DECLARE_TYPEINFO(ListInstance, Q_PRIMITIVE_TYPE|Q_MOVABLE_TYPE)
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
QList< CustomTypeData > customTypeData
void setSourceLocation(const QString &fileName, int line)
Set the location of this expression to line of url.
virtual void setTarget(const QDeclarativeProperty &)=0
Set the target property for the value source.
QDeclarativeCustomParser * customParser() const
quint16 index
FetchQmlListInstruction fetchQmlList
QFuture< T > run(Function function,...)
The QDeclarativeProperty class abstracts accessing properties on objects created from QML...
void setIdProperty(int, QObject *)
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
The QMetaProperty class provides meta-data about a property.
Definition: qmetaobject.h:176
QDeclarativeData ** prevContextObject
void setScript(const QString &)
Sets the script text.
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
StoreVector3DInstruction storeVector3D
virtual void setCustomData(QObject *, const QByteArray &)=0
const char * signature() const
Returns the signature of this method (e.g., setValue(double)).
AssignValueInterceptorInstruction assignValueInterceptor
The QDeclarativePropertyValueSource class is an interface for property value sources such as animatio...
QDeclarativeData * nextContextObject
QDeclarativeCompiledBindings * optimizedBindings
The QDeclarativeExpression class evaluates JavaScript in a QML context.
static void removeBindingOnProperty(QObject *o, int index)
void setIdPropertyData(QDeclarativeIntegerCache *)
static QMetaMethod defaultMethod(const QMetaObject *)
StoreIntegerInstruction storeInteger
The QDeclarativePropertyValueInterceptor class is inherited by property interceptors such as Behavior...
QList< TypeReference > types
AssignValueSourceInstruction assignValueSource
The QMetaMethod class provides meta-data about a member function.
Definition: qmetaobject.h:56
bool setHMS(int h, int m, int s, int ms=0)
Sets the time to hour h, minute m, seconds s and milliseconds ms.
Definition: qdatetime.cpp:1744
QList< SimpleList< QDeclarativeParserStatus > > parserStatus
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
QList< QDeclarativeInstruction > bytecode
QMetaProperty property(int index) const
Returns the meta-data for the property with the given index.
StoreStringInstruction storeString
AssignCustomTypeInstruction assignCustomType
QVariant(* StringConverter)(const QString &)
StoreScriptStringInstruction storeScriptString
QDeclarativeAbstractBinding ** m_mePtr
virtual void read(QObject *, int)=0