aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp378
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h114
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp208
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h10
-rw-r--r--tests/auto/qml/qv4debugger/tst_qv4debugger.cpp138
5 files changed, 434 insertions, 414 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 4cca1900de..a86373b627 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -89,9 +89,30 @@ QVector<QV4::Heap::ExecutionContext::ContextType> QV4DataCollector::getScopeType
return types;
}
+int QV4DataCollector::encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType)
+{
+ switch (scopeType) {
+ case QV4::Heap::ExecutionContext::Type_GlobalContext:
+ return 0;
+ break;
+ case QV4::Heap::ExecutionContext::Type_CatchContext:
+ return 4;
+ break;
+ case QV4::Heap::ExecutionContext::Type_WithContext:
+ return 2;
+ break;
+ case QV4::Heap::ExecutionContext::Type_SimpleCallContext:
+ case QV4::Heap::ExecutionContext::Type_CallContext:
+ return 1;
+ break;
+ case QV4::Heap::ExecutionContext::Type_QmlContext:
+ default:
+ return -1;
+ }
+}
QV4DataCollector::QV4DataCollector(QV4::ExecutionEngine *engine)
- : m_engine(engine), m_collectedRefs(Q_NULLPTR)
+ : m_engine(engine)
{
values.set(engine, engine->newArrayObject());
}
@@ -100,10 +121,11 @@ QV4DataCollector::~QV4DataCollector()
{
}
-void QV4DataCollector::collect(const QV4::ScopedValue &value)
+QV4DataCollector::Ref QV4DataCollector::collect(const QV4::ScopedValue &value)
{
- if (m_collectedRefs)
- m_collectedRefs->append(addRef(value));
+ Ref ref = addRef(value);
+ collectedRefs.append(ref);
+ return ref;
}
const QV4::Object *collectProperty(const QV4::ScopedValue &value, QV4::ExecutionEngine *engine,
@@ -191,6 +213,7 @@ QV4DataCollector::Ref QV4DataCollector::addFunctionRef(const QString &functionNa
dict.insert(QStringLiteral("type"), QStringLiteral("function"));
dict.insert(QStringLiteral("name"), functionName);
specialRefs.insert(ref, dict);
+ collectedRefs.append(ref);
return ref;
}
@@ -204,36 +227,133 @@ QV4DataCollector::Ref QV4DataCollector::addScriptRef(const QString &scriptName)
dict.insert(QStringLiteral("type"), QStringLiteral("script"));
dict.insert(QStringLiteral("name"), scriptName);
specialRefs.insert(ref, dict);
+ collectedRefs.append(ref);
return ref;
}
-void QV4DataCollector::collectScope(QJsonObject *dict, QV4::Debugging::V4Debugger *debugger,
+bool QV4DataCollector::isValidRef(QV4DataCollector::Ref ref) const
+{
+ QV4::Scope scope(engine());
+ QV4::ScopedObject array(scope, values.value());
+ return ref < array->getLength();
+}
+
+bool QV4DataCollector::collectScope(QJsonObject *dict, QV4::Debugging::V4Debugger *debugger,
int frameNr, int scopeNr)
{
QStringList names;
- Refs refs;
+ QV4::Scope scope(engine());
if (debugger->state() == QV4::Debugging::V4Debugger::Paused) {
- RefHolder holder(this, &refs);
- ArgumentCollectJob argumentsJob(m_engine, this, &names, frameNr, scopeNr);
- debugger->runInEngine(&argumentsJob);
- LocalCollectJob localsJob(m_engine, this, &names, frameNr, scopeNr);
- debugger->runInEngine(&localsJob);
+ QV4::Scoped<QV4::CallContext> ctxt(scope, findScope(findContext(engine(), frameNr), scopeNr));
+ if (!ctxt)
+ return false;
+
+ QV4::ScopedValue v(scope);
+ int nFormals = ctxt->formalCount();
+ for (unsigned i = 0, ei = nFormals; i != ei; ++i) {
+ QString qName;
+ if (QV4::Identifier *name = ctxt->formals()[nFormals - i - 1])
+ qName = name->string;
+ names.append(qName);
+ v = ctxt->argument(i);
+ collect(v);
+ }
+
+ for (unsigned i = 0, ei = ctxt->variableCount(); i != ei; ++i) {
+ QString qName;
+ if (QV4::Identifier *name = ctxt->variables()[i])
+ qName = name->string;
+ names.append(qName);
+ v = ctxt->d()->locals[i];
+ collect(v);
+ }
}
- QV4::Scope scope(engine());
QV4::ScopedObject scopeObject(scope, engine()->newObject());
- Q_ASSERT(names.size() == refs.size());
- for (int i = 0, ei = refs.size(); i != ei; ++i)
+ Q_ASSERT(names.size() == collectedRefs.size());
+ for (int i = 0, ei = collectedRefs.size(); i != ei; ++i)
scopeObject->put(engine(), names.at(i),
- QV4::Value::fromReturnedValue(getValue(refs.at(i))));
+ QV4::Value::fromReturnedValue(getValue(collectedRefs.at(i))));
Ref scopeObjectRef = addRef(scopeObject);
dict->insert(QStringLiteral("ref"), qint64(scopeObjectRef));
- if (m_collectedRefs)
- m_collectedRefs->append(scopeObjectRef);
+ collectedRefs.append(scopeObjectRef);
+ return true;
+}
+
+QJsonObject toRef(QV4DataCollector::Ref ref) {
+ QJsonObject dict;
+ dict.insert(QStringLiteral("ref"), qint64(ref));
+ return dict;
+}
+
+QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
+ QV4::Debugging::V4Debugger *debugger)
+{
+ QV4DataCollector::Ref ref;
+
+ QJsonObject frame;
+ frame[QLatin1String("index")] = frameNr;
+ frame[QLatin1String("debuggerFrame")] = false;
+ ref = addFunctionRef(stackFrame.function);
+ frame[QLatin1String("func")] = toRef(ref);
+ ref = addScriptRef(stackFrame.source);
+ frame[QLatin1String("script")] = toRef(ref);
+ frame[QLatin1String("line")] = stackFrame.line - 1;
+ if (stackFrame.column >= 0)
+ frame[QLatin1String("column")] = stackFrame.column;
+
+ QJsonArray scopes;
+ if (debugger->state() == QV4::Debugging::V4Debugger::Paused) {
+ QV4::Scope scope(engine());
+ QV4::ScopedContext ctxt(scope, findContext(engine(), frameNr));
+ while (ctxt) {
+ if (QV4::CallContext *cCtxt = ctxt->asCallContext()) {
+ if (cCtxt->d()->activation)
+ break;
+ }
+ ctxt = ctxt->d()->outer;
+ }
+
+ if (ctxt) {
+ QV4::ScopedValue o(scope, ctxt->asCallContext()->d()->activation);
+ frame[QLatin1String("receiver")] = toRef(collect(o));
+ }
+
+ // Only type and index are used by Qt Creator, so we keep it easy:
+ QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes = getScopeTypes(engine(), frameNr);
+ for (int i = 0, ei = scopeTypes.count(); i != ei; ++i) {
+ int type = encodeScopeType(scopeTypes[i]);
+ if (type == -1)
+ continue;
+
+ QJsonObject scope;
+ scope[QLatin1String("index")] = i;
+ scope[QLatin1String("type")] = type;
+ scopes.push_back(scope);
+ }
+ }
+ frame[QLatin1String("scopes")] = scopes;
+
+ return frame;
+}
+
+QJsonArray QV4DataCollector::flushCollectedRefs()
+{
+ QJsonArray refs;
+ std::sort(collectedRefs.begin(), collectedRefs.end());
+ for (int i = 0, ei = collectedRefs.size(); i != ei; ++i) {
+ QV4DataCollector::Ref ref = collectedRefs.at(i);
+ if (i > 0 && ref == collectedRefs.at(i - 1))
+ continue;
+ refs.append(lookupRef(ref));
+ }
+
+ collectedRefs.clear();
+ return refs;
}
QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicate)
@@ -316,14 +436,117 @@ QJsonObject QV4DataCollector::collectAsJson(const QString &name, const QV4::Scop
if (value->isManaged() && !value->isString()) {
Ref ref = addRef(value);
dict.insert(QStringLiteral("ref"), qint64(ref));
- if (m_collectedRefs)
- m_collectedRefs->append(ref);
+ collectedRefs.append(ref);
}
collectProperty(value, engine(), dict);
return dict;
}
+BacktraceJob::BacktraceJob(QV4DataCollector *collector, int fromFrame, int toFrame) :
+ CollectJob(collector), fromFrame(fromFrame), toFrame(toFrame)
+{
+}
+
+void BacktraceJob::run()
+{
+ QJsonArray frameArray;
+ QVector<QV4::StackFrame> frames = collector->engine()->stackTrace(toFrame);
+ QV4::Debugging::V4Debugger *debugger =
+ qobject_cast<QV4::Debugging::V4Debugger *>(collector->engine()->debugger);
+ if (debugger) {
+ for (int i = fromFrame; i < toFrame && i < frames.size(); ++i)
+ frameArray.push_back(collector->buildFrame(frames[i], i, debugger));
+ }
+ if (frameArray.isEmpty()) {
+ result.insert(QStringLiteral("totalFrames"), 0);
+ } else {
+ result.insert(QStringLiteral("fromFrame"), fromFrame);
+ result.insert(QStringLiteral("toFrame"), fromFrame + frameArray.size());
+ result.insert(QStringLiteral("frames"), frameArray);
+ }
+ collectedRefs = collector->flushCollectedRefs();
+}
+
+FrameJob::FrameJob(QV4DataCollector *collector, int frameNr) :
+ CollectJob(collector), frameNr(frameNr), success(false)
+{
+}
+
+void FrameJob::run()
+{
+ QVector<QV4::StackFrame> frames = collector->engine()->stackTrace(frameNr + 1);
+ if (frameNr >= frames.length()) {
+ success = false;
+ } else {
+ QV4::Debugging::V4Debugger *debugger =
+ qobject_cast<QV4::Debugging::V4Debugger *>(collector->engine()->debugger);
+ if (debugger) {
+ result = collector->buildFrame(frames[frameNr], frameNr, debugger);
+ collectedRefs = collector->flushCollectedRefs();
+ success = true;
+ } else {
+ success = false;
+ }
+ }
+}
+
+bool FrameJob::wasSuccessful() const
+{
+ return success;
+}
+
+ScopeJob::ScopeJob(QV4DataCollector *collector, int frameNr, int scopeNr) :
+ CollectJob(collector), frameNr(frameNr), scopeNr(scopeNr), success(false)
+{
+}
+
+void ScopeJob::run()
+{
+ QJsonObject object;
+ QV4::Debugging::V4Debugger *debugger =
+ qobject_cast<QV4::Debugging::V4Debugger *>(collector->engine()->debugger);
+ success = (debugger && collector->collectScope(&object, debugger, frameNr, scopeNr));
+
+ if (success) {
+ QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes =
+ QV4DataCollector::getScopeTypes(collector->engine(), frameNr);
+ result[QLatin1String("type")] = QV4DataCollector::encodeScopeType(scopeTypes[scopeNr]);
+ } else {
+ result[QLatin1String("type")] = -1;
+ }
+ result[QLatin1String("index")] = scopeNr;
+ result[QLatin1String("frameIndex")] = frameNr;
+ result[QLatin1String("object")] = object;
+ collectedRefs = collector->flushCollectedRefs();
+}
+
+bool ScopeJob::wasSuccessful() const
+{
+ return success;
+}
+
+ValueLookupJob::ValueLookupJob(const QJsonArray &handles, QV4DataCollector *collector) :
+ CollectJob(collector), handles(handles) {}
+
+void ValueLookupJob::run()
+{
+ foreach (const QJsonValue &handle, handles) {
+ QV4DataCollector::Ref ref = handle.toInt();
+ if (!collector->isValidRef(ref)) {
+ exception = QString::fromLatin1("Invalid Ref: %1").arg(ref);
+ break;
+ }
+ result[QString::number(ref)] = collector->lookupRef(ref);
+ }
+ collectedRefs = collector->flushCollectedRefs();
+}
+
+const QString &ValueLookupJob::exceptionMessage() const
+{
+ return exception;
+}
+
ExpressionEvalJob::ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr,
const QString &expression,
QV4DataCollector *collector)
@@ -336,7 +559,8 @@ void ExpressionEvalJob::handleResult(QV4::ScopedValue &result)
{
if (hasExeption())
exception = result->toQStringNoThrow();
- collector->collect(result);
+ value = collector->lookupRef(collector->collect(result));
+ collectedRefs = collector->flushCollectedRefs();
}
const QString &ExpressionEvalJob::exceptionMessage() const
@@ -344,6 +568,16 @@ const QString &ExpressionEvalJob::exceptionMessage() const
return exception;
}
+const QJsonObject &ExpressionEvalJob::returnValue() const
+{
+ return value;
+}
+
+const QJsonArray &ExpressionEvalJob::refs() const
+{
+ return collectedRefs;
+}
+
GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine, int seq)
: engine(engine)
, seq(seq)
@@ -364,111 +598,21 @@ void GatherSourcesJob::run()
emit debugger->sourcesCollected(debugger, sources, seq);
}
-ArgumentCollectJob::ArgumentCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector,
- QStringList *names, int frameNr, int scopeNr)
- : engine(engine)
- , collector(collector)
- , names(names)
- , frameNr(frameNr)
- , scopeNr(scopeNr)
-{}
-
-void ArgumentCollectJob::run()
-{
- if (frameNr < 0)
- return;
-
- QV4::Scope scope(engine);
- QV4::Scoped<QV4::CallContext> ctxt(
- scope, QV4DataCollector::findScope(QV4DataCollector::findContext(engine, frameNr), scopeNr));
- if (!ctxt)
- return;
-
- QV4::ScopedValue v(scope);
- int nFormals = ctxt->formalCount();
- for (unsigned i = 0, ei = nFormals; i != ei; ++i) {
- QString qName;
- if (QV4::Identifier *name = ctxt->formals()[nFormals - i - 1])
- qName = name->string;
- names->append(qName);
- v = ctxt->argument(i);
- collector->collect(v);
- }
-}
-
-LocalCollectJob::LocalCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector,
- QStringList *names, int frameNr, int scopeNr)
- : engine(engine)
- , collector(collector)
- , names(names)
- , frameNr(frameNr)
- , scopeNr(scopeNr)
-{}
-
-void LocalCollectJob::run()
-{
- if (frameNr < 0)
- return;
-
- QV4::Scope scope(engine);
- QV4::Scoped<QV4::CallContext> ctxt(
- scope, QV4DataCollector::findScope(QV4DataCollector::findContext(engine, frameNr), scopeNr));
- if (!ctxt)
- return;
-
- QV4::ScopedValue v(scope);
- for (unsigned i = 0, ei = ctxt->variableCount(); i != ei; ++i) {
- QString qName;
- if (QV4::Identifier *name = ctxt->variables()[i])
- qName = name->string;
- names->append(qName);
- v = ctxt->d()->locals[i];
- collector->collect(v);
- }
-}
-
-ThisCollectJob::ThisCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector,
- int frameNr, bool *foundThis)
+ExceptionCollectJob::ExceptionCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector)
: engine(engine)
, collector(collector)
- , frameNr(frameNr)
- , foundThis(foundThis)
+ , exception(-1)
{}
-void ThisCollectJob::run()
-{
- *foundThis = myRun();
-}
-
-bool ThisCollectJob::myRun()
-{
+void ExceptionCollectJob::run() {
QV4::Scope scope(engine);
- QV4::ScopedContext ctxt(scope, QV4DataCollector::findContext(engine, frameNr));
- while (ctxt) {
- if (QV4::CallContext *cCtxt = ctxt->asCallContext())
- if (cCtxt->d()->activation)
- break;
- ctxt = ctxt->d()->outer;
- }
-
- if (!ctxt)
- return false;
-
- QV4::ScopedValue o(scope, ctxt->asCallContext()->d()->activation);
- collector->collect(o);
- return true;
+ QV4::ScopedValue v(scope, *engine->exceptionValue);
+ exception = collector->collect(v);
}
-ExceptionCollectJob::ExceptionCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector)
- : engine(engine)
- , collector(collector)
-{}
-
-void ExceptionCollectJob::run()
+QV4DataCollector::Ref ExceptionCollectJob::exceptionValue() const
{
- QV4::Scope scope(engine);
- QV4::ScopedValue v(scope, *engine->exceptionValue);
- collector->collect(v);
+ return exception;
}
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
index d0e4a4ad18..5a2c8ff33b 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
@@ -37,6 +37,9 @@
#include <private/qv4engine_p.h>
#include <private/qv4debugging_p.h>
+#include <QtCore/QJsonObject>
+#include <QtCore/QJsonArray>
+
QT_BEGIN_NAMESPACE
class QV4DataCollector
@@ -49,25 +52,27 @@ public:
static QV4::Heap::CallContext *findScope(QV4::ExecutionContext *ctxt, int scope);
static QVector<QV4::Heap::ExecutionContext::ContextType> getScopeTypes(
QV4::ExecutionEngine *engine, int frame);
+ static int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType);
QV4DataCollector(QV4::ExecutionEngine *engine);
~QV4DataCollector();
- void collect(const QV4::ScopedValue &value);
-
+ Ref collect(const QV4::ScopedValue &value);
+ bool isValidRef(Ref ref) const;
QJsonObject lookupRef(Ref ref);
Ref addFunctionRef(const QString &functionName);
Ref addScriptRef(const QString &scriptName);
- void collectScope(QJsonObject *dict, QV4::Debugging::V4Debugger *debugger, int frameNr,
+ bool collectScope(QJsonObject *dict, QV4::Debugging::V4Debugger *debugger, int frameNr,
int scopeNr);
+ QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
+ QV4::Debugging::V4Debugger *debugger);
QV4::ExecutionEngine *engine() const { return m_engine; }
+ QJsonArray flushCollectedRefs();
private:
- friend class RefHolder;
-
Ref addRef(QV4::Value value, bool deduplicate = true);
QV4::ReturnedValue getValue(Ref ref);
bool lookupSpecialRef(Ref ref, QJsonObject *dict);
@@ -77,102 +82,103 @@ private:
void collectArgumentsInContext();
QV4::ExecutionEngine *m_engine;
- Refs *m_collectedRefs;
+ Refs collectedRefs;
QV4::PersistentValue values;
typedef QHash<Ref, QJsonObject> SpecialRefs;
SpecialRefs specialRefs;
};
-class RefHolder {
+class CollectJob : public QV4::Debugging::V4Debugger::Job
+{
+protected:
+ QV4DataCollector *collector;
+ QJsonObject result;
+ QJsonArray collectedRefs;
public:
- RefHolder(QV4DataCollector *collector, QV4DataCollector::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:
- QV4DataCollector *m_collector;
- QV4DataCollector::Refs *m_previousRefs;
+ CollectJob(QV4DataCollector *collector) : collector(collector) {}
+ const QJsonObject &returnValue() const { return result; }
+ const QJsonArray &refs() const { return collectedRefs; }
};
-class ExpressionEvalJob: public QV4::Debugging::V4Debugger::JavaScriptJob
+class BacktraceJob: public CollectJob
{
- QV4DataCollector *collector;
- QString exception;
-
+ int fromFrame;
+ int toFrame;
public:
- ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr, const QString &expression,
- QV4DataCollector *collector);
- virtual void handleResult(QV4::ScopedValue &result);
- const QString &exceptionMessage() const;
+ BacktraceJob(QV4DataCollector *collector, int fromFrame, int toFrame);
+ void run();
};
-class GatherSourcesJob: public QV4::Debugging::V4Debugger::Job
+class FrameJob: public CollectJob
{
- QV4::ExecutionEngine *engine;
- const int seq;
+ int frameNr;
+ bool success;
public:
- GatherSourcesJob(QV4::ExecutionEngine *engine, int seq);
+ FrameJob(QV4DataCollector *collector, int frameNr);
void run();
+ bool wasSuccessful() const;
};
-class ArgumentCollectJob: public QV4::Debugging::V4Debugger::Job
+class ScopeJob: public CollectJob
{
- QV4::ExecutionEngine *engine;
- QV4DataCollector *collector;
- QStringList *names;
int frameNr;
int scopeNr;
+ bool success;
public:
- ArgumentCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector,
- QStringList *names, int frameNr, int scopeNr);
+ ScopeJob(QV4DataCollector *collector, int frameNr, int scopeNr);
void run();
+ bool wasSuccessful() const;
};
-class LocalCollectJob: public QV4::Debugging::V4Debugger::Job
+class ValueLookupJob: public CollectJob
{
- QV4::ExecutionEngine *engine;
- QV4DataCollector *collector;
- QStringList *names;
- int frameNr;
- int scopeNr;
+ const QJsonArray handles;
+ QString exception;
public:
- LocalCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector, QStringList *names,
- int frameNr, int scopeNr);
+ ValueLookupJob(const QJsonArray &handles, QV4DataCollector *collector);
void run();
+ const QString &exceptionMessage() const;
};
-class ThisCollectJob: public QV4::Debugging::V4Debugger::Job
+class ExpressionEvalJob: public QV4::Debugging::V4Debugger::JavaScriptJob
{
- QV4::ExecutionEngine *engine;
QV4DataCollector *collector;
- int frameNr;
- bool *foundThis;
+ QString exception;
+ QJsonObject value;
+ QJsonArray collectedRefs;
public:
- ThisCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector, int frameNr,
- bool *foundThis);
+ ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr, const QString &expression,
+ QV4DataCollector *collector);
+ virtual void handleResult(QV4::ScopedValue &result);
+ const QString &exceptionMessage() const;
+ const QJsonObject &returnValue() const;
+ const QJsonArray &refs() const;
+};
+
+class GatherSourcesJob: public QV4::Debugging::V4Debugger::Job
+{
+ QV4::ExecutionEngine *engine;
+ const int seq;
+
+public:
+ GatherSourcesJob(QV4::ExecutionEngine *engine, int seq);
void run();
- bool myRun();
};
class ExceptionCollectJob: public QV4::Debugging::V4Debugger::Job
{
QV4::ExecutionEngine *engine;
QV4DataCollector *collector;
+ QV4DataCollector::Ref exception;
public:
ExceptionCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector);
void run();
+ QV4DataCollector::Ref exceptionValue() const;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index 5233a09992..e9bcd772e5 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -114,9 +114,9 @@ protected:
response.insert(QStringLiteral("running"), debugService->debuggerAgent.isRunning());
}
- void addRefs()
+ void addRefs(const QJsonArray &refs)
{
- response.insert(QStringLiteral("refs"), debugService->buildRefs());
+ response.insert(QStringLiteral("refs"), refs);
}
void createErrorResponse(const QString &msg)
@@ -271,28 +271,16 @@ public:
int toFrame = arguments.value(QStringLiteral("toFrame")).toInt(fromFrame + 10);
// no idea what the bottom property is for, so we'll ignore it.
- QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
-
- QJsonArray frameArray;
- QVector<QV4::StackFrame> frames = debugger->stackTrace(toFrame);
- for (int i = fromFrame; i < toFrame && i < frames.size(); ++i)
- frameArray.push_back(debugService->buildFrame(frames[i], i, debugger));
+ BacktraceJob job(debugService->collector(), fromFrame, toFrame);
+ debugService->debuggerAgent.firstDebugger()->runInEngine(&job);
// response:
addCommand();
addRequestSequence();
addSuccess(true);
addRunning();
- QJsonObject body;
- if (frameArray.isEmpty()) {
- body.insert(QStringLiteral("totalFrames"), 0);
- } else {
- body.insert(QStringLiteral("fromFrame"), fromFrame);
- body.insert(QStringLiteral("toFrame"), fromFrame + frameArray.size());
- body.insert(QStringLiteral("frames"), frameArray);
- }
- addBody(body);
- addRefs();
+ addBody(job.returnValue());
+ addRefs(job.refs());
}
};
@@ -308,23 +296,27 @@ public:
const int frameNr = arguments.value(QStringLiteral("number")).toInt(
debugService->selectedFrame());
- QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
- QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
- if (frameNr < 0 || frameNr >= frames.size()) {
+ if (frameNr < 0) {
createErrorResponse(QStringLiteral("frame command has invalid frame number"));
return;
}
+ FrameJob job(debugService->collector(), frameNr);
+ debugService->debuggerAgent.firstDebugger()->runInEngine(&job);
+ if (!job.wasSuccessful()) {
+ createErrorResponse(QStringLiteral("frame retrieval failed"));
+ return;
+ }
+
debugService->selectFrame(frameNr);
- QJsonObject frame = debugService->buildFrame(frames[frameNr], frameNr, debugger);
// response:
addCommand();
addRequestSequence();
addSuccess(true);
addRunning();
- addBody(frame);
- addRefs();
+ addBody(job.returnValue());
+ addRefs(job.refs());
}
};
@@ -341,9 +333,7 @@ public:
debugService->selectedFrame());
const int scopeNr = arguments.value(QStringLiteral("number")).toInt(0);
- QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
- QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
- if (frameNr < 0 || frameNr >= frames.size()) {
+ if (frameNr < 0) {
createErrorResponse(QStringLiteral("scope command has invalid frame number"));
return;
}
@@ -352,15 +342,20 @@ public:
return;
}
- QJsonObject scope = debugService->buildScope(frameNr, scopeNr, debugger);
+ ScopeJob job(debugService->collector(), frameNr, scopeNr);
+ debugService->debuggerAgent.firstDebugger()->runInEngine(&job);
+ if (!job.wasSuccessful()) {
+ createErrorResponse(QStringLiteral("scope retrieval failed"));
+ return;
+ }
// response:
addCommand();
addRequestSequence();
addSuccess(true);
addRunning();
- addBody(scope);
- addRefs();
+ addBody(job.returnValue());
+ addRefs(job.refs());
}
};
@@ -375,17 +370,19 @@ public:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
QJsonArray handles = arguments.value(QStringLiteral("handles")).toArray();
- QJsonObject body;
- foreach (const QJsonValue &handle, handles)
- body[QString::number(handle.toInt())] = debugService->lookup(handle.toInt());
-
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- addBody(body);
- addRefs();
+ ValueLookupJob job(handles, debugService->collector());
+ debugService->debuggerAgent.firstDebugger()->runInEngine(&job);
+ if (!job.exceptionMessage().isEmpty()) {
+ createErrorResponse(job.exceptionMessage());
+ } else {
+ // response:
+ addCommand();
+ addRequestSequence();
+ addSuccess(true);
+ addRunning();
+ addBody(job.returnValue());
+ addRefs(job.refs());
+ }
}
};
@@ -557,7 +554,6 @@ public:
const int frame = arguments.value(QStringLiteral("frame")).toInt(0);
QV4DataCollector *collector = debugService->collector();
- RefHolder holder(collector, debugService->refs());
ExpressionEvalJob job(debugger->engine(), frame, expression, collector);
debugger->runInEngine(&job);
if (job.hasExeption()) {
@@ -567,8 +563,8 @@ public:
addRequestSequence();
addSuccess(true);
addRunning();
- addBody(collector->lookupRef(debugService->refs()->last()));
- addRefs();
+ addBody(job.returnValue());
+ addRefs(job.refs());
}
} else {
createErrorResponse(QStringLiteral("Debugger has to be paused for evaluate to work."));
@@ -789,135 +785,11 @@ void QV4DebugServiceImpl::clearHandles(QV4::ExecutionEngine *engine)
theCollector.reset(new QV4DataCollector(engine));
}
-QJsonObject QV4DebugServiceImpl::buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
- QV4::Debugging::V4Debugger *debugger)
-{
- QV4DataCollector::Ref ref;
-
- QJsonObject frame;
- frame[QLatin1String("index")] = frameNr;
- frame[QLatin1String("debuggerFrame")] = false;
- ref = theCollector->addFunctionRef(stackFrame.function);
- collectedRefs.append(ref);
- frame[QLatin1String("func")] = toRef(ref);
- ref = theCollector->addScriptRef(stackFrame.source);
- collectedRefs.append(ref);
- frame[QLatin1String("script")] = toRef(ref);
- frame[QLatin1String("line")] = stackFrame.line - 1;
- if (stackFrame.column >= 0)
- frame[QLatin1String("column")] = stackFrame.column;
-
- QJsonArray scopes;
- if (debugger->state() == QV4::Debugging::V4Debugger::Paused) {
- RefHolder holder(theCollector.data(), &collectedRefs);
- bool foundThis = false;
- ThisCollectJob job(debugger->engine(), theCollector.data(), frameNr, &foundThis);
- debugger->runInEngine(&job);
- if (foundThis)
- frame[QLatin1String("receiver")] = toRef(collectedRefs.last());
-
- // Only type and index are used by Qt Creator, so we keep it easy:
- QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes =
- QV4DataCollector::getScopeTypes(debugger->engine(), frameNr);
- for (int i = 0, ei = scopeTypes.count(); i != ei; ++i) {
- int type = encodeScopeType(scopeTypes[i]);
- if (type == -1)
- continue;
-
- QJsonObject scope;
- scope[QLatin1String("index")] = i;
- scope[QLatin1String("type")] = type;
- scopes.push_back(scope);
- }
- }
- frame[QLatin1String("scopes")] = scopes;
-
- return frame;
-}
-
-int QV4DebugServiceImpl::encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType)
-{
- switch (scopeType) {
- case QV4::Heap::ExecutionContext::Type_GlobalContext:
- return 0;
- break;
- case QV4::Heap::ExecutionContext::Type_CatchContext:
- return 4;
- break;
- case QV4::Heap::ExecutionContext::Type_WithContext:
- return 2;
- break;
- case QV4::Heap::ExecutionContext::Type_SimpleCallContext:
- case QV4::Heap::ExecutionContext::Type_CallContext:
- return 1;
- break;
- case QV4::Heap::ExecutionContext::Type_QmlContext:
- default:
- return -1;
- }
-}
-
-QJsonObject QV4DebugServiceImpl::buildScope(int frameNr, int scopeNr,
- QV4::Debugging::V4Debugger *debugger)
-{
- QJsonObject scope;
-
- QJsonObject object;
- RefHolder holder(theCollector.data(), &collectedRefs);
- theCollector->collectScope(&object, debugger, frameNr, scopeNr);
-
- if (debugger->state() == QV4::Debugging::V4Debugger::Paused) {
- QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes =
- QV4DataCollector::getScopeTypes(debugger->engine(), frameNr);
- scope[QLatin1String("type")] = encodeScopeType(scopeTypes[scopeNr]);
- } else {
- scope[QLatin1String("type")] = -1;
- }
- scope[QLatin1String("index")] = scopeNr;
- scope[QLatin1String("frameIndex")] = frameNr;
- scope[QLatin1String("object")] = object;
-
- return scope;
-}
-
-QJsonValue QV4DebugServiceImpl::lookup(QV4DataCollector::Ref refId)
-{
- RefHolder holder(theCollector.data(), &collectedRefs);
- return theCollector->lookupRef(refId);
-}
-
-QJsonArray QV4DebugServiceImpl::buildRefs()
-{
- QJsonArray refs;
- std::sort(collectedRefs.begin(), collectedRefs.end());
- for (int i = 0, ei = collectedRefs.size(); i != ei; ++i) {
- QV4DataCollector::Ref ref = collectedRefs.at(i);
- if (i > 0 && ref == collectedRefs.at(i - 1))
- continue;
- refs.append(lookup(ref));
- }
-
- collectedRefs.clear();
- return refs;
-}
-
-QJsonValue QV4DebugServiceImpl::toRef(QV4DataCollector::Ref ref)
-{
- QJsonObject dict;
- dict.insert(QStringLiteral("ref"), qint64(ref));
- return dict;
-}
-
QV4DataCollector *QV4DebugServiceImpl::collector() const
{
return theCollector.data();
}
-QV4DataCollector::Refs *QV4DebugServiceImpl::refs()
-{
- return &collectedRefs;
-}
-
void QV4DebugServiceImpl::selectFrame(int frameNr)
{
theSelectedFrame = frameNr;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
index 273e5ffd62..658b1b3998 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
@@ -78,13 +78,6 @@ public:
void signalEmitted(const QString &signal);
void send(QJsonObject v8Payload);
- QJsonObject buildScope(int frameNr, int scopeNr, QV4::Debugging::V4Debugger *debugger);
- QJsonArray buildRefs();
- QJsonValue lookup(QV4DataCollector::Ref refId);
- QJsonValue toRef(QV4DataCollector::Ref ref);
-
- QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
- QV4::Debugging::V4Debugger *debugger);
int selectedFrame() const;
void selectFrame(int frameNr);
@@ -92,7 +85,6 @@ public:
QV4DataCollector *collector() const;
QV4DebuggerAgent debuggerAgent;
- QV4DataCollector::Refs *refs();
protected:
void messageReceived(const QByteArray &);
@@ -106,14 +98,12 @@ private:
const QByteArray &message = QByteArray());
void processCommand(const QByteArray &command, const QByteArray &data);
V8CommandHandler *v8CommandHandler(const QString &command) const;
- int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType);
QStringList breakOnSignals;
QMap<int, QV4::Debugging::V4Debugger *> debuggerMap;
static int debuggerIndex;
static int sequence;
const int version;
- QV4DataCollector::Refs collectedRefs;
QScopedPointer<QV4DataCollector> theCollector;
int theSelectedFrame;
diff --git a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
index 39a1fbc173..2532f73466 100644
--- a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
@@ -103,19 +103,24 @@ public:
typedef QV4DataCollector::Refs Refs;
typedef QV4DataCollector::Ref Ref;
struct NamedRefs {
- NamedRefs(QV4DataCollector *collector = 0): collector(collector) {}
-
- QStringList names;
- Refs refs;
- QV4DataCollector *collector;
+ QJsonArray refs;
+ QJsonObject scope;
int size() const {
- Q_ASSERT(names.size() == refs.size());
- return names.size();
+ return scope.size();
}
bool contains(const QString &name) const {
- return names.contains(name);
+ return scope.contains(name);
+ }
+
+ QJsonObject resolveRef(int ref) const {
+ foreach (const QJsonValue &val, refs) {
+ QJsonObject obj = val.toObject();
+ if (obj.value(QLatin1String("handle")).toInt() == ref)
+ return obj;
+ }
+ return QJsonObject();
}
#define DUMP_JSON(x) {\
@@ -125,7 +130,7 @@ public:
QJsonObject rawValue(const QString &name) const {
Q_ASSERT(contains(name));
- return collector->lookupRef(refs.at(names.indexOf(name)));
+ return scope[name].toObject();
}
QJsonValue value(const QString &name) const {
@@ -142,7 +147,7 @@ public:
return;
}
- QJsonObject o = collector->lookupRef(refs.at(names.indexOf(name)));
+ QJsonObject o = scope[name].toObject();
QJsonDocument d;
d.setObject(o);
qDebug() << name << "=" << d.toJson(QJsonDocument::Indented);
@@ -169,12 +174,9 @@ public slots:
if (debugger->state() == V4Debugger::Paused &&
debugger->engine()->hasException) {
- Refs refs;
- RefHolder holder(&collector, &refs);
ExceptionCollectJob job(debugger->engine(), &collector);
debugger->runInEngine(&job);
- Q_ASSERT(refs.size() > 0);
- m_thrownValue = refs.first();
+ m_thrownValue = job.exceptionValue();
}
foreach (const TestBreakPoint &bp, m_breakPointsToAddWhenPaused)
@@ -186,11 +188,11 @@ public slots:
while (!m_expressionRequests.isEmpty()) {
Q_ASSERT(debugger->state() == V4Debugger::Paused);
ExpressionRequest request = m_expressionRequests.takeFirst();
- m_expressionResults << Refs();
- RefHolder holder(&collector, &m_expressionResults.last());
ExpressionEvalJob job(debugger->engine(), request.frameNr, request.expression,
&collector);
debugger->runInEngine(&job);
+ m_expressionResults << job.returnValue();
+ m_expressionRefs << job.refs();
}
if (m_captureContextInfo)
@@ -212,17 +214,30 @@ public:
void captureContextInfo(V4Debugger *debugger)
{
for (int i = 0, ei = m_stackTrace.size(); i != ei; ++i) {
- m_capturedArguments.append(NamedRefs(&collector));
- RefHolder argHolder(&collector, &m_capturedArguments.last().refs);
- ArgumentCollectJob argumentsJob(debugger->engine(), &collector,
- &m_capturedArguments.last().names, i, 0);
- debugger->runInEngine(&argumentsJob);
-
- m_capturedLocals.append(NamedRefs(&collector));
- RefHolder localHolder(&collector, &m_capturedLocals.last().refs);
- LocalCollectJob localsJob(debugger->engine(), &collector,
- &m_capturedLocals.last().names, i, 0);
- debugger->runInEngine(&localsJob);
+ m_capturedScope.append(NamedRefs());
+ ScopeJob job(&collector, i, 0);
+ debugger->runInEngine(&job);
+ NamedRefs &refs = m_capturedScope.last();
+ refs.refs = job.refs();
+ QJsonObject object = job.returnValue();
+ object = object.value(QLatin1String("object")).toObject();
+ int ref = object.value(QLatin1String("ref")).toInt();
+ object = refs.resolveRef(ref);
+ foreach (const QJsonValue &value, object.value(QLatin1String("properties")).toArray()) {
+ QJsonObject property = value.toObject();
+ QString name = property.value(QLatin1String("name")).toString();
+ property.remove(QLatin1String("name"));
+ if (property.contains(QLatin1String("ref"))) {
+ int childRef = property.value(QLatin1String("ref")).toInt();
+ if (childRef >= 0 && refs.refs.size() > childRef) {
+ property.remove(QLatin1String("ref"));
+ property.insert(QLatin1String("properties"),
+ refs.resolveRef(childRef).value(
+ QLatin1String("properties")).toArray());
+ }
+ }
+ refs.scope.insert(name, property);
+ }
}
}
@@ -240,8 +255,7 @@ public:
QList<V4Debugger::ExecutionState> m_statesWhenPaused;
QList<TestBreakPoint> m_breakPointsToAddWhenPaused;
QVector<QV4::StackFrame> m_stackTrace;
- QVector<NamedRefs> m_capturedArguments;
- QVector<NamedRefs> m_capturedLocals;
+ QVector<NamedRefs> m_capturedScope;
qint64 m_thrownValue;
QV4DataCollector collector;
@@ -250,7 +264,8 @@ public:
int frameNr;
};
QVector<ExpressionRequest> m_expressionRequests;
- QVector<Refs> m_expressionResults;
+ QList<QJsonObject> m_expressionResults;
+ QList<QJsonArray> m_expressionRefs;
V4Debugger *m_debugger;
// Utility methods:
@@ -454,8 +469,8 @@ void tst_qv4debugger::conditionalBreakPoint()
QCOMPARE(state.fileName, QString("conditionalBreakPoint"));
QCOMPARE(state.lineNumber, 3);
- QVERIFY(m_debuggerAgent->m_capturedLocals.size() > 1);
- const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedLocals.at(0);
+ QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1);
+ const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0);
QCOMPARE(frame0.size(), 2);
QVERIFY(frame0.contains("i"));
QCOMPARE(frame0.value("i").toInt(), 11);
@@ -511,13 +526,13 @@ void tst_qv4debugger::readArguments()
debugger()->addBreakPoint("readArguments", 2);
evaluateJavaScript(script, "readArguments");
QVERIFY(m_debuggerAgent->m_wasPaused);
- QVERIFY(m_debuggerAgent->m_capturedArguments.size() > 1);
- const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedArguments.at(0);
+ QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1);
+ const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0);
QCOMPARE(frame0.size(), 4);
QVERIFY(frame0.contains(QStringLiteral("a")));
QCOMPARE(frame0.type(QStringLiteral("a")), QStringLiteral("number"));
QCOMPARE(frame0.value(QStringLiteral("a")).toDouble(), 1.0);
- QVERIFY(frame0.names.contains("b"));
+ QVERIFY(frame0.scope.contains("b"));
QCOMPARE(frame0.type(QStringLiteral("b")), QStringLiteral("string"));
QCOMPARE(frame0.value(QStringLiteral("b")).toString(), QStringLiteral("two"));
}
@@ -535,9 +550,9 @@ void tst_qv4debugger::readLocals()
debugger()->addBreakPoint("readLocals", 3);
evaluateJavaScript(script, "readLocals");
QVERIFY(m_debuggerAgent->m_wasPaused);
- QVERIFY(m_debuggerAgent->m_capturedLocals.size() > 1);
- const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedLocals.at(0);
- QCOMPARE(frame0.size(), 2);
+ QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1);
+ const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0);
+ QCOMPARE(frame0.size(), 4); // locals and parameters
QVERIFY(frame0.contains("c"));
QCOMPARE(frame0.type("c"), QStringLiteral("number"));
QCOMPARE(frame0.value("c").toDouble(), 3.0);
@@ -557,9 +572,9 @@ void tst_qv4debugger::readObject()
debugger()->addBreakPoint("readObject", 3);
evaluateJavaScript(script, "readObject");
QVERIFY(m_debuggerAgent->m_wasPaused);
- QVERIFY(m_debuggerAgent->m_capturedLocals.size() > 1);
- const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedLocals.at(0);
- QCOMPARE(frame0.size(), 1);
+ QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1);
+ const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0);
+ QCOMPARE(frame0.size(), 2);
QVERIFY(frame0.contains("b"));
QCOMPARE(frame0.type("b"), QStringLiteral("object"));
QJsonObject b = frame0.rawValue("b");
@@ -578,7 +593,7 @@ void tst_qv4debugger::readObject()
QCOMPARE(b_tail.value("name").toString(), QStringLiteral("tail"));
QVERIFY(b_tail.contains("ref"));
- QJsonObject b_tail_value = frame0.collector->lookupRef(b_tail.value("ref").toInt());
+ QJsonObject b_tail_value = m_debuggerAgent->collector.lookupRef(b_tail.value("ref").toInt());
QCOMPARE(b_tail_value.value("type").toString(), QStringLiteral("object"));
QVERIFY(b_tail_value.contains("properties"));
QJsonArray b_tail_props = b_tail_value.value("properties").toArray();
@@ -610,28 +625,23 @@ void tst_qv4debugger::readContextInAllFrames()
evaluateJavaScript(script, "readFormalsInAllFrames");
QVERIFY(m_debuggerAgent->m_wasPaused);
QCOMPARE(m_debuggerAgent->m_stackTrace.size(), 13);
- QCOMPARE(m_debuggerAgent->m_capturedArguments.size(), 13);
- QCOMPARE(m_debuggerAgent->m_capturedLocals.size(), 13);
+ QCOMPARE(m_debuggerAgent->m_capturedScope.size(), 13);
for (int i = 0; i < 12; ++i) {
- const TestAgent::NamedRefs &args = m_debuggerAgent->m_capturedArguments.at(i);
- QCOMPARE(args.size(), 1);
- QVERIFY(args.contains("n"));
- QCOMPARE(args.type("n"), QStringLiteral("number"));
- QCOMPARE(args.value("n").toDouble(), i + 1.0);
-
- const TestAgent::NamedRefs &locals = m_debuggerAgent->m_capturedLocals.at(i);
- QCOMPARE(locals.size(), 1);
- QVERIFY(locals.contains("n_1"));
+ const TestAgent::NamedRefs &scope = m_debuggerAgent->m_capturedScope.at(i);
+ QCOMPARE(scope.size(), 2);
+ QVERIFY(scope.contains("n"));
+ QCOMPARE(scope.type("n"), QStringLiteral("number"));
+ QCOMPARE(scope.value("n").toDouble(), i + 1.0);
+ QVERIFY(scope.contains("n_1"));
if (i == 0) {
- QCOMPARE(locals.type("n_1"), QStringLiteral("undefined"));
+ QCOMPARE(scope.type("n_1"), QStringLiteral("undefined"));
} else {
- QCOMPARE(locals.type("n_1"), QStringLiteral("number"));
- QCOMPARE(locals.value("n_1").toInt(), i);
+ QCOMPARE(scope.type("n_1"), QStringLiteral("number"));
+ QCOMPARE(scope.value("n_1").toInt(), i);
}
}
- QCOMPARE(m_debuggerAgent->m_capturedArguments[12].size(), 0);
- QCOMPARE(m_debuggerAgent->m_capturedLocals[12].size(), 0);
+ QCOMPARE(m_debuggerAgent->m_capturedScope[12].size(), 0);
}
void tst_qv4debugger::pauseOnThrow()
@@ -711,15 +721,13 @@ void tst_qv4debugger::evaluateExpression()
evaluateJavaScript(script, "evaluateExpression");
- QCOMPARE(m_debuggerAgent->m_expressionResults.count(), 2);
- QCOMPARE(m_debuggerAgent->m_expressionResults[0].size(), 1);
- QJsonObject result0 =
- m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_expressionResults[0].first());
+ QCOMPARE(m_debuggerAgent->m_expressionRefs.count(), 2);
+ QCOMPARE(m_debuggerAgent->m_expressionRefs[0].size(), 1);
+ QJsonObject result0 = m_debuggerAgent->m_expressionRefs[0].first().toObject();
QCOMPARE(result0.value("type").toString(), QStringLiteral("number"));
QCOMPARE(result0.value("value").toInt(), 10);
- QCOMPARE(m_debuggerAgent->m_expressionResults[1].size(), 1);
- QJsonObject result1 =
- m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_expressionResults[1].first());
+ QCOMPARE(m_debuggerAgent->m_expressionRefs[1].size(), 1);
+ QJsonObject result1 = m_debuggerAgent->m_expressionRefs[1].first().toObject();
QCOMPARE(result1.value("type").toString(), QStringLiteral("number"));
QCOMPARE(result1.value("value").toInt(), 20);
}