/****************************************************************************
**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
//
#include "qdeclarativeerror.h"
-#include "private/qbitfield_p.h"
+#include <private/qbitfield_p.h>
+#include "qdeclarativeinstruction_p.h"
+#include <private/qrecursionwatcher_p.h>
-#include <QtCore/QString>
#include <QtCore/QStack>
+#include <QtCore/QString>
+#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qcoreapplication.h>
#include <private/qv8_p.h>
+#include <private/qdeclarativeengine_p.h>
+#include <private/qfinitestack_p.h>
+
+#include <private/qdeclarativetrace_p.h>
QT_BEGIN_NAMESPACE
class QObject;
-class QScriptValue;
+class QJSValue;
class QDeclarativeScriptData;
class QDeclarativeCompiledData;
class QDeclarativeCompiledData;
class QDeclarativeContextData;
-template<typename T, int N = 128>
-class QDeclarativeVMEStack {
-public:
- QDeclarativeVMEStack() : index(-1), maxSize(N), data((T *)fixedData) {}
- ~QDeclarativeVMEStack() { if (data != (T *)fixedData) qFree(data); }
+namespace QDeclarativeVMETypes {
+ struct List
+ {
+ List() : type(0) {}
+ List(int t) : type(t) {}
- bool isEmpty() const { return index == -1; }
- const T &top() const { return data[index]; }
- void push(const T &i) { ++index; if (index == maxSize) realloc(); data[index] = i; }
- const T &pop() { --index; return data[index + 1]; }
- int count() const { return index + 1; }
- const T &at(int idx) { return data[idx]; }
+ int type;
+ QDeclarativeListProperty<void> qListProperty;
+ };
+}
+Q_DECLARE_TYPEINFO(QDeclarativeVMETypes::List, Q_PRIMITIVE_TYPE | Q_MOVABLE_TYPE);
+
+class QDeclarativeVME
+{
+ Q_DECLARE_TR_FUNCTIONS(QDeclarativeVME)
+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;
+ };
+ };
+
+ QDeclarativeVME() : data(0), componentAttached(0) {}
+ QDeclarativeVME(void *data) : data(data), componentAttached(0) {}
+
+ void *data;
+ QDeclarativeComponentAttached *componentAttached;
+ QList<QDeclarativeEnginePrivate::FinalizeCallback> finalizeCallbacks;
+
+ void init(QDeclarativeContextData *, QDeclarativeCompiledData *, int start,
+ QDeclarativeContextData * = 0);
+ bool initDeferred(QObject *);
+ void reset();
+
+ QObject *execute(QList<QDeclarativeError> *errors, const Interrupt & = Interrupt());
+ QDeclarativeContextData *complete(const Interrupt & = Interrupt());
private:
- void realloc() {
- maxSize += N;
- if (data != (T *)fixedData) {
- data = (T*)qRealloc(data, maxSize * sizeof(T));
- } else {
- data = (T*)qMalloc(maxSize * sizeof(T));
- }
- }
- int index;
- int maxSize;
- T *data;
- char fixedData[N * sizeof(T)];
+ friend class QDeclarativeVMEGuard;
+
+ QObject *run(QList<QDeclarativeError> *errors, const Interrupt &
+#ifdef QML_THREADED_VME_INTERPRETER
+ , void ***storeJumpTable = 0
+#endif
+ );
+ v8::Persistent<v8::Object> run(QDeclarativeContextData *, QDeclarativeScriptData *);
+
+#ifdef QML_THREADED_VME_INTERPRETER
+ static void **instructionJumpTable();
+ friend class QDeclarativeCompiledData;
+#endif
+
+ QDeclarativeEngine *engine;
+ QRecursionNode recursion;
+
+#ifdef QML_ENABLE_TRACE
+ QDeclarativeCompiledData *rootComponent;
+#endif
+
+ QFiniteStack<QObject *> objects;
+ QFiniteStack<QDeclarativeVMETypes::List> lists;
+
+ QFiniteStack<QDeclarativeAbstractBinding *> bindValues;
+ QFiniteStack<QDeclarativeParserStatus *> parserStatus;
+#ifdef QML_ENABLE_TRACE
+ QFiniteStack<QDeclarativeData *> parserStatusData;
+#endif
+
+ QDeclarativeGuardedContextData rootContext;
+ QDeclarativeGuardedContextData creationContext;
+
+ struct State {
+ enum Flag { Deferred = 0x00000001 };
+
+ State() : flags(0), context(0), compiledData(0), instructionStream(0) {}
+ quint32 flags;
+ QDeclarativeContextData *context;
+ QDeclarativeCompiledData *compiledData;
+ const char *instructionStream;
+ QBitField bindingSkipList;
+ };
+
+ QStack<State> states;
+
+ static void blank(QFiniteStack<QDeclarativeParserStatus *> &);
+ static void blank(QFiniteStack<QDeclarativeAbstractBinding *> &);
};
-class QDeclarativeVME
+// Used to check that a QDeclarativeVME that is interrupted mid-execution
+// is still valid. Checks all the objects and contexts have not been
+// deleted.
+class QDeclarativeVMEGuard
{
public:
- QDeclarativeVME();
-
- QObject *run(QDeclarativeContextData *, QDeclarativeCompiledData *,
- int start = -1, const QBitField & = QBitField());
+ QDeclarativeVMEGuard();
+ ~QDeclarativeVMEGuard();
- void runDeferred(QObject *);
+ void guard(QDeclarativeVME *);
+ void clear();
- bool isError() const;
- QList<QDeclarativeError> errors() const;
+ bool isOK() const;
private:
- v8::Persistent<v8::Object> run(QDeclarativeContextData *, QDeclarativeScriptData *);
-
- QObject *run(QDeclarativeVMEStack<QObject *> &,
- QDeclarativeContextData *, QDeclarativeCompiledData *,
- int start, const QBitField &);
- QList<QDeclarativeError> vmeErrors;
+ int m_objectCount;
+ QDeclarativeGuard<QObject> *m_objects;
+ int m_contextCount;
+ QDeclarativeGuardedContextData *m_contexts;
};
+QDeclarativeVME::Interrupt::Interrupt()
+: mode(None)
+{
+}
+
+QDeclarativeVME::Interrupt::Interrupt(bool *runWhile)
+: mode(Flag), runWhile(runWhile)
+{
+}
+
+QDeclarativeVME::Interrupt::Interrupt(int nsecs)
+: mode(Time), nsecs(nsecs)
+{
+}
+
+void QDeclarativeVME::Interrupt::reset()
+{
+ if (mode == Time)
+ timer.start();
+}
+
+bool QDeclarativeVME::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 // QDECLARATIVEVME_P_H