aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlvme_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlvme_p.h')
-rw-r--r--src/qml/qml/qqmlvme_p.h240
1 files changed, 240 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
new file mode 100644
index 0000000000..8c8d4d079e
--- /dev/null
+++ b/src/qml/qml/qqmlvme_p.h
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLVME_P_H
+#define QQMLVME_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qqmlerror.h"
+#include <private/qbitfield_p.h>
+#include "qqmlinstruction_p.h"
+#include <private/qrecursionwatcher_p.h>
+
+#include <QtCore/QStack>
+#include <QtCore/QString>
+#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <private/qv8_p.h>
+#include <private/qqmlengine_p.h>
+#include <private/qfinitestack_p.h>
+
+#include <private/qqmltrace_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+class QJSValue;
+class QQmlScriptData;
+class QQmlCompiledData;
+class QQmlCompiledData;
+class QQmlContextData;
+
+namespace QQmlVMETypes {
+ struct List
+ {
+ List() : type(0) {}
+ List(int t) : type(t) {}
+
+ int type;
+ QQmlListProperty<void> qListProperty;
+ };
+}
+Q_DECLARE_TYPEINFO(QQmlVMETypes::List, Q_PRIMITIVE_TYPE | Q_MOVABLE_TYPE);
+
+class QQmlVME
+{
+ Q_DECLARE_TR_FUNCTIONS(QQmlVME)
+public:
+ class Interrupt {
+ public:
+ inline Interrupt();
+ inline Interrupt(bool *runWhile);
+ inline Interrupt(int nsecs);
+
+ inline void reset();
+ inline bool shouldInterrupt() const;
+ private:
+ enum Mode { None, Time, Flag };
+ Mode mode;
+ union {
+ struct {
+ QElapsedTimer timer;
+ int nsecs;
+ };
+ bool *runWhile;
+ };
+ };
+
+ QQmlVME() : data(0), componentAttached(0) {}
+ QQmlVME(void *data) : data(data), componentAttached(0) {}
+
+ void *data;
+ QQmlComponentAttached *componentAttached;
+ QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
+
+ void init(QQmlContextData *, QQmlCompiledData *, int start,
+ QQmlContextData * = 0);
+ bool initDeferred(QObject *);
+ void reset();
+
+ QObject *execute(QList<QQmlError> *errors, const Interrupt & = Interrupt());
+ QQmlContextData *complete(const Interrupt & = Interrupt());
+
+private:
+ friend class QQmlVMEGuard;
+
+ QObject *run(QList<QQmlError> *errors, const Interrupt &
+#ifdef QML_THREADED_VME_INTERPRETER
+ , void ***storeJumpTable = 0
+#endif
+ );
+ v8::Persistent<v8::Object> run(QQmlContextData *, QQmlScriptData *);
+
+#ifdef QML_THREADED_VME_INTERPRETER
+ static void **instructionJumpTable();
+ friend class QQmlCompiledData;
+#endif
+
+ QQmlEngine *engine;
+ QRecursionNode recursion;
+
+#ifdef QML_ENABLE_TRACE
+ QQmlCompiledData *rootComponent;
+#endif
+
+ QFiniteStack<QObject *> objects;
+ QFiniteStack<QQmlVMETypes::List> lists;
+
+ QFiniteStack<QQmlAbstractBinding *> bindValues;
+ QFiniteStack<QQmlParserStatus *> parserStatus;
+#ifdef QML_ENABLE_TRACE
+ QFiniteStack<QQmlData *> parserStatusData;
+#endif
+
+ QQmlGuardedContextData rootContext;
+ QQmlGuardedContextData creationContext;
+
+ struct State {
+ enum Flag { Deferred = 0x00000001 };
+
+ State() : flags(0), context(0), compiledData(0), instructionStream(0) {}
+ quint32 flags;
+ QQmlContextData *context;
+ QQmlCompiledData *compiledData;
+ const char *instructionStream;
+ QBitField bindingSkipList;
+ };
+
+ QStack<State> states;
+
+ static void blank(QFiniteStack<QQmlParserStatus *> &);
+ static void blank(QFiniteStack<QQmlAbstractBinding *> &);
+};
+
+// Used to check that a QQmlVME that is interrupted mid-execution
+// is still valid. Checks all the objects and contexts have not been
+// deleted.
+class QQmlVMEGuard
+{
+public:
+ QQmlVMEGuard();
+ ~QQmlVMEGuard();
+
+ void guard(QQmlVME *);
+ void clear();
+
+ bool isOK() const;
+
+private:
+ int m_objectCount;
+ QQmlGuard<QObject> *m_objects;
+ int m_contextCount;
+ QQmlGuardedContextData *m_contexts;
+};
+
+QQmlVME::Interrupt::Interrupt()
+: mode(None)
+{
+}
+
+QQmlVME::Interrupt::Interrupt(bool *runWhile)
+: mode(Flag), runWhile(runWhile)
+{
+}
+
+QQmlVME::Interrupt::Interrupt(int nsecs)
+: mode(Time), nsecs(nsecs)
+{
+}
+
+void QQmlVME::Interrupt::reset()
+{
+ if (mode == Time)
+ timer.start();
+}
+
+bool QQmlVME::Interrupt::shouldInterrupt() const
+{
+ if (mode == None) {
+ return false;
+ } else if (mode == Time) {
+ return timer.nsecsElapsed() > nsecs;
+ } else if (mode == Flag) {
+ return !*runWhile;
+ } else {
+ return false;
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QQMLVME_P_H