1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQMLVME_P_H
41#define QQMLVME_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include "qqmlerror.h"
55#include <private/qbitfield_p.h>
56#include <private/qrecursionwatcher_p.h>
57
58#include <QtCore/QStack>
59#include <QtCore/QString>
60#include <QtCore/qelapsedtimer.h>
61#include <QtCore/qcoreapplication.h>
62#include <QtCore/qtypeinfo.h>
63
64#include <private/qqmlengine_p.h>
65#include <private/qfinitestack_p.h>
66
67QT_BEGIN_NAMESPACE
68
69class QObject;
70class QJSValue;
71class QQmlScriptData;
72class QQmlContextData;
73
74namespace QQmlVMETypes {
75 struct List
76 {
77 List() : type(0) {}
78 List(int t) : type(t) {}
79
80 int type;
81 QQmlListProperty<void> qListProperty;
82 };
83 struct State {
84 enum Flag { Deferred = 0x00000001 };
85
86 State() : flags(0), context(nullptr), instructionStream(nullptr) {}
87 quint32 flags;
88 QQmlContextData *context;
89 const char *instructionStream;
90 QBitField bindingSkipList;
91 };
92}
93Q_DECLARE_TYPEINFO(QQmlVMETypes::List, Q_PRIMITIVE_TYPE | Q_MOVABLE_TYPE);
94template<>
95class QTypeInfo<QQmlVMETypes::State> : public QTypeInfoMerger<QQmlVMETypes::State, QBitField> {}; //Q_DECLARE_TYPEINFO
96
97class QQmlInstantiationInterrupt {
98public:
99 inline QQmlInstantiationInterrupt();
100 inline QQmlInstantiationInterrupt(volatile bool *runWhile, int nsecs=0);
101 inline QQmlInstantiationInterrupt(int nsecs);
102
103 inline void reset();
104 inline bool shouldInterrupt() const;
105private:
106 enum Mode { None, Time, Flag };
107 Mode mode;
108 QElapsedTimer timer;
109 int nsecs;
110 volatile bool *runWhile;
111};
112
113class Q_QML_PRIVATE_EXPORT QQmlVME
114{
115public:
116 static void enableComponentComplete();
117 static void disableComponentComplete();
118 static bool componentCompleteEnabled();
119
120private:
121 static bool s_enableComponentComplete;
122};
123
124// Used to check that a QQmlVME that is interrupted mid-execution
125// is still valid. Checks all the objects and contexts have not been
126// deleted.
127//
128// VME stands for Virtual Machine Execution. QML files used to
129// be compiled to a byte code data structure that a virtual machine executed
130// (for constructing the tree of QObjects and setting properties).
131class QQmlVMEGuard
132{
133public:
134 QQmlVMEGuard();
135 ~QQmlVMEGuard();
136
137 void guard(QQmlObjectCreator *);
138 void clear();
139
140 bool isOK() const;
141
142private:
143 int m_objectCount;
144 QPointer<QObject> *m_objects;
145 int m_contextCount;
146 QQmlGuardedContextData *m_contexts;
147};
148
149QQmlInstantiationInterrupt::QQmlInstantiationInterrupt()
150 : mode(None), nsecs(0), runWhile(nullptr)
151{
152}
153
154QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(volatile bool *runWhile, int nsecs)
155 : mode(Flag), nsecs(nsecs), runWhile(runWhile)
156{
157}
158
159QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(int nsecs)
160 : mode(Time), nsecs(nsecs), runWhile(nullptr)
161{
162}
163
164void QQmlInstantiationInterrupt::reset()
165{
166 if (mode == Time || nsecs)
167 timer.start();
168}
169
170bool QQmlInstantiationInterrupt::shouldInterrupt() const
171{
172 if (mode == None) {
173 return false;
174 } else if (mode == Time) {
175 return timer.nsecsElapsed() > nsecs;
176 } else if (mode == Flag) {
177 return !*runWhile || (nsecs && timer.nsecsElapsed() > nsecs);
178 } else {
179 return false;
180 }
181}
182
183QT_END_NAMESPACE
184
185#endif // QQMLVME_P_H
186