Remove unnecessary members
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativevme.cpp
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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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/qfastmetabuilder_p.h"
49 #include "private/qdeclarativedata_p.h"
50 #include "qdeclarative.h"
51 #include "private/qdeclarativecustomparser_p.h"
52 #include "qdeclarativeengine.h"
53 #include "qdeclarativecontext.h"
54 #include "qdeclarativecomponent.h"
55 #include "private/qdeclarativebinding_p.h"
56 #include "private/qdeclarativeengine_p.h"
57 #include "private/qdeclarativecomponent_p.h"
58 #include "private/qdeclarativevmemetaobject_p.h"
59 #include "private/qdeclarativebinding_p_p.h"
60 #include "private/qdeclarativecontext_p.h"
61 #include "private/qdeclarativev4bindings_p.h"
62 #include "private/qv8bindings_p.h"
63 #include "private/qdeclarativeglobal_p.h"
64 #include "private/qfinitestack_p.h"
65 #include "qdeclarativescriptstring.h"
66 #include "qdeclarativescriptstring_p.h"
67
68 #include <QStack>
69 #include <QColor>
70 #include <QPointF>
71 #include <QSizeF>
72 #include <QRectF>
73 #include <QtCore/qdebug.h>
74 #include <QtCore/qvarlengtharray.h>
75 #include <QtCore/qcoreapplication.h>
76 #include <QtCore/qdatetime.h>
77 #include <QtCore/qvarlengtharray.h>
78 #include <QtDeclarative/qjsvalue.h>
79
80 QT_BEGIN_NAMESPACE
81
82 using namespace QDeclarativeVMETypes;
83
84 #define VME_EXCEPTION(desc, line) \
85     { \
86         QDeclarativeError error; \
87         error.setDescription(desc.trimmed()); \
88         error.setLine(line); \
89         error.setUrl(COMP->url); \
90         *errors << error; \
91         goto exceptionExit; \
92     }
93
94 void QDeclarativeVME::init(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, int start)
95 {
96     Q_ASSERT(ctxt);
97     Q_ASSERT(comp);
98
99     if (start == -1) start = 0;
100
101     State initState;
102     initState.context = ctxt;
103     initState.compiledData = comp;
104     initState.instructionStream = comp->bytecode.constData() + start;
105     states.push(initState);
106
107     typedef QDeclarativeInstruction I;
108     I *i = (I *)initState.instructionStream;
109
110     Q_ASSERT(comp->instructionType(i) == I::Init);
111
112     objects.allocate(i->init.objectStackSize);
113     lists.allocate(i->init.listStackSize);
114     bindValues.allocate(i->init.bindingsSize);
115     parserStatus.allocate(i->init.parserStatusSize);
116
117     rootContext = 0;
118     engine = ctxt->engine;
119 }
120
121 bool QDeclarativeVME::initDeferred(QObject *object)
122 {
123     QDeclarativeData *data = QDeclarativeData::get(object);
124
125     if (!data || !data->context || !data->deferredComponent)
126         return false;
127
128     QDeclarativeContextData *ctxt = data->context;
129     QDeclarativeCompiledData *comp = data->deferredComponent;
130     int start = data->deferredIdx;
131
132     State initState;
133     initState.context = ctxt;
134     initState.compiledData = comp;
135     initState.instructionStream = comp->bytecode.constData() + start;
136     states.push(initState);
137
138     typedef QDeclarativeInstruction I;
139     I *i = (I *)initState.instructionStream;
140
141     Q_ASSERT(comp->instructionType(i) == I::DeferInit);
142
143     objects.allocate(i->deferInit.objectStackSize);
144     lists.allocate(i->deferInit.listStackSize);
145     bindValues.allocate(i->deferInit.bindingsSize);
146     parserStatus.allocate(i->deferInit.parserStatusSize);
147
148     objects.push(object);
149
150     rootContext = 0;
151     engine = ctxt->engine;
152
153     return true;
154 }
155
156 namespace {
157 struct ActiveVMERestorer 
158 {
159     ActiveVMERestorer(QDeclarativeVME *me, QDeclarativeEnginePrivate *ep) 
160     : ep(ep), oldVME(ep->activeVME) { ep->activeVME = me; }
161     ~ActiveVMERestorer() { ep->activeVME = oldVME; }
162
163     QDeclarativeEnginePrivate *ep;
164     QDeclarativeVME *oldVME;
165 };
166 }
167
168 QObject *QDeclarativeVME::execute(QList<QDeclarativeError> *errors, const Interrupt &interrupt)
169 {
170     Q_ASSERT(states.count() >= 1);
171
172     QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(states.at(0).context->engine);
173
174     ActiveVMERestorer restore(this, ep);
175
176     QObject *rv = run(errors, interrupt);
177
178     return rv;
179 }
180
181 inline bool fastHasBinding(QObject *o, int index) 
182 {
183     QDeclarativeData *ddata = static_cast<QDeclarativeData *>(QObjectPrivate::get(o)->declarativeData);
184
185     return ddata && (ddata->bindingBitsSize > index) && 
186            (ddata->bindingBits[index / 32] & (1 << (index % 32)));
187 }
188
189 static void removeBindingOnProperty(QObject *o, int index)
190 {
191     QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::setBinding(o, index, -1, 0);
192     if (binding) binding->destroy();
193 }
194
195 // XXX we probably need some form of "work count" here to prevent us checking this 
196 // for every instruction.
197 #define QML_BEGIN_INSTR_COMMON(I) { \
198     if (interrupt.shouldInterrupt()) return 0; \
199     const QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::DataType &instr = QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::data(*genericInstr); \
200     INSTRUCTIONSTREAM += QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::Size; \
201     Q_UNUSED(instr);
202
203 #ifdef QML_THREADED_VME_INTERPRETER
204 #  define QML_BEGIN_INSTR(I) op_##I: \
205     QML_BEGIN_INSTR_COMMON(I)
206
207 #  define QML_NEXT_INSTR(I) { \
208     genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(INSTRUCTIONSTREAM); \
209     goto *genericInstr->common.code; \
210     }
211
212 #  define QML_END_INSTR(I) } \
213     genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(INSTRUCTIONSTREAM); \
214     goto *genericInstr->common.code;
215
216 #else
217 #  define QML_BEGIN_INSTR(I) \
218     case QDeclarativeInstruction::I: \
219     QML_BEGIN_INSTR_COMMON(I)
220
221 #  define QML_NEXT_INSTR(I) break;
222 #  define QML_END_INSTR(I) } break;
223 #endif
224
225 #define CLEAN_PROPERTY(o, index) if (fastHasBinding(o, index)) removeBindingOnProperty(o, index)
226
227 QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
228                               const Interrupt &interrupt
229 #ifdef QML_THREADED_VME_INTERPRETER
230                               , void ***storeJumpTable
231 #endif
232                               )
233 {
234 #ifdef QML_THREADED_VME_INTERPRETER
235     if (storeJumpTable) {
236 #define QML_INSTR_ADDR(I, FMT) &&op_##I,
237         static void *jumpTable[] = {
238             FOR_EACH_QML_INSTR(QML_INSTR_ADDR)
239         };
240 #undef QML_INSTR_ADDR
241         *storeJumpTable = jumpTable;
242         return 0;
243     }
244 #endif
245     Q_ASSERT(errors->isEmpty());
246     Q_ASSERT(states.count() >= 1);
247
248     QDeclarativeEngine *engine = states.at(0).context->engine;
249     QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
250
251     int status = -1; // needed for dbus
252     QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor |
253                                                     QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite;
254
255 #define COMP states.top().compiledData
256 #define CTXT states.top().context
257 #define INSTRUCTIONSTREAM states.top().instructionStream
258 #define BINDINGSKIPLIST states.top().bindingSkipList
259
260 #define TYPES COMP->types
261 #define PRIMITIVES COMP->primitives
262 #define DATAS COMP->datas
263 #define PROPERTYCACHES COMP->propertyCaches
264 #define SCRIPTS COMP->scripts
265 #define URLS COMP->urls
266
267 #ifdef QML_THREADED_VME_INTERPRETER
268     const QDeclarativeInstruction *genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(INSTRUCTIONSTREAM);
269     goto *genericInstr->common.code;
270 #else
271     for (;;) {
272         const QDeclarativeInstruction *genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(INSTRUCTIONSTREAM);
273
274         switch (genericInstr->common.instructionType) {
275 #endif
276         QML_BEGIN_INSTR(Init)
277             // Ensure that the compiled data has been initialized
278             if (!COMP->isInitialized()) COMP->initialize(engine);
279
280             QDeclarativeContextData *parentCtxt = CTXT;
281             CTXT = new QDeclarativeContextData;
282             CTXT->isInternal = true;
283             CTXT->url = COMP->url;
284             CTXT->imports = COMP->importCache;
285             CTXT->imports->addref();
286             CTXT->setParent(parentCtxt);
287             if (instr.contextCache != -1) 
288                 CTXT->setIdPropertyData(COMP->contextCaches.at(instr.contextCache));
289             if (instr.compiledBinding != -1) {
290                 const char *v4data = DATAS.at(instr.compiledBinding).constData();
291                 CTXT->v4bindings = new QDeclarativeV4Bindings(v4data, CTXT, COMP);
292             }
293             if (states.count() == 1) {
294                 rootContext = CTXT;
295                 rootContext->activeVME = this;
296             }
297         QML_END_INSTR(Init)
298
299         QML_BEGIN_INSTR(DeferInit)
300         QML_END_INSTR(DeferInit)
301
302         QML_BEGIN_INSTR(Done)
303             states.pop();
304
305             if (states.isEmpty())
306                 goto normalExit;
307         QML_END_INSTR(Done)
308
309         QML_BEGIN_INSTR(CreateQMLObject)
310             const QDeclarativeCompiledData::TypeReference &type = TYPES.at(instr.type);
311             Q_ASSERT(type.component);
312
313             states.push(State());
314
315             State *cState = &states[states.count() - 2];
316             State *nState = &states[states.count() - 1];
317
318             nState->context = cState->context;
319             nState->compiledData = type.component;
320             nState->instructionStream = type.component->bytecode.constData();
321
322             if (instr.bindingBits != -1) {
323                 const QByteArray &bits = cState->compiledData->datas.at(instr.bindingBits);
324                 nState->bindingSkipList = QBitField((const quint32*)bits.constData(),
325                                                     bits.size() * 8);
326             }
327             if (instr.isRoot)
328                 nState->bindingSkipList = nState->bindingSkipList.united(cState->bindingSkipList);
329
330             // As the state in the state stack changed, execution will continue in the new program.
331         QML_END_INSTR(CreateQMLObject)
332
333         QML_BEGIN_INSTR(CompleteQMLObject)
334             QObject *o = objects.top();
335
336             QDeclarativeData *ddata = QDeclarativeData::get(o);
337             Q_ASSERT(ddata);
338
339             if (instr.isRoot) {
340                 if (ddata->context) {
341                     Q_ASSERT(ddata->context != CTXT);
342                     Q_ASSERT(ddata->outerContext);
343                     Q_ASSERT(ddata->outerContext != CTXT);
344                     QDeclarativeContextData *c = ddata->context;
345                     while (c->linkedContext) c = c->linkedContext;
346                     c->linkedContext = CTXT;
347                 } else {
348                     CTXT->addObject(o);
349                 }
350
351                 ddata->ownContext = true;
352             } else if (!ddata->context) {
353                 CTXT->addObject(o);
354             }
355
356             ddata->setImplicitDestructible();
357             ddata->outerContext = CTXT;
358             ddata->lineNumber = instr.line;
359             ddata->columnNumber = instr.column;
360         QML_END_INSTR(CompleteQMLObject)
361
362         QML_BEGIN_INSTR(CreateCppObject)
363             const QDeclarativeCompiledData::TypeReference &type = TYPES.at(instr.type);
364             Q_ASSERT(type.type);
365
366             QObject *o = 0;
367             void *memory = 0;
368             type.type->create(&o, &memory, sizeof(QDeclarativeData));
369             QDeclarativeData *ddata = new (memory) QDeclarativeData;
370             ddata->ownMemory = false;
371             QObjectPrivate::get(o)->declarativeData = ddata;
372
373             if (type.typePropertyCache && !ddata->propertyCache) {
374                 ddata->propertyCache = type.typePropertyCache;
375                 ddata->propertyCache->addref();
376             }
377
378             if (!o) 
379                 VME_EXCEPTION(tr("Unable to create object of type %1").arg(type.className), instr.line);
380
381             if (instr.isRoot) {
382                 if (ddata->context) {
383                     Q_ASSERT(ddata->context != CTXT);
384                     Q_ASSERT(ddata->outerContext);
385                     Q_ASSERT(ddata->outerContext != CTXT);
386                     QDeclarativeContextData *c = ddata->context;
387                     while (c->linkedContext) c = c->linkedContext;
388                     c->linkedContext = CTXT;
389                 } else {
390                     CTXT->addObject(o);
391                 }
392
393                 ddata->ownContext = true;
394             } else if (!ddata->context) {
395                 CTXT->addObject(o);
396             }
397
398             ddata->setImplicitDestructible();
399             ddata->outerContext = CTXT;
400             ddata->lineNumber = instr.line;
401             ddata->columnNumber = instr.column;
402
403             if (instr.data != -1) {
404                 QDeclarativeCustomParser *customParser =
405                     TYPES.at(instr.type).type->customParser();
406                 customParser->setCustomData(o, DATAS.at(instr.data));
407             }
408             if (!objects.isEmpty()) {
409                 QObject *parent = objects.top();
410 #if 0 // ### refactor
411                 if (o->isWidgetType() && parent->isWidgetType()) 
412                     static_cast<QWidget*>(o)->setParent(static_cast<QWidget*>(parent));
413                 else 
414 #endif
415                     QDeclarative_setParent_noEvent(o, parent);
416             }
417             objects.push(o);
418         QML_END_INSTR(CreateCppObject)
419
420         QML_BEGIN_INSTR(CreateSimpleObject)
421             QObject *o = (QObject *)operator new(instr.typeSize + sizeof(QDeclarativeData));   
422             ::memset(o, 0, instr.typeSize + sizeof(QDeclarativeData));
423             instr.create(o);
424
425             QDeclarativeData *ddata = (QDeclarativeData *)(((const char *)o) + instr.typeSize);
426             const QDeclarativeCompiledData::TypeReference &ref = TYPES.at(instr.type);
427             if (!ddata->propertyCache && ref.typePropertyCache) {
428                 ddata->propertyCache = ref.typePropertyCache;
429                 ddata->propertyCache->addref();
430             }
431             ddata->lineNumber = instr.line;
432             ddata->columnNumber = instr.column;
433
434             QObjectPrivate::get(o)->declarativeData = ddata;                                                      
435             ddata->context = ddata->outerContext = CTXT;
436             ddata->nextContextObject = CTXT->contextObjects; 
437             if (ddata->nextContextObject) 
438                 ddata->nextContextObject->prevContextObject = &ddata->nextContextObject; 
439             ddata->prevContextObject = &CTXT->contextObjects; 
440             CTXT->contextObjects = ddata; 
441
442             QObject *parent = objects.top();                                                                    
443             QDeclarative_setParent_noEvent(o, parent);                                                        
444
445             objects.push(o);
446         QML_END_INSTR(CreateSimpleObject)
447
448         QML_BEGIN_INSTR(SetId)
449             QObject *target = objects.top();
450             CTXT->setIdProperty(instr.index, target);
451         QML_END_INSTR(SetId)
452
453         QML_BEGIN_INSTR(SetDefault)
454             CTXT->contextObject = objects.top();
455         QML_END_INSTR(SetDefault)
456
457         QML_BEGIN_INSTR(CreateComponent)
458             QDeclarativeComponent *qcomp = 
459                 new QDeclarativeComponent(CTXT->engine, COMP, INSTRUCTIONSTREAM - COMP->bytecode.constData(),
460                                           objects.isEmpty() ? 0 : objects.top());
461
462             QDeclarativeData *ddata = QDeclarativeData::get(qcomp, true);
463             Q_ASSERT(ddata);
464
465             CTXT->addObject(qcomp);
466
467             if (instr.isRoot)
468                 ddata->ownContext = true;
469
470             ddata->setImplicitDestructible();
471             ddata->outerContext = CTXT;
472             ddata->lineNumber = instr.line;
473             ddata->columnNumber = instr.column;
474
475             QDeclarativeComponentPrivate::get(qcomp)->creationContext = CTXT;
476
477             objects.push(qcomp);
478             INSTRUCTIONSTREAM += instr.count;
479         QML_END_INSTR(CreateComponent)
480
481         QML_BEGIN_INSTR(StoreMetaObject)
482             QObject *target = objects.top();
483
484             QMetaObject mo;
485             const QByteArray &metadata = DATAS.at(instr.data);
486             QFastMetaBuilder::fromData(&mo, 0, metadata);
487
488             const QDeclarativeVMEMetaData *data = 
489                 (const QDeclarativeVMEMetaData *)DATAS.at(instr.aliasData).constData();
490
491             (void)new QDeclarativeVMEMetaObject(target, &mo, data, COMP);
492
493             if (instr.propertyCache != -1) {
494                 QDeclarativeData *ddata = QDeclarativeData::get(target, true);
495                 if (ddata->propertyCache) ddata->propertyCache->release();
496                 ddata->propertyCache = PROPERTYCACHES.at(instr.propertyCache);
497                 ddata->propertyCache->addref();
498             }
499         QML_END_INSTR(StoreMetaObject)
500
501         QML_BEGIN_INSTR(StoreVariant)
502             QObject *target = objects.top();
503             CLEAN_PROPERTY(target, instr.propertyIndex);
504
505             // XXX - can be more efficient
506             QVariant v = QDeclarativeStringConverters::variantFromString(PRIMITIVES.at(instr.value));
507             void *a[] = { &v, 0, &status, &flags };
508             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
509                                   instr.propertyIndex, a);
510         QML_END_INSTR(StoreVariant)
511
512         QML_BEGIN_INSTR(StoreVariantInteger)
513             QObject *target = objects.top();
514             CLEAN_PROPERTY(target, instr.propertyIndex);
515
516             QVariant v(instr.value);
517             void *a[] = { &v, 0, &status, &flags };
518             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
519                                   instr.propertyIndex, a);
520         QML_END_INSTR(StoreVariantInteger)
521
522         QML_BEGIN_INSTR(StoreVariantDouble)
523             QObject *target = objects.top();
524             CLEAN_PROPERTY(target, instr.propertyIndex);
525
526             QVariant v(instr.value);
527             void *a[] = { &v, 0, &status, &flags };
528             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
529                                   instr.propertyIndex, a);
530         QML_END_INSTR(StoreVariantDouble)
531
532         QML_BEGIN_INSTR(StoreVariantBool)
533             QObject *target = objects.top();
534             CLEAN_PROPERTY(target, instr.propertyIndex);
535
536             QVariant v(instr.value);
537             void *a[] = { &v, 0, &status, &flags };
538             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
539                                   instr.propertyIndex, a);
540         QML_END_INSTR(StoreVariantBool)
541
542         QML_BEGIN_INSTR(StoreString)
543             QObject *target = objects.top();
544             CLEAN_PROPERTY(target, instr.propertyIndex);
545
546             void *a[] = { (void *)&PRIMITIVES.at(instr.value), 0, &status, &flags };
547             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
548                                   instr.propertyIndex, a);
549         QML_END_INSTR(StoreString)
550
551         QML_BEGIN_INSTR(StoreByteArray)
552             QObject *target = objects.top();
553             void *a[] = { (void *)&DATAS.at(instr.value), 0, &status, &flags };
554             QMetaObject::metacall(target, QMetaObject::WriteProperty,
555                                   instr.propertyIndex, a);
556         QML_END_INSTR(StoreByteArray)
557
558         QML_BEGIN_INSTR(StoreUrl)
559             QObject *target = objects.top();
560             CLEAN_PROPERTY(target, instr.propertyIndex);
561
562             void *a[] = { (void *)&URLS.at(instr.value), 0, &status, &flags };
563             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
564                                   instr.propertyIndex, a);
565         QML_END_INSTR(StoreUrl)
566
567         QML_BEGIN_INSTR(StoreFloat)
568             QObject *target = objects.top();
569             CLEAN_PROPERTY(target, instr.propertyIndex);
570
571             float f = instr.value;
572             void *a[] = { &f, 0, &status, &flags };
573             QMetaObject::metacall(target, QMetaObject::WriteProperty,
574                                   instr.propertyIndex, a);
575         QML_END_INSTR(StoreFloat)
576
577         QML_BEGIN_INSTR(StoreDouble)
578             QObject *target = objects.top();
579             CLEAN_PROPERTY(target, instr.propertyIndex);
580
581             double d = instr.value;
582             void *a[] = { &d, 0, &status, &flags };
583             QMetaObject::metacall(target, QMetaObject::WriteProperty,
584                                   instr.propertyIndex, a);
585         QML_END_INSTR(StoreDouble)
586
587         QML_BEGIN_INSTR(StoreBool)
588             QObject *target = objects.top();
589             CLEAN_PROPERTY(target, instr.propertyIndex);
590
591             void *a[] = { (void *)&instr.value, 0, &status, &flags };
592             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
593                                   instr.propertyIndex, a);
594         QML_END_INSTR(StoreBool)
595
596         QML_BEGIN_INSTR(StoreInteger)
597             QObject *target = objects.top();
598             CLEAN_PROPERTY(target, instr.propertyIndex);
599
600             void *a[] = { (void *)&instr.value, 0, &status, &flags };
601             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
602                                   instr.propertyIndex, a);
603         QML_END_INSTR(StoreInteger)
604
605         QML_BEGIN_INSTR(StoreColor)
606             QObject *target = objects.top();
607             CLEAN_PROPERTY(target, instr.propertyIndex);
608
609             QColor c = QColor::fromRgba(instr.value);
610             void *a[] = { &c, 0, &status, &flags };
611             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
612                                   instr.propertyIndex, a);
613         QML_END_INSTR(StoreColor)
614
615         QML_BEGIN_INSTR(StoreDate)
616             QObject *target = objects.top();
617             CLEAN_PROPERTY(target, instr.propertyIndex);
618
619             QDate d = QDate::fromJulianDay(instr.value);
620             void *a[] = { &d, 0, &status, &flags };
621             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
622                                   instr.propertyIndex, a);
623         QML_END_INSTR(StoreDate)
624
625         QML_BEGIN_INSTR(StoreTime)
626             QObject *target = objects.top();
627             CLEAN_PROPERTY(target, instr.propertyIndex);
628
629             QTime *t = (QTime *)&instr.time;
630             void *a[] = { t, 0, &status, &flags };
631             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
632                                   instr.propertyIndex, a);
633         QML_END_INSTR(StoreTime)
634
635         QML_BEGIN_INSTR(StoreDateTime)
636             QObject *target = objects.top();
637             CLEAN_PROPERTY(target, instr.propertyIndex);
638
639             QTime *t = (QTime *)&instr.time;
640             QDateTime dt(QDate::fromJulianDay(instr.date), *t);
641             void *a[] = { &dt, 0, &status, &flags };
642             QMetaObject::metacall(target, QMetaObject::WriteProperty,
643                                   instr.propertyIndex, a);
644         QML_END_INSTR(StoreDateTime)
645
646         QML_BEGIN_INSTR(StorePoint)
647             QObject *target = objects.top();
648             CLEAN_PROPERTY(target, instr.propertyIndex);
649
650             QPoint *p = (QPoint *)&instr.point;
651             void *a[] = { p, 0, &status, &flags };
652             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
653                                   instr.propertyIndex, a);
654         QML_END_INSTR(StorePoint)
655
656         QML_BEGIN_INSTR(StorePointF)
657             QObject *target = objects.top();
658             CLEAN_PROPERTY(target, instr.propertyIndex);
659
660             QPointF *p = (QPointF *)&instr.point;
661             void *a[] = { p, 0, &status, &flags };
662             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
663                                   instr.propertyIndex, a);
664         QML_END_INSTR(StorePointF)
665
666         QML_BEGIN_INSTR(StoreSize)
667             QObject *target = objects.top();
668             CLEAN_PROPERTY(target, instr.propertyIndex);
669
670             QSize *s = (QSize *)&instr.size;
671             void *a[] = { s, 0, &status, &flags };
672             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
673                                   instr.propertyIndex, a);
674         QML_END_INSTR(StoreSize)
675
676         QML_BEGIN_INSTR(StoreSizeF)
677             QObject *target = objects.top();
678             CLEAN_PROPERTY(target, instr.propertyIndex);
679
680             QSizeF *s = (QSizeF *)&instr.size;
681             void *a[] = { s, 0, &status, &flags };
682             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
683                                   instr.propertyIndex, a);
684         QML_END_INSTR(StoreSizeF)
685
686         QML_BEGIN_INSTR(StoreRect)
687             QObject *target = objects.top();
688             CLEAN_PROPERTY(target, instr.propertyIndex);
689
690             QRect *r = (QRect *)&instr.rect;
691             void *a[] = { r, 0, &status, &flags };
692             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
693                                   instr.propertyIndex, a);
694         QML_END_INSTR(StoreRect)
695
696         QML_BEGIN_INSTR(StoreRectF)
697             QObject *target = objects.top();
698             CLEAN_PROPERTY(target, instr.propertyIndex);
699
700             QRectF *r = (QRectF *)&instr.rect;
701             void *a[] = { r, 0, &status, &flags };
702             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
703                                   instr.propertyIndex, a);
704         QML_END_INSTR(StoreRectF)
705
706         QML_BEGIN_INSTR(StoreVector3D)
707             QObject *target = objects.top();
708             CLEAN_PROPERTY(target, instr.propertyIndex);
709
710             QVector3D *v = (QVector3D *)&instr.vector;
711             void *a[] = { v, 0, &status, &flags };
712             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
713                                   instr.propertyIndex, a);
714         QML_END_INSTR(StoreVector3D)
715
716         QML_BEGIN_INSTR(StoreVector4D)
717             QObject *target = objects.top();
718             CLEAN_PROPERTY(target, instr.propertyIndex);
719
720             QVector4D *v = (QVector4D *)&instr.vector;
721             void *a[] = { v, 0, &status, &flags };
722             QMetaObject::metacall(target, QMetaObject::WriteProperty,
723                                   instr.propertyIndex, a);
724         QML_END_INSTR(StoreVector4D)
725
726         QML_BEGIN_INSTR(StoreObject)
727             QObject *assignObj = objects.pop();
728             QObject *target = objects.top();
729             CLEAN_PROPERTY(target, instr.propertyIndex);
730
731             void *a[] = { (void *)&assignObj, 0, &status, &flags };
732             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
733                                   instr.propertyIndex, a);
734         QML_END_INSTR(StoreObject)
735
736         QML_BEGIN_INSTR(AssignCustomType)
737             QObject *target = objects.top();
738             CLEAN_PROPERTY(target, instr.propertyIndex);
739
740             const QString &primitive = PRIMITIVES.at(instr.primitive);
741             int type = instr.type;
742             QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type);
743             QVariant v = (*converter)(primitive);
744
745             QMetaProperty prop = 
746                     target->metaObject()->property(instr.propertyIndex);
747             if (v.isNull() || ((int)prop.type() != type && prop.userType() != type)) 
748                 VME_EXCEPTION(tr("Cannot assign value %1 to property %2").arg(primitive).arg(QString::fromUtf8(prop.name())), instr.line);
749
750             void *a[] = { (void *)v.data(), 0, &status, &flags };
751             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
752                                   instr.propertyIndex, a);
753         QML_END_INSTR(AssignCustomType)
754
755         QML_BEGIN_INSTR(AssignSignalObject)
756             // XXX optimize
757
758             QObject *assign = objects.pop();
759             QObject *target = objects.top();
760             int sigIdx = instr.signal;
761             const QString &pr = PRIMITIVES.at(sigIdx);
762
763             QDeclarativeProperty prop(target, pr);
764             if (prop.type() & QDeclarativeProperty::SignalProperty) {
765
766                 QMetaMethod method = QDeclarativeMetaType::defaultMethod(assign);
767                 if (method.signature() == 0)
768                     VME_EXCEPTION(tr("Cannot assign object type %1 with no default method").arg(QString::fromLatin1(assign->metaObject()->className())), instr.line);
769
770                 if (!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature()))
771                     VME_EXCEPTION(tr("Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature())), instr.line);
772
773                 QDeclarativePropertyPrivate::connect(target, prop.index(), assign, method.methodIndex());
774
775             } else {
776                 VME_EXCEPTION(tr("Cannot assign an object to signal property %1").arg(pr), instr.line);
777             }
778
779
780         QML_END_INSTR(AssignSignalObject)
781
782         QML_BEGIN_INSTR(StoreSignal)
783             QObject *target = objects.top();
784             QObject *context = objects.at(objects.count() - 1 - instr.context);
785
786             QMetaMethod signal = target->metaObject()->method(instr.signalIndex);
787
788             QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target);
789             QDeclarativeExpression *expr = 
790                 new QDeclarativeExpression(CTXT, context, PRIMITIVES.at(instr.value));
791             expr->setSourceLocation(COMP->name, instr.line);
792             static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = QString::fromUtf8(DATAS.at(instr.name));
793             bs->setExpression(expr);
794         QML_END_INSTR(StoreSignal)
795
796         QML_BEGIN_INSTR(StoreImportedScript)
797             CTXT->importedScripts << run(CTXT, SCRIPTS.at(instr.value));
798         QML_END_INSTR(StoreImportedScript)
799
800         QML_BEGIN_INSTR(StoreScriptString)
801             QObject *target = objects.top();
802             QObject *scope = objects.at(objects.count() - 1 - instr.scope);
803             QDeclarativeScriptString ss;
804             ss.setContext(CTXT->asQDeclarativeContext());
805             ss.setScopeObject(scope);
806             ss.setScript(PRIMITIVES.at(instr.value));
807             ss.d.data()->bindingId = instr.bindingId;
808             ss.d.data()->lineNumber = instr.line;
809
810             void *a[] = { &ss, 0, &status, &flags };
811             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
812                                   instr.propertyIndex, a);
813         QML_END_INSTR(StoreScriptString)
814
815         QML_BEGIN_INSTR(BeginObject)
816             QObject *target = objects.top();
817             QDeclarativeParserStatus *status = reinterpret_cast<QDeclarativeParserStatus *>(reinterpret_cast<char *>(target) + instr.castValue);
818             parserStatus.push(status);
819             status->d = &parserStatus.top();
820
821             status->classBegin();
822         QML_END_INSTR(BeginObject)
823
824         QML_BEGIN_INSTR(InitV8Bindings)
825             CTXT->v8bindings = new QV8Bindings(PRIMITIVES.at(instr.program), instr.programIndex, 
826                                                        instr.line, COMP, CTXT);
827         QML_END_INSTR(InitV8Bindings)
828
829         QML_BEGIN_INSTR(StoreBinding)
830             QObject *target = 
831                 objects.at(objects.count() - 1 - instr.owner);
832             QObject *context = 
833                 objects.at(objects.count() - 1 - instr.context);
834
835             QDeclarativeProperty mp = 
836                 QDeclarativePropertyPrivate::restore(DATAS.at(instr.property), target, CTXT);
837
838             int coreIndex = mp.index();
839
840             if (instr.isRoot && BINDINGSKIPLIST.testBit(coreIndex)) 
841                 QML_NEXT_INSTR(StoreBinding);
842
843             QDeclarativeBinding *bind = new QDeclarativeBinding(PRIMITIVES.at(instr.value), true, 
844                                                                 context, CTXT, COMP->name, instr.line);
845             bindValues.push(bind);
846             bind->m_mePtr = &bindValues.top();
847             bind->setTarget(mp);
848
849             bind->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp));
850         QML_END_INSTR(StoreBinding)
851
852         QML_BEGIN_INSTR(StoreBindingOnAlias)
853             QObject *target = 
854                 objects.at(objects.count() - 1 - instr.owner);
855             QObject *context = 
856                 objects.at(objects.count() - 1 - instr.context);
857
858             QDeclarativeProperty mp = 
859                 QDeclarativePropertyPrivate::restore(DATAS.at(instr.property), target, CTXT);
860
861             int coreIndex = mp.index();
862
863             if (instr.isRoot && BINDINGSKIPLIST.testBit(coreIndex)) 
864                 QML_NEXT_INSTR(StoreBindingOnAlias);
865
866             QDeclarativeBinding *bind = new QDeclarativeBinding(PRIMITIVES.at(instr.value), true,
867                                                                 context, CTXT, COMP->name, instr.line);
868             bindValues.push(bind);
869             bind->m_mePtr = &bindValues.top();
870             bind->setTarget(mp);
871
872             QDeclarativeAbstractBinding *old = QDeclarativePropertyPrivate::setBindingNoEnable(target, coreIndex, QDeclarativePropertyPrivate::valueTypeCoreIndex(mp), bind);
873             if (old) { old->destroy(); }
874         QML_END_INSTR(StoreBindingOnAlias)
875
876         QML_BEGIN_INSTR(StoreV4Binding)
877             QObject *target = 
878                 objects.at(objects.count() - 1 - instr.owner);
879             QObject *scope = 
880                 objects.at(objects.count() - 1 - instr.context);
881
882             int property = instr.property;
883             if (instr.isRoot && BINDINGSKIPLIST.testBit(property & 0xFFFF))
884                 QML_NEXT_INSTR(StoreV4Binding);
885
886             QDeclarativeAbstractBinding *binding = 
887                 CTXT->v4bindings->configBinding(instr.value, target, scope, property);
888             bindValues.push(binding);
889             binding->m_mePtr = &bindValues.top();
890             binding->addToObject(target, property);
891         QML_END_INSTR(StoreV4Binding)
892
893         QML_BEGIN_INSTR(StoreV8Binding)
894             QObject *target = 
895                 objects.at(objects.count() - 1 - instr.owner);
896             QObject *scope = 
897                 objects.at(objects.count() - 1 - instr.context);
898
899             QDeclarativeProperty mp = 
900                 QDeclarativePropertyPrivate::restore(DATAS.at(instr.property), target, CTXT);
901
902             int coreIndex = mp.index();
903
904             if (instr.isRoot && BINDINGSKIPLIST.testBit(coreIndex))
905                 QML_NEXT_INSTR(StoreV8Binding);
906
907             QDeclarativeAbstractBinding *binding = 
908                 CTXT->v8bindings->configBinding(instr.value, target, scope, mp, instr.line);
909             bindValues.push(binding);
910             binding->m_mePtr = &bindValues.top();
911             binding->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp));
912         QML_END_INSTR(StoreV8Binding)
913
914         QML_BEGIN_INSTR(StoreValueSource)
915             QObject *obj = objects.pop();
916             QDeclarativePropertyValueSource *vs = reinterpret_cast<QDeclarativePropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.castValue);
917             QObject *target = objects.at(objects.count() - 1 - instr.owner);
918
919             QDeclarativeProperty prop = 
920                 QDeclarativePropertyPrivate::restore(DATAS.at(instr.property), target, CTXT);
921             obj->setParent(target);
922             vs->setTarget(prop);
923         QML_END_INSTR(StoreValueSource)
924
925         QML_BEGIN_INSTR(StoreValueInterceptor)
926             QObject *obj = objects.pop();
927             QDeclarativePropertyValueInterceptor *vi = reinterpret_cast<QDeclarativePropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.castValue);
928             QObject *target = objects.at(objects.count() - 1 - instr.owner);
929             QDeclarativeProperty prop = 
930                 QDeclarativePropertyPrivate::restore(DATAS.at(instr.property), target, CTXT);
931             obj->setParent(target);
932             vi->setTarget(prop);
933             QDeclarativeVMEMetaObject *mo = static_cast<QDeclarativeVMEMetaObject *>((QMetaObject*)target->metaObject());
934             mo->registerInterceptor(prop.index(), QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), vi);
935         QML_END_INSTR(StoreValueInterceptor)
936
937         QML_BEGIN_INSTR(StoreObjectQList)
938             QObject *assign = objects.pop();
939
940             const List &list = lists.top();
941             list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, assign);
942         QML_END_INSTR(StoreObjectQList)
943
944         QML_BEGIN_INSTR(AssignObjectList)
945             // This is only used for assigning interfaces
946             QObject *assign = objects.pop();
947             const List &list = lists.top();
948
949             int type = list.type;
950
951             void *ptr = 0;
952
953             const char *iid = QDeclarativeMetaType::interfaceIId(type);
954             if (iid) 
955                 ptr = assign->qt_metacast(iid);
956             if (!ptr) 
957                 VME_EXCEPTION(tr("Cannot assign object to list"), instr.line);
958
959
960             list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, ptr);
961         QML_END_INSTR(AssignObjectList)
962
963         QML_BEGIN_INSTR(StoreVariantObject)
964             QObject *assign = objects.pop();
965             QObject *target = objects.top();
966             CLEAN_PROPERTY(target, instr.propertyIndex);
967
968             QVariant v = QVariant::fromValue(assign);
969             void *a[] = { &v, 0, &status, &flags };
970             QMetaObject::metacall(target, QMetaObject::WriteProperty, 
971                                   instr.propertyIndex, a);
972         QML_END_INSTR(StoreVariantObject)
973
974         QML_BEGIN_INSTR(StoreInterface)
975             QObject *assign = objects.pop();
976             QObject *target = objects.top();
977             CLEAN_PROPERTY(target, instr.propertyIndex);
978
979             int coreIdx = instr.propertyIndex;
980             QMetaProperty prop = target->metaObject()->property(coreIdx);
981             int t = prop.userType();
982             const char *iid = QDeclarativeMetaType::interfaceIId(t);
983             bool ok = false;
984             if (iid) {
985                 void *ptr = assign->qt_metacast(iid);
986                 if (ptr) {
987                     void *a[] = { &ptr, 0, &status, &flags };
988                     QMetaObject::metacall(target, 
989                                           QMetaObject::WriteProperty,
990                                           coreIdx, a);
991                     ok = true;
992                 }
993             } 
994
995             if (!ok) 
996                 VME_EXCEPTION(tr("Cannot assign object to interface property"), instr.line);
997         QML_END_INSTR(StoreInterface)
998             
999         QML_BEGIN_INSTR(FetchAttached)
1000             QObject *target = objects.top();
1001
1002             QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.id, target);
1003
1004             if (!qmlObject)
1005                 VME_EXCEPTION(tr("Unable to create attached object"), instr.line);
1006
1007             objects.push(qmlObject);
1008         QML_END_INSTR(FetchAttached)
1009
1010         QML_BEGIN_INSTR(FetchQList)
1011             QObject *target = objects.top();
1012
1013             lists.push(List(instr.type));
1014
1015             void *a[1];
1016             a[0] = (void *)&(lists.top().qListProperty);
1017             QMetaObject::metacall(target, QMetaObject::ReadProperty, 
1018                                   instr.property, a);
1019         QML_END_INSTR(FetchQList)
1020
1021         QML_BEGIN_INSTR(FetchObject)
1022             QObject *target = objects.top();
1023
1024             QObject *obj = 0;
1025             // NOTE: This assumes a cast to QObject does not alter the 
1026             // object pointer
1027             void *a[1];
1028             a[0] = &obj;
1029             QMetaObject::metacall(target, QMetaObject::ReadProperty, 
1030                                   instr.property, a);
1031
1032             if (!obj)
1033                 VME_EXCEPTION(tr("Cannot set properties on %1 as it is null").arg(QString::fromUtf8(target->metaObject()->property(instr.property).name())), instr.line);
1034
1035             objects.push(obj);
1036         QML_END_INSTR(FetchObject)
1037
1038         QML_BEGIN_INSTR(PopQList)
1039             lists.pop();
1040         QML_END_INSTR(PopQList)
1041
1042         QML_BEGIN_INSTR(Defer)
1043             if (instr.deferCount) {
1044                 QObject *target = objects.top();
1045                 QDeclarativeData *data = 
1046                     QDeclarativeData::get(target, true);
1047                 COMP->addref();
1048                 data->deferredComponent = COMP;
1049                 data->deferredIdx = INSTRUCTIONSTREAM - COMP->bytecode.constData();
1050                 INSTRUCTIONSTREAM += instr.deferCount;
1051             }
1052         QML_END_INSTR(Defer)
1053
1054         QML_BEGIN_INSTR(PopFetchedObject)
1055             objects.pop();
1056         QML_END_INSTR(PopFetchedObject)
1057
1058         QML_BEGIN_INSTR(FetchValueType)
1059             QObject *target = objects.top();
1060
1061             if (instr.bindingSkipList != 0) {
1062                 // Possibly need to clear bindings
1063                 QDeclarativeData *targetData = QDeclarativeData::get(target);
1064                 if (targetData) {
1065                     QDeclarativeAbstractBinding *binding = 
1066                         QDeclarativePropertyPrivate::binding(target, instr.property, -1);
1067
1068                     if (binding && binding->bindingType() != QDeclarativeAbstractBinding::ValueTypeProxy) {
1069                         QDeclarativePropertyPrivate::setBinding(target, instr.property, -1, 0);
1070                         binding->destroy();
1071                     } else if (binding) {
1072                         QDeclarativeValueTypeProxyBinding *proxy = 
1073                             static_cast<QDeclarativeValueTypeProxyBinding *>(binding);
1074                         proxy->removeBindings(instr.bindingSkipList);
1075                     }
1076                 }
1077             }
1078
1079             QDeclarativeValueType *valueHandler = ep->valueTypes[instr.type];
1080             valueHandler->read(target, instr.property);
1081             objects.push(valueHandler);
1082         QML_END_INSTR(FetchValueType)
1083
1084         QML_BEGIN_INSTR(PopValueType)
1085             QDeclarativeValueType *valueHandler = 
1086                 static_cast<QDeclarativeValueType *>(objects.pop());
1087             QObject *target = objects.top();
1088             valueHandler->write(target, instr.property, QDeclarativePropertyPrivate::BypassInterceptor);
1089         QML_END_INSTR(PopValueType)
1090
1091 #ifdef QML_THREADED_VME_INTERPRETER
1092     // nothing to do
1093 #else
1094         default:
1095             qFatal("QDeclarativeCompiledData: Internal error - unknown instruction %d", genericInstr->common.instructionType);
1096             break;
1097         }
1098     }
1099 #endif
1100
1101 exceptionExit:
1102     if (!objects.isEmpty()) 
1103         delete objects.at(0); // XXX What about failures in deferred creation?
1104     
1105     // XXX does context get leaked in this case?
1106
1107     Q_ASSERT(!errors->isEmpty());
1108
1109     // Remove the QDeclarativeParserStatus and QDeclarativeAbstractBinding back pointers
1110     blank(parserStatus);
1111     blank(bindValues);
1112
1113     objects.deallocate();
1114     lists.deallocate();
1115     states.clear();
1116     bindValues.deallocate();
1117     parserStatus.deallocate();
1118     finalizeCallbacks.clear();
1119
1120     return 0;
1121
1122 normalExit:
1123     Q_ASSERT(objects.count() == 1);
1124
1125     QObject *rv = objects.top();
1126
1127     objects.deallocate();
1128     lists.deallocate();
1129     states.clear();
1130
1131     return rv;
1132 }
1133
1134 // Must be called with a handle scope and context
1135 void QDeclarativeScriptData::initialize(QDeclarativeEngine *engine)
1136 {
1137     Q_ASSERT(m_program.IsEmpty());
1138     Q_ASSERT(engine);
1139     Q_ASSERT(!hasEngine());
1140
1141     QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
1142     QV8Engine *v8engine = ep->v8engine();
1143
1144     // XXX Handle errors during the script compile!
1145     v8::Local<v8::Script> program = v8engine->qmlModeCompile(m_programSource, url.toString(), 1);
1146     m_program = qPersistentNew<v8::Script>(program);
1147
1148     addToEngine(engine);
1149
1150     addref();
1151 }
1152
1153 v8::Persistent<v8::Object> QDeclarativeVME::run(QDeclarativeContextData *parentCtxt, QDeclarativeScriptData *script)
1154 {
1155     if (script->m_loaded)
1156         return qPersistentNew<v8::Object>(script->m_value);
1157
1158     QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(parentCtxt->engine);
1159     QV8Engine *v8engine = ep->v8engine();
1160
1161     bool shared = script->pragmas & QDeclarativeScript::Object::ScriptBlock::Shared;
1162
1163     QDeclarativeContextData *effectiveCtxt = parentCtxt;
1164     if (shared)
1165         effectiveCtxt = 0;
1166
1167     // Create the script context if required
1168     QDeclarativeContextData *ctxt = new QDeclarativeContextData;
1169     ctxt->isInternal = true;
1170     ctxt->isJSContext = true;
1171     if (shared)
1172         ctxt->isPragmaLibraryContext = true;
1173     else
1174         ctxt->isPragmaLibraryContext = parentCtxt->isPragmaLibraryContext;
1175     ctxt->url = script->url;
1176
1177     // For backward compatibility, if there are no imports, we need to use the
1178     // imports from the parent context.  See QTBUG-17518.
1179     if (!script->importCache->isEmpty()) {
1180         ctxt->imports = script->importCache;
1181     } else if (effectiveCtxt) {
1182         ctxt->imports = effectiveCtxt->imports;
1183         ctxt->importedScripts = effectiveCtxt->importedScripts;
1184         for (int ii = 0; ii < ctxt->importedScripts.count(); ++ii)
1185             ctxt->importedScripts[ii] = qPersistentNew<v8::Object>(ctxt->importedScripts[ii]);
1186     }
1187
1188     if (ctxt->imports) {
1189         ctxt->imports->addref();
1190     }
1191
1192     if (effectiveCtxt)
1193         ctxt->setParent(effectiveCtxt, true);
1194
1195     for (int ii = 0; ii < script->scripts.count(); ++ii) {
1196         ctxt->importedScripts << run(ctxt, script->scripts.at(ii)->scriptData());
1197     }
1198
1199     v8::HandleScope handle_scope;
1200     v8::Context::Scope scope(v8engine->context());
1201
1202     if (!script->isInitialized()) 
1203         script->initialize(parentCtxt->engine);
1204
1205     v8::Local<v8::Object> qmlglobal = v8engine->qmlScope(ctxt, 0);
1206
1207     v8::TryCatch try_catch;
1208     script->m_program->Run(qmlglobal);
1209
1210     v8::Persistent<v8::Object> rv;
1211     
1212     if (try_catch.HasCaught()) {
1213         v8::Local<v8::Message> message = try_catch.Message();
1214         if (!message.IsEmpty()) {
1215             QDeclarativeError error;
1216             QDeclarativeExpressionPrivate::exceptionToError(message, error);
1217             ep->warning(error);
1218         }
1219     } 
1220
1221     rv = qPersistentNew<v8::Object>(qmlglobal);
1222     if (shared) {
1223         script->m_value = qPersistentNew<v8::Object>(qmlglobal);
1224         script->m_loaded = true;
1225     }
1226
1227     return rv;
1228 }
1229
1230 #ifdef QML_THREADED_VME_INTERPRETER
1231 void **QDeclarativeVME::instructionJumpTable()
1232 {
1233     static void **jumpTable = 0;
1234     if (!jumpTable) {
1235         QDeclarativeVME dummy;
1236         QDeclarativeVME::Interrupt i;
1237         dummy.run(0, i, &jumpTable);
1238     }
1239     return jumpTable;
1240 }
1241 #endif
1242
1243 bool QDeclarativeVME::complete(const Interrupt &interrupt) 
1244 {
1245     ActiveVMERestorer restore(this, QDeclarativeEnginePrivate::get(engine));
1246
1247     while (!bindValues.isEmpty()) {
1248         QDeclarativeAbstractBinding *b = bindValues.pop();
1249
1250         if(b) {
1251             b->m_mePtr = 0;
1252             b->setEnabled(true, QDeclarativePropertyPrivate::BypassInterceptor | 
1253                                 QDeclarativePropertyPrivate::DontRemoveBinding);
1254         }
1255
1256         if (interrupt.shouldInterrupt())
1257             return false;
1258     }
1259     bindValues.deallocate();
1260
1261     while (!parserStatus.isEmpty()) {
1262         QDeclarativeParserStatus *status = parserStatus.pop();
1263
1264         if (status && status->d) {
1265             status->d = 0;
1266             status->componentComplete();
1267         }
1268         
1269         if (interrupt.shouldInterrupt())
1270             return false;
1271     }
1272     parserStatus.deallocate();
1273
1274     while (componentAttached) {
1275         QDeclarativeComponentAttached *a = componentAttached;
1276         a->rem();
1277         QDeclarativeData *d = QDeclarativeData::get(a->parent());
1278         Q_ASSERT(d);
1279         Q_ASSERT(d->context);
1280         a->add(&d->context->componentAttached);
1281         emit a->completed();
1282
1283         if (interrupt.shouldInterrupt())
1284             return false;
1285     }
1286
1287     // XXX (what if its deleted?)
1288     if (rootContext) 
1289         rootContext->activeVME = 0;
1290
1291     for (int ii = 0; ii < finalizeCallbacks.count(); ++ii) {
1292         QDeclarativeEnginePrivate::FinalizeCallback callback = finalizeCallbacks.at(ii);
1293         QObject *obj = callback.first;
1294         if (obj) {
1295             void *args[] = { 0 };
1296             QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, callback.second, args);
1297         }
1298     }
1299     finalizeCallbacks.clear();
1300
1301     return true;
1302 }
1303
1304 void QDeclarativeVME::blank(QFiniteStack<QDeclarativeAbstractBinding *> &bs)
1305 {
1306     for (int ii = 0; ii < bs.count(); ++ii) {
1307         QDeclarativeAbstractBinding *b = bs.at(ii);
1308         if (b) b->m_mePtr = 0;
1309     }
1310 }
1311
1312 void QDeclarativeVME::blank(QFiniteStack<QDeclarativeParserStatus *> &pss)
1313 {
1314     for (int ii = 0; ii < pss.count(); ++ii) {
1315         QDeclarativeParserStatus *ps = pss.at(ii);
1316         if(ps) ps->d = 0;
1317     }
1318 }
1319
1320 QT_END_NAMESPACE