diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2015-07-27 14:40:26 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2015-08-10 10:05:01 +0000 |
commit | dc341e6c1c524330b838a62ceeaa148a01dc0729 (patch) | |
tree | e42e93b6af0ecb347d4f3850b8e04acd796a4b66 /src/qml/jsruntime/qv4debugging_p.h | |
parent | e01bea8999d2f58add58874bd3e6792f509b131b (diff) |
Change data collection for debugging to use QV4::Value.
This patch changes the variable collection to store QV4::Value values
into a JS array, which is retained by the collector. This prevents any
GC issues, and gives a nice mapping from handle (used in the debugging
protocol) to JS value. It also allows for easy "shallow" object
serialization: any lookup can start with the QV4::Value, and add any
values it encounters to the array.
Testing is changed to use this collector directly, thereby testing the
class that is actually used to generate protocol data.
Task-number: QTBUG-47061
Change-Id: Iec75c4f74c08495e2a8af0fedf304f76f8385fd7
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
Diffstat (limited to 'src/qml/jsruntime/qv4debugging_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4debugging_p.h | 99 |
1 files changed, 65 insertions, 34 deletions
diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h index e6a9750351..424459a7d9 100644 --- a/src/qml/jsruntime/qv4debugging_p.h +++ b/src/qml/jsruntime/qv4debugging_p.h @@ -44,6 +44,8 @@ #include <QMutex> #include <QWaitCondition> +#include <QtCore/QJsonObject> + QT_BEGIN_NAMESPACE namespace QV4 { @@ -79,6 +81,61 @@ inline bool operator==(const DebuggerBreakPoint &a, const DebuggerBreakPoint &b) typedef QHash<DebuggerBreakPoint, QString> BreakPoints; +class Q_QML_PRIVATE_EXPORT DataCollector +{ +public: + typedef uint Ref; + typedef QVector<uint> Refs; + + DataCollector(QV4::ExecutionEngine *engine); + ~DataCollector(); + + void collect(const QV4::ScopedValue &value); + + QJsonObject lookupRef(Ref ref); + + Ref addFunctionRef(const QString &functionName); + Ref addScriptRef(const QString &scriptName); + + void collectScope(QJsonObject *dict, QV4::Debugging::Debugger *debugger, int frameNr, + int scopeNr); + + QV4::ExecutionEngine *engine() const { return m_engine; } + +private: + friend class RefHolder; + + Ref addRef(QV4::Value value, bool deduplicate = true); + QV4::ReturnedValue getValue(Ref ref); + bool lookupSpecialRef(Ref ref, QJsonObject *dict); + + QJsonArray collectProperties(QV4::Object *object); + QJsonObject collectAsJson(const QString &name, const QV4::ScopedValue &value); + + QV4::ExecutionEngine *m_engine; + Refs *m_collectedRefs; + QV4::PersistentValue values; + typedef QHash<Ref, QJsonObject> SpecialRefs; + SpecialRefs specialRefs; +}; + +class RefHolder { +public: + RefHolder(DataCollector *collector, DataCollector::Refs *target) : + m_collector(collector), m_previousRefs(collector->m_collectedRefs) + { + m_collector->m_collectedRefs = target; + } + + ~RefHolder() + { + std::swap(m_collector->m_collectedRefs, m_previousRefs); + } + +private: + DataCollector *m_collector; + DataCollector::Refs *m_previousRefs; +}; class Q_QML_EXPORT Debugger { @@ -90,34 +147,6 @@ public: virtual void run() = 0; }; - class Q_QML_EXPORT Collector - { - public: - Collector(ExecutionEngine *engine): m_engine(engine), m_isProperty(false) {} - virtual ~Collector(); - - void collect(const QString &name, const ScopedValue &value); - void collect(Object *object); - - protected: - virtual void addUndefined(const QString &name) = 0; - virtual void addNull(const QString &name) = 0; - virtual void addBoolean(const QString &name, bool value) = 0; - virtual void addString(const QString &name, const QString &value) = 0; - virtual void addObject(const QString &name, const Value &value) = 0; - virtual void addInteger(const QString &name, int value) = 0; - virtual void addDouble(const QString &name, double value) = 0; - - QV4::ExecutionEngine *engine() const { return m_engine; } - - bool isProperty() const { return m_isProperty; } - void setIsProperty(bool onoff) { m_isProperty = onoff; } - - private: - QV4::ExecutionEngine *m_engine; - bool m_isProperty; - }; - enum State { Running, Paused @@ -166,14 +195,16 @@ public: } QVector<StackFrame> stackTrace(int frameLimit = -1) const; - void collectArgumentsInContext(Collector *collector, int frameNr = 0, int scopeNr = 0); - void collectLocalsInContext(Collector *collector, int frameNr = 0, int scopeNr = 0); - bool collectThisInContext(Collector *collector, int frame = 0); - void collectThrownValue(Collector *collector); - void collectReturnedValue(Collector *collector) const; + void collectArgumentsInContext(DataCollector *collector, QStringList *names, int frameNr = 0, + int scopeNr = 0); + void collectLocalsInContext(DataCollector *collector, QStringList *names, int frameNr = 0, + int scopeNr = 0); + bool collectThisInContext(DataCollector *collector, int frame = 0); + bool collectThrownValue(DataCollector *collector); QVector<Heap::ExecutionContext::ContextType> getScopeTypes(int frame = 0) const; - void evaluateExpression(int frameNr, const QString &expression, Collector *resultsCollector); + void evaluateExpression(int frameNr, const QString &expression, + DataCollector *resultsCollector); public: // compile-time interface void maybeBreakAtInstruction(); |