From 456632225f3173d401c68e301fb6d38f6c42e493 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sun, 13 Aug 2017 22:29:41 +0200 Subject: Some prospective fixes to the debugging plugin Adjust to the context/frame changes Change-Id: I06e691654961c8c1f60765a4fd469f03607be4d0 Reviewed-by: Erik Verbruggen --- .../qmldbg_debugger/qv4datacollector.cpp | 41 +++++++------ .../qmltooling/qmldbg_debugger/qv4datacollector.h | 3 +- .../qqmlnativedebugservice.cpp | 70 +++++++++------------- 3 files changed, 54 insertions(+), 60 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp index 0097fed0d6..0d1dcb8397 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp @@ -55,15 +55,21 @@ QT_BEGIN_NAMESPACE -QV4::Heap::CallContext *QV4DataCollector::findContext(int frame) +QV4::CppStackFrame *QV4DataCollector::findFrame(int frame) { QV4::CppStackFrame *f = engine()->currentStackFrame; while (f && frame) { --frame; f = f->parent; } + return f; +} + +QV4::Heap::ExecutionContext *QV4DataCollector::findContext(int frame) +{ + QV4::CppStackFrame *f = findFrame(frame); - return f ? f->callContext() : 0; + return f ? f->context()->d() : 0; } QV4::Heap::CallContext *QV4DataCollector::findScope(QV4::Heap::ExecutionContext *ctx, int scope) @@ -82,7 +88,7 @@ QVector QV4DataCollector::getScopeType { QVector types; - QV4::Heap::ExecutionContext *it = findContext(frame); + QV4::Heap::ExecutionContext *it = findFrame(frame)->context()->d(); for (; it; it = it->outer) types.append(QV4::Heap::ExecutionContext::ContextType(it->type)); @@ -258,27 +264,26 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr) QStringList names; QV4::Scope scope(engine()); + QV4::CppStackFrame *frame = findFrame(frameNr); + if (frame->v4Function->canUseSimpleCall) { + if (!scopeNr) { + // ### collect locals from the stack frame + } else { + // the current call context is actually the parent's context + --scopeNr; + } + } + QV4::Scoped ctxt(scope, findScope(findContext(frameNr), scopeNr)); if (!ctxt) return false; Refs collectedRefs; 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); - collectedRefs.append(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); + QV4::InternalClass *ic = ctxt->internalClass(); + for (uint i = 0; i < ic->size; ++i) { + QString name = ic->nameMap[i]->string; + names.append(name); v = ctxt->d()->locals[i]; collectedRefs.append(collect(v)); } diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h index c924f10d8c..87be009de5 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h @@ -62,7 +62,8 @@ public: static int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType); QVector getScopeTypes(int frame); - QV4::Heap::CallContext *findContext(int frame); + QV4::Heap::ExecutionContext *findContext(int frame); + QV4::CppStackFrame *findFrame(int frame); QV4DataCollector(QV4::ExecutionEngine *engine); diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp index 167083155c..c879c77fcd 100644 --- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp @@ -312,19 +312,19 @@ void NativeDebugger::handleCommand(QJsonObject *response, const QString &cmd, handleContinue(response, NotStepping); } -static QString encodeContext(QV4::ExecutionContext *executionContext) +static QString encodeFrame(QV4::CppStackFrame *f) { QQmlDebugPacket ds; - ds << quintptr(executionContext); + ds << quintptr(f); return QString::fromLatin1(ds.data().toHex()); } -static void decodeContext(const QString &context, QV4::ExecutionContext **executionContext) +static void decodeFrame(const QString &f, QV4::CppStackFrame **frame) { - quintptr rawContext; - QQmlDebugPacket ds(QByteArray::fromHex(context.toLatin1())); - ds >> rawContext; - *executionContext = reinterpret_cast(rawContext); + quintptr rawFrame; + QQmlDebugPacket ds(QByteArray::fromHex(f.toLatin1())); + ds >> rawFrame; + *frame = reinterpret_cast(rawFrame); } void NativeDebugger::handleBacktrace(QJsonObject *response, const QJsonObject &arguments) @@ -338,7 +338,7 @@ void NativeDebugger::handleBacktrace(QJsonObject *response, const QJsonObject &a QJsonObject frame; frame.insert(QStringLiteral("language"), QStringLiteral("js")); - frame.insert(QStringLiteral("context"), encodeContext(nullptr /*#### context*/)); + frame.insert(QStringLiteral("context"), encodeFrame(f)); if (QV4::Heap::String *functionName = function->name()) frame.insert(QStringLiteral("function"), functionName->toQString()); @@ -454,15 +454,15 @@ void Collector::collect(QJsonArray *out, const QString &parentIName, const QStri void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &arguments) { TRACE_PROTOCOL("Build variables"); - QV4::ExecutionContext *executionContext = 0; - decodeContext(arguments.value(QLatin1String("context")).toString(), &executionContext); - if (!executionContext) { - setError(response, QStringLiteral("No execution context passed")); + QV4::CppStackFrame *frame = 0; + decodeFrame(arguments.value(QLatin1String("context")).toString(), &frame); + if (!frame) { + setError(response, QStringLiteral("No stack frame passed")); return; } - TRACE_PROTOCOL("Context: " << executionContext); + TRACE_PROTOCOL("Context: " << frame); - QV4::ExecutionEngine *engine = executionContext->engine(); + QV4::ExecutionEngine *engine = frame->v4Function->internalClass->engine; if (!engine) { setError(response, QStringLiteral("No execution engine passed")); return; @@ -478,28 +478,16 @@ void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &a QJsonArray output; QV4::Scope scope(engine); - if (QV4::CallContext *callContext = executionContext->asCallContext()) { - QV4::Value thisObject = callContext->thisObject(); - collector.collect(&output, QString(), QStringLiteral("this"), thisObject); - QV4::Identifier *const *variables = callContext->variables(); - QV4::Identifier *const *formals = callContext->formals(); - if (callContext->d()->type == QV4::Heap::ExecutionContext::Type_CallContext) { - QV4::CallContext *ctx = static_cast(callContext); - for (unsigned i = 0, ei = ctx->variableCount(); i != ei; ++i) { - QString qName; - if (QV4::Identifier *name = variables[i]) - qName = name->string; - QV4::Value val = ctx->d()->locals[i]; - collector.collect(&output, QString(), qName, val); - } - } - for (unsigned i = 0, ei = callContext->formalCount(); i != ei; ++i) { - QString qName; - if (QV4::Identifier *name = formals[i]) - qName = name->string; - QV4::ReturnedValue rval = callContext->argument(i); - QV4::ScopedValue sval(scope, rval); - collector.collect(&output, QString(), qName, *sval); + QV4::ScopedValue thisObject(scope, frame->thisObject()); + collector.collect(&output, QString(), QStringLiteral("this"), thisObject); + QV4::Scoped callContext(scope, frame->callContext()); + if (callContext) { + QV4::InternalClass *ic = callContext->internalClass(); + QV4::ScopedValue v(scope); + for (uint i = 0; i < ic->size; ++i) { + QString name = ic->nameMap[i]->string; + v = callContext->d()->locals[i]; + collector.collect(&output, QString(), name, v); } } @@ -509,15 +497,15 @@ void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &a void NativeDebugger::handleExpressions(QJsonObject *response, const QJsonObject &arguments) { TRACE_PROTOCOL("Evaluate expressions"); - QV4::ExecutionContext *executionContext = 0; - decodeContext(arguments.value(QLatin1String("context")).toString(), &executionContext); - if (!executionContext) { - setError(response, QStringLiteral("No execution context passed")); + QV4::CppStackFrame *frame = 0; + decodeFrame(arguments.value(QLatin1String("context")).toString(), &frame); + if (!frame) { + setError(response, QStringLiteral("No stack frame passed")); return; } TRACE_PROTOCOL("Context: " << executionContext); - QV4::ExecutionEngine *engine = executionContext->engine(); + QV4::ExecutionEngine *engine = frame->v4Function->internalClass->engine; if (!engine) { setError(response, QStringLiteral("No execution engine passed")); return; -- cgit v1.2.3