From 8397f640e81f0eff1f6f32ae4a35d40f115ea339 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 5 Dec 2014 13:16:14 +0100 Subject: QML Debugging: Fix crash when stepping through try-catch block. Also fix the stack-trace generation, otherwise the debugger engine would report a breakpoint hit on the wrong line. Task-number: QTBUG-42723 Change-Id: I1f655a5174b28a1c9c31c85bbe023fbce5ddbb96 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4context_p.h | 22 +++++++++++++++++++++- src/qml/jsruntime/qv4debugging.cpp | 17 +++++++++-------- src/qml/jsruntime/qv4engine.cpp | 14 ++++++-------- src/qml/jsruntime/qv4functionobject_p.h | 2 +- 4 files changed, 37 insertions(+), 18 deletions(-) (limited to 'src/qml/jsruntime') 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 @@ -54,7 +54,6 @@ struct CompilationUnit; 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(this) : 0; } +inline const CatchContext *ExecutionContext::asCatchContext() const +{ + return d()->type == Type_CatchContext ? static_cast(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 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 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; } -- cgit v1.2.3 From 26c3b0654a768b181142cea5aab2641956975e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sun, 7 Dec 2014 01:37:57 +0000 Subject: Windows: Don't disable JIT [ChangeLog][QtQml][Windows] V4 JIT was re-enabled after it was disabled by mistake in 5.4.0. Task-number: QTBUG-43171 Change-Id: I16206e094c210b1eadbfef9ee04cf78d3a7dcebe Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4global_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 81f1240d89..a58beb3aaa 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -69,9 +69,9 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); } // // NOTE: This should match the logic in qv4targetplatform_p.h! -#if defined(Q_PROCESSOR_X86) && (defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD)) +#if defined(Q_PROCESSOR_X86) && (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD)) #define V4_ENABLE_JIT -#elif defined(Q_PROCESSOR_X86_64) && (defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD)) +#elif defined(Q_PROCESSOR_X86_64) && (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD)) #define V4_ENABLE_JIT #elif defined(Q_PROCESSOR_ARM_32) -- cgit v1.2.3 From 5586af99c15af8fef27bedfbf84a05d107b4320c Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 5 Dec 2014 13:58:22 +0100 Subject: QML Debugging: Fix breakpoints/stepping in a with-statement. Also fix the stack-trace generation, otherwise the debugger engine would report a breakpoint hit on the wrong line. Change-Id: I6eb4b508fbdca64d03badd8f9312a05c78781ded Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4context_p.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index c0ca4aec19..99a982aa7f 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -149,6 +149,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed inline CallContext *asCallContext(); inline const CallContext *asCallContext() const; inline const CatchContext *asCatchContext() const; + inline const WithContext *asWithContext() const; inline FunctionObject *getFunctionObject() const; @@ -232,12 +233,17 @@ inline const CatchContext *ExecutionContext::asCatchContext() const return d()->type == Type_CatchContext ? static_cast(this) : 0; } +inline const WithContext *ExecutionContext::asWithContext() const +{ + return d()->type == Type_WithContext ? static_cast(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()) + else if (it->asCatchContext() || it->asWithContext()) continue; // look in the parent context for a FunctionObject else break; -- cgit v1.2.3 From 7aa90e7123d05bd47340977d7282821eb56fa058 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 19 Dec 2014 12:39:21 +0100 Subject: Fix GC crash with conditional breakpoints and JS console We may choose to execute an expression in a specific frame within the debugger, which is where we pop context's until we reached the frame in question. If we are trying to execute an expression at the top of the stack (or with a conditional breakpoint expression), then we don't have a frame and don't need to pop contexts. But also also don't need to call Scope::alloc(-1). Change-Id: I1f6754a3d77d943aed9bf4468e817a5269a3c547 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4debugging.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index a835d835fb..50142ab155 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -65,10 +65,12 @@ public: ExecutionContextSaver saver(engine->currentContext()); - Value *savedContexts = scope.alloc(frameNr); - for (int i = 0; i < frameNr; ++i) { - savedContexts[i] = engine->currentContext(); - engine->popContext(); + if (frameNr > 0) { + Value *savedContexts = scope.alloc(frameNr); + for (int i = 0; i < frameNr; ++i) { + savedContexts[i] = engine->currentContext(); + engine->popContext(); + } } ExecutionContext *ctx = engine->currentContext(); -- cgit v1.2.3 From 5cfe7d2074306a72909ea20718c1c4bebeb27bad Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Mon, 5 Jan 2015 14:44:36 +0100 Subject: Parse dates as Qt::RFC2822Date too [ChangeLog][QtQml] Fix JavaScript Date parsing to correctly accept RC2822 dates. Task-number: QTBUG-38011 Change-Id: Ic7d3f5b8c624d6780d4c3595fd2efe22c427ffd3 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4dateobject.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index e00a705700..b3c340ccb2 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -480,6 +480,8 @@ static inline double ParseString(const QString &s) QDateTime dt = QDateTime::fromString(s, Qt::TextDate); if (!dt.isValid()) dt = QDateTime::fromString(s, Qt::ISODate); + if (!dt.isValid()) + dt = QDateTime::fromString(s, Qt::RFC2822Date); if (!dt.isValid()) { QStringList formats; formats << QStringLiteral("M/d/yyyy") -- cgit v1.2.3 From e2c1e7b8a274b2b00e19f00f0c24d9b17810f603 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 5 Jan 2015 15:31:20 +0100 Subject: Print exceptions in JS slots Do print JS exceptions raised in slots to the console, and clear the status afterwards. Otherwise exceptions raised might silently propagate to later JS calls. Change-Id: I122f3026aa18028415c5a4672cb3287e7d58ac4d Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4qobjectwrapper.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index f2c30e618f..db1315dc87 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -802,13 +802,17 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase f->call(callData); if (scope.hasException() && v4->v8Engine) { + QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx); + if (error.description().isEmpty()) { + QV4::ScopedString name(scope, f->name()); + error.setDescription(QString::fromLatin1("Unknown exception occurred during evaluation of connected function: %1").arg(name->toQString())); + } if (QQmlEngine *qmlEngine = v4->v8Engine->engine()) { - QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx); - if (error.description().isEmpty()) { - QV4::ScopedString name(scope, f->name()); - error.setDescription(QString(QLatin1String("Unknown exception occurred during evaluation of connected function: %1")).arg(name->toQString())); - } QQmlEnginePrivate::get(qmlEngine)->warning(error); + } else { + QMessageLogger(error.url().toString().toLatin1().constData(), + error.line(), 0).warning().noquote() + << error.toString(); } } } -- cgit v1.2.3