aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmltooling/qmldbg_debugger
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmltooling/qmldbg_debugger')
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp165
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h19
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp21
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h16
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp280
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h24
7 files changed, 213 insertions, 318 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 95e6d5704c..8c92b4b170 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -46,6 +46,7 @@
#include <private/qv4objectiterator_p.h>
#include <private/qv4identifier_p.h>
#include <private/qv4runtime_p.h>
+#include <private/qv4identifiertable_p.h>
#include <private/qqmlcontext_p.h>
#include <private/qqmlengine_p.h>
@@ -96,33 +97,28 @@ int QV4DataCollector::encodeScopeType(QV4::Heap::ExecutionContext::ContextType s
{
switch (scopeType) {
case QV4::Heap::ExecutionContext::Type_GlobalContext:
- return 0;
- case QV4::Heap::ExecutionContext::Type_CatchContext:
- return 4;
+ break;
case QV4::Heap::ExecutionContext::Type_WithContext:
return 2;
case QV4::Heap::ExecutionContext::Type_CallContext:
return 1;
case QV4::Heap::ExecutionContext::Type_QmlContext:
return 3;
- default:
- return -1;
+ case QV4::Heap::ExecutionContext::Type_BlockContext:
+ return 4;
}
+ return 0;
}
QV4DataCollector::QV4DataCollector(QV4::ExecutionEngine *engine)
- : m_engine(engine), m_namesAsObjects(true), m_redundantRefs(true)
+ : m_engine(engine)
{
m_values.set(engine, engine->newArrayObject());
}
-// TODO: Directly call addRef() once we don't need to support redundantRefs anymore
-QV4DataCollector::Ref QV4DataCollector::collect(const QV4::ScopedValue &value)
+QV4DataCollector::Ref QV4DataCollector::addValueRef(const QV4::ScopedValue &value)
{
- Ref ref = addRef(value);
- if (m_redundantRefs)
- m_collectedRefs.append(ref);
- return ref;
+ return addRef(value);
}
const QV4::Object *collectProperty(const QV4::ScopedValue &value, QV4::ExecutionEngine *engine,
@@ -158,15 +154,12 @@ const QV4::Object *collectProperty(const QV4::ScopedValue &value, QV4::Execution
int numProperties = 0;
QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
QV4::PropertyAttributes attrs;
- uint index;
- QV4::ScopedProperty p(scope);
- QV4::ScopedString name(scope);
+ QV4::ScopedPropertyKey name(scope);
while (true) {
- it.next(name.getRef(), &index, p, &attrs);
- if (attrs.isEmpty())
+ name = it.next(nullptr, &attrs);
+ if (!name->isValid())
break;
- else
- ++numProperties;
+ ++numProperties;
}
dict.insert(valueKey, numProperties);
return o;
@@ -192,61 +185,21 @@ const QV4::Object *collectProperty(const QV4::ScopedValue &value, QV4::Execution
}
}
-QJsonObject QV4DataCollector::lookupRef(Ref ref, bool deep)
+QJsonObject QV4DataCollector::lookupRef(Ref ref)
{
QJsonObject dict;
- if (m_namesAsObjects) {
- if (lookupSpecialRef(ref, &dict))
- return dict;
- }
-
- if (m_redundantRefs)
- deep = true;
-
dict.insert(QStringLiteral("handle"), qint64(ref));
QV4::Scope scope(engine());
QV4::ScopedValue value(scope, getValue(ref));
const QV4::Object *object = collectProperty(value, engine(), dict);
- if (deep && object)
+ if (object)
dict.insert(QStringLiteral("properties"), collectProperties(object));
return dict;
}
-// TODO: Drop this method once we don't need to support namesAsObjects anymore
-QV4DataCollector::Ref QV4DataCollector::addFunctionRef(const QString &functionName)
-{
- Q_ASSERT(m_namesAsObjects);
- Ref ref = addRef(QV4::Primitive::emptyValue(), false);
-
- QJsonObject dict;
- dict.insert(QStringLiteral("handle"), qint64(ref));
- dict.insert(QStringLiteral("type"), QStringLiteral("function"));
- dict.insert(QStringLiteral("name"), functionName);
- m_specialRefs.insert(ref, dict);
- m_collectedRefs.append(ref);
-
- return ref;
-}
-
-// TODO: Drop this method once we don't need to support namesAsObjects anymore
-QV4DataCollector::Ref QV4DataCollector::addScriptRef(const QString &scriptName)
-{
- Q_ASSERT(m_namesAsObjects);
- Ref ref = addRef(QV4::Primitive::emptyValue(), false);
-
- QJsonObject dict;
- dict.insert(QStringLiteral("handle"), qint64(ref));
- dict.insert(QStringLiteral("type"), QStringLiteral("script"));
- dict.insert(QStringLiteral("name"), scriptName);
- m_specialRefs.insert(ref, dict);
- m_collectedRefs.append(ref);
-
- return ref;
-}
-
bool QV4DataCollector::isValidRef(QV4DataCollector::Ref ref) const
{
QV4::Scope scope(engine());
@@ -268,12 +221,12 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr)
Refs collectedRefs;
QV4::ScopedValue v(scope);
- QV4::InternalClass *ic = ctxt->internalClass();
+ QV4::Heap::InternalClass *ic = ctxt->internalClass();
for (uint i = 0; i < ic->size; ++i) {
- QString name = ic->nameMap[i]->string;
+ QString name = ic->keyAt(i);
names.append(name);
v = static_cast<QV4::Heap::CallContext *>(ctxt->d())->locals[i];
- collectedRefs.append(collect(v));
+ collectedRefs.append(addValueRef(v));
}
Q_ASSERT(names.size() == collectedRefs.size());
@@ -284,13 +237,7 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr)
}
}
- Ref scopeObjectRef = addRef(scopeObject);
- if (m_redundantRefs) {
- dict->insert(QStringLiteral("ref"), qint64(scopeObjectRef));
- m_collectedRefs.append(scopeObjectRef);
- } else {
- *dict = lookupRef(scopeObjectRef, true);
- }
+ *dict = lookupRef(addRef(scopeObject));
return true;
}
@@ -306,13 +253,8 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int
QJsonObject frame;
frame[QLatin1String("index")] = frameNr;
frame[QLatin1String("debuggerFrame")] = false;
- if (m_namesAsObjects) {
- frame[QLatin1String("func")] = toRef(addFunctionRef(stackFrame.function));
- frame[QLatin1String("script")] = toRef(addScriptRef(stackFrame.source));
- } else {
- frame[QLatin1String("func")] = stackFrame.function;
- frame[QLatin1String("script")] = stackFrame.source;
- }
+ frame[QLatin1String("func")] = stackFrame.function;
+ frame[QLatin1String("script")] = stackFrame.source;
frame[QLatin1String("line")] = stackFrame.line - 1;
if (stackFrame.column >= 0)
frame[QLatin1String("column")] = stackFrame.column;
@@ -330,7 +272,7 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int
if (ctxt) {
QV4::ScopedValue o(scope, ctxt->d()->activation);
- frame[QLatin1String("receiver")] = toRef(collect(o));
+ frame[QLatin1String("receiver")] = toRef(addValueRef(o));
}
// Only type and index are used by Qt Creator, so we keep it easy:
@@ -351,30 +293,9 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int
return frame;
}
-// TODO: Drop this method once we don't need to support redundantRefs anymore
-QJsonArray QV4DataCollector::flushCollectedRefs()
-{
- Q_ASSERT(m_redundantRefs);
- QJsonArray refs;
- std::sort(m_collectedRefs.begin(), m_collectedRefs.end());
- for (int i = 0, ei = m_collectedRefs.size(); i != ei; ++i) {
- QV4DataCollector::Ref ref = m_collectedRefs.at(i);
- if (i > 0 && ref == m_collectedRefs.at(i - 1))
- continue;
- refs.append(lookupRef(ref, true));
- }
-
- m_collectedRefs.clear();
- return refs;
-}
-
void QV4DataCollector::clear()
{
m_values.set(engine(), engine()->newArrayObject());
- m_collectedRefs.clear();
- m_specialRefs.clear();
- m_namesAsObjects = true;
- m_redundantRefs = true;
}
QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicate)
@@ -394,18 +315,18 @@ QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicat
{ std::swap(*hasExceptionLoc, hadException); }
};
- // if we wouldn't do this, the putIndexed won't work.
+ // if we wouldn't do this, the put won't work.
ExceptionStateSaver resetExceptionState(engine());
QV4::Scope scope(engine());
QV4::ScopedObject array(scope, m_values.value());
if (deduplicate) {
for (Ref i = 0; i < array->getLength(); ++i) {
- if (array->getIndexed(i) == value.rawValue() && !m_specialRefs.contains(i))
+ if (array->get(i) == value.rawValue())
return i;
}
}
Ref ref = array->getLength();
- array->putIndexed(ref, value);
+ array->put(ref, value);
Q_ASSERT(array->getLength() - 1 == ref);
return ref;
}
@@ -415,23 +336,39 @@ QV4::ReturnedValue QV4DataCollector::getValue(Ref ref)
QV4::Scope scope(engine());
QV4::ScopedObject array(scope, m_values.value());
Q_ASSERT(ref < array->getLength());
- return array->getIndexed(ref, nullptr);
+ return array->get(ref, nullptr);
}
-// TODO: Drop this method once we don't need to support namesAsObjects anymore
-bool QV4DataCollector::lookupSpecialRef(Ref ref, QJsonObject *dict)
+class CapturePreventer
{
- Q_ASSERT(m_namesAsObjects);
- SpecialRefs::const_iterator it = m_specialRefs.constFind(ref);
- if (it == m_specialRefs.cend())
- return false;
+public:
+ CapturePreventer(QV4::ExecutionEngine *engine)
+ {
+ if (QQmlEngine *e = engine->qmlEngine()) {
+ m_engine = QQmlEnginePrivate::get(e);
+ m_capture = m_engine->propertyCapture;
+ m_engine->propertyCapture = nullptr;
+ }
+ }
- *dict = it.value();
- return true;
-}
+ ~CapturePreventer()
+ {
+ if (m_engine && m_capture) {
+ Q_ASSERT(!m_engine->propertyCapture);
+ m_engine->propertyCapture = m_capture;
+ }
+ }
+
+private:
+ QQmlEnginePrivate *m_engine = nullptr;
+ QQmlPropertyCapture *m_capture = nullptr;
+};
QJsonArray QV4DataCollector::collectProperties(const QV4::Object *object)
{
+ CapturePreventer capturePreventer(engine());
+ Q_UNUSED(capturePreventer);
+
QJsonArray res;
QV4::Scope scope(engine());
@@ -459,8 +396,6 @@ 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_redundantRefs)
- m_collectedRefs.append(ref);
}
collectProperty(value, engine(), dict);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
index 5494e10e9a..bc178fa2db 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
@@ -67,42 +67,27 @@ public:
QV4DataCollector(QV4::ExecutionEngine *engine);
- Ref collect(const QV4::ScopedValue &value); // only for redundantRefs
- Ref addFunctionRef(const QString &functionName); // only for namesAsObjects
- Ref addScriptRef(const QString &scriptName); // only for namesAsObjects
-
- void setNamesAsObjects(bool namesAsObjects) { m_namesAsObjects = namesAsObjects; }
- bool namesAsObjects() const { return m_namesAsObjects; }
-
- void setRedundantRefs(bool redundantRefs) { m_redundantRefs = redundantRefs; }
- bool redundantRefs() const { return m_redundantRefs; }
+ Ref addValueRef(const QV4::ScopedValue &value);
bool isValidRef(Ref ref) const;
- QJsonObject lookupRef(Ref ref, bool deep);
+ QJsonObject lookupRef(Ref ref);
bool collectScope(QJsonObject *dict, int frameNr, int scopeNr);
QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr);
QV4::ExecutionEngine *engine() const { return m_engine; }
- QJsonArray flushCollectedRefs(); // only for redundantRefs
void clear();
private:
Ref addRef(QV4::Value value, bool deduplicate = true);
QV4::ReturnedValue getValue(Ref ref);
- bool lookupSpecialRef(Ref ref, QJsonObject *dict); // only for namesAsObjects
QJsonArray collectProperties(const QV4::Object *object);
QJsonObject collectAsJson(const QString &name, const QV4::ScopedValue &value);
void collectArgumentsInContext();
QV4::ExecutionEngine *m_engine;
- Refs m_collectedRefs; // only for redundantRefs
QV4::PersistentValue m_values;
- typedef QHash<Ref, QJsonObject> SpecialRefs; // only for namesAsObjects
- SpecialRefs m_specialRefs; // only for namesAsObjects
- bool m_namesAsObjects;
- bool m_redundantRefs;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
index a1ed211a55..5521e7628b 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
@@ -70,7 +70,7 @@ QV4Debugger::QV4Debugger(QV4::ExecutionEngine *engine)
, m_pauseRequested(false)
, m_haveBreakPoints(false)
, m_breakOnThrow(false)
- , m_returnedValue(engine, QV4::Primitive::undefinedValue())
+ , m_returnedValue(engine, QV4::Value::undefinedValue())
, m_gatherSources(nullptr)
, m_runningJob(nullptr)
, m_collector(engine)
@@ -157,7 +157,7 @@ void QV4Debugger::clearPauseRequest()
QV4Debugger::ExecutionState QV4Debugger::currentExecutionState() const
{
ExecutionState state;
- state.fileName = getFunction()->sourceFile();
+ state.fileName = QUrl(getFunction()->sourceFile()).fileName();
state.lineNumber = engine()->currentStackFrame->lineNumber();
return state;
@@ -288,7 +288,7 @@ void QV4Debugger::pauseAndWait(PauseReason reason)
bool QV4Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr)
{
QHash<BreakPoint, QString>::iterator it = m_breakPoints.find(
- BreakPoint(filename.mid(filename.lastIndexOf('/') + 1), linenr));
+ BreakPoint(QUrl(filename).fileName(), linenr));
if (it == m_breakPoints.end())
return false;
QString condition = it.value();
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index 7950d21612..b424ef9f6c 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -65,7 +65,7 @@ void JavaScriptJob::run()
QV4::Scope scope(engine);
QV4::ScopedContext ctx(scope, engine->currentStackFrame ? engine->currentContext()
- : engine->rootContext());
+ : engine->scriptContext());
QObject scopeObject;
QV4::CppStackFrame *frame = engine->currentStackFrame;
@@ -103,7 +103,7 @@ void JavaScriptJob::run()
}
}
- QV4::Script script(ctx, QV4::Compiler::EvalCode, this->script);
+ QV4::Script script(ctx, QV4::Compiler::ContextType::Eval, this->script);
if (const QV4::Function *function = frame ? frame->v4Function : engine->globalCode)
script.strictMode = function->isStrict();
@@ -150,7 +150,6 @@ void BacktraceJob::run()
result.insert(QStringLiteral("toFrame"), fromFrame + frameArray.size());
result.insert(QStringLiteral("frames"), frameArray);
}
- flushRedundantRefs();
}
FrameJob::FrameJob(QV4DataCollector *collector, int frameNr) :
@@ -165,7 +164,6 @@ void FrameJob::run()
success = false;
} else {
result = collector->buildFrame(frames[frameNr], frameNr);
- flushRedundantRefs();
success = true;
}
}
@@ -195,7 +193,6 @@ void ScopeJob::run()
result[QLatin1String("index")] = scopeNr;
result[QLatin1String("frameIndex")] = frameNr;
result[QLatin1String("object")] = object;
- flushRedundantRefs();
}
bool ScopeJob::wasSuccessful() const
@@ -228,9 +225,8 @@ void ValueLookupJob::run()
exception = QString::fromLatin1("Invalid Ref: %1").arg(ref);
break;
}
- result[QString::number(ref)] = collector->lookupRef(ref, true);
+ result[QString::number(ref)] = collector->lookupRef(ref);
}
- flushRedundantRefs();
}
const QString &ValueLookupJob::exceptionMessage() const
@@ -249,9 +245,7 @@ void ExpressionEvalJob::handleResult(QV4::ScopedValue &value)
{
if (hasExeption())
exception = value->toQStringNoThrow();
- result = collector->lookupRef(collector->collect(value), true);
- if (collector->redundantRefs())
- collectedRefs = collector->flushCollectedRefs();
+ result = collector->lookupRef(collector->addValueRef(value));
}
const QString &ExpressionEvalJob::exceptionMessage() const
@@ -264,13 +258,6 @@ const QJsonObject &ExpressionEvalJob::returnValue() const
return result;
}
-// TODO: Drop this method once we don't need to support redundantRefs anymore
-const QJsonArray &ExpressionEvalJob::refs() const
-{
- Q_ASSERT(collector->redundantRefs());
- return collectedRefs;
-}
-
GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine)
: engine(engine)
{}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h
index eca8710e15..d1c7495863 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.h
@@ -78,24 +78,10 @@ class CollectJob : public QV4DebugJob
protected:
QV4DataCollector *collector;
QJsonObject result;
- QJsonArray collectedRefs; // only for redundantRefs
-
- void flushRedundantRefs()
- {
- if (collector->redundantRefs())
- collectedRefs = collector->flushCollectedRefs();
- }
public:
CollectJob(QV4DataCollector *collector) : collector(collector) {}
const QJsonObject &returnValue() const { return result; }
-
- // TODO: Drop this method once we don't need to support redundantRefs anymore
- const QJsonArray &refs() const
- {
- Q_ASSERT(collector->redundantRefs());
- return collectedRefs;
- }
};
class BacktraceJob: public CollectJob
@@ -146,7 +132,6 @@ class ExpressionEvalJob: public JavaScriptJob
QV4DataCollector *collector;
QString exception;
QJsonObject result;
- QJsonArray collectedRefs; // only for redundantRefs
public:
ExpressionEvalJob(QV4::ExecutionEngine *engine, int frameNr, int context,
@@ -154,7 +139,6 @@ public:
void handleResult(QV4::ScopedValue &value) override;
const QString &exceptionMessage() const;
const QJsonObject &returnValue() const;
- const QJsonArray &refs() const; // only for redundantRefs
};
class GatherSourcesJob: public QV4DebugJob
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index 32de8e9027..5866163ca6 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -67,21 +67,21 @@ const char *const V4_PAUSE = "interrupt";
QT_BEGIN_NAMESPACE
-class V8CommandHandler;
-class UnknownV8CommandHandler;
+class V4CommandHandler;
+class UnknownV4CommandHandler;
using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
int QV4DebugServiceImpl::sequence = 0;
-class V8CommandHandler
+class V4CommandHandler
{
public:
- V8CommandHandler(const QString &command)
+ V4CommandHandler(const QString &command)
: cmd(command)
{}
- virtual ~V8CommandHandler()
+ virtual ~V4CommandHandler()
{}
QString command() const { return cmd; }
@@ -122,21 +122,6 @@ protected:
response.insert(QStringLiteral("running"), debugService->debuggerAgent.isRunning());
}
- QV4DataCollector *saneCollector(QV4Debugger *debugger)
- {
- QV4DataCollector *collector = debugger->collector();
- collector->setNamesAsObjects(debugService->clientRequiresNamesAsObjects());
- collector->setRedundantRefs(debugService->clientRequiresRedundantRefs());
- return collector;
- }
-
- // TODO: drop this method once we don't need to support redundantRefs anymore.
- void addRefs(const QJsonArray &refs)
- {
- Q_ASSERT(debugService->clientRequiresRedundantRefs());
- response.insert(QStringLiteral("refs"), refs);
- }
-
void createErrorResponse(const QString &msg)
{
QJsonValue command = req.value(QLatin1String("command"));
@@ -158,10 +143,10 @@ protected:
QJsonObject response;
};
-class UnknownV8CommandHandler: public V8CommandHandler
+class UnknownV4CommandHandler: public V4CommandHandler
{
public:
- UnknownV8CommandHandler(): V8CommandHandler(QString()) {}
+ UnknownV4CommandHandler(): V4CommandHandler(QString()) {}
void handleRequest() override
{
@@ -173,10 +158,10 @@ public:
};
namespace {
-class V8VersionRequest: public V8CommandHandler
+class V4VersionRequest: public V4CommandHandler
{
public:
- V8VersionRequest(): V8CommandHandler(QStringLiteral("version")) {}
+ V4VersionRequest(): V4CommandHandler(QStringLiteral("version")) {}
void handleRequest() override
{
@@ -189,98 +174,137 @@ public:
QLatin1String("this is not V8, this is V4 in Qt " QT_VERSION_STR));
body.insert(QStringLiteral("UnpausedEvaluate"), true);
body.insert(QStringLiteral("ContextEvaluate"), true);
+ body.insert(QStringLiteral("ChangeBreakpoint"), true);
addBody(body);
}
};
-class V8SetBreakPointRequest: public V8CommandHandler
+class V4BreakPointRequest: public V4CommandHandler
{
public:
- V8SetBreakPointRequest(): V8CommandHandler(QStringLiteral("setbreakpoint")) {}
+ V4BreakPointRequest(const QString &name): V4CommandHandler(name) {}
- void handleRequest() override
+ void handleRequest() final
{
+ // Other types are currently not supported
+ m_type = QStringLiteral("scriptRegExp");
+
// decypher the payload:
- QJsonObject args = req.value(QLatin1String("arguments")).toObject();
- if (args.isEmpty())
+ m_args = req.value(QLatin1String("arguments")).toObject();
+ if (m_args.isEmpty()) {
+ createErrorResponse(QStringLiteral("breakpoint request with empty arguments object"));
return;
+ }
- QString type = args.value(QLatin1String("type")).toString();
+ const int id = handleBreakPointRequest();
+ if (id < 0) {
+ createErrorResponse(m_error);
+ } else {
+ // response:
+ addCommand();
+ addRequestSequence();
+ addSuccess(true);
+ addRunning();
+ QJsonObject body;
+ body.insert(QStringLiteral("type"), m_type);
+ body.insert(QStringLiteral("breakpoint"), id);
+ addBody(body);
+ }
+ }
+
+protected:
+ virtual int handleBreakPointRequest() = 0;
+
+ QJsonObject m_args;
+ QString m_type;
+ QString m_error;
+};
+
+class V4SetBreakPointRequest: public V4BreakPointRequest
+{
+public:
+ V4SetBreakPointRequest(): V4BreakPointRequest(QStringLiteral("setbreakpoint")) {}
+
+ int handleBreakPointRequest() final
+ {
+ // decypher the payload:
+ const QString type = m_args.value(QLatin1String("type")).toString();
if (type != QLatin1String("scriptRegExp")) {
- createErrorResponse(QStringLiteral("breakpoint type \"%1\" is not implemented").arg(type));
- return;
+ m_error = QStringLiteral("breakpoint type \"%1\" is not implemented").arg(type);
+ return -1;
}
- QString fileName = args.value(QLatin1String("target")).toString();
+ const QString fileName = m_args.value(QLatin1String("target")).toString();
if (fileName.isEmpty()) {
- createErrorResponse(QStringLiteral("breakpoint has no file name"));
- return;
+ m_error = QStringLiteral("breakpoint has no file name");
+ return -1;
}
- int line = args.value(QLatin1String("line")).toInt(-1);
+
+ const int line = m_args.value(QLatin1String("line")).toInt(-1);
if (line < 0) {
- createErrorResponse(QStringLiteral("breakpoint has an invalid line number"));
- return;
+ m_error = QStringLiteral("breakpoint has an invalid line number");
+ return -1;
}
- bool enabled = args.value(QStringLiteral("enabled")).toBool(true);
- QString condition = args.value(QStringLiteral("condition")).toString();
+ const bool enabled = m_args.value(QStringLiteral("enabled")).toBool(true);
+ const QString condition = m_args.value(QStringLiteral("condition")).toString();
// set the break point:
- int id = debugService->debuggerAgent.addBreakPoint(fileName, line + 1, enabled, condition);
+ return debugService->debuggerAgent.addBreakPoint(fileName, line + 1, enabled, condition);
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- QJsonObject body;
- body.insert(QStringLiteral("type"), type);
- body.insert(QStringLiteral("breakpoint"), id);
// It's undocumented, but V8 sends back an actual_locations array too. However, our
// Debugger currently doesn't tell us when it resolved a breakpoint, so we'll leave them
// pending until the breakpoint is hit for the first time.
- addBody(body);
}
};
-class V8ClearBreakPointRequest: public V8CommandHandler
+class V4ClearBreakPointRequest: public V4BreakPointRequest
{
public:
- V8ClearBreakPointRequest(): V8CommandHandler(QStringLiteral("clearbreakpoint")) {}
+ V4ClearBreakPointRequest(): V4BreakPointRequest(QStringLiteral("clearbreakpoint")) {}
- void handleRequest() override
+ int handleBreakPointRequest() final
{
- // decypher the payload:
- QJsonObject args = req.value(QLatin1String("arguments")).toObject();
- if (args.isEmpty())
- return;
+ const int id = m_args.value(QLatin1String("breakpoint")).toInt(-1);
+ if (id < 0)
+ m_error = QStringLiteral("breakpoint has an invalid number");
+ else // remove the break point:
+ debugService->debuggerAgent.removeBreakPoint(id);
- int id = args.value(QLatin1String("breakpoint")).toInt(-1);
+ return id;
+ }
+};
+
+class V4ChangeBreakPointRequest: public V4BreakPointRequest
+{
+public:
+ V4ChangeBreakPointRequest(): V4BreakPointRequest(QStringLiteral("changebreakpoint")) {}
+
+ int handleBreakPointRequest() final
+ {
+ const int id = m_args.value(QLatin1String("breakpoint")).toInt(-1);
if (id < 0) {
- createErrorResponse(QStringLiteral("breakpoint has an invalid number"));
- return;
+ m_error = QStringLiteral("breakpoint has an invalid number");
+ return id;
}
- // remove the break point:
- debugService->debuggerAgent.removeBreakPoint(id);
+ const QJsonValue enabled = m_args.value(QLatin1String("enabled"));
+ if (!enabled.isBool()) {
+ m_error = QStringLiteral("missing bool \"enabled\" in breakpoint change request");
+ return -1;
+ }
- // response:
- addCommand();
- addRequestSequence();
- addSuccess(true);
- addRunning();
- QJsonObject body;
- body.insert(QStringLiteral("type"), QStringLiteral("scriptRegExp"));
- body.insert(QStringLiteral("breakpoint"), id);
- addBody(body);
+ // enable or disable the break point:
+ debugService->debuggerAgent.enableBreakPoint(id, enabled.toBool());
+ return id;
}
};
-class V8BacktraceRequest: public V8CommandHandler
+class V4BacktraceRequest: public V4CommandHandler
{
public:
- V8BacktraceRequest(): V8CommandHandler(QStringLiteral("backtrace")) {}
+ V4BacktraceRequest(): V4CommandHandler(QStringLiteral("backtrace")) {}
void handleRequest() override
{
@@ -297,7 +321,7 @@ public:
return;
}
- BacktraceJob job(saneCollector(debugger), fromFrame, toFrame);
+ BacktraceJob job(debugger->collector(), fromFrame, toFrame);
debugger->runInEngine(&job);
// response:
@@ -306,15 +330,13 @@ public:
addSuccess(true);
addRunning();
addBody(job.returnValue());
- if (debugService->clientRequiresRedundantRefs())
- addRefs(job.refs());
}
};
-class V8FrameRequest: public V8CommandHandler
+class V4FrameRequest: public V4CommandHandler
{
public:
- V8FrameRequest(): V8CommandHandler(QStringLiteral("frame")) {}
+ V4FrameRequest(): V4CommandHandler(QStringLiteral("frame")) {}
void handleRequest() override
{
@@ -334,7 +356,7 @@ public:
return;
}
- FrameJob job(saneCollector(debugger), frameNr);
+ FrameJob job(debugger->collector(), frameNr);
debugger->runInEngine(&job);
if (!job.wasSuccessful()) {
createErrorResponse(QStringLiteral("frame retrieval failed"));
@@ -349,15 +371,13 @@ public:
addSuccess(true);
addRunning();
addBody(job.returnValue());
- if (debugService->clientRequiresRedundantRefs())
- addRefs(job.refs());
}
};
-class V8ScopeRequest: public V8CommandHandler
+class V4ScopeRequest: public V4CommandHandler
{
public:
- V8ScopeRequest(): V8CommandHandler(QStringLiteral("scope")) {}
+ V4ScopeRequest(): V4CommandHandler(QStringLiteral("scope")) {}
void handleRequest() override
{
@@ -382,7 +402,7 @@ public:
return;
}
- ScopeJob job(saneCollector(debugger), frameNr, scopeNr);
+ ScopeJob job(debugger->collector(), frameNr, scopeNr);
debugger->runInEngine(&job);
if (!job.wasSuccessful()) {
createErrorResponse(QStringLiteral("scope retrieval failed"));
@@ -395,15 +415,13 @@ public:
addSuccess(true);
addRunning();
addBody(job.returnValue());
- if (debugService->clientRequiresRedundantRefs())
- addRefs(job.refs());
}
};
-class V8LookupRequest: public V8CommandHandler
+class V4LookupRequest: public V4CommandHandler
{
public:
- V8LookupRequest(): V8CommandHandler(QStringLiteral("lookup")) {}
+ V4LookupRequest(): V4CommandHandler(QStringLiteral("lookup")) {}
void handleRequest() override
{
@@ -424,7 +442,7 @@ public:
debugger = debuggers.first();
}
- ValueLookupJob job(handles, saneCollector(debugger));
+ ValueLookupJob job(handles, debugger->collector());
debugger->runInEngine(&job);
if (!job.exceptionMessage().isEmpty()) {
createErrorResponse(job.exceptionMessage());
@@ -435,16 +453,14 @@ public:
addSuccess(true);
addRunning();
addBody(job.returnValue());
- if (debugService->clientRequiresRedundantRefs())
- addRefs(job.refs());
}
}
};
-class V8ContinueRequest: public V8CommandHandler
+class V4ContinueRequest: public V4CommandHandler
{
public:
- V8ContinueRequest(): V8CommandHandler(QStringLiteral("continue")) {}
+ V4ContinueRequest(): V4CommandHandler(QStringLiteral("continue")) {}
void handleRequest() override
{
@@ -487,10 +503,10 @@ public:
}
};
-class V8DisconnectRequest: public V8CommandHandler
+class V4DisconnectRequest: public V4CommandHandler
{
public:
- V8DisconnectRequest(): V8CommandHandler(QStringLiteral("disconnect")) {}
+ V4DisconnectRequest(): V4CommandHandler(QStringLiteral("disconnect")) {}
void handleRequest() override
{
@@ -505,10 +521,10 @@ public:
}
};
-class V8SetExceptionBreakRequest: public V8CommandHandler
+class V4SetExceptionBreakRequest: public V4CommandHandler
{
public:
- V8SetExceptionBreakRequest(): V8CommandHandler(QStringLiteral("setexceptionbreak")) {}
+ V4SetExceptionBreakRequest(): V4CommandHandler(QStringLiteral("setexceptionbreak")) {}
void handleRequest() override
{
@@ -545,10 +561,10 @@ public:
}
};
-class V8ScriptsRequest: public V8CommandHandler
+class V4ScriptsRequest: public V4CommandHandler
{
public:
- V8ScriptsRequest(): V8CommandHandler(QStringLiteral("scripts")) {}
+ V4ScriptsRequest(): V4CommandHandler(QStringLiteral("scripts")) {}
void handleRequest() override
{
@@ -617,10 +633,10 @@ public:
// }
//
// The "value" key in "body" is the result of evaluating the expression in the request.
-class V8EvaluateRequest: public V8CommandHandler
+class V4EvaluateRequest: public V4CommandHandler
{
public:
- V8EvaluateRequest(): V8CommandHandler(QStringLiteral("evaluate")) {}
+ V4EvaluateRequest(): V4CommandHandler(QStringLiteral("evaluate")) {}
void handleRequest() override
{
@@ -645,7 +661,7 @@ public:
}
ExpressionEvalJob job(debugger->engine(), frame, context, expression,
- saneCollector(debugger));
+ debugger->collector());
debugger->runInEngine(&job);
if (job.hasExeption()) {
createErrorResponse(job.exceptionMessage());
@@ -655,44 +671,43 @@ public:
addSuccess(true);
addRunning();
addBody(job.returnValue());
- if (debugService->clientRequiresRedundantRefs())
- addRefs(job.refs());
}
}
};
} // anonymous namespace
-void QV4DebugServiceImpl::addHandler(V8CommandHandler* handler)
+void QV4DebugServiceImpl::addHandler(V4CommandHandler* handler)
{
handlers[handler->command()] = handler;
}
-V8CommandHandler *QV4DebugServiceImpl::v8CommandHandler(const QString &command) const
+V4CommandHandler *QV4DebugServiceImpl::v4CommandHandler(const QString &command) const
{
- V8CommandHandler *handler = handlers.value(command, 0);
+ V4CommandHandler *handler = handlers.value(command, 0);
if (handler)
return handler;
else
- return unknownV8CommandHandler.data();
+ return unknownV4CommandHandler.data();
}
QV4DebugServiceImpl::QV4DebugServiceImpl(QObject *parent) :
QQmlConfigurableDebugService<QV4DebugService>(1, parent),
- debuggerAgent(this), theSelectedFrame(0), redundantRefs(true), namesAsObjects(true),
- unknownV8CommandHandler(new UnknownV8CommandHandler)
+ debuggerAgent(this), theSelectedFrame(0),
+ unknownV4CommandHandler(new UnknownV4CommandHandler)
{
- addHandler(new V8VersionRequest);
- addHandler(new V8SetBreakPointRequest);
- addHandler(new V8ClearBreakPointRequest);
- addHandler(new V8BacktraceRequest);
- addHandler(new V8FrameRequest);
- addHandler(new V8ScopeRequest);
- addHandler(new V8LookupRequest);
- addHandler(new V8ContinueRequest);
- addHandler(new V8DisconnectRequest);
- addHandler(new V8SetExceptionBreakRequest);
- addHandler(new V8ScriptsRequest);
- addHandler(new V8EvaluateRequest);
+ addHandler(new V4VersionRequest);
+ addHandler(new V4SetBreakPointRequest);
+ addHandler(new V4ClearBreakPointRequest);
+ addHandler(new V4ChangeBreakPointRequest);
+ addHandler(new V4BacktraceRequest);
+ addHandler(new V4FrameRequest);
+ addHandler(new V4ScopeRequest);
+ addHandler(new V4LookupRequest);
+ addHandler(new V4ContinueRequest);
+ addHandler(new V4DisconnectRequest);
+ addHandler(new V4SetExceptionBreakRequest);
+ addHandler(new V4ScriptsRequest);
+ addHandler(new V4EvaluateRequest);
}
QV4DebugServiceImpl::~QV4DebugServiceImpl()
@@ -782,12 +797,7 @@ void QV4DebugServiceImpl::messageReceived(const QByteArray &message)
if (type == V4_CONNECT) {
QJsonObject parameters = QJsonDocument::fromJson(payload).object();
- namesAsObjects = true;
- redundantRefs = true;
- if (parameters.contains("namesAsObjects"))
- namesAsObjects = parameters.value("namesAsObjects").toBool();
- if (parameters.contains("redundantRefs"))
- redundantRefs = parameters.value("redundantRefs").toBool();
+ Q_UNUSED(parameters); // For future protocol changes
emit messageToClient(name(), packMessage(type));
stopWaiting();
@@ -805,10 +815,10 @@ void QV4DebugServiceImpl::messageReceived(const QByteArray &message)
else
breakOnSignals.removeOne(signalName);
} else if (type == "v8request") {
- handleV8Request(payload);
+ handleV4Request(payload);
} else if (type == V4_DISCONNECT) {
TRACE_PROTOCOL(qDebug() << "... payload:" << payload.constData());
- handleV8Request(payload);
+ handleV4Request(payload);
} else {
sendSomethingToSomebody(type, 0);
}
@@ -823,7 +833,7 @@ void QV4DebugServiceImpl::sendSomethingToSomebody(const char *type, int magicNum
emit messageToClient(name(), packMessage(type, rs.data()));
}
-void QV4DebugServiceImpl::handleV8Request(const QByteArray &payload)
+void QV4DebugServiceImpl::handleV4Request(const QByteArray &payload)
{
TRACE_PROTOCOL(qDebug() << "v8request, payload:" << payload.constData());
@@ -832,7 +842,7 @@ void QV4DebugServiceImpl::handleV8Request(const QByteArray &payload)
QJsonValue type = o.value(QLatin1String("type"));
if (type.toString() == QLatin1String("request")) {
QJsonValue command = o.value(QLatin1String("command"));
- V8CommandHandler *h = v8CommandHandler(command.toString());
+ V4CommandHandler *h = v4CommandHandler(command.toString());
if (h)
h->handle(o, this);
}
@@ -846,11 +856,11 @@ QByteArray QV4DebugServiceImpl::packMessage(const QByteArray &command, const QBy
return rs.data();
}
-void QV4DebugServiceImpl::send(QJsonObject v8Payload)
+void QV4DebugServiceImpl::send(QJsonObject v4Payload)
{
- v8Payload[QLatin1String("seq")] = sequence++;
+ v4Payload[QLatin1String("seq")] = sequence++;
QJsonDocument doc;
- doc.setObject(v8Payload);
+ doc.setObject(v4Payload);
#ifdef NO_PROTOCOL_TRACING
QByteArray responseData = doc.toJson(QJsonDocument::Compact);
#else
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
index 5401956994..d0b104dfad 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
@@ -64,15 +64,15 @@ QT_BEGIN_NAMESPACE
namespace QV4 { struct ExecutionEngine; }
class VariableCollector;
-class V8CommandHandler;
-class UnknownV8CommandHandler;
+class V4CommandHandler;
+class UnknownV4CommandHandler;
class QV4DebugServiceImpl;
class QV4DebugServiceImpl : public QQmlConfigurableDebugService<QV4DebugService>
{
Q_OBJECT
public:
- explicit QV4DebugServiceImpl(QObject *parent = 0);
+ explicit QV4DebugServiceImpl(QObject *parent = nullptr);
~QV4DebugServiceImpl() override;
void engineAdded(QJSEngine *engine) override;
@@ -81,14 +81,11 @@ public:
void stateAboutToBeChanged(State state) override;
void signalEmitted(const QString &signal) override;
- void send(QJsonObject v8Payload);
+ void send(QJsonObject v4Payload);
int selectedFrame() const;
void selectFrame(int frameNr);
- bool clientRequiresRedundantRefs() const { return redundantRefs; }
- bool clientRequiresNamesAsObjects() const { return namesAsObjects; }
-
QV4DebuggerAgent debuggerAgent;
protected:
@@ -98,22 +95,19 @@ protected:
private:
friend class QQmlDebuggerServiceFactory;
- void handleV8Request(const QByteArray &payload);
+ void handleV4Request(const QByteArray &payload);
static QByteArray packMessage(const QByteArray &command,
const QByteArray &message = QByteArray());
void processCommand(const QByteArray &command, const QByteArray &data);
- V8CommandHandler *v8CommandHandler(const QString &command) const;
+ V4CommandHandler *v4CommandHandler(const QString &command) const;
QStringList breakOnSignals;
static int sequence;
int theSelectedFrame;
- bool redundantRefs;
- bool namesAsObjects;
-
- void addHandler(V8CommandHandler* handler);
- QHash<QString, V8CommandHandler*> handlers;
- QScopedPointer<UnknownV8CommandHandler> unknownV8CommandHandler;
+ void addHandler(V4CommandHandler* handler);
+ QHash<QString, V4CommandHandler*> handlers;
+ QScopedPointer<UnknownV4CommandHandler> unknownV4CommandHandler;
};
QT_END_NAMESPACE