aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-11-21 12:29:40 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2017-11-21 12:29:40 +0100
commitd373d5e7d70e968cfba8957596ed6fe4f46990c8 (patch)
treec52bf2b0fbbfdb13d644b4050aa7a931ef4b7109 /src/plugins
parent9880acb424fd814501ba5fc4ae1caa989e23fafa (diff)
parent9af8a47746b69b6040fc149c1d24602a1e25b08f (diff)
Merge remote-tracking branch 'origin/wip/new-backend' into dev
Conflicts: src/qml/compiler/qv4isel_moth.cpp src/qml/compiler/qv4jsir_p.h src/qml/jsruntime/qv4engine_p.h src/qml/jsruntime/qv4vme_moth.cpp tests/auto/qml/qml.pro Change-Id: Ia7b6ec24c7fcbcbb1786d9e798d2df294020ae37
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp69
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h5
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp29
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp17
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp50
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp155
8 files changed, 142 insertions, 187 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 8ff0a3ca64..a538956e8e 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -55,47 +55,43 @@
QT_BEGIN_NAMESPACE
-QV4::SimpleCallContext *QV4DataCollector::findContext(int frame)
+QV4::CppStackFrame *QV4DataCollector::findFrame(int frame)
{
- QV4::ExecutionContext *ctx = engine()->currentContext;
- while (ctx) {
- QV4::SimpleCallContext *cCtxt = ctx->asSimpleCallContext();
- if (cCtxt && cCtxt->d()->v4Function) {
- if (frame < 1)
- return cCtxt;
- --frame;
- }
- ctx = engine()->parentContext(ctx);
+ QV4::CppStackFrame *f = engine()->currentStackFrame;
+ while (f && frame) {
+ --frame;
+ f = f->parent;
}
+ return f;
+}
- return 0;
+QV4::Heap::ExecutionContext *QV4DataCollector::findContext(int frame)
+{
+ QV4::CppStackFrame *f = findFrame(frame);
+
+ return f ? f->context()->d() : 0;
}
-QV4::Heap::SimpleCallContext *QV4DataCollector::findScope(QV4::ExecutionContext *ctxt, int scope)
+QV4::Heap::CallContext *QV4DataCollector::findScope(QV4::Heap::ExecutionContext *ctx, int scope)
{
- if (!ctxt)
+ if (!ctx)
return 0;
- QV4::Scope s(ctxt);
- QV4::ScopedContext ctx(s, ctxt);
for (; scope > 0 && ctx; --scope)
- ctx = ctx->d()->outer;
+ ctx = ctx->outer;
- return (ctx && ctx->d()) ? ctx->asSimpleCallContext()->d() : 0;
+ return (ctx && ctx->type == QV4::Heap::ExecutionContext::Type_CallContext) ?
+ static_cast<QV4::Heap::CallContext *>(ctx) : 0;
}
QVector<QV4::Heap::ExecutionContext::ContextType> QV4DataCollector::getScopeTypes(int frame)
{
QVector<QV4::Heap::ExecutionContext::ContextType> types;
- QV4::Scope scope(engine());
- QV4::SimpleCallContext *sctxt = findContext(frame);
- if (!sctxt || sctxt->d()->type < QV4::Heap::ExecutionContext::Type_QmlContext)
- return types;
+ QV4::Heap::ExecutionContext *it = findFrame(frame)->context()->d();
- QV4::ScopedContext it(scope, sctxt);
- for (; it; it = it->d()->outer)
- types.append(QV4::Heap::ExecutionContext::ContextType(it->d()->type));
+ for (; it; it = it->outer)
+ types.append(QV4::Heap::ExecutionContext::ContextType(it->type));
return types;
}
@@ -109,7 +105,6 @@ int QV4DataCollector::encodeScopeType(QV4::Heap::ExecutionContext::ContextType s
return 4;
case QV4::Heap::ExecutionContext::Type_WithContext:
return 2;
- case QV4::Heap::ExecutionContext::Type_SimpleCallContext:
case QV4::Heap::ExecutionContext::Type_CallContext:
return 1;
case QV4::Heap::ExecutionContext::Type_QmlContext:
@@ -267,27 +262,17 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr)
QStringList names;
QV4::Scope scope(engine());
+
QV4::Scoped<QV4::CallContext> 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));
}
@@ -338,7 +323,7 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int
QV4::Scope scope(engine());
QV4::ScopedContext ctxt(scope, findContext(frameNr));
while (ctxt) {
- if (QV4::SimpleCallContext *cCtxt = ctxt->asSimpleCallContext()) {
+ if (QV4::CallContext *cCtxt = ctxt->asCallContext()) {
if (cCtxt->d()->activation)
break;
}
@@ -346,7 +331,7 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int
}
if (ctxt) {
- QV4::ScopedValue o(scope, ctxt->asSimpleCallContext()->d()->activation);
+ QV4::ScopedValue o(scope, ctxt->d()->activation);
frame[QLatin1String("receiver")] = toRef(collect(o));
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
index de12e8d527..87be009de5 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
@@ -58,11 +58,12 @@ public:
typedef uint Ref;
typedef QVector<uint> Refs;
- static QV4::Heap::SimpleCallContext *findScope(QV4::ExecutionContext *ctxt, int scope);
+ static QV4::Heap::CallContext *findScope(QV4::Heap::ExecutionContext *ctxt, int scope);
static int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType);
QVector<QV4::Heap::ExecutionContext::ContextType> getScopeTypes(int frame);
- QV4::SimpleCallContext *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_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
index b82df9c6a9..1581cf637d 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
@@ -115,7 +115,7 @@ void QV4Debugger::resume(Speed speed)
if (!m_returnedValue.isUndefined())
m_returnedValue.set(m_engine, QV4::Encode::undefined());
- m_currentContext.set(m_engine, *m_engine->currentContext);
+ m_currentFrame = m_engine->currentStackFrame;
m_stepping = speed;
m_runningCondition.wakeAll();
}
@@ -158,7 +158,7 @@ QV4Debugger::ExecutionState QV4Debugger::currentExecutionState() const
{
ExecutionState state;
state.fileName = getFunction()->sourceFile();
- state.lineNumber = engine()->current->lineNumber;
+ state.lineNumber = engine()->currentStackFrame->lineNumber();
return state;
}
@@ -187,7 +187,7 @@ void QV4Debugger::maybeBreakAtInstruction()
switch (m_stepping) {
case StepOver:
- if (m_currentContext.asManaged()->d() != m_engine->current)
+ if (m_currentFrame != m_engine->currentStackFrame)
break;
// fall through
case StepIn:
@@ -203,7 +203,8 @@ void QV4Debugger::maybeBreakAtInstruction()
pauseAndWait(PauseRequest);
} else if (m_haveBreakPoints) {
if (QV4::Function *f = getFunction()) {
- const int lineNumber = engine()->current->lineNumber;
+ // lineNumber will be negative for Ret instructions, so those won't match
+ const int lineNumber = engine()->currentStackFrame->lineNumber();
if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber))
pauseAndWait(BreakPointHit);
}
@@ -216,9 +217,8 @@ void QV4Debugger::enteringFunction()
return;
QMutexLocker locker(&m_lock);
- if (m_stepping == StepIn) {
- m_currentContext.set(m_engine, *m_engine->currentContext);
- }
+ if (m_stepping == StepIn)
+ m_currentFrame = m_engine->currentStackFrame;
}
void QV4Debugger::leavingFunction(const QV4::ReturnedValue &retVal)
@@ -229,13 +229,8 @@ void QV4Debugger::leavingFunction(const QV4::ReturnedValue &retVal)
QMutexLocker locker(&m_lock);
- if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) {
- if (QV4::ExecutionContext *parentContext
- = m_engine->parentContext(m_engine->currentContext)) {
- m_currentContext.set(m_engine, *parentContext);
- } else {
- m_currentContext.clear();
- }
+ if (m_stepping != NotStepping && m_currentFrame == m_engine->currentStackFrame) {
+ m_currentFrame = m_currentFrame->parent;
m_stepping = StepOver;
m_returnedValue.set(m_engine, retVal);
}
@@ -255,10 +250,8 @@ void QV4Debugger::aboutToThrow()
QV4::Function *QV4Debugger::getFunction() const
{
- QV4::Scope scope(m_engine);
- QV4::ExecutionContext *context = m_engine->currentContext;
- if (QV4::Function *function = context->getFunction())
- return function;
+ if (m_engine->currentStackFrame)
+ return m_engine->currentStackFrame->v4Function;
else
return m_engine->globalCode;
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
index 06014302e6..4a755f2b72 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
@@ -150,7 +150,7 @@ private:
void runJobUnpaused();
QV4::ExecutionEngine *m_engine;
- QV4::PersistentValue m_currentContext;
+ QV4::CppStackFrame *m_currentFrame = 0;
QMutex m_lock;
QWaitCondition m_runningCondition;
State m_state;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
index 9a34d5770a..87e75c49b5 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
@@ -79,20 +79,19 @@ void QV4DebuggerAgent::debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseR
case QV4Debugger::PauseRequest:
case QV4Debugger::BreakPointHit: {
event.insert(QStringLiteral("event"), QStringLiteral("break"));
- QVector<QV4::StackFrame> frames = debugger->stackTrace(1);
- if (frames.isEmpty())
+ QV4::CppStackFrame *frame = debugger->engine()->currentStackFrame;
+ if (!frame)
break;
- const QV4::StackFrame &topFrame = frames.first();
- body.insert(QStringLiteral("invocationText"), topFrame.function);
- body.insert(QStringLiteral("sourceLine"), topFrame.line - 1);
- if (topFrame.column > 0)
- body.insert(QStringLiteral("sourceColumn"), topFrame.column);
+ body.insert(QStringLiteral("invocationText"), frame->function());
+ body.insert(QStringLiteral("sourceLine"), qAbs(frame->lineNumber()) - 1);
+// if (frame->column > 0)
+// body.insert(QStringLiteral("sourceColumn"), frame->column);
QJsonArray breakPoints;
- foreach (int breakPointId, breakPointIds(topFrame.source, topFrame.line))
+ foreach (int breakPointId, breakPointIds(frame->source(), frame->lineNumber()))
breakPoints.push_back(breakPointId);
body.insert(QStringLiteral("breakpoints"), breakPoints);
- script.insert(QStringLiteral("name"), topFrame.source);
+ script.insert(QStringLiteral("name"), frame->source());
} break;
case QV4Debugger::Throwing:
// TODO: complete this!
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index d57d7e7406..6f254c9e28 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -44,6 +44,7 @@
#include <private/qv4qmlcontext_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <private/qqmldebugservice_p.h>
+#include <private/qv4jscall_p.h>
#include <QtQml/qqmlengine.h>
@@ -63,26 +64,21 @@ void JavaScriptJob::run()
{
QV4::Scope scope(engine);
- QV4::ExecutionContextSaver saver(scope);
-
- QV4::ExecutionContext *ctx = engine->currentContext;
+ QV4::ScopedContext ctx(scope, engine->currentStackFrame ? engine->currentContext()
+ : engine->rootContext());
QObject scopeObject;
- if (frameNr > 0) {
- for (int i = 0; i < frameNr; ++i) {
- ctx = engine->parentContext(ctx);
- }
- engine->pushContext(ctx);
- ctx = engine->currentContext;
- }
+ QV4::CppStackFrame *frame = engine->currentStackFrame;
+
+ for (int i = 0; frame && i < frameNr; ++i)
+ frame = frame->parent;
+ if (frameNr > 0 && frame)
+ ctx = static_cast<QV4::ExecutionContext *>(&frame->jsFrame->context);
if (context >= 0) {
QQmlContext *extraContext = qmlContext(QQmlDebugService::objectForId(context));
- if (extraContext) {
- engine->pushContext(QV4::QmlContext::create(ctx, QQmlContextData::get(extraContext),
- &scopeObject));
- ctx = engine->currentContext;
- }
+ if (extraContext)
+ ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(extraContext), &scopeObject);
} else if (frameNr < 0) { // Use QML context if available
QQmlEngine *qmlEngine = engine->qmlEngine();
if (qmlEngine) {
@@ -102,18 +98,15 @@ void JavaScriptJob::run()
}
}
}
- if (!engine->qmlContext()) {
- engine->pushContext(QV4::QmlContext::create(ctx, QQmlContextData::get(qmlRootContext),
- &scopeObject));
- ctx = engine->currentContext;
- }
- engine->pushContext(ctx->newWithContext(withContext->toObject(engine)));
- ctx = engine->currentContext;
+ if (!engine->qmlContext())
+ ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(qmlRootContext), &scopeObject);
}
}
- QV4::Script script(ctx, this->script);
- script.strictMode = ctx->d()->strictMode;
+ QV4::Script script(ctx, QV4::Compiler::EvalCode, this->script);
+ if (const QV4::Function *function = frame ? frame->v4Function : engine->globalCode)
+ script.strictMode = function->isStrict();
+
// In order for property lookups in QML to work, we need to disable fast v4 lookups. That
// is a side-effect of inheritContext.
script.inheritContext = true;
@@ -214,12 +207,15 @@ void ValueLookupJob::run()
// set if the engine is currently executing QML code.
QScopedPointer<QObject> scopeObject;
QV4::ExecutionEngine *engine = collector->engine();
+ QV4::Scope scope(engine);
+ QV4::Heap::ExecutionContext *qmlContext = 0;
if (engine->qmlEngine() && !engine->qmlContext()) {
scopeObject.reset(new QObject);
- engine->pushContext(QV4::QmlContext::create(engine->currentContext,
+ qmlContext = QV4::QmlContext::create(engine->currentContext(),
QQmlContextData::get(engine->qmlEngine()->rootContext()),
- scopeObject.data()));
+ scopeObject.data());
}
+ QV4::ScopedStackFrame frame(scope, qmlContext);
for (const QJsonValue &handle : handles) {
QV4DataCollector::Ref ref = handle.toInt();
if (!collector->isValidRef(ref)) {
@@ -229,8 +225,6 @@ void ValueLookupJob::run()
result[QString::number(ref)] = collector->lookupRef(ref, true);
}
flushRedundantRefs();
- if (scopeObject)
- engine->popContext();
}
const QString &ValueLookupJob::exceptionMessage() const
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index fe00ed1e28..fca811cb28 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -42,7 +42,6 @@
#include "qqmlengine.h"
#include <private/qv4engine_p.h>
-#include <private/qv4isel_moth_p.h>
#include <private/qv4function_p.h>
#include <private/qqmldebugconnector_p.h>
#include <private/qv8engine_p.h>
@@ -706,7 +705,6 @@ void QV4DebugServiceImpl::engineAdded(QJSEngine *engine)
QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
if (QQmlDebugConnector *server = QQmlDebugConnector::instance()) {
if (ee) {
- ee->iselFactory.reset(new QV4::Moth::ISelFactory);
QV4Debugger *debugger = new QV4Debugger(ee);
if (state() == Enabled)
ee->setDebugger(debugger);
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
index cff1728f49..eeedb59ce6 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
@@ -49,7 +49,6 @@
#include <private/qv4objectiterator_p.h>
#include <private/qv4identifier_p.h>
#include <private/qv4runtime_p.h>
-#include <private/qv4isel_moth_p.h>
#include <private/qqmldebugpacket_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
@@ -208,7 +207,7 @@ private:
void handleDebuggerDeleted(QObject *debugger);
- void evaluateExpression(QV4::Scope &scope, const QString &expression);
+ QV4::ReturnedValue evaluateExpression(const QString &expression);
bool checkCondition(const QString &expression);
QStringList breakOnSignals;
@@ -230,7 +229,7 @@ private:
QV4::ExecutionEngine *m_engine;
QQmlNativeDebugServiceImpl *m_service;
- QV4::PersistentValue m_currentContext;
+ QV4::CppStackFrame *m_currentFrame = 0;
Speed m_stepping;
bool m_pauseRequested;
bool m_runningJob;
@@ -241,29 +240,31 @@ private:
bool NativeDebugger::checkCondition(const QString &expression)
{
QV4::Scope scope(m_engine);
- evaluateExpression(scope, expression);
- return scope.result.booleanValue();
+ QV4::ScopedValue r(scope, evaluateExpression(expression));
+ return r->booleanValue();
}
-void NativeDebugger::evaluateExpression(QV4::Scope &scope, const QString &expression)
+QV4::ReturnedValue NativeDebugger::evaluateExpression(const QString &expression)
{
+ QV4::Scope scope(m_engine);
m_runningJob = true;
- QV4::ExecutionContextSaver saver(scope);
-
- QV4::ExecutionContext *ctx = m_engine->currentContext;
- m_engine->pushContext(ctx);
+ QV4::ExecutionContext *ctx = m_engine->currentStackFrame ? m_engine->currentContext()
+ : m_engine->rootContext();
- QV4::Script script(ctx, expression);
- script.strictMode = ctx->d()->strictMode;
+ QV4::Script script(ctx, QV4::Compiler::EvalCode, expression);
+ if (const QV4::Function *function = m_engine->currentStackFrame
+ ? m_engine->currentStackFrame->v4Function : m_engine->globalCode)
+ script.strictMode = function->isStrict();
// In order for property lookups in QML to work, we need to disable fast v4 lookups.
// That is a side-effect of inheritContext.
script.inheritContext = true;
script.parse();
if (!m_engine->hasException)
- scope.result = script.run();
+ return script.run();
m_runningJob = false;
+ return QV4::Encode::undefined();
}
NativeDebugger::NativeDebugger(QQmlNativeDebugServiceImpl *service, QV4::ExecutionEngine *engine)
@@ -314,19 +315,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<QV4::ExecutionContext *>(rawContext);
+ quintptr rawFrame;
+ QQmlDebugPacket ds(QByteArray::fromHex(f.toLatin1()));
+ ds >> rawFrame;
+ *frame = reinterpret_cast<QV4::CppStackFrame *>(rawFrame);
}
void NativeDebugger::handleBacktrace(QJsonObject *response, const QJsonObject &arguments)
@@ -334,25 +335,24 @@ void NativeDebugger::handleBacktrace(QJsonObject *response, const QJsonObject &a
int limit = arguments.value(QLatin1String("limit")).toInt(0);
QJsonArray frameArray;
- QV4::ExecutionContext *executionContext = m_engine->currentContext;
- for (int i = 0; i < limit && executionContext; ++i) {
- if (QV4::Function *function = executionContext->getFunction()) {
+ QV4::CppStackFrame *f= m_engine->currentStackFrame;
+ for (int i = 0; i < limit && f; ++i) {
+ QV4::Function *function = f->v4Function;
- QJsonObject frame;
- frame.insert(QStringLiteral("language"), QStringLiteral("js"));
- frame.insert(QStringLiteral("context"), encodeContext(executionContext));
+ QJsonObject frame;
+ frame.insert(QStringLiteral("language"), QStringLiteral("js"));
+ frame.insert(QStringLiteral("context"), encodeFrame(f));
- if (QV4::Heap::String *functionName = function->name())
- frame.insert(QStringLiteral("function"), functionName->toQString());
- frame.insert(QStringLiteral("file"), function->sourceFile());
+ if (QV4::Heap::String *functionName = function->name())
+ frame.insert(QStringLiteral("function"), functionName->toQString());
+ frame.insert(QStringLiteral("file"), function->sourceFile());
- int line = executionContext->d()->lineNumber;
- frame.insert(QStringLiteral("line"), (line < 0 ? -line : line));
+ int line = f->lineNumber();
+ frame.insert(QStringLiteral("line"), (line < 0 ? -line : line));
- frameArray.push_back(frame);
- }
+ frameArray.push_back(frame);
- executionContext = m_engine->parentContext(executionContext);
+ f = f->parent;
}
response->insert(QStringLiteral("frames"), frameArray);
@@ -457,15 +457,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;
@@ -481,28 +481,16 @@ void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &a
QJsonArray output;
QV4::Scope scope(engine);
- if (QV4::SimpleCallContext *callContext = executionContext->asSimpleCallContext()) {
- 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<QV4::CallContext *>(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<QV4::CallContext> 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);
}
}
@@ -512,15 +500,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;
@@ -543,8 +531,7 @@ void NativeDebugger::handleExpressions(QJsonObject *response, const QJsonObject
TRACE_PROTOCOL("Evaluate expression: " << expression);
m_runningJob = true;
- evaluateExpression(scope, expression);
- QV4::ScopedValue result(scope, scope.result);
+ QV4::ScopedValue result(scope, evaluateExpression(expression));
m_runningJob = false;
if (result->isUndefined()) {
@@ -595,7 +582,7 @@ void NativeDebugger::handleContinue(QJsonObject *response, Speed speed)
if (!m_returnedValue.isUndefined())
m_returnedValue.set(m_engine, QV4::Encode::undefined());
- m_currentContext.set(m_engine, *m_engine->currentContext);
+ m_currentFrame = m_engine->currentStackFrame;
m_stepping = speed;
}
@@ -605,7 +592,7 @@ void NativeDebugger::maybeBreakAtInstruction()
return;
if (m_stepping == StepOver) {
- if (m_currentContext.asManaged()->d() == m_engine->current)
+ if (m_currentFrame == m_engine->currentStackFrame)
pauseAndWait();
return;
}
@@ -623,7 +610,8 @@ void NativeDebugger::maybeBreakAtInstruction()
if (m_service->m_breakHandler->m_haveBreakPoints) {
if (QV4::Function *function = getFunction()) {
- const int lineNumber = m_engine->current->lineNumber;
+ // lineNumber will be negative for Ret instructions, so those won't match
+ const int lineNumber = m_engine->currentStackFrame->lineNumber();
if (reallyHitTheBreakPoint(function, lineNumber))
pauseAndWait();
}
@@ -636,7 +624,7 @@ void NativeDebugger::enteringFunction()
return;
if (m_stepping == StepIn) {
- m_currentContext.set(m_engine, *m_engine->currentContext);
+ m_currentFrame = m_engine->currentStackFrame;
}
}
@@ -645,8 +633,8 @@ void NativeDebugger::leavingFunction(const QV4::ReturnedValue &retVal)
if (m_runningJob)
return;
- if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) {
- m_currentContext.set(m_engine, *m_engine->parentContext(m_engine->currentContext));
+ if (m_stepping != NotStepping && m_currentFrame == m_engine->currentStackFrame) {
+ m_currentFrame = m_currentFrame->parent;
m_stepping = StepOver;
m_returnedValue.set(m_engine, retVal);
}
@@ -668,9 +656,8 @@ void NativeDebugger::aboutToThrow()
QV4::Function *NativeDebugger::getFunction() const
{
- QV4::ExecutionContext *context = m_engine->currentContext;
- if (QV4::Function *function = context->getFunction())
- return function;
+ if (m_engine->currentStackFrame)
+ return m_engine->currentStackFrame->v4Function;
else
return m_engine->globalCode;
}
@@ -681,12 +668,11 @@ void NativeDebugger::pauseAndWait()
event.insert(QStringLiteral("event"), QStringLiteral("break"));
event.insert(QStringLiteral("language"), QStringLiteral("js"));
- if (QV4::ExecutionContext *executionContext = m_engine->currentContext) {
- if (QV4::Function *function = executionContext->getFunction()) {
- event.insert(QStringLiteral("file"), function->sourceFile());
- int line = executionContext->d()->lineNumber;
- event.insert(QStringLiteral("line"), (line < 0 ? -line : line));
- }
+ if (QV4::CppStackFrame *frame = m_engine->currentStackFrame) {
+ QV4::Function *function = frame->v4Function;
+ event.insert(QStringLiteral("file"), function->sourceFile());
+ int line = frame->lineNumber();
+ event.insert(QStringLiteral("line"), (line < 0 ? -line : line));
}
m_service->emitAsynchronousMessageToClient(event);
@@ -731,7 +717,6 @@ void QQmlNativeDebugServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
TRACE_PROTOCOL("Adding execution engine" << ee);
if (ee) {
NativeDebugger *debugger = new NativeDebugger(this, ee);
- ee->iselFactory.reset(new QV4::Moth::ISelFactory);
if (state() == Enabled)
ee->setDebugger(debugger);
m_debuggers.append(QPointer<NativeDebugger>(debugger));