Allow incubators to be driven recursively
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativevme_p.h
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 #ifndef QDECLARATIVEVME_P_H
43 #define QDECLARATIVEVME_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "qdeclarativeerror.h"
57 #include "private/qbitfield_p.h"
58 #include "private/qdeclarativeinstruction_p.h"
59 #include "private/qrecursionwatcher_p.h"
60
61 #include <QtCore/QStack>
62 #include <QtCore/QString>
63 #include <QtCore/qelapsedtimer.h>
64 #include <QtCore/qcoreapplication.h>
65
66 #include <private/qv8_p.h>
67 #include <private/qdeclarativeengine_p.h>
68 #include <private/qfinitestack_p.h>
69
70 QT_BEGIN_NAMESPACE
71
72 class QObject;
73 class QJSValue;
74 class QDeclarativeScriptData;
75 class QDeclarativeCompiledData;
76 class QDeclarativeCompiledData;
77 class QDeclarativeContextData;
78
79 namespace QDeclarativeVMETypes {
80     struct List
81     {
82         List() : type(0) {}
83         List(int t) : type(t) {}
84
85         int type;
86         QDeclarativeListProperty<void> qListProperty;
87     };
88 }
89 Q_DECLARE_TYPEINFO(QDeclarativeVMETypes::List, Q_PRIMITIVE_TYPE  | Q_MOVABLE_TYPE);
90
91 class QDeclarativeVME
92 {
93     Q_DECLARE_TR_FUNCTIONS(QDeclarativeVME)
94 public:
95     class Interrupt {
96     public:
97         inline Interrupt();
98         inline Interrupt(bool *runWhile);
99         inline Interrupt(int nsecs);
100
101         inline void reset();
102         inline bool shouldInterrupt() const;
103     private:
104         enum Mode { None, Time, Flag };
105         Mode mode;
106         union {
107             struct {
108                 QElapsedTimer timer;
109                 int nsecs;
110             };
111             bool *runWhile;
112         };
113     };
114
115     QDeclarativeVME() : data(0), componentAttached(0) {}
116     QDeclarativeVME(void *data) : data(data), componentAttached(0) {}
117
118     void *data;
119     QDeclarativeComponentAttached *componentAttached;
120     QList<QDeclarativeEnginePrivate::FinalizeCallback> finalizeCallbacks;
121
122     void init(QDeclarativeContextData *, QDeclarativeCompiledData *, int start);
123     bool initDeferred(QObject *);
124     void reset();
125
126     QObject *execute(QList<QDeclarativeError> *errors, const Interrupt & = Interrupt());
127     bool complete(const Interrupt & = Interrupt());
128
129 private:
130     friend class QDeclarativeVMEGuard;
131
132     QObject *run(QList<QDeclarativeError> *errors, const Interrupt &
133 #ifdef QML_THREADED_VME_INTERPRETER
134                  , void ***storeJumpTable = 0
135 #endif
136                 );
137     v8::Persistent<v8::Object> run(QDeclarativeContextData *, QDeclarativeScriptData *);
138
139 #ifdef QML_THREADED_VME_INTERPRETER
140     static void **instructionJumpTable();
141     friend class QDeclarativeCompiledData;
142 #endif
143
144     QDeclarativeEngine *engine;
145     QRecursionNode recursion;
146
147     QFiniteStack<QObject *> objects;
148     QFiniteStack<QDeclarativeVMETypes::List> lists;
149
150     QFiniteStack<QDeclarativeAbstractBinding *> bindValues;
151     QFiniteStack<QDeclarativeParserStatus *> parserStatus;
152     QDeclarativeGuardedContextData rootContext;
153
154     struct State {
155         enum Flag { Deferred = 0x00000001 };
156
157         State() : flags(0), context(0), compiledData(0), instructionStream(0) {}
158         quint32 flags;
159         QDeclarativeContextData *context;
160         QDeclarativeCompiledData *compiledData;
161         const char *instructionStream;
162         QBitField bindingSkipList;
163     };
164
165     QStack<State> states;
166
167     static void blank(QFiniteStack<QDeclarativeParserStatus *> &);
168     static void blank(QFiniteStack<QDeclarativeAbstractBinding *> &);
169 };
170
171 // Used to check that a QDeclarativeVME that is interrupted mid-execution
172 // is still valid.  Checks all the objects and contexts have not been 
173 // deleted.
174 class QDeclarativeVMEGuard
175 {
176 public:
177     QDeclarativeVMEGuard();
178     ~QDeclarativeVMEGuard();
179
180     void guard(QDeclarativeVME *);
181     void clear();
182
183     bool isOK() const;
184
185 private:
186     int m_objectCount;
187     QDeclarativeGuard<QObject> *m_objects;
188     int m_contextCount;
189     QDeclarativeGuardedContextData *m_contexts;
190 };
191
192 QDeclarativeVME::Interrupt::Interrupt()
193 : mode(None)
194 {
195 }
196
197 QDeclarativeVME::Interrupt::Interrupt(bool *runWhile)
198 : mode(Flag), runWhile(runWhile)
199 {
200 }
201
202 QDeclarativeVME::Interrupt::Interrupt(int nsecs)
203 : mode(Time), nsecs(nsecs)
204 {
205 }
206
207 void QDeclarativeVME::Interrupt::reset()
208 {
209     if (mode == Time) 
210         timer.start();
211 }
212
213 bool QDeclarativeVME::Interrupt::shouldInterrupt() const
214 {
215     if (mode == None) {
216         return false;
217     } else if (mode == Time) {
218         return timer.nsecsElapsed() > nsecs;
219     } else if (mode == Flag) {
220         return !*runWhile;
221     } else {
222         return false;
223     }
224 }
225
226 QT_END_NAMESPACE
227
228 #endif // QDECLARATIVEVME_P_H