Remove QJS exception API
authorKent Hansen <kent.hansen@nokia.com>
Wed, 7 Mar 2012 12:56:33 +0000 (13:56 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 3 May 2012 07:52:41 +0000 (09:52 +0200)
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 <jedrzej.nowacki@nokia.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
14 files changed:
doc/src/snippets/code/src_script_qjsengine.cpp
examples/qml/script/shell/main.cpp
src/qml/qml/v8/qjsengine.cpp
src/qml/qml/v8/qjsengine.h
src/qml/qml/v8/qjsvalue.cpp
src/qml/qml/v8/qjsvalue_impl_p.h
src/qml/qml/v8/qjsvalue_p.h
src/qml/qml/v8/qv8engine.cpp
src/qml/qml/v8/qv8engine_impl_p.h
src/qml/qml/v8/qv8engine_p.h
tests/auto/qml/qjsengine/tst_qjsengine.cpp
tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
tests/benchmarks/qml/js/qjsengine/tst_qjsengine.cpp

index efde346..042bdd2 100644 (file)
@@ -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]
 
index a405912..4ea36f7 100644 (file)
@@ -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;
         }
index 92c968f..254b8e7 100644 (file)
@@ -87,8 +87,7 @@ Q_DECLARE_METATYPE(QList<int>)
   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<int>)
   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
index fa2584b..bf1e215 100644 (file)
@@ -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);
 
index 6ecb97d..3cde607 100644 (file)
@@ -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()
 */
index 8d22204..e6bbd43 100644 (file)
@@ -260,10 +260,8 @@ QString QJSValuePrivate::toString() const
         v8::HandleScope handleScope;
         v8::TryCatch tryCatch;
         v8::Local<v8::String> 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<QJSValuePrivate> cmp(eng->evaluate(QString::fromLatin1("(function(a,b){return a<b})")));
-        Q_ASSERT(cmp->isFunction());
-        v8::Handle<v8::Value> args[2];
-        cmp->prepareArgumentsForCall(args, QJSValueList() << QJSValuePrivate::get(this) << QJSValuePrivate::get(other));
-        QScriptSharedDataPointer<QJSValuePrivate> 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> QJSValuePrivate::prototype() const
 {
     if (isObject()) {
@@ -631,8 +594,6 @@ inline void QJSValuePrivate::setProperty(v8::Handle<v8::String> 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> QJSValuePrivate::property(const QString& name) const
@@ -700,11 +658,8 @@ inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(T name) con
 
     v8::TryCatch tryCatch;
     v8::Handle<v8::Value> 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> QJSValuePrivate::call(QJSValuePrivate* thisO
 
     if (argc < 0) {
         v8::Local<v8::Value> 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> 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> QJSValuePrivate::callAsConstructor(in
 
     if (argc < 0) {
         v8::Local<v8::Value> 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<v8::Value> 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);
 }
index 099d53e..31b30aa 100644 (file)
@@ -134,7 +134,6 @@ public:
 
     inline bool equals(QJSValuePrivate* other);
     inline bool strictlyEquals(QJSValuePrivate* other);
-    inline bool lessThan(QJSValuePrivate *other) const;
 
     inline QScriptPassPointer<QJSValuePrivate> prototype() const;
     inline void setPrototype(QJSValuePrivate* prototype);
index 8444d65..eeedeb5 100644 (file)
@@ -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<v8::Value> value, v8::Handle<v8::Message> msg)
-{
-    m_exception.set(value, msg);
-}
-
 v8::Handle<v8::Value> QV8Engine::throwException(v8::Handle<v8::Value> value)
 {
-    setException(value);
     v8::ThrowException(value);
     return value;
 }
 
-void QV8Engine::clearExceptions()
-{
-    m_exception.clear();
-}
-
-v8::Handle<v8::Value> QV8Engine::uncaughtException() const
-{
-    if (!hasUncaughtException())
-        return v8::Handle<v8::Value>();
-    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<v8::Value> value, v8::Handle<v8::Message> message)
-{
-    Q_ASSERT_X(!value.IsEmpty(), Q_FUNC_INFO, "Throwing an empty value handle is highly suspected");
-    clear();
-    m_value = v8::Persistent<v8::Value>::New(value);
-    m_message = v8::Persistent<v8::Message>::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<v8::Value>() 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<v8::StackTrace> 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<v8::StackFrame> 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<QJSValuePrivate> QV8Engine::evaluate(v8::Handle<v8::Script> s
 {
     v8::HandleScope handleScope;
 
-    clearExceptions();
     if (script.IsEmpty()) {
         v8::Handle<v8::Value> 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<v8::Value> result;
@@ -1521,7 +1383,6 @@ QScriptPassPointer<QJSValuePrivate> QV8Engine::evaluate(v8::Handle<v8::Script> 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<QJSValuePrivate> 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())
index 7173ae4..41518bb 100644 (file)
@@ -162,7 +162,6 @@ QScriptPassPointer<QJSValuePrivate> QV8Engine::evaluate(const QString& program,
         // TODO: Why don't we get the exception, as with Script::Compile()?
         // Q_ASSERT(tryCatch.HasCaught());
         v8::Handle<v8::Value> error = v8::Exception::SyntaxError(v8::String::New(""));
-        setException(error);
         return new QJSValuePrivate(this, error);
     }
     return evaluate(script, tryCatch);
index 09e1ae5..ca1d290 100644 (file)
@@ -241,29 +241,6 @@ public:
         virtual ~Deletable() {}
     };
 
-    class Exception
-    {
-        typedef QPair<v8::Persistent<v8::Value>, v8::Persistent<v8::Message> > ValueMessagePair;
-
-        v8::Persistent<v8::Value> m_value;
-        v8::Persistent<v8::Message> m_message;
-        QStack<ValueMessagePair> m_stack;
-
-        Q_DISABLE_COPY(Exception)
-    public:
-        inline Exception();
-        inline ~Exception();
-        inline void set(v8::Handle<v8::Value> value, v8::Handle<v8::Message> message);
-        inline void clear();
-        inline operator bool() const;
-        inline operator v8::Handle<v8::Value>() 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<v8::Value> value, v8::Handle<v8::Message> message = v8::Handle<v8::Message>());
     v8::Handle<v8::Value> throwException(v8::Handle<v8::Value> value);
-    bool hasUncaughtException() const;
-    int uncaughtExceptionLineNumber() const;
-    QStringList uncaughtExceptionBacktrace() const;
-    v8::Handle<v8::Value> uncaughtException() const;
-    void saveException();
-    void restoreException();
 
 #ifdef QML_GLOBAL_HANDLE_DEBUGGING
     // Used for handle debugging
@@ -414,8 +383,6 @@ public:
 
     QJSValue scriptValueFromInternal(v8::Handle<v8::Value>) 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<bool> m_illegalNames;
 
-    Exception m_exception;
-
     QElapsedTimer m_time;
     QHash<QString, qint64> m_startedTimers;
 
index 5ebc42a..bf76adb 100644 (file)
@@ -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);
 }
index 3522f22..6393ae5 100644 (file)
@@ -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)
index 3091497..4e7f1a2 100644 (file)
@@ -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);
index 5713eb2..7bf4bd2 100644 (file)
@@ -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()
 {