diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-07-04 17:01:02 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-08-08 10:45:12 +0200 |
commit | 6333e0913fc0078c0221a8909ced8df03a568992 (patch) | |
tree | 40661d956eb9a87ba3f695811de0e3c591ab7583 /src/qml/jsruntime/qv4debugging.cpp | |
parent | 94669499fd943fc72095afd739a21cd8e675f14f (diff) |
Add support for conditional breakpoints and evaluate.
Also centralized the context state saver and added line number saving, so that the
JS jobs for evaluation of breakpoint conditions don't change the state of the current
engine context.
Task-number: QTBUG-37119
Task-number: QTCREATORBUG-11516
Change-Id: Ia21b3d64e239e5b67f3c07e1c006d8e6748f29b6
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4debugging.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4debugging.cpp | 80 |
1 files changed, 72 insertions, 8 deletions
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 04422b9f5e..78de614664 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -45,6 +45,7 @@ #include "qv4function_p.h" #include "qv4instr_moth_p.h" #include "qv4runtime_p.h" +#include "qv4script_p.h" #include <iostream> #include <algorithm> @@ -53,29 +54,74 @@ using namespace QV4; using namespace QV4::Debugging; namespace { -class EvalJob: public Debugger::Job +class JavaScriptJob: public Debugger::Job { QV4::ExecutionEngine *engine; const QString &script; public: - EvalJob(QV4::ExecutionEngine *engine, const QString &script) + JavaScriptJob(QV4::ExecutionEngine *engine, const QString &script) : engine(engine) , script(script) {} - ~EvalJob() {} - void run() { - // TODO - qDebug() << "Evaluating script:" << script; - Q_UNUSED(engine); + QV4::Scope scope(engine); + QV4::ExecutionContext *ctx = engine->currentContext(); + ContextStateSaver ctxSaver(ctx); + QV4::ScopedValue result(scope); + + QV4::Script script(ctx, this->script); + script.strictMode = ctx->d()->strictMode; + script.inheritContext = false; + script.parse(); + if (!scope.engine->hasException) + result = script.run(); + if (scope.engine->hasException) + result = ctx->catchException(); + handleResult(result); + } + +protected: + virtual void handleResult(QV4::ScopedValue &result) = 0; +}; + +class EvalJob: public JavaScriptJob +{ + bool result; + +public: + EvalJob(QV4::ExecutionEngine *engine, const QString &script) + : JavaScriptJob(engine, script) + , result(false) + {} + + virtual void handleResult(QV4::ScopedValue &result) + { + this->result = result->toBoolean(); } bool resultAsBoolean() const { - return true; + return result; + } +}; + +class ExpressionEvalJob: public JavaScriptJob +{ + Debugger::Collector *collector; + +public: + ExpressionEvalJob(ExecutionEngine *engine, const QString &expression, Debugger::Collector *collector) + : JavaScriptJob(engine, expression) + , collector(collector) + { + } + + virtual void handleResult(QV4::ScopedValue &result) + { + collector->collect(QStringLiteral("body"), result); } }; @@ -444,6 +490,19 @@ QVector<ExecutionContext::ContextType> Debugger::getScopeTypes(int frame) const return types; } + +void Debugger::evaluateExpression(int frameNr, const QString &expression, Debugger::Collector *resultsCollector) +{ + Q_ASSERT(state() == Paused); + Q_UNUSED(frameNr); + + Q_ASSERT(m_runningJob == 0); + ExpressionEvalJob job(m_engine, expression, resultsCollector); + m_runningJob = &job; + m_runningJob->run(); + m_runningJob = 0; +} + void Debugger::maybeBreakAtInstruction() { if (m_runningJob) // do not re-enter when we're doing a job for the debugger. @@ -481,6 +540,8 @@ void Debugger::maybeBreakAtInstruction() void Debugger::enteringFunction() { + if (m_runningJob) + return; QMutexLocker locker(&m_lock); if (m_stepping == StepIn) { @@ -490,6 +551,8 @@ void Debugger::enteringFunction() void Debugger::leavingFunction(const ReturnedValue &retVal) { + if (m_runningJob) + return; Q_UNUSED(retVal); // TODO QMutexLocker locker(&m_lock); @@ -560,6 +623,7 @@ bool Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr) EvalJob evilJob(m_engine, condition); m_runningJob = &evilJob; m_runningJob->run(); + m_runningJob = 0; return evilJob.resultAsBoolean(); } |