summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/qt
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/qt')
-rw-r--r--JavaScriptCore/qt/ChangeLog59
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.cpp75
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.h7
-rw-r--r--JavaScriptCore/qt/api/qscriptengine_p.cpp27
-rw-r--r--JavaScriptCore/qt/api/qscriptengine_p.h74
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue.cpp38
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue.h12
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue_p.h72
-rw-r--r--JavaScriptCore/qt/benchmarks/benchmarks.pri19
-rw-r--r--JavaScriptCore/qt/benchmarks/benchmarks.pro4
-rw-r--r--JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro13
-rw-r--r--JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp142
-rw-r--r--JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro9
-rw-r--r--JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp442
-rw-r--r--JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp104
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp13
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h1
17 files changed, 1100 insertions, 11 deletions
diff --git a/JavaScriptCore/qt/ChangeLog b/JavaScriptCore/qt/ChangeLog
new file mode 100644
index 0000000..8f2d423
--- /dev/null
+++ b/JavaScriptCore/qt/ChangeLog
@@ -0,0 +1,59 @@
+2010-07-02 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Compilation fix.
+
+ QScriptEnginePrivate::newArray can't be const because it can
+ throw an exception.
+
+ [Qt] QScriptEnginePrivate compilation fix
+ https://bugs.webkit.org/show_bug.cgi?id=41520
+
+ * api/qscriptengine_p.cpp:
+ (QScriptEnginePrivate::newArray):
+ * api/qscriptengine_p.h:
+
+2010-06-28 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Implement exception reporting in the QtScript API.
+
+ The exception should be accessible through the API by the uncaughtException
+ function. Functions; hasUncaughtException, clearExceptions, uncaughtExceptionLineNumber,
+ uncaughtExceptionBacktrace were added to facilitate error checking and debugging.
+
+ [Qt] QtScript API should be exceptions aware.
+ https://bugs.webkit.org/show_bug.cgi?id=41199
+
+ * api/qscriptengine.cpp:
+ (QScriptEngine::hasUncaughtException):
+ (QScriptEngine::uncaughtException):
+ (QScriptEngine::clearExceptions):
+ (QScriptEngine::uncaughtExceptionLineNumber):
+ (QScriptEngine::uncaughtExceptionBacktrace):
+ * api/qscriptengine.h:
+ * api/qscriptengine_p.cpp:
+ (QScriptEnginePrivate::QScriptEnginePrivate):
+ (QScriptEnginePrivate::~QScriptEnginePrivate):
+ (QScriptEnginePrivate::uncaughtException):
+ * api/qscriptengine_p.h:
+ (QScriptEnginePrivate::):
+ (QScriptEnginePrivate::evaluate):
+ (QScriptEnginePrivate::hasUncaughtException):
+ (QScriptEnginePrivate::clearExceptions):
+ (QScriptEnginePrivate::setException):
+ (QScriptEnginePrivate::uncaughtExceptionLineNumber):
+ (QScriptEnginePrivate::uncaughtExceptionBacktrace):
+ * api/qscriptvalue_p.h:
+ (QScriptValuePrivate::toString):
+ (QScriptValuePrivate::toNumber):
+ (QScriptValuePrivate::toObject):
+ (QScriptValuePrivate::equals):
+ (QScriptValuePrivate::instanceOf):
+ (QScriptValuePrivate::call):
+ (QScriptValuePrivate::inherits):
+ * tests/qscriptengine/tst_qscriptengine.cpp:
+ (tst_QScriptEngine::uncaughtException):
+
diff --git a/JavaScriptCore/qt/api/qscriptengine.cpp b/JavaScriptCore/qt/api/qscriptengine.cpp
index e1bdf77..4b2319b 100644
--- a/JavaScriptCore/qt/api/qscriptengine.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine.cpp
@@ -96,6 +96,71 @@ QScriptValue QScriptEngine::evaluate(const QScriptProgram& program)
}
/*!
+ 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 QScriptEngine::hasUncaughtException() const
+{
+ return d_ptr->hasUncaughtException();
+}
+
+/*!
+ Returns the current uncaught exception, or an invalid QScriptValue
+ 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()
+*/
+QScriptValue QScriptEngine::uncaughtException() const
+{
+ return QScriptValuePrivate::get(d_ptr->uncaughtException());
+}
+
+/*!
+ Clears any uncaught exceptions in this engine.
+
+ \sa hasUncaughtException()
+*/
+void QScriptEngine::clearExceptions()
+{
+ d_ptr->clearExceptions();
+}
+
+/*!
+ Returns the line number where the last uncaught exception occurred.
+
+ Line numbers are 1-based, unless a different base was specified as
+ the second argument to evaluate().
+
+ \sa hasUncaughtException(), uncaughtExceptionBacktrace()
+*/
+int QScriptEngine::uncaughtExceptionLineNumber() const
+{
+ return d_ptr->uncaughtExceptionLineNumber();
+}
+
+/*!
+ Returns a human-readable backtrace of the last uncaught exception.
+
+ Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}.
+
+ \sa uncaughtException()
+*/
+QStringList QScriptEngine::uncaughtExceptionBacktrace() const
+{
+ return d_ptr->uncaughtExceptionBacktrace();
+}
+
+/*!
Runs the garbage collector.
The garbage collector will attempt to reclaim memory by locating and disposing of objects that are
@@ -206,6 +271,16 @@ QScriptValue QScriptEngine::newObject()
}
/*!
+ Creates a QtScript object of class Array with the given \a length.
+
+ \sa newObject()
+*/
+QScriptValue QScriptEngine::newArray(uint length)
+{
+ return QScriptValuePrivate::get(d_ptr->newArray(length));
+}
+
+/*!
Returns this engine's Global Object.
By default, the Global Object contains the built-in objects that are
diff --git a/JavaScriptCore/qt/api/qscriptengine.h b/JavaScriptCore/qt/api/qscriptengine.h
index 653dffe..1a87a37 100644
--- a/JavaScriptCore/qt/api/qscriptengine.h
+++ b/JavaScriptCore/qt/api/qscriptengine.h
@@ -42,6 +42,12 @@ public:
QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1);
QScriptValue evaluate(const QScriptProgram& program);
+ bool hasUncaughtException() const;
+ QScriptValue uncaughtException() const;
+ void clearExceptions();
+ int uncaughtExceptionLineNumber() const;
+ QStringList uncaughtExceptionBacktrace() const;
+
void collectGarbage();
void reportAdditionalMemoryCost(int cost);
@@ -51,6 +57,7 @@ public:
QScriptValue nullValue();
QScriptValue undefinedValue();
QScriptValue newObject();
+ QScriptValue newArray(uint length = 0);
QScriptValue globalObject() const;
private:
friend class QScriptEnginePrivate;
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp
index fd7978b..23e41c4 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp
@@ -31,11 +31,14 @@
QScriptEnginePrivate::QScriptEnginePrivate(const QScriptEngine* engine)
: q_ptr(const_cast<QScriptEngine*>(engine))
, m_context(JSGlobalContextCreate(0))
+ , m_exception(0)
{
}
QScriptEnginePrivate::~QScriptEnginePrivate()
{
+ if (m_exception)
+ JSValueUnprotect(m_context, m_exception);
JSGlobalContextRelease(m_context);
}
@@ -77,11 +80,35 @@ QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QScriptProgramPrivate*
return new QScriptValuePrivate(this, evaluate(*program, program->file(), program->line()));
}
+QScriptValuePrivate* QScriptEnginePrivate::uncaughtException() const
+{
+ return m_exception ? new QScriptValuePrivate(this, m_exception) : new QScriptValuePrivate();
+}
+
QScriptValuePrivate* QScriptEnginePrivate::newObject() const
{
return new QScriptValuePrivate(this, JSObjectMake(m_context, /* jsClass */ 0, /* userData */ 0));
}
+QScriptValuePrivate* QScriptEnginePrivate::newArray(uint length)
+{
+ JSValueRef exception = 0;
+ JSObjectRef array = JSObjectMakeArray(m_context, /* argumentCount */ 0, /* arguments */ 0, &exception);
+
+ if (!exception) {
+ if (length > 0) {
+ JSRetainPtr<JSStringRef> lengthRef(Adopt, JSStringCreateWithUTF8CString("length"));
+ // array is an Array instance, so an exception should not occure here.
+ JSObjectSetProperty(m_context, array, lengthRef.get(), JSValueMakeNumber(m_context, length), kJSPropertyAttributeNone, /* exception */ 0);
+ }
+ } else {
+ setException(exception, NotNullException);
+ return new QScriptValuePrivate();
+ }
+
+ return new QScriptValuePrivate(this, array);
+}
+
QScriptValuePrivate* QScriptEnginePrivate::globalObject() const
{
JSObjectRef globalObject = JSContextGetGlobalObject(m_context);
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h
index 9083f7d..30ee039 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.h
+++ b/JavaScriptCore/qt/api/qscriptengine_p.h
@@ -26,9 +26,11 @@
#include "qscriptsyntaxcheckresult_p.h"
#include "qscriptvalue.h"
#include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/JSRetainPtr.h>
#include <JSBasePrivate.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
class QScriptEngine;
class QScriptSyntaxCheckResultPrivate;
@@ -41,11 +43,23 @@ public:
QScriptEnginePrivate(const QScriptEngine*);
~QScriptEnginePrivate();
+ enum SetExceptionFlag {
+ IgnoreNullException = 0x01,
+ NotNullException = 0x02,
+ };
+
QScriptSyntaxCheckResultPrivate* checkSyntax(const QString& program);
QScriptValuePrivate* evaluate(const QString& program, const QString& fileName, int lineNumber);
QScriptValuePrivate* evaluate(const QScriptProgramPrivate* program);
inline JSValueRef evaluate(JSStringRef program, JSStringRef fileName, int lineNumber);
+ inline bool hasUncaughtException() const;
+ QScriptValuePrivate* uncaughtException() const;
+ inline void clearExceptions();
+ inline void setException(JSValueRef exception, const /* SetExceptionFlags */ unsigned flags = IgnoreNullException);
+ inline int uncaughtExceptionLineNumber() const;
+ inline QStringList uncaughtExceptionBacktrace() const;
+
inline void collectGarbage();
inline void reportAdditionalMemoryCost(int cost);
@@ -57,6 +71,7 @@ public:
inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const;
QScriptValuePrivate* newObject() const;
+ QScriptValuePrivate* newArray(uint length);
QScriptValuePrivate* globalObject() const;
inline QScriptStringPrivate* toStringHandle(const QString& str) const;
@@ -65,6 +80,7 @@ public:
private:
QScriptEngine* q_ptr;
JSGlobalContextRef m_context;
+ JSValueRef m_exception;
};
@@ -77,11 +93,67 @@ JSValueRef QScriptEnginePrivate::evaluate(JSStringRef program, JSStringRef fileN
{
JSValueRef exception;
JSValueRef result = JSEvaluateScript(m_context, program, /* Global Object */ 0, fileName, lineNumber, &exception);
- if (!result)
+ if (!result) {
+ setException(exception, NotNullException);
return exception; // returns an exception
+ }
+ clearExceptions();
return result;
}
+bool QScriptEnginePrivate::hasUncaughtException() const
+{
+ return m_exception;
+}
+
+void QScriptEnginePrivate::clearExceptions()
+{
+ if (m_exception)
+ JSValueUnprotect(m_context, m_exception);
+ m_exception = 0;
+}
+
+void QScriptEnginePrivate::setException(JSValueRef exception, const /* SetExceptionFlags */ unsigned flags)
+{
+ if (!((flags & NotNullException) || exception))
+ return;
+ Q_ASSERT(exception);
+
+ if (m_exception)
+ JSValueUnprotect(m_context, m_exception);
+ JSValueProtect(m_context, exception);
+ m_exception = exception;
+}
+
+int QScriptEnginePrivate::uncaughtExceptionLineNumber() const
+{
+ if (!hasUncaughtException() || !JSValueIsObject(m_context, m_exception))
+ return -1;
+
+ JSValueRef exception = 0;
+ JSRetainPtr<JSStringRef> lineNumberPropertyName(Adopt, QScriptConverter::toString("line"));
+ JSValueRef lineNumber = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), lineNumberPropertyName.get(), &exception);
+ int result = JSValueToNumber(m_context, lineNumber, &exception);
+ return exception ? -1 : result;
+}
+
+QStringList QScriptEnginePrivate::uncaughtExceptionBacktrace() const
+{
+ if (!hasUncaughtException() || !JSValueIsObject(m_context, m_exception))
+ return QStringList();
+
+ JSValueRef exception = 0;
+ JSRetainPtr<JSStringRef> fileNamePropertyName(Adopt, QScriptConverter::toString("sourceURL"));
+ JSRetainPtr<JSStringRef> lineNumberPropertyName(Adopt, QScriptConverter::toString("line"));
+ JSValueRef jsFileName = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), fileNamePropertyName.get(), &exception);
+ JSValueRef jsLineNumber = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), lineNumberPropertyName.get(), &exception);
+ JSRetainPtr<JSStringRef> fileName(Adopt, JSValueToStringCopy(m_context, jsFileName, &exception));
+ int lineNumber = JSValueToNumber(m_context, jsLineNumber, &exception);
+ return QStringList(QString::fromLatin1("<anonymous>()@%0:%1")
+ .arg(QScriptConverter::toString(fileName.get()))
+ .arg(QScriptConverter::toString(exception ? -1 : lineNumber)));
+}
+
void QScriptEnginePrivate::collectGarbage()
{
JSGarbageCollect(m_context);
diff --git a/JavaScriptCore/qt/api/qscriptvalue.cpp b/JavaScriptCore/qt/api/qscriptvalue.cpp
index 8ad76a5..e309fb7 100644
--- a/JavaScriptCore/qt/api/qscriptvalue.cpp
+++ b/JavaScriptCore/qt/api/qscriptvalue.cpp
@@ -627,3 +627,41 @@ bool QScriptValue::instanceOf(const QScriptValue& other) const
{
return d_ptr->instanceOf(QScriptValuePrivate::get(other));
}
+
+/*!
+ Returns the value of this QScriptValue's property with the given \a name,
+ using the given \a mode to resolve the property.
+
+ If no such property exists, an invalid QScriptValue is returned.
+
+ If the property is implemented using a getter function (i.e. has the
+ PropertyGetter flag set), calling property() has side-effects on the
+ script engine, since the getter function will be called (possibly
+ resulting in an uncaught script exception). If an exception
+ occurred, property() returns the value that was thrown (typically
+ an \c{Error} object).
+
+ \sa setProperty(), propertyFlags(), QScriptValueIterator
+*/
+QScriptValue QScriptValue::property(const QString& name, const ResolveFlags& mode) const
+{
+ return QScriptValuePrivate::get(d_ptr->property(name, mode));
+}
+
+/*!
+ \overload
+
+ Returns the property at the given \a arrayIndex, using the given \a
+ mode to resolve the property.
+
+ This function is provided for convenience and performance when
+ working with array objects.
+
+ If this QScriptValue is not an Array object, this function behaves
+ as if property() was called with the string representation of \a
+ arrayIndex.
+*/
+QScriptValue QScriptValue::property(quint32 arrayIndex, const ResolveFlags& mode) const
+{
+ return QScriptValuePrivate::get(d_ptr->property(arrayIndex, mode));
+}
diff --git a/JavaScriptCore/qt/api/qscriptvalue.h b/JavaScriptCore/qt/api/qscriptvalue.h
index c82ef55..c55d461 100644
--- a/JavaScriptCore/qt/api/qscriptvalue.h
+++ b/JavaScriptCore/qt/api/qscriptvalue.h
@@ -32,7 +32,14 @@ typedef QList<QScriptValue> QScriptValueList;
typedef double qsreal;
class QScriptValue {
-public:
+public:
+ enum ResolveFlag {
+ ResolveLocal = 0x00,
+ ResolvePrototype = 0x01
+ };
+
+ Q_DECLARE_FLAGS(ResolveFlags, ResolveFlag)
+
enum SpecialValue {
NullValue,
UndefinedValue
@@ -67,6 +74,9 @@ public:
bool strictlyEquals(const QScriptValue& other) const;
bool instanceOf(const QScriptValue& other) const;
+ QScriptValue property(const QString& name, const ResolveFlags& mode = ResolvePrototype) const;
+ QScriptValue property(quint32 arrayIndex, const ResolveFlags& mode = ResolvePrototype) const;
+
QScriptEngine* engine() const;
bool isValid() const;
diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h
index f8a1e7a..49bec97 100644
--- a/JavaScriptCore/qt/api/qscriptvalue_p.h
+++ b/JavaScriptCore/qt/api/qscriptvalue_p.h
@@ -120,6 +120,9 @@ public:
inline bool instanceOf(QScriptValuePrivate* other);
inline bool assignEngine(QScriptEnginePrivate* engine);
+ inline QScriptValuePrivate* property(const QString& name, const QScriptValue::ResolveFlags& mode);
+ inline QScriptValuePrivate* property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode);
+
inline QScriptValuePrivate* call(const QScriptValuePrivate* , const QScriptValueList& args);
inline operator JSValueRef() const;
@@ -442,7 +445,9 @@ QString QScriptValuePrivate::toString() const
case JSValue:
case JSPrimitive:
case JSObject:
- JSRetainPtr<JSStringRef> ptr(Adopt, JSValueToStringCopy(*m_engine, *this, /* exception */ 0));
+ JSValueRef exception = 0;
+ JSRetainPtr<JSStringRef> ptr(Adopt, JSValueToStringCopy(*m_engine, *this, &exception));
+ m_engine->setException(exception);
return QScriptConverter::toString(ptr.get());
}
@@ -456,7 +461,12 @@ qsreal QScriptValuePrivate::toNumber() const
case JSValue:
case JSPrimitive:
case JSObject:
- return JSValueToNumber(*m_engine, *this, /* exception */ 0);
+ {
+ JSValueRef exception = 0;
+ qsreal result = JSValueToNumber(*m_engine, *this, &exception);
+ m_engine->setException(exception);
+ return result;
+ }
case CNumber:
return u.m_number;
case CBool:
@@ -585,9 +595,13 @@ QScriptValuePrivate* QScriptValuePrivate::toObject(QScriptEnginePrivate* engine)
{
if (engine != this->engine())
qWarning("QScriptEngine::toObject: cannot convert value created in a different engine");
- JSObjectRef object = JSValueToObject(*m_engine, *this, /* exception */ 0);
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject(*m_engine, *this, &exception);
if (object)
return new QScriptValuePrivate(m_engine.constData(), object);
+ else
+ m_engine->setException(exception, QScriptEnginePrivate::NotNullException);
+
}
return new QScriptValuePrivate;
case JSObject:
@@ -621,7 +635,7 @@ inline QScriptValuePrivate* QScriptValuePrivate::prototype()
return new QScriptValuePrivate(engine(), prototype);
// The prototype could be either a null or a JSObject, so it is safe to cast the prototype
// to the JSObjectRef here.
- return new QScriptValuePrivate(engine(), prototype, const_cast<JSObjectRef>(prototype));
+ return new QScriptValuePrivate(engine(), const_cast<JSObjectRef>(prototype));
}
return new QScriptValuePrivate;
}
@@ -672,7 +686,10 @@ bool QScriptValuePrivate::equals(QScriptValuePrivate* other)
}
}
- return JSValueIsEqual(*m_engine, *this, *other, /* exception */ 0);
+ JSValueRef exception = 0;
+ bool result = JSValueIsEqual(*m_engine, *this, *other, &exception);
+ m_engine->setException(exception);
+ return result;
}
bool QScriptValuePrivate::strictlyEquals(QScriptValuePrivate* other)
@@ -716,7 +733,10 @@ inline bool QScriptValuePrivate::instanceOf(QScriptValuePrivate* other)
{
if (!isJSBased() || !other->isObject())
return false;
- return JSValueIsInstanceOfConstructor(*m_engine, *this, *other, /* exception */ 0);
+ JSValueRef exception = 0;
+ bool result = JSValueIsInstanceOfConstructor(*m_engine, *this, *other, &exception);
+ m_engine->setException(exception);
+ return result;
}
/*!
@@ -756,6 +776,35 @@ bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine)
return true;
}
+inline QScriptValuePrivate* QScriptValuePrivate::property(const QString& name, const QScriptValue::ResolveFlags& mode)
+{
+ if (!isObject())
+ return new QScriptValuePrivate;
+
+ if (mode & QScriptValue::ResolveLocal) {
+ qWarning("QScriptValue::property(): ResolveLocal not supported yet.");
+ return new QScriptValuePrivate;
+ }
+
+ JSRetainPtr<JSStringRef> nameRef(Adopt, QScriptConverter::toString(name));
+ QScriptValuePrivate* result = new QScriptValuePrivate(m_engine.constData(), JSObjectGetProperty(*m_engine, *this, nameRef.get(), /* exception */ 0));
+
+ return result;
+}
+
+inline QScriptValuePrivate* QScriptValuePrivate::property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode)
+{
+ if (!isObject())
+ return new QScriptValuePrivate;
+
+ if (mode & QScriptValue::ResolveLocal) {
+ qWarning("QScriptValue::property(): ResolveLocal not supported yet.");
+ return new QScriptValuePrivate;
+ }
+
+ return new QScriptValuePrivate(m_engine.constData(), JSObjectGetPropertyAtIndex(*m_engine, *this, arrayIndex, /* exception */ 0));
+}
+
QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const QScriptValueList& args)
{
switch (m_state) {
@@ -781,8 +830,10 @@ QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const
// Make the call
JSValueRef exception = 0;
JSValueRef result = JSObjectCallAsFunction(*m_engine, *this, /* thisObject */ 0, argc, argv.constData(), &exception);
- if (!result && exception)
+ if (!result && exception) {
+ m_engine->setException(exception);
return new QScriptValuePrivate(engine(), exception);
+ }
if (result && !exception)
return new QScriptValuePrivate(engine(), result);
}
@@ -823,9 +874,12 @@ bool QScriptValuePrivate::inherits(const char* name)
Q_ASSERT(isJSBased());
JSObjectRef globalObject = JSContextGetGlobalObject(*m_engine);
JSStringRef errorAttrName = QScriptConverter::toString(name);
- JSValueRef error = JSObjectGetProperty(*m_engine, globalObject, errorAttrName, /* exception */ 0);
+ JSValueRef exception = 0;
+ JSValueRef error = JSObjectGetProperty(*m_engine, globalObject, errorAttrName, &exception);
JSStringRelease(errorAttrName);
- return JSValueIsInstanceOfConstructor(*m_engine, *this, JSValueToObject(*m_engine, error, /* exception */ 0), /* exception */ 0);
+ bool result = JSValueIsInstanceOfConstructor(*m_engine, *this, JSValueToObject(*m_engine, error, &exception), &exception);
+ m_engine->setException(exception);
+ return result;
}
/*!
diff --git a/JavaScriptCore/qt/benchmarks/benchmarks.pri b/JavaScriptCore/qt/benchmarks/benchmarks.pri
new file mode 100644
index 0000000..5af3383
--- /dev/null
+++ b/JavaScriptCore/qt/benchmarks/benchmarks.pri
@@ -0,0 +1,19 @@
+QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR
+QMAKE_LIBDIR = $$OUTPUT_DIR/lib $$QMAKE_LIBDIR
+mac:!static:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework) {
+ LIBS += -framework QtScript
+ QMAKE_FRAMEWORKPATH = $$OUTPUT_DIR/lib $$QMAKE_FRAMEWORKPATH
+} else {
+ win32-*|wince* {
+ LIBS += -lQtScript$${QT_MAJOR_VERSION}
+ } else {
+ LIBS += -lQtScript
+ }
+}
+
+CONFIG(release, debug|release) {
+ DEFINES += NDEBUG
+}
+
+INCLUDEPATH += $$PWD/../api
+
diff --git a/JavaScriptCore/qt/benchmarks/benchmarks.pro b/JavaScriptCore/qt/benchmarks/benchmarks.pro
new file mode 100644
index 0000000..85fa82c
--- /dev/null
+++ b/JavaScriptCore/qt/benchmarks/benchmarks.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = qscriptengine \
+ qscriptvalue \
+
diff --git a/JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro b/JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro
new file mode 100644
index 0000000..e94137d
--- /dev/null
+++ b/JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = tst_bench_qscriptengine
+
+SOURCES += tst_qscriptengine.cpp
+
+QT += testlib
+
+include(../benchmarks.pri)
+
+symbian* {
+ TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 // Min 128kB, Max 32MB
+ TARGET.EPOCSTACKSIZE = 0x14000
+}
diff --git a/JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp
new file mode 100644
index 0000000..0c447c6
--- /dev/null
+++ b/JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp
@@ -0,0 +1,142 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "qscriptengine.h"
+#include "qscriptvalue.h"
+#include <qtest.h>
+
+class tst_QScriptEngine : public QObject {
+ Q_OBJECT
+
+private slots:
+ void checkSyntax_data();
+ void checkSyntax();
+ void constructor();
+ void evaluateString_data();
+ void evaluateString();
+ void evaluateProgram_data();
+ void evaluateProgram();
+ void newObject();
+ void nullValue();
+ void undefinedValue();
+ void globalObject();
+ void toStringHandle();
+};
+
+void tst_QScriptEngine::checkSyntax_data()
+{
+ evaluateString_data();
+}
+
+void tst_QScriptEngine::checkSyntax()
+{
+ QFETCH(QString, code);
+ QScriptEngine engine;
+ QBENCHMARK {
+ engine.checkSyntax(code);
+ }
+}
+
+void tst_QScriptEngine::constructor()
+{
+ QBENCHMARK {
+ QScriptEngine engine;
+ }
+}
+
+void tst_QScriptEngine::evaluateString_data()
+{
+ QTest::addColumn<QString>("code");
+ QTest::newRow("empty script") << QString::fromLatin1("");
+ QTest::newRow("number literal") << QString::fromLatin1("123");
+ QTest::newRow("string literal") << QString::fromLatin1("'ciao'");
+ QTest::newRow("regexp literal") << QString::fromLatin1("/foo/gim");
+ QTest::newRow("null literal") << QString::fromLatin1("null");
+ QTest::newRow("undefined literal") << QString::fromLatin1("undefined");
+ QTest::newRow("empty object literal") << QString::fromLatin1("{}");
+ QTest::newRow("this") << QString::fromLatin1("this");
+}
+
+void tst_QScriptEngine::evaluateString()
+{
+ QFETCH(QString, code);
+ QScriptEngine engine;
+ QBENCHMARK {
+ engine.evaluate(code);
+ }
+}
+
+void tst_QScriptEngine::evaluateProgram_data()
+{
+ evaluateString_data();
+}
+
+void tst_QScriptEngine::evaluateProgram()
+{
+ QFETCH(QString, code);
+ QScriptEngine engine;
+ QScriptProgram program(code);
+ QBENCHMARK {
+ engine.evaluate(program);
+ }
+}
+
+void tst_QScriptEngine::newObject()
+{
+ QScriptEngine engine;
+ QBENCHMARK {
+ engine.newObject();
+ }
+}
+
+void tst_QScriptEngine::nullValue()
+{
+ QScriptEngine engine;
+ QBENCHMARK {
+ engine.nullValue();
+ }
+}
+
+void tst_QScriptEngine::undefinedValue()
+{
+ QScriptEngine engine;
+ QBENCHMARK {
+ engine.undefinedValue();
+ }
+}
+
+void tst_QScriptEngine::globalObject()
+{
+ QScriptEngine engine;
+ QBENCHMARK {
+ engine.globalObject();
+ }
+}
+
+void tst_QScriptEngine::toStringHandle()
+{
+ QScriptEngine engine;
+ QString str = QString::fromLatin1("foobarbaz");
+ QBENCHMARK {
+ engine.toStringHandle(str);
+ }
+}
+
+QTEST_MAIN(tst_QScriptEngine)
+#include "tst_qscriptengine.moc"
diff --git a/JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro b/JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro
new file mode 100644
index 0000000..673fe65
--- /dev/null
+++ b/JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET = tst_bench_qscriptvalue
+QT += testlib
+
+isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../..
+include(../benchmarks.pri)
+
+SOURCES += tst_qscriptvalue.cpp
+
diff --git a/JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp
new file mode 100644
index 0000000..7c39b8e
--- /dev/null
+++ b/JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp
@@ -0,0 +1,442 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "qscriptengine.h"
+#include "qscriptstring.h"
+#include "qscriptvalue.h"
+#include <qtest.h>
+
+Q_DECLARE_METATYPE(QScriptValue);
+
+class tst_QScriptValue : public QObject {
+ Q_OBJECT
+
+public:
+ tst_QScriptValue()
+ : m_engine(0)
+ {}
+
+ ~tst_QScriptValue()
+ {
+ if (m_engine)
+ delete m_engine;
+ }
+
+private slots:
+ void values_data();
+
+ void ctorBool();
+ void ctorReal();
+ void ctorNumber();
+ void ctorQString();
+ void ctorCString();
+ void ctorSpecial();
+ void ctorQScriptValue();
+
+ void isValid_data();
+ void isValid();
+ void isBool_data();
+ void isBool();
+ void isNumber_data();
+ void isNumber();
+ void isFunction_data();
+ void isFunction();
+ void isNull_data();
+ void isNull();
+ void isString_data();
+ void isString();
+ void isUndefined_data();
+ void isUndefined();
+ void isObject_data();
+ void isObject();
+ void isError_data();
+ void isError();
+
+ void toString_data();
+ void toString();
+ void toNumber_data();
+ void toNumber();
+ void toBool_data();
+ void toBool();
+ void toInteger_data();
+ void toInteger();
+ void toInt32_data();
+ void toInt32();
+ void toUInt32_data();
+ void toUInt32();
+ void toUInt16_data();
+ void toUInt16();
+ void toObject_data();
+ void toObject();
+
+ void equals_data();
+ void equals();
+ void strictlyEquals_data();
+ void strictlyEquals();
+ void instanceOf_data();
+ void instanceOf();
+
+private:
+ QScriptEngine* m_engine;
+};
+
+void tst_QScriptValue::values_data()
+{
+ if (m_engine)
+ delete m_engine;
+ m_engine = new QScriptEngine;
+
+ QTest::addColumn<QScriptValue>("value");
+
+ QTest::newRow("invalid") << QScriptValue();
+
+ QTest::newRow("cbool") << QScriptValue(true);
+ QTest::newRow("cnumber") << QScriptValue(1234);
+ QTest::newRow("cstring") << QScriptValue("abc");
+ QTest::newRow("cnull") << QScriptValue(QScriptValue::NullValue);
+ QTest::newRow("cundefined") << QScriptValue(QScriptValue::UndefinedValue);
+
+ QTest::newRow("jsbool") << m_engine->evaluate("true");
+ QTest::newRow("jsnumber") << m_engine->evaluate("12345");
+ QTest::newRow("jsstring") << m_engine->evaluate("'go'");
+ QTest::newRow("jsfunction") << m_engine->evaluate("(function {})");
+ QTest::newRow("jsnull") << m_engine->nullValue();
+ QTest::newRow("jsundefined") << m_engine->undefinedValue();
+ QTest::newRow("jsobject") << m_engine->newObject();
+ QTest::newRow("jserror") << m_engine->evaluate("new Error()");
+}
+
+void tst_QScriptValue::ctorBool()
+{
+ QBENCHMARK {
+ QScriptValue(true);
+ }
+}
+
+void tst_QScriptValue::ctorReal()
+{
+ QBENCHMARK {
+ QScriptValue(12.3);
+ }
+}
+
+void tst_QScriptValue::ctorNumber()
+{
+ QBENCHMARK {
+ QScriptValue(123);
+ }
+}
+
+void tst_QScriptValue::ctorQString()
+{
+ QString str = QString::fromLatin1("ciao");
+ QBENCHMARK {
+ QScriptValue(str);
+ }
+}
+
+void tst_QScriptValue::ctorCString()
+{
+ QBENCHMARK {
+ QScriptValue("Pong!");
+ }
+}
+
+void tst_QScriptValue::ctorSpecial()
+{
+ QBENCHMARK {
+ (void)QScriptValue(QScriptValue::NullValue);
+ }
+}
+
+void tst_QScriptValue::ctorQScriptValue()
+{
+ QScriptValue tmp(1234);
+ QBENCHMARK {
+ QScriptValue(tmp);
+ }
+}
+
+void tst_QScriptValue::isValid_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::isValid()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.isValid();
+ }
+}
+
+void tst_QScriptValue::isBool_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::isBool()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.isBool();
+ }
+}
+
+void tst_QScriptValue::isNumber_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::isNumber()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.isNumber();
+ }
+}
+
+void tst_QScriptValue::isFunction_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::isFunction()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.isFunction();
+ }
+}
+
+void tst_QScriptValue::isNull_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::isNull()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.isNull();
+ }
+}
+
+void tst_QScriptValue::isString_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::isString()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.isString();
+ }
+}
+
+void tst_QScriptValue::isUndefined_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::isUndefined()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.isUndefined();
+ }
+}
+
+void tst_QScriptValue::isObject_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::isObject()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.isObject();
+ }
+}
+
+void tst_QScriptValue::isError_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::isError()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.isError();
+ }
+}
+
+void tst_QScriptValue::toString_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::toString()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.toString();
+ }
+}
+
+void tst_QScriptValue::toNumber_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::toNumber()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.toNumber();
+ }
+}
+
+void tst_QScriptValue::toBool_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::toBool()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.toBool();
+ }
+}
+
+void tst_QScriptValue::toInteger_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::toInteger()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.toInteger();
+ }
+}
+
+void tst_QScriptValue::toInt32_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::toInt32()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.toInt32();
+ }
+}
+
+void tst_QScriptValue::toUInt32_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::toUInt32()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.toUInt32();
+ }
+}
+
+void tst_QScriptValue::toUInt16_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::toUInt16()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.toUInt16();
+ }
+}
+
+void tst_QScriptValue::toObject_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::toObject()
+{
+ QFETCH(QScriptValue, value);
+ QBENCHMARK {
+ value.toObject();
+ }
+}
+
+void tst_QScriptValue::equals_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::equals()
+{
+ QFETCH(QScriptValue, value);
+ static QScriptValue previous;
+ QBENCHMARK {
+ value.equals(previous);
+ }
+ previous = value;
+}
+
+void tst_QScriptValue::strictlyEquals_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::strictlyEquals()
+{
+ QFETCH(QScriptValue, value);
+ static QScriptValue previous;
+ QBENCHMARK {
+ value.strictlyEquals(previous);
+ }
+ previous = value;
+}
+
+void tst_QScriptValue::instanceOf_data()
+{
+ values_data();
+}
+
+void tst_QScriptValue::instanceOf()
+{
+ QFETCH(QScriptValue, value);
+ static QScriptValue object = m_engine->newObject();
+ QBENCHMARK {
+ value.instanceOf(object);
+ }
+}
+
+QTEST_MAIN(tst_QScriptValue)
+#include "tst_qscriptvalue.moc"
diff --git a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
index d545f37..753fcd0 100644
--- a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
+++ b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
@@ -47,6 +47,8 @@ private slots:
void checkSyntax();
void toObject();
void toObjectTwoEngines();
+ void newArray();
+ void uncaughtException();
};
/* Evaluating a script that throw an unhandled exception should return an invalid value. */
@@ -409,5 +411,107 @@ void tst_QScriptEngine::toObjectTwoEngines()
}
}
+void tst_QScriptEngine::newArray()
+{
+ QScriptEngine eng;
+ QScriptValue array = eng.newArray();
+ QCOMPARE(array.isValid(), true);
+ // QCOMPARE(array.isArray(), true);
+ QCOMPARE(array.isObject(), true);
+ QVERIFY(!array.isFunction());
+ // QCOMPARE(array.scriptClass(), (QScriptClass*)0);
+
+ // Prototype should be Array.prototype.
+ QCOMPARE(array.prototype().isValid(), true);
+ // QCOMPARE(array.prototype().isArray(), true);
+ QCOMPARE(array.prototype().strictlyEquals(eng.evaluate("Array.prototype")), true);
+
+ QScriptValue arrayWithSize = eng.newArray(42);
+ QCOMPARE(arrayWithSize.isValid(), true);
+ // QCOMPARE(arrayWithSize.isArray(), true);
+ QCOMPARE(arrayWithSize.isObject(), true);
+ QCOMPARE(arrayWithSize.property("length").toInt32(), 42);
+}
+
+void tst_QScriptEngine::uncaughtException()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function foo () { return null; });");
+ QVERIFY(!eng.uncaughtException().isValid());
+ QVERIFY(fun.isFunction());
+ QScriptValue throwFun = eng.evaluate("( function() { throw new Error('Pong'); });");
+ QVERIFY(throwFun.isFunction());
+ {
+ eng.evaluate("a = 10");
+ QVERIFY(!eng.hasUncaughtException());
+ QVERIFY(!eng.uncaughtException().isValid());
+ }
+ {
+ eng.evaluate("1 = 2");
+ QVERIFY(eng.hasUncaughtException());
+ eng.clearExceptions();
+ QVERIFY(!eng.hasUncaughtException());
+ }
+ {
+ // Check if the call or toString functions can remove the last exception.
+ QVERIFY(throwFun.call().isError());
+ QVERIFY(eng.hasUncaughtException());
+ QScriptValue exception = eng.uncaughtException();
+ fun.call();
+ exception.toString();
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(eng.uncaughtException().strictlyEquals(exception));
+ }
+ eng.clearExceptions();
+ {
+ // Check if in the call function a new exception can override an existing one.
+ throwFun.call();
+ QVERIFY(eng.hasUncaughtException());
+ QScriptValue exception = eng.uncaughtException();
+ throwFun.call();
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(!exception.strictlyEquals(eng.uncaughtException()));
+ }
+ {
+ eng.evaluate("throwFun = (function foo () { throw new Error('bla') });");
+ eng.evaluate("1;\nthrowFun();");
+ QVERIFY(eng.hasUncaughtException());
+ QCOMPARE(eng.uncaughtExceptionLineNumber(), 1);
+ eng.clearExceptions();
+ QVERIFY(!eng.hasUncaughtException());
+ }
+ for (int x = 1; x < 4; ++x) {
+ QScriptValue ret = eng.evaluate("a = 10;\nb = 20;\n0 = 0;\n",
+ QString::fromLatin1("FooScript") + QString::number(x),
+ /* lineNumber */ x);
+ QVERIFY(eng.hasUncaughtException());
+ QCOMPARE(eng.uncaughtExceptionLineNumber(), x + 2);
+ QVERIFY(eng.uncaughtException().strictlyEquals(ret));
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(eng.uncaughtException().strictlyEquals(ret));
+ QString backtrace = QString::fromLatin1("<anonymous>()@FooScript") + QString::number(x) + ":" + QString::number(x + 2);
+ QCOMPARE(eng.uncaughtExceptionBacktrace().join(""), backtrace);
+ QVERIFY(fun.call().isNull());
+ QVERIFY(eng.hasUncaughtException());
+ QCOMPARE(eng.uncaughtExceptionLineNumber(), x + 2);
+ QVERIFY(eng.uncaughtException().strictlyEquals(ret));
+ eng.clearExceptions();
+ QVERIFY(!eng.hasUncaughtException());
+ QCOMPARE(eng.uncaughtExceptionLineNumber(), -1);
+ QVERIFY(!eng.uncaughtException().isValid());
+ eng.evaluate("2 = 3");
+ QVERIFY(eng.hasUncaughtException());
+ QScriptValue ret2 = throwFun.call();
+ QVERIFY(ret2.isError());
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(eng.uncaughtException().strictlyEquals(ret2));
+ QCOMPARE(eng.uncaughtExceptionLineNumber(), 1);
+ eng.clearExceptions();
+ QVERIFY(!eng.hasUncaughtException());
+ eng.evaluate("1 + 2");
+ QVERIFY(!eng.hasUncaughtException());
+ }
+}
+
QTEST_MAIN(tst_QScriptEngine)
#include "tst_qscriptengine.moc"
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
index 27d6df2..2a2a6b1 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
@@ -580,4 +580,17 @@ void tst_QScriptValue::toObjectSimple()
}
}
+void tst_QScriptValue::propertySimple()
+{
+ QScriptEngine eng;
+
+ QScriptValue simpleObject(eng.evaluate("new Object({ test: 1, other: 2 })"));
+ QCOMPARE(simpleObject.property("test").toUInt32(), quint32(1));
+ QCOMPARE(simpleObject.property("other").toUInt32(), quint32(2));
+
+ QScriptValue simpleArray(eng.evaluate("new Array(7, 8, 9)"));
+ QCOMPARE(simpleArray.property("length").toUInt32(), quint32(3));
+ QCOMPARE(simpleArray.property(2).toUInt32(), quint32(9));
+}
+
QTEST_MAIN(tst_QScriptValue)
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
index f9fcedb..af600a6 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
@@ -51,6 +51,7 @@ private slots:
void call();
void ctor();
void toObjectSimple();
+ void propertySimple();
// Generated test functions.
void isBool_data();