source: trunk/src/declarative/qml/qdeclarativevme.cpp@ 883

Last change on this file since 883 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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