From b9ccb579c4c93f23e6ceeea26b07d418ad4e5562 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 7 Mar 2012 13:56:33 +0100 Subject: [PATCH] Remove QJS exception API MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This API has been deprecated for a while. It's legacy stuff from QtScript. Until someone proves that QJSValue::isError() isn't sufficient to handle JavaScript exceptions, we won't provide any additional API for that. Also removed QJSValuePrivate::lessThan(), which was using the exception mechanism, but the function itself wasn't used anymore (another remnant from the QtScript days). Change-Id: I3dffc6a7835874153f90d25ae2a72c93ea6db39a Reviewed-by: Jędrzej Nowacki Reviewed-by: Lars Knoll --- doc/src/snippets/code/src_script_qjsengine.cpp | 2 +- examples/qml/script/shell/main.cpp | 2 +- src/qml/qml/v8/qjsengine.cpp | 83 ++---------- src/qml/qml/v8/qjsengine.h | 9 -- src/qml/qml/v8/qjsvalue.cpp | 14 +- src/qml/qml/v8/qjsvalue_impl_p.h | 56 +------- src/qml/qml/v8/qjsvalue_p.h | 1 - src/qml/qml/v8/qv8engine.cpp | 144 -------------------- src/qml/qml/v8/qv8engine_impl_p.h | 1 - src/qml/qml/v8/qv8engine_p.h | 35 ----- tests/auto/qml/qjsengine/tst_qjsengine.cpp | 32 +---- tests/auto/qml/qjsvalue/tst_qjsvalue.cpp | 32 +---- .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 6 +- .../benchmarks/qml/js/qjsengine/tst_qjsengine.cpp | 9 -- 14 files changed, 39 insertions(+), 387 deletions(-) diff --git a/doc/src/snippets/code/src_script_qjsengine.cpp b/doc/src/snippets/code/src_script_qjsengine.cpp index efde346..042bdd2 100644 --- a/doc/src/snippets/code/src_script_qjsengine.cpp +++ b/doc/src/snippets/code/src_script_qjsengine.cpp @@ -73,7 +73,7 @@ QJSValue myNumberPlusOne = myEngine.evaluate("myNumber + 1"); //! [4] QJSValue result = myEngine.evaluate(...); -if (myEngine.hasUncaughtException()) +if (result.isError()) qDebug() << "uncaught exception:" << result.toString(); //! [4] diff --git a/examples/qml/script/shell/main.cpp b/examples/qml/script/shell/main.cpp index a405912..4ea36f7 100644 --- a/examples/qml/script/shell/main.cpp +++ b/examples/qml/script/shell/main.cpp @@ -141,7 +141,7 @@ int main(int argc, char *argv[]) continue; QJSValue result = eng->evaluate(contents, fileName, lineNumber); - if (eng->hasUncaughtException()) { + if (result.isError()) { fprintf (stderr, " %s\n\n", qPrintable(result.toString())); return EXIT_FAILURE; } diff --git a/src/qml/qml/v8/qjsengine.cpp b/src/qml/qml/v8/qjsengine.cpp index 92c968f..254b8e7 100644 --- a/src/qml/qml/v8/qjsengine.cpp +++ b/src/qml/qml/v8/qjsengine.cpp @@ -87,8 +87,7 @@ Q_DECLARE_METATYPE(QList) Here we pass the name of the file as the second argument to evaluate(). This does not affect evaluation in any way; the second argument is a general-purpose string that is used to identify the - script for debugging purposes (for example, our filename will now - show up in any uncaughtExceptionBacktrace() involving the script). + script for debugging purposes. \section1 Engine Configuration @@ -111,12 +110,9 @@ Q_DECLARE_METATYPE(QList) evaluate() can throw a script exception (e.g. due to a syntax error); in that case, the return value is the value that was thrown (typically an \c{Error} object). You can check whether the - evaluation caused an exception by calling hasUncaughtException(). In - that case, you can call toString() on the error object to obtain an - error message. The current uncaught exception is also available - through uncaughtException(). - Calling clearExceptions() will cause any uncaught exceptions to be - cleared. + evaluation caused an exception by calling isError() on the return + value. If isError() returns true, you can call toString() on the + error object to obtain an error message. \snippet doc/src/snippets/code/src_script_qjsengine.cpp 4 @@ -200,62 +196,6 @@ QJSEngine::~QJSEngine() \internal */ -#ifdef QT_DEPRECATED - -/*! - \obsolete - - Returns true if the last script evaluation resulted in an uncaught - exception; otherwise returns false. - - The exception state is cleared when evaluate() is called. - - \sa uncaughtException(), uncaughtExceptionLineNumber(), - uncaughtExceptionBacktrace() -*/ -bool QJSEngine::hasUncaughtException() const -{ - Q_D(const QJSEngine); - QScriptIsolate api(d); - return d->hasUncaughtException(); -} - -/*! - \obsolete - - Returns the current uncaught exception, or an invalid QJSValue - if there is no uncaught exception. - - The exception value is typically an \c{Error} object; in that case, - you can call toString() on the return value to obtain an error - message. - - \sa hasUncaughtException(), uncaughtExceptionLineNumber(), - uncaughtExceptionBacktrace() -*/ -QJSValue QJSEngine::uncaughtException() const -{ - Q_D(const QJSEngine); - QScriptIsolate api(d); - return d->scriptValueFromInternal(d->uncaughtException()); -} - -/*! - \obsolete - - Clears any uncaught exceptions in this engine. - - \sa hasUncaughtException() -*/ -void QJSEngine::clearExceptions() -{ - Q_D(QJSEngine); - QScriptIsolate api(d); - d->clearExceptions(); -} - -#endif // QT_DEPRECATED - /*! Runs the garbage collector. @@ -285,17 +225,16 @@ void QJSEngine::collectGarbage() The evaluation of \a program can cause an exception in the engine; in this case the return value will be the exception that was thrown (typically an \c{Error} object). You can call - hasUncaughtException() to determine if an exception occurred in - the last call to evaluate(). + isError() on the return value to determine whether an exception + occurred. \a lineNumber is used to specify a starting line number for \a program; line number information reported by the engine that pertain - to this evaluation (e.g. uncaughtExceptionLineNumber()) will be - based on this argument. For example, if \a program consists of two - lines of code, and the statement on the second line causes a script - exception, uncaughtExceptionLineNumber() would return the given \a - lineNumber plus one. When no starting line number is specified, line - numbers will be 1-based. + to this evaluation will be based on this argument. For example, if + \a program consists of two lines of code, and the statement on the + second line causes a script exception, the exception line number + would be \a lineNumber plus one. When no starting line number is + specified, line numbers will be 1-based. \a fileName is used for error reporting. For example in error objects the file name is accessible through the "fileName" property if it's diff --git a/src/qml/qml/v8/qjsengine.h b/src/qml/qml/v8/qjsengine.h index fa2584b..bf1e215 100644 --- a/src/qml/qml/v8/qjsengine.h +++ b/src/qml/qml/v8/qjsengine.h @@ -101,15 +101,6 @@ public: QV8Engine *handle() const { return d; } -#ifdef QT_DEPRECATED - QT_DEPRECATED bool hasUncaughtException() const; - QT_DEPRECATED QJSValue uncaughtException() const; - QT_DEPRECATED void clearExceptions(); -#endif - -Q_SIGNALS: - void signalHandlerException(const QJSValue &exception); - private: QJSValue create(int type, const void *ptr); diff --git a/src/qml/qml/v8/qjsvalue.cpp b/src/qml/qml/v8/qjsvalue.cpp index 6ecb97d..3cde607 100644 --- a/src/qml/qml/v8/qjsvalue.cpp +++ b/src/qml/qml/v8/qjsvalue.cpp @@ -459,9 +459,8 @@ QVariant QJSValue::toVariant() const Calling call() can cause an exception to occur in the script engine; in that case, call() returns the value that was thrown (typically an - \c{Error} object). You can call - QJSEngine::hasUncaughtException() to determine if an exception - occurred. + \c{Error} object). You can call isError() on the return value to + determine whether an exception occurred. \sa isCallable(), callWithInstance(), callAsConstructor() */ @@ -487,9 +486,8 @@ QJSValue QJSValue::call(const QJSValueList &args) Calling call() can cause an exception to occur in the script engine; in that case, call() returns the value that was thrown (typically an - \c{Error} object). You can call - QJSEngine::hasUncaughtException() to determine if an exception - occurred. + \c{Error} object). You can call isError() on the return value to + determine whether an exception occurred. \sa call() */ @@ -513,8 +511,8 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList Calling this function can cause an exception to occur in the script engine; in that case, the value that was thrown (typically an \c{Error} object) is returned. You can call - QJSEngine::hasUncaughtException() to determine if an exception - occurred. + isError() on the return value to determine whether an + exception occurred. \sa call(), QJSEngine::newObject() */ diff --git a/src/qml/qml/v8/qjsvalue_impl_p.h b/src/qml/qml/v8/qjsvalue_impl_p.h index 8d22204..e6bbd43 100644 --- a/src/qml/qml/v8/qjsvalue_impl_p.h +++ b/src/qml/qml/v8/qjsvalue_impl_p.h @@ -260,10 +260,8 @@ QString QJSValuePrivate::toString() const v8::HandleScope handleScope; v8::TryCatch tryCatch; v8::Local result = m_value->ToString(); - if (result.IsEmpty()) { + if (result.IsEmpty()) result = tryCatch.Exception()->ToString(); - m_engine->setException(tryCatch.Exception(), tryCatch.Message()); - } return QJSConverter::toString(result); } @@ -542,41 +540,6 @@ inline bool QJSValuePrivate::strictlyEquals(QJSValuePrivate* other) || (isNull() && other->isNull()); } -inline bool QJSValuePrivate::lessThan(QJSValuePrivate *other) const -{ - if (engine() != other->engine() && engine() && other->engine()) { - qWarning("QJSValue::lessThan: cannot compare to a value created in a different engine"); - return false; - } - - if (isString() && other->isString()) - return toString() < other->toString(); - - if (isObject() || other->isObject()) { - v8::HandleScope handleScope; - QV8Engine *eng = m_engine ? engine() : other->engine(); - // FIXME: lessThan can throw an exception which will be dropped by this code: - Q_ASSERT(eng); - eng->saveException(); - QScriptSharedDataPointer cmp(eng->evaluate(QString::fromLatin1("(function(a,b){return aisFunction()); - v8::Handle args[2]; - cmp->prepareArgumentsForCall(args, QJSValueList() << QJSValuePrivate::get(this) << QJSValuePrivate::get(other)); - QScriptSharedDataPointer resultValue(cmp->call(0, 2, args)); - bool result = resultValue->toBool(); - eng->restoreException(); - return result; - } - - double nthis = toNumber(); - double nother = other->toNumber(); - if (qIsNaN(nthis) || qIsNaN(nother)) { - // Should return undefined in ECMA standard. - return false; - } - return nthis < nother; -} - inline QScriptPassPointer QJSValuePrivate::prototype() const { if (isObject()) { @@ -631,8 +594,6 @@ inline void QJSValuePrivate::setProperty(v8::Handle name, QJSValuePr // } else { v8::Object::Cast(*m_value)->Set(name, value->m_value, v8::PropertyAttribute(attribs & QJSConverter::PropertyAttributeMask)); // } - if (tryCatch.HasCaught()) - engine()->setException(tryCatch.Exception(), tryCatch.Message()); } inline void QJSValuePrivate::setProperty(quint32 index, QJSValuePrivate* value, uint attribs) @@ -659,10 +620,7 @@ inline void QJSValuePrivate::setProperty(quint32 index, QJSValuePrivate* value, } v8::HandleScope handleScope; - v8::TryCatch tryCatch; v8::Object::Cast(*m_value)->Set(index, value->m_value); - if (tryCatch.HasCaught()) - engine()->setException(tryCatch.Exception(), tryCatch.Message()); } inline QScriptPassPointer QJSValuePrivate::property(const QString& name) const @@ -700,11 +658,8 @@ inline QScriptPassPointer QJSValuePrivate::property(T name) con v8::TryCatch tryCatch; v8::Handle result = self->Get(name); - if (tryCatch.HasCaught()) { + if (tryCatch.HasCaught()) result = tryCatch.Exception(); - engine()->setException(result, tryCatch.Message()); - return new QJSValuePrivate(engine(), result); - } if (result.IsEmpty()) return new QJSValuePrivate(engine()); return new QJSValuePrivate(engine(), result); @@ -795,7 +750,6 @@ QScriptPassPointer QJSValuePrivate::call(QJSValuePrivate* thisO if (argc < 0) { v8::Local exeption = v8::Exception::TypeError(v8::String::New("Arguments must be an array")); - e->setException(exeption); return new QJSValuePrivate(e, exeption); } @@ -808,7 +762,6 @@ QScriptPassPointer QJSValuePrivate::call(QJSValuePrivate* thisO //Q_ASSERT(!result.IsEmpty()); if (result.IsEmpty()) result = v8::Exception::Error(v8::String::New("missing exception value")); - e->setException(result, tryCatch.Message()); } return new QJSValuePrivate(e, result); @@ -820,17 +773,14 @@ inline QScriptPassPointer QJSValuePrivate::callAsConstructor(in if (argc < 0) { v8::Local exeption = v8::Exception::TypeError(v8::String::New("Arguments must be an array")); - e->setException(exeption); return new QJSValuePrivate(e, exeption); } v8::TryCatch tryCatch; v8::Handle result = v8::Object::Cast(*m_value)->CallAsConstructor(argc, argv); - if (result.IsEmpty()) { + if (result.IsEmpty()) result = tryCatch.Exception(); - e->setException(result, tryCatch.Message()); - } return new QJSValuePrivate(e, result); } diff --git a/src/qml/qml/v8/qjsvalue_p.h b/src/qml/qml/v8/qjsvalue_p.h index 099d53e..31b30aa 100644 --- a/src/qml/qml/v8/qjsvalue_p.h +++ b/src/qml/qml/v8/qjsvalue_p.h @@ -134,7 +134,6 @@ public: inline bool equals(QJSValuePrivate* other); inline bool strictlyEquals(QJSValuePrivate* other); - inline bool lessThan(QJSValuePrivate *other) const; inline QScriptPassPointer prototype() const; inline void setPrototype(QJSValuePrivate* prototype); diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 8444d65..eeedeb5 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -182,7 +182,6 @@ QV8Engine::~QV8Engine() qPersistentDispose(m_getOwnPropertyNames); invalidateAllValues(); - clearExceptions(); qPersistentDispose(m_strongReferencer); @@ -888,147 +887,12 @@ void QV8Engine::setEngine(QQmlEngine *engine) initQmlGlobalObject(); } -void QV8Engine::setException(v8::Handle value, v8::Handle msg) -{ - m_exception.set(value, msg); -} - v8::Handle QV8Engine::throwException(v8::Handle value) { - setException(value); v8::ThrowException(value); return value; } -void QV8Engine::clearExceptions() -{ - m_exception.clear(); -} - -v8::Handle QV8Engine::uncaughtException() const -{ - if (!hasUncaughtException()) - return v8::Handle(); - return m_exception; -} - -bool QV8Engine::hasUncaughtException() const -{ - return m_exception; -} - -int QV8Engine::uncaughtExceptionLineNumber() const -{ - return m_exception.lineNumber(); -} - -QStringList QV8Engine::uncaughtExceptionBacktrace() const -{ - return m_exception.backtrace(); -} - -/*! - \internal - Save the current exception on stack so it can be set again later. - \sa QV8Engine::restoreException -*/ -void QV8Engine::saveException() -{ - m_exception.push(); -} - -/*! - \internal - Load a saved exception from stack. Current exception, if exists will be dropped - \sa QV8Engine::saveException -*/ -void QV8Engine::restoreException() -{ - m_exception.pop(); -} - -QV8Engine::Exception::Exception() {} - -QV8Engine::Exception::~Exception() -{ - Q_ASSERT_X(m_stack.isEmpty(), Q_FUNC_INFO, "Some saved exceptions left. Asymetric pop/push found."); - clear(); -} - -void QV8Engine::Exception::set(v8::Handle value, v8::Handle message) -{ - Q_ASSERT_X(!value.IsEmpty(), Q_FUNC_INFO, "Throwing an empty value handle is highly suspected"); - clear(); - m_value = v8::Persistent::New(value); - m_message = v8::Persistent::New(message); -} - -void QV8Engine::Exception::clear() -{ - m_value.Dispose(); - m_value.Clear(); - m_message.Dispose(); - m_message.Clear(); -} - -QV8Engine::Exception::operator bool() const -{ - return !m_value.IsEmpty(); -} - -QV8Engine::Exception::operator v8::Handle() const -{ - Q_ASSERT(*this); - return m_value; -} - -int QV8Engine::Exception::lineNumber() const -{ - if (m_message.IsEmpty()) - return -1; - return m_message->GetLineNumber(); -} - -QStringList QV8Engine::Exception::backtrace() const -{ - if (m_message.IsEmpty()) - return QStringList(); - - QStringList backtrace; - v8::Handle trace = m_message->GetStackTrace(); - if (trace.IsEmpty()) - // FIXME it should not happen (SetCaptureStackTraceForUncaughtExceptions is called). - return QStringList(); - - for (int i = 0; i < trace->GetFrameCount(); ++i) { - v8::Local frame = trace->GetFrame(i); - backtrace.append(QJSConverter::toString(frame->GetFunctionName())); - backtrace.append(QJSConverter::toString(frame->GetFunctionName())); - backtrace.append(QString::fromAscii("()@")); - backtrace.append(QJSConverter::toString(frame->GetScriptName())); - backtrace.append(QString::fromAscii(":")); - backtrace.append(QString::number(frame->GetLineNumber())); - } - return backtrace; -} - -void QV8Engine::Exception::push() -{ - m_stack.push(qMakePair(m_value, m_message)); - m_value.Clear(); - m_message.Clear(); -} - -void QV8Engine::Exception::pop() -{ - Q_ASSERT_X(!m_stack.empty(), Q_FUNC_INFO, "Attempt to load unsaved exception found"); - ValueMessagePair pair = m_stack.pop(); - clear(); - m_value = pair.first; - m_message = pair.second; -} - - // Converts a QVariantList to JS. // The result is a new Array object with length equal to the length // of the QVariantList, and the elements being the QVariantList's @@ -1503,14 +1367,12 @@ QScriptPassPointer QV8Engine::evaluate(v8::Handle s { v8::HandleScope handleScope; - clearExceptions(); if (script.IsEmpty()) { v8::Handle exception = tryCatch.Exception(); if (exception.IsEmpty()) { // This is possible on syntax errors like { a:12, b:21 } <- missing "(", ")" around expression. return new QJSValuePrivate(this); } - setException(exception, tryCatch.Message()); return new QJSValuePrivate(this, exception); } v8::Handle result; @@ -1521,7 +1383,6 @@ QScriptPassPointer QV8Engine::evaluate(v8::Handle s //Q_ASSERT(!exception.IsEmpty()); if (exception.IsEmpty()) exception = v8::Exception::Error(v8::String::New("missing exception value")); - setException(exception, tryCatch.Message()); return new QJSValuePrivate(this, exception); } return new QJSValuePrivate(this, result); @@ -1539,11 +1400,6 @@ QScriptPassPointer QV8Engine::newArray(uint length) return new QJSValuePrivate(this, v8::Array::New(length)); } -void QV8Engine::emitSignalHandlerException() -{ - emit q->signalHandlerException(scriptValueFromInternal(uncaughtException())); -} - void QV8Engine::startTimer(const QString &timerName) { if (!m_time.isValid()) diff --git a/src/qml/qml/v8/qv8engine_impl_p.h b/src/qml/qml/v8/qv8engine_impl_p.h index 7173ae4..41518bb 100644 --- a/src/qml/qml/v8/qv8engine_impl_p.h +++ b/src/qml/qml/v8/qv8engine_impl_p.h @@ -162,7 +162,6 @@ QScriptPassPointer QV8Engine::evaluate(const QString& program, // TODO: Why don't we get the exception, as with Script::Compile()? // Q_ASSERT(tryCatch.HasCaught()); v8::Handle error = v8::Exception::SyntaxError(v8::String::New("")); - setException(error); return new QJSValuePrivate(this, error); } return evaluate(script, tryCatch); diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 09e1ae5..ca1d290 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -241,29 +241,6 @@ public: virtual ~Deletable() {} }; - class Exception - { - typedef QPair, v8::Persistent > ValueMessagePair; - - v8::Persistent m_value; - v8::Persistent m_message; - QStack m_stack; - - Q_DISABLE_COPY(Exception) - public: - inline Exception(); - inline ~Exception(); - inline void set(v8::Handle value, v8::Handle message); - inline void clear(); - inline operator bool() const; - inline operator v8::Handle() const; - inline int lineNumber() const; - inline QStringList backtrace() const; - - inline void push(); - inline void pop(); - }; - void initQmlGlobalObject(); void setEngine(QQmlEngine *engine); QQmlEngine *engine() { return m_engine; } @@ -352,15 +329,7 @@ public: inline void collectGarbage() { gc(); } static void gc(); - void clearExceptions(); - void setException(v8::Handle value, v8::Handle message = v8::Handle()); v8::Handle throwException(v8::Handle value); - bool hasUncaughtException() const; - int uncaughtExceptionLineNumber() const; - QStringList uncaughtExceptionBacktrace() const; - v8::Handle uncaughtException() const; - void saveException(); - void restoreException(); #ifdef QML_GLOBAL_HANDLE_DEBUGGING // Used for handle debugging @@ -414,8 +383,6 @@ public: QJSValue scriptValueFromInternal(v8::Handle) const; - void emitSignalHandlerException(); - // used for console.time(), console.timeEnd() void startTimer(const QString &timerName); qint64 stopTimer(const QString &timerName, bool *wasRunning); @@ -477,8 +444,6 @@ protected: QStringHash m_illegalNames; - Exception m_exception; - QElapsedTimer m_time; QHash m_startedTimers; diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 5ebc42a..bf76adb 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -2114,13 +2114,13 @@ void tst_QJSEngine::evaluate() ret = eng.evaluate(code, /*fileName =*/QString(), lineNumber); else ret = eng.evaluate(code); - QCOMPARE(eng.hasUncaughtException(), expectHadError); + QCOMPARE(ret.isError(), expectHadError); #if 0 // ###FIXME: No support for the line number of an uncaught exception QEXPECT_FAIL("f()", "SyntaxError do not report line number", Continue); QEXPECT_FAIL("duplicateLabel: { duplicateLabel: ; }", "SyntaxError do not report line number", Continue); QCOMPARE(eng.uncaughtExceptionLineNumber(), expectErrorLineNumber); #endif - if (eng.hasUncaughtException() && ret.isError()) { + if (ret.isError()) { QEXPECT_FAIL("", "we have no more lineNumber property ", Continue); QVERIFY(ret.property("lineNumber").strictlyEquals(eng.toScriptValue(expectErrorLineNumber))); } else { @@ -3089,7 +3089,7 @@ void tst_QJSEngine::gcWithNestedDataStructure() // The GC must be able to traverse deeply nested objects, otherwise this // test would crash. QJSEngine eng; - eng.evaluate( + QJSValue ret = eng.evaluate( "function makeList(size)" "{" " var head = { };" @@ -3101,10 +3101,10 @@ void tst_QJSEngine::gcWithNestedDataStructure() " l.next = null;" " return head;" "}"); - QCOMPARE(eng.hasUncaughtException(), false); + QVERIFY(!ret.isError()); const int size = 200; QJSValue head = eng.evaluate(QString::fromLatin1("makeList(%0)").arg(size)); - QCOMPARE(eng.hasUncaughtException(), false); + QVERIFY(!head.isError()); for (int x = 0; x < 2; ++x) { if (x == 1) eng.evaluate("gc()"); @@ -3294,14 +3294,8 @@ void tst_QJSEngine::stacktrace() QJSEngine eng; QJSValue result = eng.evaluate(script, fileName); - QVERIFY(eng.hasUncaughtException()); QVERIFY(result.isError()); - // QEXPECT_FAIL("", "QTBUG-6139: uncaughtExceptionBacktrace() doesn't give the full backtrace", Abort); - // ###FIXME: no uncahgutExceptionBacktrace: QCOMPARE(eng.uncaughtExceptionBacktrace(), backtrace); - QVERIFY(eng.hasUncaughtException()); - QVERIFY(result.strictlyEquals(eng.uncaughtException())); - // FIXME? it is not standard. //QCOMPARE(result.property("fileName").toString(), fileName); //QCOMPARE(result.property("lineNumber").toInt(), 9); @@ -3344,7 +3338,6 @@ void tst_QJSEngine::stacktrace() // } // throw something that isn't an Error object - eng.clearExceptions(); // ###FIXME: No uncaughtExceptionBacktrace: QVERIFY(eng.uncaughtExceptionBacktrace().isEmpty()); QString script2 = QString::fromLatin1( "function foo(counter) {\n" @@ -3361,16 +3354,8 @@ void tst_QJSEngine::stacktrace() "foo(0);"); QJSValue result2 = eng.evaluate(script2, fileName); - QVERIFY(eng.hasUncaughtException()); QVERIFY(!result2.isError()); QVERIFY(result2.isString()); - - // ###FIXME: No uncaughtExceptionBacktrace: QCOMPARE(eng.uncaughtExceptionBacktrace(), backtrace); - QVERIFY(eng.hasUncaughtException()); - - eng.clearExceptions(); - QVERIFY(!eng.hasUncaughtException()); - // ###FIXME: No uncaughtExceptionBacktrace: QVERIFY(eng.uncaughtExceptionBacktrace().isEmpty()); } void tst_QJSEngine::numberParsing_data() @@ -3949,8 +3934,6 @@ void tst_QJSEngine::errorConstructors() code += name + QLatin1String("()"); QJSValue ret = eng.evaluate(code); QVERIFY(ret.isError()); - QCOMPARE(eng.hasUncaughtException(), x == 0); - eng.clearExceptions(); QVERIFY(ret.toString().startsWith(name)); //QTBUG-6138: JSC doesn't assign lineNumber when errors are not thrown QEXPECT_FAIL("", "we have no more lineNumber property ", Continue); @@ -4797,7 +4780,6 @@ void tst_QJSEngine::jsThrowInsideWithStatement() QVERIFY(ret.toString().contains(QString::fromLatin1("ReferenceError"))); } { - eng.clearExceptions(); QJSValue ret = eng.evaluate( "o = { bug : \"no bug\" };" "with (o) {" @@ -4807,12 +4789,11 @@ void tst_QJSEngine::jsThrowInsideWithStatement() " bug;" " }" "}"); + QVERIFY(!ret.isError()); QVERIFY(ret.isNumber()); QCOMPARE(ret.toInt(), 123); - QVERIFY(eng.hasUncaughtException()); } { - eng.clearExceptions(); QJSValue ret = eng.evaluate( "o = { bug : \"no bug\" };" "with (o) {" @@ -6337,7 +6318,6 @@ void tst_QJSEngine::functionPrototypeExtensions() // No properties should appear in for-in statements. QJSValue props = eng.evaluate("props = []; for (var p in Function.prototype) props.push(p); props"); - QVERIFY(!eng.hasUncaughtException()); QVERIFY(props.isArray()); QCOMPARE(props.property("length").toInt(), 0); } diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index 3522f22..6393ae5 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -382,22 +382,17 @@ void tst_QJSValue::toString() " return o;" "})()"); QCOMPARE(objectObject.toString(), QLatin1String("Error: toString")); - QVERIFY(eng.hasUncaughtException()); - QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: toString")); } { - eng.clearExceptions(); QJSValue objectObject = eng.evaluate( "(function(){" " var f = function() {};" " f.prototype = Date;" " return new f;" "})()"); - QVERIFY(!eng.hasUncaughtException()); + QVERIFY(!objectObject.isError()); QVERIFY(objectObject.isObject()); QCOMPARE(objectObject.toString(), QString::fromLatin1("TypeError: Function.prototype.toString is not generic")); - QVERIFY(eng.hasUncaughtException()); - eng.clearExceptions(); } QJSValue inv = QJSValue(); @@ -1690,17 +1685,15 @@ void tst_QJSValue::getSetProperty_gettersAndSettersThrowErrorJS() "o.__defineGetter__('foo', function() { throw new Error('get foo') }); " "o.__defineSetter__('foo', function() { throw new Error('set foo') }); "); QJSValue object = eng.evaluate("o"); - QVERIFY(!eng.hasUncaughtException()); + QVERIFY(!object.isError()); QJSValue ret = object.property("foo"); QVERIFY(ret.isError()); - QVERIFY(eng.hasUncaughtException()); - QVERIFY(ret.strictlyEquals(eng.uncaughtException())); QCOMPARE(ret.toString(), QLatin1String("Error: get foo")); - eng.evaluate("Object"); // clear exception state... - QVERIFY(!eng.hasUncaughtException()); + QVERIFY(!eng.evaluate("Object").isError()); // clear exception state... object.setProperty("foo", str); - QVERIFY(eng.hasUncaughtException()); - QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo")); +// ### No way to check whether setProperty() threw an exception +// QVERIFY(eng.hasUncaughtException()); +// QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo")); } void tst_QJSValue::getSetProperty_gettersAndSettersOnNative() @@ -2041,8 +2034,6 @@ void tst_QJSValue::getSetPrototype_evalCyclicPrototype() { QJSEngine eng; QJSValue ret = eng.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o"); - QCOMPARE(eng.hasUncaughtException(), true); - QVERIFY(ret.strictlyEquals(eng.uncaughtException())); QCOMPARE(ret.isError(), true); QCOMPARE(ret.toString(), QLatin1String("Error: Cyclic __proto__ value")); } @@ -2051,7 +2042,6 @@ void tst_QJSValue::getSetPrototype_eval() { QJSEngine eng; QJSValue ret = eng.evaluate("p = { }; p.__proto__ = { }"); - QCOMPARE(eng.hasUncaughtException(), false); QCOMPARE(ret.isError(), false); } @@ -2499,13 +2489,11 @@ void tst_QJSValue::call() { QJSValue fun = eng.evaluate("(function() { throw new Error('foo'); })"); QCOMPARE(fun.isCallable(), true); - QVERIFY(!eng.hasUncaughtException()); + QVERIFY(!fun.isError()); { QJSValue result = fun.call(); QCOMPARE(result.isError(), true); - QCOMPARE(eng.hasUncaughtException(), true); - QVERIFY(result.strictlyEquals(eng.uncaughtException())); } } #if 0 // FIXME: No c-style callbacks @@ -2828,8 +2816,6 @@ void tst_QJSValue::construct_throw() QCOMPARE(fun.isCallable(), true); QJSValue ret = fun.callAsConstructor(); QCOMPARE(ret.isError(), true); - QCOMPARE(eng.hasUncaughtException(), true); - QVERIFY(ret.strictlyEquals(eng.uncaughtException())); } #if 0 // FIXME: The feature of interpreting an array as argument list has been removed from the API @@ -2896,9 +2882,7 @@ void tst_QJSValue::construct_constructorThrowsPrimitive() QJSValue ret = fun.callAsConstructor(); QVERIFY(ret.isNumber()); QCOMPARE(ret.toNumber(), 123.0); - QVERIFY(eng.hasUncaughtException()); - QVERIFY(ret.strictlyEquals(eng.uncaughtException())); - eng.clearExceptions(); + QVERIFY(!ret.isError()); } #if 0 // FIXME: The feature of interpreting an array as argument list has been removed from the API // construct(QJSValue) diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 3091497..4e7f1a2 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -3391,7 +3391,7 @@ void tst_qqmlecmascript::signalWithJSValueInVariant() QVERIFY(object != 0); QJSValue value = engine.evaluate(expression); - QVERIFY(!engine.hasUncaughtException()); + QVERIFY(!value.isError()); object->setProperty("expression", expression); object->setProperty("compare", compare); object->setProperty("pass", false); @@ -3416,7 +3416,7 @@ void tst_qqmlecmascript::signalWithJSValueInVariant_twoEngines() QJSEngine engine2; QJSValue value = engine2.evaluate(expression); - QVERIFY(!engine2.hasUncaughtException()); + QVERIFY(!value.isError()); object->setProperty("expression", expression); object->setProperty("compare", compare); object->setProperty("pass", false); @@ -3441,7 +3441,7 @@ void tst_qqmlecmascript::signalWithQJSValue() QVERIFY(object != 0); QJSValue value = engine.evaluate(expression); - QVERIFY(!engine.hasUncaughtException()); + QVERIFY(!value.isError()); object->setProperty("expression", expression); object->setProperty("compare", compare); object->setProperty("pass", false); diff --git a/tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp b/tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp index 5713eb2..7bf4bd2 100644 --- a/tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp +++ b/tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp @@ -74,7 +74,6 @@ private slots: void connectAndDisconnect(); #endif void globalObject(); - void hasUncaughtException(); #if 0 // no is Evaluating for now void isEvaluating(); #endif @@ -271,14 +270,6 @@ void tst_QJSEngine::globalObject() } } -void tst_QJSEngine::hasUncaughtException() -{ - newEngine(); - QBENCHMARK { - m_engine->hasUncaughtException(); - } -} - #if 0 void tst_QJSEngine::isEvaluating() { -- 1.7.2.5