aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp')
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp243
1 files changed, 56 insertions, 187 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index adba1dbdd9..96f60b24bb 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -1,37 +1,45 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company 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 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qv4datacollector.h"
+#include "qv4debugger.h"
+#include "qv4debugjob.h"
#include <private/qv4script_p.h>
#include <private/qv4string_p.h>
@@ -39,7 +47,11 @@
#include <private/qv4identifier_p.h>
#include <private/qv4runtime_p.h>
+#include <private/qqmlcontext_p.h>
+#include <private/qqmlengine_p.h>
+
#include <QtCore/qjsonarray.h>
+#include <QtCore/qjsonobject.h>
QT_BEGIN_NAMESPACE
@@ -93,17 +105,13 @@ int QV4DataCollector::encodeScopeType(QV4::Heap::ExecutionContext::ContextType s
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;
@@ -112,17 +120,13 @@ int QV4DataCollector::encodeScopeType(QV4::Heap::ExecutionContext::ContextType s
QV4DataCollector::QV4DataCollector(QV4::ExecutionEngine *engine) : m_engine(engine)
{
- values.set(engine, engine->newArrayObject());
-}
-
-QV4DataCollector::~QV4DataCollector()
-{
+ m_values.set(engine, engine->newArrayObject());
}
QV4DataCollector::Ref QV4DataCollector::collect(const QV4::ScopedValue &value)
{
Ref ref = addRef(value);
- collectedRefs.append(ref);
+ m_collectedRefs.append(ref);
return ref;
}
@@ -210,8 +214,8 @@ QV4DataCollector::Ref QV4DataCollector::addFunctionRef(const QString &functionNa
dict.insert(QStringLiteral("handle"), qint64(ref));
dict.insert(QStringLiteral("type"), QStringLiteral("function"));
dict.insert(QStringLiteral("name"), functionName);
- specialRefs.insert(ref, dict);
- collectedRefs.append(ref);
+ m_specialRefs.insert(ref, dict);
+ m_collectedRefs.append(ref);
return ref;
}
@@ -224,8 +228,8 @@ QV4DataCollector::Ref QV4DataCollector::addScriptRef(const QString &scriptName)
dict.insert(QStringLiteral("handle"), qint64(ref));
dict.insert(QStringLiteral("type"), QStringLiteral("script"));
dict.insert(QStringLiteral("name"), scriptName);
- specialRefs.insert(ref, dict);
- collectedRefs.append(ref);
+ m_specialRefs.insert(ref, dict);
+ m_collectedRefs.append(ref);
return ref;
}
@@ -233,7 +237,7 @@ QV4DataCollector::Ref QV4DataCollector::addScriptRef(const QString &scriptName)
bool QV4DataCollector::isValidRef(QV4DataCollector::Ref ref) const
{
QV4::Scope scope(engine());
- QV4::ScopedObject array(scope, values.value());
+ QV4::ScopedObject array(scope, m_values.value());
return ref < array->getLength();
}
@@ -268,14 +272,14 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr)
QV4::ScopedObject scopeObject(scope, engine()->newObject());
- Q_ASSERT(names.size() == collectedRefs.size());
- for (int i = 0, ei = collectedRefs.size(); i != ei; ++i)
+ Q_ASSERT(names.size() == m_collectedRefs.size());
+ for (int i = 0, ei = m_collectedRefs.size(); i != ei; ++i)
scopeObject->put(engine(), names.at(i),
- QV4::Value::fromReturnedValue(getValue(collectedRefs.at(i))));
+ QV4::Value::fromReturnedValue(getValue(m_collectedRefs.at(i))));
Ref scopeObjectRef = addRef(scopeObject);
dict->insert(QStringLiteral("ref"), qint64(scopeObjectRef));
- collectedRefs.append(scopeObjectRef);
+ m_collectedRefs.append(scopeObjectRef);
return true;
}
@@ -328,6 +332,7 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int
scope[QLatin1String("type")] = type;
scopes.push_back(scope);
}
+
frame[QLatin1String("scopes")] = scopes;
return frame;
@@ -336,18 +341,25 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int
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))
+ 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));
}
- collectedRefs.clear();
+ m_collectedRefs.clear();
return refs;
}
+void QV4DataCollector::clear()
+{
+ m_values.set(engine(), engine()->newArrayObject());
+ m_collectedRefs.clear();
+ m_specialRefs.clear();
+}
+
QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicate)
{
class ExceptionStateSaver
@@ -368,10 +380,10 @@ QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicat
// if we wouldn't do this, the putIndexed won't work.
ExceptionStateSaver resetExceptionState(engine());
QV4::Scope scope(engine());
- QV4::ScopedObject array(scope, values.value());
+ QV4::ScopedObject array(scope, m_values.value());
if (deduplicate) {
for (Ref i = 0; i < array->getLength(); ++i) {
- if (array->getIndexed(i) == value.rawValue() && !specialRefs.contains(i))
+ if (array->getIndexed(i) == value.rawValue() && !m_specialRefs.contains(i))
return i;
}
}
@@ -384,15 +396,15 @@ QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicat
QV4::ReturnedValue QV4DataCollector::getValue(Ref ref)
{
QV4::Scope scope(engine());
- QV4::ScopedObject array(scope, values.value());
+ QV4::ScopedObject array(scope, m_values.value());
Q_ASSERT(ref < array->getLength());
return array->getIndexed(ref, Q_NULLPTR);
}
bool QV4DataCollector::lookupSpecialRef(Ref ref, QJsonObject *dict)
{
- SpecialRefs::const_iterator it = specialRefs.find(ref);
- if (it == specialRefs.end())
+ SpecialRefs::const_iterator it = m_specialRefs.constFind(ref);
+ if (it == m_specialRefs.cend())
return false;
*dict = it.value();
@@ -428,154 +440,11 @@ QJsonObject QV4DataCollector::collectAsJson(const QString &name, const QV4::Scop
if (value->isManaged() && !value->isString()) {
Ref ref = addRef(value);
dict.insert(QStringLiteral("ref"), qint64(ref));
- collectedRefs.append(ref);
+ m_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);
- for (int i = fromFrame; i < toFrame && i < frames.size(); ++i)
- frameArray.push_back(collector->buildFrame(frames[i], i));
- 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 {
- result = collector->buildFrame(frames[frameNr], frameNr);
- collectedRefs = collector->flushCollectedRefs();
- success = true;
- }
-}
-
-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;
- success = collector->collectScope(&object, frameNr, scopeNr);
-
- if (success) {
- QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes =
- collector->getScopeTypes(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)
- : JavaScriptJob(engine, frameNr, expression)
- , collector(collector)
-{
-}
-
-void ExpressionEvalJob::handleResult(QV4::ScopedValue &value)
-{
- if (hasExeption())
- exception = value->toQStringNoThrow();
- result = collector->lookupRef(collector->collect(value));
- collectedRefs = collector->flushCollectedRefs();
-}
-
-const QString &ExpressionEvalJob::exceptionMessage() const
-{
- return exception;
-}
-
-const QJsonObject &ExpressionEvalJob::returnValue() const
-{
- return result;
-}
-
-const QJsonArray &ExpressionEvalJob::refs() const
-{
- return collectedRefs;
-}
-
-GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine, int seq)
- : engine(engine)
- , seq(seq)
-{}
-
-void GatherSourcesJob::run()
-{
- QStringList sources;
-
- foreach (QV4::CompiledData::CompilationUnit *unit, engine->compilationUnits) {
- QString fileName = unit->fileName();
- if (!fileName.isEmpty())
- sources.append(fileName);
- }
-
- QV4::Debugging::V4Debugger *debugger
- = static_cast<QV4::Debugging::V4Debugger *>(engine->debugger);
- emit debugger->sourcesCollected(debugger, sources, seq);
-}
-
QT_END_NAMESPACE