diff options
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 22 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4debugging.cpp | 17 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 2 | ||||
-rw-r--r-- | tests/auto/qml/qv4debugger/tst_qv4debugger.cpp | 20 |
5 files changed, 57 insertions, 18 deletions
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 6d95f039c5..c0ca4aec19 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -55,7 +55,6 @@ struct Function; } struct CallContext; -struct CallContext; struct CatchContext; struct WithContext; @@ -149,6 +148,9 @@ struct Q_QML_EXPORT ExecutionContext : public Managed inline CallContext *asCallContext(); inline const CallContext *asCallContext() const; + inline const CatchContext *asCatchContext() const; + + inline FunctionObject *getFunctionObject() const; static void markObjects(Managed *m, ExecutionEngine *e); }; @@ -225,6 +227,24 @@ inline const CallContext *ExecutionContext::asCallContext() const return d()->type >= Type_SimpleCallContext ? static_cast<const CallContext *>(this) : 0; } +inline const CatchContext *ExecutionContext::asCatchContext() const +{ + return d()->type == Type_CatchContext ? static_cast<const CatchContext *>(this) : 0; +} + +inline FunctionObject *ExecutionContext::getFunctionObject() const +{ + for (const ExecutionContext *it = this; it; it = it->d()->parent) { + if (const CallContext *callCtx = it->asCallContext()) + return callCtx->d()->function; + else if (it->asCatchContext()) + continue; // look in the parent context for a FunctionObject + else + break; + } + + return 0; +} inline void ExecutionEngine::pushContext(CallContext *context) { diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 6a8d364a08..a835d835fb 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -509,7 +509,6 @@ void Debugger::maybeBreakAtInstruction() return; QMutexLocker locker(&m_lock); - int lineNumber = engine()->currentContext()->d()->lineNumber; if (m_gatherSources) { m_gatherSources->run(); @@ -533,8 +532,12 @@ void Debugger::maybeBreakAtInstruction() if (m_pauseRequested) { // Serve debugging requests from the agent m_pauseRequested = false; pauseAndWait(PauseRequest); - } else if (m_haveBreakPoints && reallyHitTheBreakPoint(getFunction()->sourceFile(), lineNumber)) { - pauseAndWait(BreakPoint); + } else if (m_haveBreakPoints) { + if (Function *f = getFunction()) { + const int lineNumber = engine()->currentContext()->d()->lineNumber; + if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber)) + pauseAndWait(BreakPoint); + } } } @@ -579,12 +582,10 @@ void Debugger::aboutToThrow() Function *Debugger::getFunction() const { ExecutionContext *context = m_engine->currentContext(); - if (CallContext *callCtx = context->asCallContext()) - return callCtx->d()->function->function(); - else { - Q_ASSERT(context->d()->type == QV4::ExecutionContext::Type_GlobalContext); + if (const FunctionObject *function = context->getFunctionObject()) + return function->function(); + else return context->d()->engine->globalCode; - } } void Debugger::pauseAndWait(PauseReason reason) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index ea075f9cbd..74b262e86d 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -700,19 +700,18 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const QV4::ExecutionContext *c = currentContext(); while (c && frameLimit) { - CallContext *callCtx = c->asCallContext(); - if (callCtx && callCtx->d()->function) { + if (FunctionObject *function = c->getFunctionObject()) { StackFrame frame; - if (callCtx->d()->function->function()) - frame.source = callCtx->d()->function->function()->sourceFile(); - name = callCtx->d()->function->name(); + if (const Function *f = function->function()) + frame.source = f->sourceFile(); + name = function->name(); frame.function = name->toQString(); frame.line = -1; frame.column = -1; - if (callCtx->d()->function->function()) + if (function->function()) // line numbers can be negative for places where you can't set a real breakpoint - frame.line = qAbs(callCtx->d()->lineNumber); + frame.line = qAbs(c->d()->lineNumber); stack.append(frame); --frameLimit; @@ -727,7 +726,6 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const frame.line = rootContext->d()->lineNumber; frame.column = -1; - stack.append(frame); } return stack; diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index c8edb765de..adedb9fb7d 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -116,7 +116,7 @@ struct Q_QML_EXPORT FunctionObject: Object { ExecutionContext *scope() { return d()->scope; } - Function *function() { return d()->function; } + Function *function() const { return d()->function; } ReturnedValue name(); unsigned int formalParameterCount() { return function() ? function()->compiledFunction->nFormals : 0; } diff --git a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp index 63bfffacaa..fcbdcbc201 100644 --- a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp @@ -286,6 +286,7 @@ private slots: // exceptions: void pauseOnThrow(); + void breakInCatch(); void evaluateExpression(); @@ -612,6 +613,25 @@ void tst_qv4debugger::pauseOnThrow() QCOMPARE(m_debuggerAgent->m_thrownValue.toString(), QString("hard")); } +void tst_qv4debugger::breakInCatch() +{ + QString script = + "try {\n" + " throw 'catch...'\n" + "} catch (e) {\n" + " console.log(e, 'me');\n" + "}\n"; + + m_debuggerAgent->addBreakPoint("breakInCatch", 4); + evaluateJavaScript(script, "breakInCatch"); + QVERIFY(m_debuggerAgent->m_wasPaused); + QCOMPARE(m_debuggerAgent->m_pauseReason, BreakPoint); + QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1); + QV4::Debugging::Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); + QCOMPARE(state.fileName, QString("breakInCatch")); + QCOMPARE(state.lineNumber, 4); +} + void tst_qv4debugger::evaluateExpression() { QString script = |